-rw-r--r-- | library/backend/categories.cpp | 327 | ||||
-rw-r--r-- | library/backend/contact.cpp | 526 | ||||
-rw-r--r-- | library/backend/contact.h | 102 | ||||
-rw-r--r-- | library/backend/event.cpp | 539 | ||||
-rw-r--r-- | library/backend/event.h | 173 | ||||
-rw-r--r-- | library/backend/palmtoprecord.cpp | 42 | ||||
-rw-r--r-- | library/backend/palmtoprecord.h | 33 | ||||
-rw-r--r-- | library/backend/palmtopuidgen.h | 26 | ||||
-rw-r--r-- | library/backend/qfiledirect_p.h | 72 | ||||
-rw-r--r-- | library/backend/qpcglobal.h | 9 | ||||
-rw-r--r-- | library/backend/recordfields.h | 24 | ||||
-rw-r--r-- | library/backend/stringutil.cpp | 415 | ||||
-rw-r--r-- | library/backend/stringutil.h | 57 | ||||
-rw-r--r-- | library/backend/task.cpp | 173 | ||||
-rw-r--r-- | library/backend/task.h | 21 | ||||
-rw-r--r-- | library/backend/timeconversion.cpp | 237 | ||||
-rw-r--r-- | library/backend/timeconversion.h | 45 | ||||
-rw-r--r-- | library/backend/vcc.y | 2407 | ||||
-rw-r--r-- | library/backend/vcc_yacc.cpp | 169 | ||||
-rw-r--r-- | library/backend/vobject.cpp | 2534 | ||||
-rw-r--r-- | library/backend/vobject_p.h | 810 |
21 files changed, 4871 insertions, 3870 deletions
diff --git a/library/backend/categories.cpp b/library/backend/categories.cpp index 6e011c4..e37b3b9 100644 --- a/library/backend/categories.cpp +++ b/library/backend/categories.cpp | |||
@@ -1,677 +1,936 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. |
3 | ** | 3 | ** |
4 | ** This file is part of Qtopia Environment. | 4 | ** This file is part of the Qtopia Environment. |
5 | ** | 5 | ** |
6 | ** This file may be distributed and/or modified under the terms of the | 6 | ** This file may be distributed and/or modified under the terms of the |
7 | ** GNU General Public License version 2 as published by the Free | 7 | ** GNU General Public License version 2 as published by the Free Software |
8 | ** Software Foundation and appearing in the file LICENSE.GPL included | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** in the packaging of this file. | 9 | ** packaging of this file. |
10 | ** | 10 | ** |
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING | 11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
12 | ** THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
13 | ** PARTICULAR PURPOSE. | ||
14 | ** | 13 | ** |
15 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
16 | ** | 15 | ** |
17 | ** Contact info@trolltech.com if any conditions of this licensing are | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
18 | ** not clear to you. | 17 | ** not clear to you. |
19 | ** | 18 | ** |
20 | **********************************************************************/ | 19 | **********************************************************************/ |
21 | #include "categories.h" | 20 | #include <qtopia/categories.h> |
21 | #include <qtopia/stringutil.h> | ||
22 | #include <qfile.h> | 22 | #include <qfile.h> |
23 | #include <qcstring.h> | 23 | #include <qcstring.h> |
24 | #include <qtextstream.h> | 24 | #include <qtextstream.h> |
25 | #include "stringutil.h" | ||
26 | 25 | ||
27 | using namespace Qtopia; | 26 | using namespace Qtopia; |
28 | 27 | ||
29 | /*********************************************************** | 28 | /*********************************************************** |
30 | * | 29 | * |
31 | * CategoryGroup | 30 | * CategoryGroup |
32 | * | 31 | * |
33 | **********************************************************/ | 32 | **********************************************************/ |
34 | 33 | ||
35 | #ifdef PALMTOPCENTER | 34 | #ifdef PALMTOPCENTER |
36 | UidGen CategoryGroup::sUidGen( UidGen::PalmtopCenter ); | 35 | UidGen CategoryGroup::sUidGen( UidGen::PalmtopCenter ); |
37 | #else | 36 | #else |
38 | UidGen CategoryGroup::sUidGen( UidGen::Qtopia ); | 37 | UidGen CategoryGroup::sUidGen( UidGen::Qtopia ); |
39 | #endif | 38 | #endif |
40 | 39 | ||
40 | /*! \class CategoryGroup categories.h | ||
41 | \brief Helper class that is used by Categories | ||
42 | |||
43 | CategoryGroup is a group of categories that is associated with an | ||
44 | application or global set. Mainly it defines a map of ids to | ||
45 | category labels and category labels to ids. Lookups can be done with | ||
46 | labels or unique idenifiers. | ||
47 | |||
48 | \ingroup qtopiaemb | ||
49 | \ingroup qtopiadesktop | ||
50 | \warning Categories API will likely change between Qtopia 1.5 and Qtopia 3 | ||
51 | \sa Categories::appGroupMap(), Categories::globalGroup() | ||
52 | */ | ||
53 | |||
54 | /*! Add \a label and return the UID. If failure, then 0 is returned. Note | ||
55 | that All and Unfiled are reserved labels. | ||
56 | \internal | ||
57 | */ | ||
41 | int CategoryGroup::add( const QString &label ) | 58 | int CategoryGroup::add( const QString &label ) |
42 | { | 59 | { |
43 | if ( label == QObject::tr("All") || label == QObject::tr("Unfiled") ) | 60 | if ( label == QObject::tr("All") || label == QObject::tr("Unfiled") ) |
44 | return 0; | 61 | return 0; |
45 | 62 | ||
46 | QMap<QString,int>::Iterator findIt = mLabelIdMap.find( label ); | 63 | QMap<QString,int>::Iterator findIt = mLabelIdMap.find( label ); |
47 | if ( findIt != mLabelIdMap.end() ) | 64 | if ( findIt != mLabelIdMap.end() ) |
48 | return 0; | 65 | return 0; |
49 | int newUid = uidGen().generate(); | 66 | int newUid = uidGen().generate(); |
50 | insert( newUid, label ); | 67 | insert( newUid, label ); |
51 | return newUid; | 68 | return newUid; |
52 | } | 69 | } |
53 | 70 | ||
54 | void CategoryGroup::insert( int uid, const QString &label ) | 71 | void CategoryGroup::insert( int uid, const QString &label ) |
55 | { | 72 | { |
56 | uidGen().store( uid ); | 73 | uidGen().store( uid ); |
57 | mIdLabelMap[uid] = label; | 74 | mIdLabelMap[uid] = label; |
58 | mLabelIdMap[label] = uid; | 75 | mLabelIdMap[label] = uid; |
59 | } | 76 | } |
60 | 77 | ||
78 | /*! \internal | ||
79 | */ | ||
61 | bool CategoryGroup::add( int uid, const QString &label ) | 80 | bool CategoryGroup::add( int uid, const QString &label ) |
62 | { | 81 | { |
63 | if ( label == QObject::tr("All") || label == QObject::tr("Unfiled") ) | 82 | if ( label == QObject::tr("All") || label == QObject::tr("Unfiled") ) |
64 | return FALSE; | 83 | return FALSE; |
65 | 84 | ||
66 | QMap<QString,int>::ConstIterator labelIt = mLabelIdMap.find( label ); | 85 | QMap<QString,int>::ConstIterator labelIt = mLabelIdMap.find( label ); |
67 | if ( labelIt != mLabelIdMap.end() ) | 86 | if ( labelIt != mLabelIdMap.end() ) |
68 | return FALSE; | 87 | return FALSE; |
69 | QMap<int,QString>::ConstIterator idIt = mIdLabelMap.find( uid ); | 88 | QMap<int,QString>::ConstIterator idIt = mIdLabelMap.find( uid ); |
70 | if ( idIt != mIdLabelMap.end() ) | 89 | if ( idIt != mIdLabelMap.end() ) |
71 | return FALSE; | 90 | return FALSE; |
72 | insert( uid, label ); | 91 | insert( uid, label ); |
73 | return TRUE; | 92 | return TRUE; |
74 | } | 93 | } |
75 | 94 | ||
95 | /*! Returns TRUE if \a label was removed from the group, FALSE if not. | ||
96 | \internal | ||
97 | */ | ||
76 | bool CategoryGroup::remove( const QString &label ) | 98 | bool CategoryGroup::remove( const QString &label ) |
77 | { | 99 | { |
78 | QMap<QString,int>::Iterator findIt = mLabelIdMap.find( label ); | 100 | QMap<QString,int>::Iterator findIt = mLabelIdMap.find( label ); |
79 | if ( findIt == mLabelIdMap.end() ) | 101 | if ( findIt == mLabelIdMap.end() ) |
80 | return FALSE; | 102 | return FALSE; |
81 | 103 | ||
82 | mIdLabelMap.remove( *findIt ); | 104 | mIdLabelMap.remove( *findIt ); |
83 | mLabelIdMap.remove( findIt ); | 105 | mLabelIdMap.remove( findIt ); |
84 | 106 | ||
85 | return TRUE; | 107 | return TRUE; |
86 | } | 108 | } |
87 | 109 | ||
110 | /*! Returns TRUE if \a uid was removed from the group, FALSE if not. | ||
111 | \internal | ||
112 | */ | ||
88 | bool CategoryGroup::remove( int uid ) | 113 | bool CategoryGroup::remove( int uid ) |
89 | { | 114 | { |
90 | QMap<int,QString>::Iterator idIt = mIdLabelMap.find( uid ); | 115 | QMap<int,QString>::Iterator idIt = mIdLabelMap.find( uid ); |
91 | if ( idIt == mIdLabelMap.end() ) | 116 | if ( idIt == mIdLabelMap.end() ) |
92 | return FALSE; | 117 | return FALSE; |
93 | 118 | ||
94 | mLabelIdMap.remove( *idIt ); | 119 | mLabelIdMap.remove( *idIt ); |
95 | mIdLabelMap.remove( idIt ); | 120 | mIdLabelMap.remove( idIt ); |
96 | 121 | ||
97 | return TRUE; | 122 | return TRUE; |
98 | } | 123 | } |
99 | 124 | ||
125 | /*! \internal | ||
126 | */ | ||
100 | bool CategoryGroup::rename( int uid, const QString &newLabel ) | 127 | bool CategoryGroup::rename( int uid, const QString &newLabel ) |
101 | { | 128 | { |
102 | if ( newLabel == QObject::tr("All") || newLabel == QObject::tr("Unfiled") ) | 129 | if ( newLabel == QObject::tr("All") || newLabel == QObject::tr("Unfiled") ) |
103 | return FALSE; | 130 | return FALSE; |
104 | 131 | ||
105 | QMap<int, QString>::Iterator idIt = mIdLabelMap.find( uid ); | 132 | QMap<int, QString>::Iterator idIt = mIdLabelMap.find( uid ); |
106 | if ( idIt == mIdLabelMap.end() ) | 133 | if ( idIt == mIdLabelMap.end() ) |
107 | return FALSE; | 134 | return FALSE; |
108 | 135 | ||
109 | mLabelIdMap.remove( *idIt ); | 136 | mLabelIdMap.remove( *idIt ); |
110 | mLabelIdMap[newLabel] = uid; | 137 | mLabelIdMap[newLabel] = uid; |
111 | *idIt = newLabel; | 138 | *idIt = newLabel; |
112 | 139 | ||
113 | return TRUE; | 140 | return TRUE; |
114 | } | 141 | } |
115 | 142 | ||
143 | /*! \internal | ||
144 | */ | ||
116 | bool CategoryGroup::rename( const QString &oldLabel, const QString &newLabel ) | 145 | bool CategoryGroup::rename( const QString &oldLabel, const QString &newLabel ) |
117 | { | 146 | { |
118 | return rename( id(oldLabel), newLabel ); | 147 | return rename( id(oldLabel), newLabel ); |
119 | } | 148 | } |
120 | 149 | ||
150 | /*! Returns TRUE if \a uid is stored in this group, FALSE if not. */ | ||
121 | bool CategoryGroup::contains(int uid) const | 151 | bool CategoryGroup::contains(int uid) const |
122 | { | 152 | { |
123 | return ( mIdLabelMap.find( uid ) != mIdLabelMap.end() ); | 153 | return ( mIdLabelMap.find( uid ) != mIdLabelMap.end() ); |
124 | } | 154 | } |
125 | 155 | ||
156 | /*! Returns TRUE if \a label is stored in this group, FALSE if not. */ | ||
126 | bool CategoryGroup::contains(const QString &label) const | 157 | bool CategoryGroup::contains(const QString &label) const |
127 | { | 158 | { |
128 | return ( mLabelIdMap.find( label ) != mLabelIdMap.end() ); | 159 | return ( mLabelIdMap.find( label ) != mLabelIdMap.end() ); |
129 | } | 160 | } |
130 | 161 | ||
131 | /** Returns label associated with the uid or QString::null if | 162 | /*! Returns label associated with the \a uid or QString::null if |
132 | * not found | 163 | not found |
133 | */ | 164 | */ |
134 | const QString &CategoryGroup::label(int uid) const | 165 | const QString &CategoryGroup::label(int uid) const |
135 | { | 166 | { |
136 | QMap<int,QString>::ConstIterator idIt = mIdLabelMap.find( uid ); | 167 | QMap<int,QString>::ConstIterator idIt = mIdLabelMap.find( uid ); |
137 | if ( idIt == mIdLabelMap.end() ) | 168 | if ( idIt == mIdLabelMap.end() ) |
138 | return QString::null; | 169 | return QString::null; |
139 | return *idIt; | 170 | return *idIt; |
140 | } | 171 | } |
141 | 172 | ||
142 | /** Returns the uid associated with label or 0 if not found */ | 173 | /*! Returns the uid associated with \a label or 0 if not found */ |
143 | int CategoryGroup::id(const QString &label) const | 174 | int CategoryGroup::id(const QString &label) const |
144 | { | 175 | { |
145 | QMap<QString,int>::ConstIterator labelIt = mLabelIdMap.find( label ); | 176 | QMap<QString,int>::ConstIterator labelIt = mLabelIdMap.find( label ); |
146 | if ( labelIt == mLabelIdMap.end() ) | 177 | if ( labelIt == mLabelIdMap.end() ) |
147 | return 0; | 178 | return 0; |
148 | return *labelIt; | 179 | return *labelIt; |
149 | } | 180 | } |
150 | 181 | ||
182 | /*! Returns a list of all labels stored in this group. */ | ||
151 | QStringList CategoryGroup::labels() const | 183 | QStringList CategoryGroup::labels() const |
152 | { | 184 | { |
153 | QStringList labels; | 185 | QStringList labels; |
154 | for ( QMap<int, QString>::ConstIterator it = mIdLabelMap.begin(); | 186 | for ( QMap<int, QString>::ConstIterator it = mIdLabelMap.begin(); |
155 | it != mIdLabelMap.end(); ++it ) | 187 | it != mIdLabelMap.end(); ++it ) |
156 | labels += *it; | 188 | labels += *it; |
157 | // ### I don't think this is the place for this... | 189 | // ### I don't think this is the place for this... |
158 | // labels.sort(); | 190 | // labels.sort(); |
159 | return labels; | 191 | return labels; |
160 | } | 192 | } |
161 | 193 | ||
194 | /*! Returns a list of all labels associated with the \a catids */ | ||
162 | QStringList CategoryGroup::labels(const QArray<int> &catids ) const | 195 | QStringList CategoryGroup::labels(const QArray<int> &catids ) const |
163 | { | 196 | { |
164 | QStringList labels; | 197 | QStringList labels; |
165 | if ( catids.count() == 0 ) | 198 | if ( catids.count() == 0 ) |
166 | return labels; | 199 | return labels; |
167 | for ( QMap<int, QString>::ConstIterator it = mIdLabelMap.begin(); | 200 | for ( QMap<int, QString>::ConstIterator it = mIdLabelMap.begin(); |
168 | it != mIdLabelMap.end(); ++it ) | 201 | it != mIdLabelMap.end(); ++it ) |
169 | if ( catids.find( it.key() ) != -1 ) | 202 | if ( catids.find( it.key() ) != -1 ) |
170 | labels += *it; | 203 | labels += *it; |
171 | return labels; | 204 | return labels; |
172 | } | 205 | } |
173 | 206 | ||
174 | /*********************************************************** | 207 | /*********************************************************** |
175 | * | 208 | * |
176 | * Categories | 209 | * Categories |
177 | * | 210 | * |
178 | **********************************************************/ | 211 | **********************************************************/ |
179 | 212 | ||
180 | /** Add the category name as long as it doesn't already exist locally | 213 | /*! |
181 | * or globally. Return TRUE if added, FALSE if conflicts. | 214 | \class Categories categories.h |
182 | */ | 215 | \brief The Categories class is a database that groups categories and maps ids to names. |
216 | |||
217 | The Categories class is the low level Categories accessor class. To | ||
218 | add a category menu and filter for your application, see CategoryMenu. | ||
219 | |||
220 | The Categories class allows the developer to add, remove, and rename | ||
221 | categories. Categories can be created for an individual application | ||
222 | such as Todo List or to be used for all applications. Categories | ||
223 | that can be used by all applications are called global | ||
224 | categories. Each PalmtopRecord subclass stores categories as an | ||
225 | QArray<int> using PalmtopRecord::setCategories() and | ||
226 | PalmtopRecord::categories(). This allows each record to be assigned | ||
227 | to multiple categories. This also allows the user to rename a | ||
228 | category and for it to update automatically in all records. | ||
229 | |||
230 | This class provides several methods to convert between a category id | ||
231 | and it's associated string such as id(), ids(), label() and labels(). A | ||
232 | helper class called CategoryGroup is used to access categories of a | ||
233 | single application group, such as Todo List. Global categories can | ||
234 | also be accessed via CategoryGroup objects. See appGroupMap() and | ||
235 | globalGroup() for the appropriate accessor methods. | ||
236 | |||
237 | Categories are stored in an xml file in the Settings directory | ||
238 | (Categories.xml). A global function called categoryFileName() will | ||
239 | return to appropriate QString file location to be passed to load() | ||
240 | and save() for the master categories database. | ||
241 | |||
242 | \ingroup qtopiaemb | ||
243 | \ingroup qtopiadesktop | ||
244 | \warning Categories API will likely change between Qtopia 1.5 and Qtopia 3 | ||
245 | \sa CategoryGroup, CategoryMenu | ||
246 | */ | ||
247 | |||
248 | |||
249 | /*! | ||
250 | Add the category name as long as it doesn't already exist locally or | ||
251 | globally. The \a uid is assigned to the category if successfully | ||
252 | added. Return \a uid if added, 0 if conflicts (error). | ||
253 | |||
254 | \internal | ||
255 | */ | ||
183 | int Categories::addCategory( const QString &appname, | 256 | int Categories::addCategory( const QString &appname, |
184 | const QString &catname, | 257 | const QString &catname, |
185 | int uid ) | 258 | int uid ) |
186 | { | 259 | { |
187 | if ( mGlobalCats.contains(catname) ) | 260 | if ( mGlobalCats.contains(catname) ) |
188 | return 0; | 261 | return 0; |
189 | 262 | ||
190 | QMap< QString, CategoryGroup >::Iterator | 263 | QMap< QString, CategoryGroup >::Iterator |
191 | appIt = mAppCats.find( appname ); | 264 | appIt = mAppCats.find( appname ); |
192 | 265 | ||
193 | if ( appIt == mAppCats.end() ) { | 266 | if ( appIt == mAppCats.end() ) { |
194 | CategoryGroup newgroup; | 267 | CategoryGroup newgroup; |
195 | newgroup.add( uid, catname ); | 268 | newgroup.add( uid, catname ); |
196 | mAppCats.insert( appname, newgroup ); | 269 | mAppCats.insert( appname, newgroup ); |
197 | emit categoryAdded( *this, appname, uid ); | 270 | emit categoryAdded( *this, appname, uid ); |
198 | return uid; | 271 | return uid; |
199 | } | 272 | } |
200 | 273 | ||
201 | CategoryGroup &cats = *appIt; | 274 | CategoryGroup &cats = *appIt; |
202 | cats.add( uid, catname ); | 275 | cats.add( uid, catname ); |
203 | emit categoryAdded( *this, appname, uid ); | 276 | emit categoryAdded( *this, appname, uid ); |
204 | return uid; | 277 | return uid; |
205 | } | 278 | } |
206 | 279 | ||
280 | /*! | ||
281 | Add the category name as long as it doesn't already exist locally or | ||
282 | globally. Return UID if added, 0 if conflicts (error). | ||
283 | */ | ||
284 | |||
207 | int Categories::addCategory( const QString &appname, | 285 | int Categories::addCategory( const QString &appname, |
208 | const QString &catname ) | 286 | const QString &catname ) |
209 | { | 287 | { |
210 | if ( mGlobalCats.contains(catname) ) | 288 | if ( mGlobalCats.contains(catname) ) |
211 | return 0; | 289 | return 0; |
212 | 290 | ||
213 | QMap< QString, CategoryGroup >::Iterator | 291 | QMap< QString, CategoryGroup >::Iterator |
214 | appIt = mAppCats.find( appname ); | 292 | appIt = mAppCats.find( appname ); |
215 | 293 | ||
216 | if ( appIt == mAppCats.end() ) { | 294 | if ( appIt == mAppCats.end() ) { |
217 | CategoryGroup newgroup; | 295 | CategoryGroup newgroup; |
218 | int uid = newgroup.add( catname ); | 296 | int uid = newgroup.add( catname ); |
219 | mAppCats.insert( appname, newgroup ); | 297 | mAppCats.insert( appname, newgroup ); |
220 | emit categoryAdded( *this, appname, uid ); | 298 | emit categoryAdded( *this, appname, uid ); |
221 | return uid; | 299 | return uid; |
222 | } | 300 | } |
223 | 301 | ||
224 | CategoryGroup &cats = *appIt; | 302 | CategoryGroup &cats = *appIt; |
225 | int uid = cats.add( catname ); | 303 | int uid = cats.add( catname ); |
226 | if ( !uid ) | 304 | if ( !uid ) |
227 | return 0; | 305 | return 0; |
228 | emit categoryAdded( *this, appname, uid ); | 306 | emit categoryAdded( *this, appname, uid ); |
229 | return uid; | 307 | return uid; |
230 | } | 308 | } |
231 | 309 | ||
310 | /*! | ||
311 | \internal | ||
312 | */ | ||
232 | int Categories::addGlobalCategory( const QString &catname, int uid ) | 313 | int Categories::addGlobalCategory( const QString &catname, int uid ) |
233 | { | 314 | { |
234 | mGlobalCats.add( uid, catname ); | 315 | mGlobalCats.add( uid, catname ); |
235 | emit categoryAdded( *this, QString::null, uid ); | 316 | emit categoryAdded( *this, QString::null, uid ); |
236 | return uid; | 317 | return uid; |
237 | } | 318 | } |
238 | 319 | ||
320 | /*! | ||
321 | Add the global category \a catname while checking that it doesn't | ||
322 | already exist globally. Return UID if added, 0 if conflicts. | ||
323 | |||
324 | \sa addCategory() | ||
325 | */ | ||
239 | int Categories::addGlobalCategory( const QString &catname ) | 326 | int Categories::addGlobalCategory( const QString &catname ) |
240 | { | 327 | { |
241 | int uid = mGlobalCats.add( catname ); | 328 | int uid = mGlobalCats.add( catname ); |
242 | if ( !uid ) | 329 | if ( !uid ) |
243 | return 0; | 330 | return 0; |
244 | emit categoryAdded( *this, QString::null, uid ); | 331 | emit categoryAdded( *this, QString::null, uid ); |
245 | return uid; | 332 | return uid; |
246 | } | 333 | } |
247 | 334 | ||
248 | /** Removes the category from the application; if it is not found | 335 | /*! |
249 | * in the application, then it attempts to remove it from | 336 | |
250 | * the global list | 337 | Removes the \a catname from the application group. If it is not |
251 | */ | 338 | found in the application group and \a checkGlobal is TRUE, then it |
339 | attempts to remove it from the global list | ||
340 | */ | ||
252 | bool Categories::removeCategory( const QString &appname, | 341 | bool Categories::removeCategory( const QString &appname, |
253 | const QString &catname, | 342 | const QString &catname, |
254 | bool checkGlobal ) | 343 | bool checkGlobal ) |
255 | { | 344 | { |
256 | QMap< QString, CategoryGroup >::Iterator | 345 | QMap< QString, CategoryGroup >::Iterator |
257 | appIt = mAppCats.find( appname ); | 346 | appIt = mAppCats.find( appname ); |
258 | if ( appIt != mAppCats.end() ) { | 347 | if ( appIt != mAppCats.end() ) { |
259 | CategoryGroup &cats = *appIt; | 348 | CategoryGroup &cats = *appIt; |
260 | int uid = cats.id( catname ); | 349 | int uid = cats.id( catname ); |
261 | if ( cats.remove( uid ) ) { | 350 | if ( cats.remove( uid ) ) { |
262 | emit categoryRemoved( *this, appname, uid ); | 351 | emit categoryRemoved( *this, appname, uid ); |
263 | return TRUE; | 352 | return TRUE; |
264 | } | 353 | } |
265 | } | 354 | } |
266 | if ( !checkGlobal ) | 355 | if ( !checkGlobal ) |
267 | return FALSE; | 356 | return FALSE; |
268 | return removeGlobalCategory( catname ); | 357 | return removeGlobalCategory( catname ); |
269 | } | 358 | } |
270 | 359 | ||
360 | |||
361 | /*! | ||
362 | Removes the \a uid from the application group \a appname. Returns TRUE | ||
363 | if success, FALSE if not found. | ||
364 | */ | ||
271 | bool Categories::removeCategory( const QString &appname, int uid ) | 365 | bool Categories::removeCategory( const QString &appname, int uid ) |
272 | { | 366 | { |
273 | QMap< QString, CategoryGroup >::Iterator | 367 | QMap< QString, CategoryGroup >::Iterator |
274 | appIt = mAppCats.find( appname ); | 368 | appIt = mAppCats.find( appname ); |
275 | if ( appIt != mAppCats.end() ) { | 369 | if ( appIt != mAppCats.end() ) { |
276 | CategoryGroup &cats = *appIt; | 370 | CategoryGroup &cats = *appIt; |
277 | if ( cats.remove( uid ) ) { | 371 | if ( cats.remove( uid ) ) { |
278 | emit categoryRemoved( *this, appname, uid ); | 372 | emit categoryRemoved( *this, appname, uid ); |
279 | return TRUE; | 373 | return TRUE; |
280 | } | 374 | } |
281 | } | 375 | } |
282 | return FALSE; | 376 | return FALSE; |
283 | } | 377 | } |
284 | 378 | ||
379 | /*! | ||
380 | Removes the global category \a catname. Returns TRUE | ||
381 | if success, FALSE if not found. | ||
382 | */ | ||
285 | bool Categories::removeGlobalCategory( const QString &catname ) | 383 | bool Categories::removeGlobalCategory( const QString &catname ) |
286 | { | 384 | { |
287 | int uid = mGlobalCats.id( catname ); | 385 | int uid = mGlobalCats.id( catname ); |
288 | if ( mGlobalCats.remove( uid ) ) { | 386 | if ( mGlobalCats.remove( uid ) ) { |
289 | emit categoryRemoved( *this, QString::null, uid ); | 387 | emit categoryRemoved( *this, QString::null, uid ); |
290 | return TRUE; | 388 | return TRUE; |
291 | } | 389 | } |
292 | return FALSE; | 390 | return FALSE; |
293 | } | 391 | } |
294 | 392 | ||
295 | 393 | /*! | |
394 | Removes the global category \a uid. Returns TRUE | ||
395 | if success, FALSE if not found. | ||
396 | */ | ||
296 | bool Categories::removeGlobalCategory( int uid ) | 397 | bool Categories::removeGlobalCategory( int uid ) |
297 | { | 398 | { |
298 | if ( mGlobalCats.remove( uid ) ) { | 399 | if ( mGlobalCats.remove( uid ) ) { |
299 | emit categoryRemoved( *this, QString::null, uid ); | 400 | emit categoryRemoved( *this, QString::null, uid ); |
300 | return TRUE; | 401 | return TRUE; |
301 | } | 402 | } |
302 | return FALSE; | 403 | return FALSE; |
303 | } | 404 | } |
304 | 405 | ||
305 | /** Returns the sorted list of all categories that are associated with | 406 | /*! |
306 | * the app. If includeGlobal parameter is TRUE then the returned | 407 | Returns the sorted list of all categories that are associated with |
307 | * categories will include the global category items. | 408 | the \a app. If \a includeGlobal is TRUE then the returned |
409 | categories will include the global category items. | ||
308 | */ | 410 | */ |
309 | QStringList Categories::labels( const QString &app, | 411 | QStringList Categories::labels( const QString &app, |
310 | bool includeGlobal, | 412 | bool includeGlobal, |
311 | ExtraLabels extra ) const | 413 | ExtraLabels extra ) const |
312 | { | 414 | { |
313 | QMap< QString, CategoryGroup >::ConstIterator | 415 | QMap< QString, CategoryGroup >::ConstIterator |
314 | appIt = mAppCats.find( app ); | 416 | appIt = mAppCats.find( app ); |
315 | QStringList cats; | 417 | QStringList cats; |
316 | 418 | ||
317 | if ( appIt != mAppCats.end() ) | 419 | if ( appIt != mAppCats.end() ) |
318 | cats += (*appIt).labels(); | 420 | cats += (*appIt).labels(); |
319 | else qDebug("Categories::labels didn't find app %s", app.latin1() ); | 421 | //else qDebug("Categories::labels didn't find app %s", app.latin1() ); |
320 | if ( includeGlobal ) | 422 | if ( includeGlobal ) |
321 | cats += mGlobalCats.labels(); | 423 | cats += mGlobalCats.labels(); |
322 | 424 | ||
323 | cats.sort(); | 425 | cats.sort(); |
324 | switch ( extra ) { | 426 | switch ( extra ) { |
325 | case NoExtra: break; | 427 | case NoExtra: break; |
326 | case AllUnfiled: | 428 | case AllUnfiled: |
327 | cats.append( tr("All") ); | 429 | cats.append( tr("All") ); |
328 | cats.append( tr("Unfiled") ); | 430 | cats.append( tr("Unfiled") ); |
329 | break; | 431 | break; |
330 | case AllLabel: | 432 | case AllLabel: |
331 | cats.append( tr("All") ); | 433 | cats.append( tr("All") ); |
332 | break; | 434 | break; |
333 | case UnfiledLabel: | 435 | case UnfiledLabel: |
334 | cats.append( tr("Unfiled") ); | 436 | cats.append( tr("Unfiled") ); |
335 | break; | 437 | break; |
336 | } | 438 | } |
337 | 439 | ||
338 | return cats; | 440 | return cats; |
339 | } | 441 | } |
340 | 442 | ||
443 | /*! | ||
444 | Returns the label associated with the id | ||
445 | */ | ||
341 | QString Categories::label( const QString &app, int id ) const | 446 | QString Categories::label( const QString &app, int id ) const |
342 | { | 447 | { |
343 | if ( mGlobalCats.contains( id ) ) | 448 | if ( mGlobalCats.contains( id ) ) |
344 | return mGlobalCats.label( id ); | 449 | return mGlobalCats.label( id ); |
345 | QMap< QString, CategoryGroup >::ConstIterator | 450 | QMap< QString, CategoryGroup >::ConstIterator |
346 | appIt = mAppCats.find( app ); | 451 | appIt = mAppCats.find( app ); |
347 | if ( appIt == mAppCats.end() ) | 452 | if ( appIt == mAppCats.end() ) |
348 | return QString::null; | 453 | return QString::null; |
349 | return (*appIt).label( id ); | 454 | return (*appIt).label( id ); |
350 | } | 455 | } |
351 | 456 | ||
352 | /** Returns a single string associated with the cat ids for display in | 457 | /*! |
353 | * a combobox or any area that requires one string. If catids are empty | 458 | Returns a single string associated with \a catids for display in a |
354 | * then "Unfiled" will be returned. If multiple categories are assigned | 459 | combobox or any area that requires one string. If \a catids are empty |
355 | * the first cat id is shown with " (multi)" appended to the string. | 460 | then "Unfiled" will be returned. If multiple categories are |
356 | */ | 461 | assigned then the behavior depends on the DisplaySingle type. |
462 | |||
463 | If \a display is set to ShowMulti then " (multi)" appended to the | ||
464 | first string. If \a display is set to ShowAll, then a space | ||
465 | seperated string is returned with all categories. If ShowFirst is | ||
466 | set, the just the first string is returned. | ||
467 | */ | ||
357 | QString Categories::displaySingle( const QString &app, | 468 | QString Categories::displaySingle( const QString &app, |
358 | const QArray<int> &catids, | 469 | const QArray<int> &catids, |
359 | DisplaySingle display ) const | 470 | DisplaySingle display ) const |
360 | { | 471 | { |
361 | QStringList strs = labels( app, catids ); | 472 | QStringList strs = labels( app, catids ); |
362 | if ( !strs.count() ) | 473 | if ( !strs.count() ) |
363 | return tr("Unfiled"); | 474 | return tr("Unfiled"); |
364 | strs.sort(); | 475 | strs.sort(); |
365 | QString r; | 476 | QString r; |
366 | if ( strs.count() > 1 ) { | 477 | if ( strs.count() > 1 ) { |
367 | switch ( display ) { | 478 | switch ( display ) { |
368 | case ShowFirst: | 479 | case ShowFirst: |
369 | r = strs.first(); | 480 | r = strs.first(); |
370 | break; | 481 | break; |
371 | case ShowMulti: | 482 | case ShowMulti: |
372 | r = strs.first() + tr(" (multi.)"); | 483 | r = strs.first() + tr(" (multi.)"); |
373 | break; | 484 | break; |
374 | case ShowAll: | 485 | case ShowAll: |
375 | r = strs.join(" "); | 486 | r = strs.join(" "); |
376 | break; | 487 | break; |
377 | } | 488 | } |
378 | } | 489 | } |
379 | else r = strs.first(); | 490 | else r = strs.first(); |
380 | return r; | 491 | return r; |
381 | } | 492 | } |
382 | 493 | ||
494 | /*! | ||
495 | |||
496 | Returns all ids associated with the application CategoryGroup \a app | ||
497 | and the passed in \a labels in that group. | ||
498 | */ | ||
383 | QArray<int> Categories::ids( const QString &app, const QStringList &labels) const | 499 | QArray<int> Categories::ids( const QString &app, const QStringList &labels) const |
384 | { | 500 | { |
385 | QArray<int> results; | 501 | QArray<int> results; |
386 | QStringList::ConstIterator it; | 502 | QStringList::ConstIterator it; |
387 | int i; | 503 | int i; |
388 | 504 | ||
389 | for ( i=0, it=labels.begin(); it!=labels.end(); i++, ++it ) { | 505 | for ( i=0, it=labels.begin(); it!=labels.end(); i++, ++it ) { |
390 | int value = id( app, *it ); | 506 | int value = id( app, *it ); |
391 | if ( value != 0 ) { | 507 | if ( value != 0 ) { |
392 | int tmp = results.size(); | 508 | int tmp = results.size(); |
393 | results.resize( tmp + 1 ); | 509 | results.resize( tmp + 1 ); |
394 | results[ tmp ] = value; | 510 | results[ tmp ] = value; |
395 | } | 511 | } |
396 | } | 512 | } |
397 | return results; | 513 | return results; |
398 | } | 514 | } |
399 | 515 | ||
516 | /*! | ||
517 | Returns the id associated with the app. If the id is not found in the | ||
518 | application CategoryGroup, then it searches the global CategoryGroup. | ||
519 | If it is not found it either, 0 is returned. | ||
520 | */ | ||
400 | int Categories::id( const QString &app, const QString &cat ) const | 521 | int Categories::id( const QString &app, const QString &cat ) const |
401 | { | 522 | { |
402 | if ( cat == tr("Unfiled") || cat.contains( tr(" (multi.)") ) ) | 523 | if ( cat == tr("Unfiled") || cat.contains( tr(" (multi.)") ) ) |
403 | return 0; | 524 | return 0; |
404 | int uid = mGlobalCats.id( cat ); | 525 | int uid = mGlobalCats.id( cat ); |
405 | if ( uid != 0 ) | 526 | if ( uid != 0 ) |
406 | return uid; | 527 | return uid; |
407 | return mAppCats[app].id( cat ); | 528 | return mAppCats[app].id( cat ); |
408 | } | 529 | } |
409 | 530 | ||
410 | 531 | ||
411 | /** Return TRUE if renaming succeeded; FALSE if app name not found, | 532 | /*! |
412 | * or if there was a name conflict | 533 | Return TRUE if renaming succeeded; FALSE if \a appname or \a oldName |
534 | is not found, or if \a newName conflicts with an existing category | ||
535 | in the CategoryGroup. | ||
536 | |||
537 | It will first search the CategoryGroup associated with \a appname | ||
538 | and if not found it will try to replace in global CategoryGroup. | ||
413 | */ | 539 | */ |
414 | bool Categories::renameCategory( const QString &appname, | 540 | bool Categories::renameCategory( const QString &appname, |
415 | const QString &oldName, | 541 | const QString &oldName, |
416 | const QString &newName ) | 542 | const QString &newName ) |
417 | { | 543 | { |
418 | QMap< QString, CategoryGroup >::Iterator | 544 | QMap< QString, CategoryGroup >::Iterator |
419 | appIt = mAppCats.find( appname ); | 545 | appIt = mAppCats.find( appname ); |
420 | 546 | ||
421 | if ( appIt != mAppCats.end() ) { | 547 | if ( appIt != mAppCats.end() ) { |
422 | CategoryGroup &cats = *appIt; | 548 | CategoryGroup &cats = *appIt; |
423 | int id = cats.id( oldName ); | 549 | int id = cats.id( oldName ); |
424 | if ( id != 0 && cats.rename( id, newName ) ) { | 550 | if ( id != 0 && cats.rename( id, newName ) ) { |
425 | emit categoryRenamed( *this, appname, id ); | 551 | emit categoryRenamed( *this, appname, id ); |
426 | return TRUE; | 552 | return TRUE; |
427 | } | 553 | } |
428 | } | 554 | } |
429 | return renameGlobalCategory( oldName, newName ); | 555 | return renameGlobalCategory( oldName, newName ); |
430 | } | 556 | } |
431 | 557 | ||
558 | /*! | ||
559 | Return TRUE if renaming succeeded; FALSE if \a appname or \a oldName | ||
560 | is not found, or if \a newName conflicts with an existing category | ||
561 | in the CategoryGroup. This function will only rename categories found | ||
562 | in the global CategoryGroup. | ||
563 | */ | ||
432 | bool Categories::renameGlobalCategory( const QString &oldName, | 564 | bool Categories::renameGlobalCategory( const QString &oldName, |
433 | const QString &newName ) | 565 | const QString &newName ) |
434 | { | 566 | { |
435 | int uid = mGlobalCats.id( oldName ); | 567 | int uid = mGlobalCats.id( oldName ); |
436 | if ( uid != 0 && mGlobalCats.rename( uid, newName ) ) { | 568 | if ( uid != 0 && mGlobalCats.rename( uid, newName ) ) { |
437 | emit categoryRenamed( *this, QString::null, uid ); | 569 | emit categoryRenamed( *this, QString::null, uid ); |
438 | return TRUE; | 570 | return TRUE; |
439 | } | 571 | } |
440 | return FALSE; | 572 | return FALSE; |
441 | } | 573 | } |
442 | 574 | ||
575 | /*! | ||
576 | Changes the grouping of a category. If a category was global and \a global | ||
577 | is set to TRUE, then the \a catname will be moved to the \a appname group. | ||
578 | */ | ||
443 | void Categories::setGlobal( const QString &appname, | 579 | void Categories::setGlobal( const QString &appname, |
444 | const QString &catname, | 580 | const QString &catname, |
445 | bool global ) | 581 | bool global ) |
446 | { | 582 | { |
447 | // if in global and should be in app; then move it | 583 | // if in global and should be in app; then move it |
448 | if ( mGlobalCats.contains( catname ) && !global ) { | 584 | if ( mGlobalCats.contains( catname ) && !global ) { |
449 | mGlobalCats.remove( catname ); | 585 | mGlobalCats.remove( catname ); |
450 | addCategory( appname, catname ); | 586 | addCategory( appname, catname ); |
451 | return ; | 587 | return ; |
452 | } | 588 | } |
453 | 589 | ||
454 | // if in app and should be in global, then move it | 590 | // if in app and should be in global, then move it |
455 | if ( !global ) | 591 | if ( !global ) |
456 | return; | 592 | return; |
457 | if ( removeCategory( appname, catname, FALSE ) ) | 593 | if ( removeCategory( appname, catname, FALSE ) ) |
458 | addGlobalCategory( catname ); | 594 | addGlobalCategory( catname ); |
459 | } | 595 | } |
460 | 596 | ||
597 | /*! | ||
598 | Returns TRUE if the \a catname is in the global CategoryGroup, FALSE if not. | ||
599 | */ | ||
461 | bool Categories::isGlobal( const QString &catname ) const | 600 | bool Categories::isGlobal( const QString &catname ) const |
462 | { | 601 | { |
463 | return mGlobalCats.contains( catname ); | 602 | return mGlobalCats.contains( catname ); |
464 | } | 603 | } |
465 | 604 | ||
466 | 605 | ||
467 | /** Returns true if the catname is associated with any application | 606 | /*! |
607 | Returns true if the \a catname is associated with any CategoryGroup, | ||
608 | including global. | ||
468 | */ | 609 | */ |
469 | bool Categories::exists( const QString &catname ) const | 610 | bool Categories::exists( const QString &catname ) const |
470 | { | 611 | { |
471 | if ( isGlobal(catname) ) | 612 | if ( isGlobal(catname) ) |
472 | return TRUE; | 613 | return TRUE; |
473 | 614 | ||
474 | for ( QMap<QString, CategoryGroup>::ConstIterator appsIt = mAppCats.begin(); appsIt != mAppCats.end(); ++appsIt ) | 615 | for ( QMap<QString, CategoryGroup>::ConstIterator appsIt = mAppCats.begin(); appsIt != mAppCats.end(); ++appsIt ) |
475 | if ( exists( appsIt.key(), catname ) ) | 616 | if ( exists( appsIt.key(), catname ) ) |
476 | return TRUE; | 617 | return TRUE; |
477 | 618 | ||
478 | return FALSE; | 619 | return FALSE; |
479 | } | 620 | } |
480 | 621 | ||
622 | /*! | ||
623 | Returns TRUE if the \a catname is associated with the \a appname | ||
624 | CategoryGroup, FALSE if not found. | ||
625 | */ | ||
481 | bool Categories::exists( const QString &appname, | 626 | bool Categories::exists( const QString &appname, |
482 | const QString &catname) const | 627 | const QString &catname) const |
483 | { | 628 | { |
484 | QMap< QString, CategoryGroup >::ConstIterator | 629 | QMap< QString, CategoryGroup >::ConstIterator |
485 | appIt = mAppCats.find( appname ); | 630 | appIt = mAppCats.find( appname ); |
486 | 631 | ||
487 | if ( appIt == mAppCats.end() ) | 632 | if ( appIt == mAppCats.end() ) |
488 | return FALSE; | 633 | return FALSE; |
489 | 634 | ||
490 | return (*appIt).contains( catname ); | 635 | return (*appIt).contains( catname ); |
491 | } | 636 | } |
492 | 637 | ||
638 | /*! | ||
639 | Saves the Categories database to the \a fname. See categoryFileName() | ||
640 | for the default file name string used for the shared category database. | ||
493 | 641 | ||
642 | Returns FALSE if there is error writing the file or TRUE on success. | ||
643 | */ | ||
494 | bool Categories::save( const QString &fname ) const | 644 | bool Categories::save( const QString &fname ) const |
495 | { | 645 | { |
496 | QString strNewFile = fname + ".new"; | 646 | QString strNewFile = fname + ".new"; |
497 | QFile f( strNewFile ); | 647 | QFile f( strNewFile ); |
498 | QString out; | 648 | QString out; |
499 | int total_written; | 649 | int total_written; |
500 | 650 | ||
501 | if ( !f.open( IO_WriteOnly|IO_Raw ) ) { | 651 | if ( !f.open( IO_WriteOnly|IO_Raw ) ) { |
502 | qWarning("Unable to write to %s", fname.latin1()); | 652 | qWarning("Unable to write to %s", fname.latin1()); |
503 | return FALSE; | 653 | return FALSE; |
504 | } | 654 | } |
505 | 655 | ||
506 | out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; | 656 | out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; |
507 | out += "<!DOCTYPE CategoryList>\n"; | 657 | out += "<!DOCTYPE CategoryList>\n"; |
508 | 658 | ||
509 | out += "<Categories>\n"; | 659 | out += "<Categories>\n"; |
510 | 660 | ||
511 | for ( QMap<int, QString>::ConstIterator git = mGlobalCats.idMap().begin(); | 661 | for ( QMap<int, QString>::ConstIterator git = mGlobalCats.idMap().begin(); |
512 | git != mGlobalCats.idMap().end(); ++git ) | 662 | git != mGlobalCats.idMap().end(); ++git ) |
513 | out += "<Category id=\"" + QString::number(git.key()) + "\"" + | 663 | out += "<Category id=\"" + QString::number(git.key()) + "\"" + |
514 | " name=\"" + escapeString(*git) + "\" />\n"; | 664 | " name=\"" + escapeString(*git) + "\" />\n"; |
515 | 665 | ||
516 | for ( QMap<QString, CategoryGroup>::ConstIterator appsIt=mAppCats.begin(); | 666 | for ( QMap<QString, CategoryGroup>::ConstIterator appsIt=mAppCats.begin(); |
517 | appsIt != mAppCats.end(); ++appsIt ) { | 667 | appsIt != mAppCats.end(); ++appsIt ) { |
518 | const QString &app = appsIt.key(); | 668 | const QString &app = appsIt.key(); |
519 | const QMap<int, QString> &appcats = (*appsIt).idMap(); | 669 | const QMap<int, QString> &appcats = (*appsIt).idMap(); |
520 | for ( QMap<int, QString>::ConstIterator appcatit = appcats.begin(); | 670 | for ( QMap<int, QString>::ConstIterator appcatit = appcats.begin(); |
521 | appcatit != appcats.end(); ++appcatit ) | 671 | appcatit != appcats.end(); ++appcatit ) |
522 | out += "<Category id=\"" + QString::number(appcatit.key()) + "\"" + | 672 | out += "<Category id=\"" + QString::number(appcatit.key()) + "\"" + |
523 | " app=\"" + escapeString(app) + "\"" + | 673 | " app=\"" + escapeString(app) + "\"" + |
524 | " name=\"" + escapeString(*appcatit) + "\" />\n"; | 674 | " name=\"" + escapeString(*appcatit) + "\" />\n"; |
525 | } | 675 | } |
526 | out += "</Categories>\n"; | 676 | out += "</Categories>\n"; |
527 | 677 | ||
528 | QCString cstr = out.utf8(); | 678 | QCString cstr = out.utf8(); |
529 | total_written = f.writeBlock( cstr.data(), cstr.length() ); | 679 | total_written = f.writeBlock( cstr.data(), cstr.length() ); |
530 | if ( total_written != int(cstr.length()) ) { | 680 | if ( total_written != int(cstr.length()) ) { |
531 | f.close(); | 681 | f.close(); |
532 | QFile::remove( strNewFile ); | 682 | QFile::remove( strNewFile ); |
533 | return FALSE; | 683 | return FALSE; |
534 | } | 684 | } |
535 | f.close(); | 685 | f.close(); |
536 | 686 | ||
687 | #ifdef Q_OS_WIN32 | ||
688 | QFile::remove( fname ); | ||
689 | #endif | ||
537 | if ( ::rename( strNewFile.latin1(), fname.latin1() ) < 0 ) { | 690 | if ( ::rename( strNewFile.latin1(), fname.latin1() ) < 0 ) { |
538 | qWarning( "problem renaming file %s to %s", | 691 | qWarning( "problem renaming file %s to %s", |
539 | strNewFile.latin1(), fname.latin1()); | 692 | strNewFile.latin1(), fname.latin1()); |
540 | // remove the tmp file... | 693 | // remove the tmp file... |
541 | QFile::remove( strNewFile ); | 694 | QFile::remove( strNewFile ); |
542 | } | 695 | } |
543 | 696 | ||
544 | return TRUE; | 697 | return TRUE; |
545 | } | 698 | } |
546 | 699 | ||
700 | /*! | ||
701 | Loads the Categories database using \a fname. See categoryFileName() | ||
702 | for the default file name string used for the shared category database. | ||
703 | |||
704 | Returns FALSE if there is error reading the file or TRUE on success. | ||
705 | */ | ||
547 | bool Categories::load( const QString &fname ) | 706 | bool Categories::load( const QString &fname ) |
548 | { | 707 | { |
549 | QFile file( fname ); | 708 | QFile file( fname ); |
550 | if ( !file.open( IO_ReadOnly ) ) { | 709 | if ( !file.open( IO_ReadOnly ) ) { |
551 | qWarning("Unable to open %s", fname.latin1()); | 710 | qWarning("Unable to open %s", fname.latin1()); |
552 | 711 | ||
553 | addGlobalCategory(tr("Business")); | 712 | addGlobalCategory(tr("Business")); |
554 | addGlobalCategory(tr("Personal")); | 713 | addGlobalCategory(tr("Personal")); |
555 | save(fname); | 714 | save(fname); |
556 | 715 | ||
557 | return FALSE; | 716 | return FALSE; |
558 | } | 717 | } |
559 | 718 | ||
560 | clear(); | 719 | clear(); |
561 | QByteArray ba = file.readAll(); | 720 | QByteArray ba = file.readAll(); |
562 | QString data = QString::fromUtf8( ba.data(), ba.size() ); | 721 | QString data = QString::fromUtf8( ba.data(), ba.size() ); |
563 | QChar *uc = (QChar *)data.unicode(); | 722 | QChar *uc = (QChar *)data.unicode(); |
564 | int len = data.length(); | 723 | int len = data.length(); |
565 | 724 | ||
566 | // QTime t; | 725 | // QTime t; |
567 | // t.start(); | 726 | // t.start(); |
568 | QString name; | 727 | QString name; |
569 | QString id; | 728 | QString id; |
570 | QString app; | 729 | QString app; |
571 | int i = 0; | 730 | int i = 0; |
572 | while ( (i = data.find( "<Category ", i)) != -1 ) { | 731 | while ( (i = data.find( "<Category ", i)) != -1 ) { |
573 | 732 | ||
574 | i += 10; | 733 | i += 10; |
575 | name = QString::null; | 734 | name = QString::null; |
576 | app = QString::null; | 735 | app = QString::null; |
577 | while ( 1 ) { | 736 | while ( 1 ) { |
578 | // skip white space | 737 | // skip white space |
579 | while ( i < len && | 738 | while ( i < len && |
580 | (uc[i] == ' ' || uc[i] == '\n' || uc[i] == '\r') ) | 739 | (uc[i] == ' ' || uc[i] == '\n' || uc[i] == '\r') ) |
581 | i++; | 740 | i++; |
582 | // if at the end, then done | 741 | // if at the end, then done |
583 | if ( i >= len-2 || (uc[i] == '/' && uc[i+1] == '>') ) | 742 | if ( i >= len-2 || (uc[i] == '/' && uc[i+1] == '>') ) |
584 | break; | 743 | break; |
585 | // we have another attribute read it. | 744 | // we have another attribute read it. |
586 | int j = i; | 745 | int j = i; |
587 | while ( j < len && uc[j] != '=' ) | 746 | while ( j < len && uc[j] != '=' ) |
588 | j++; | 747 | j++; |
589 | QString attr = QConstString( uc+i, j-i ).string(); | 748 | QString attr = QConstString( uc+i, j-i ).string(); |
590 | i = ++j; // skip = | 749 | i = ++j; // skip = |
591 | while ( i < len && uc[i] != '"' ) | 750 | while ( i < len && uc[i] != '"' ) |
592 | i++; | 751 | i++; |
593 | j = ++i; | 752 | j = ++i; |
594 | while ( j < len && uc[j] != '"' ) | 753 | while ( j < len && uc[j] != '"' ) |
595 | j++; | 754 | j++; |
596 | QString value = Qtopia::plainString( QConstString( uc+i, j-i ).string() ); | 755 | QString value = Qtopia::plainString( QConstString( uc+i, j-i ).string() ); |
597 | i = j + 1; | 756 | i = j + 1; |
598 | 757 | ||
599 | // qDebug("attr='%s' value='%s'", attr.latin1(), value.latin1() ); | 758 | // qDebug("attr='%s' value='%s'", attr.latin1(), value.latin1() ); |
600 | if ( attr == "id" ) | 759 | if ( attr == "id" ) |
601 | id = value; | 760 | id = value; |
602 | else if ( attr == "app" ) | 761 | else if ( attr == "app" ) |
603 | app = value; | 762 | app = value; |
604 | 763 | ||
605 | else if ( attr == "name" ) | 764 | else if ( attr == "name" ) |
606 | name = value; | 765 | name = value; |
607 | } | 766 | } |
608 | 767 | ||
609 | if ( name.isNull() || id.isNull() ) { | 768 | if ( name.isNull() || id.isNull() ) { |
610 | qWarning("No name or id in the category"); | 769 | qWarning("No name or id in the category"); |
611 | continue; | 770 | continue; |
612 | } | 771 | } |
613 | if ( app.isNull() ) | 772 | if ( app.isNull() ) |
614 | mGlobalCats.add( id.toInt(), name ); | 773 | mGlobalCats.add( id.toInt(), name ); |
615 | else | 774 | else |
616 | mAppCats[ app ].add( id.toInt(), name ); | 775 | mAppCats[ app ].add( id.toInt(), name ); |
617 | } | 776 | } |
618 | 777 | ||
619 | return TRUE; | 778 | return TRUE; |
620 | } | 779 | } |
621 | 780 | ||
781 | /*! | ||
782 | Clear the categories in memory. Equivelent to creating an empty Categories | ||
783 | object. | ||
784 | */ | ||
622 | void Categories::clear() | 785 | void Categories::clear() |
623 | { | 786 | { |
624 | mGlobalCats.clear(); | 787 | mGlobalCats.clear(); |
625 | mAppCats.clear(); | 788 | mAppCats.clear(); |
626 | } | 789 | } |
627 | 790 | ||
791 | /*! | ||
792 | Dump the contents to standard out. Used for debugging only. | ||
793 | */ | ||
628 | void Categories::dump() const | 794 | void Categories::dump() const |
629 | { | 795 | { |
630 | qDebug("\tglobal categories = %s", mGlobalCats.labels().join(", ").latin1() ); | 796 | qDebug("\tglobal categories = %s", mGlobalCats.labels().join(", ").latin1() ); |
631 | for ( QMap<QString, CategoryGroup>::ConstIterator appsIt = mAppCats.begin(); appsIt != mAppCats.end(); ++appsIt ) { | 797 | for ( QMap<QString, CategoryGroup>::ConstIterator appsIt = mAppCats.begin(); appsIt != mAppCats.end(); ++appsIt ) { |
632 | const QString &app = appsIt.key(); | 798 | const QString &app = appsIt.key(); |
633 | QStringList appcats = (*appsIt).labels(); | 799 | QStringList appcats = (*appsIt).labels(); |
634 | qDebug("\tapp = %s\tcategories = %s", app.latin1(), | 800 | qDebug("\tapp = %s\tcategories = %s", app.latin1(), |
635 | appcats.join(", ").latin1() ); | 801 | appcats.join(", ").latin1() ); |
636 | 802 | ||
637 | } | 803 | } |
638 | } | 804 | } |
639 | 805 | ||
640 | QStringList CheckedListView::checked() const | 806 | QStringList CheckedListView::checked() const |
641 | { | 807 | { |
642 | QStringList strs; | 808 | QStringList strs; |
643 | for ( QCheckListItem *i = (QCheckListItem *) firstChild(); | 809 | for ( QCheckListItem *i = (QCheckListItem *) firstChild(); |
644 | i; i = (QCheckListItem *)i->nextSibling() ) | 810 | i; i = (QCheckListItem *)i->nextSibling() ) |
645 | if ( i->isOn() ) | 811 | if ( i->isOn() ) |
646 | strs += i->text( 0 ); | 812 | strs += i->text( 0 ); |
647 | return strs; | 813 | return strs; |
648 | } | 814 | } |
649 | 815 | ||
650 | void CheckedListView::addCheckableList( const QStringList &options ) | 816 | void CheckedListView::addCheckableList( const QStringList &options ) |
651 | { | 817 | { |
652 | for ( QStringList::ConstIterator it = options.begin(); | 818 | for ( QStringList::ConstIterator it = options.begin(); |
653 | it != options.end(); ++it ) { | 819 | it != options.end(); ++it ) { |
654 | (void) new QCheckListItem( this, *it, | 820 | (void) new QCheckListItem( this, *it, |
655 | QCheckListItem::CheckBox ); | 821 | QCheckListItem::CheckBox ); |
656 | } | 822 | } |
657 | } | 823 | } |
658 | 824 | ||
659 | void CheckedListView::setChecked( const QStringList &checked ) | 825 | void CheckedListView::setChecked( const QStringList &checked ) |
660 | { | 826 | { |
661 | // iterate over all items | 827 | // iterate over all items |
662 | bool showingChecked = FALSE; | 828 | bool showingChecked = FALSE; |
663 | for ( QCheckListItem *i = (QCheckListItem *) firstChild(); | 829 | for ( QCheckListItem *i = (QCheckListItem *) firstChild(); |
664 | i; i = (QCheckListItem *)i->nextSibling() ) | 830 | i; i = (QCheckListItem *)i->nextSibling() ) |
665 | // see if the item should be checked by searching the | 831 | // see if the item should be checked by searching the |
666 | // checked list | 832 | // checked list |
667 | if ( checked.find( i->text( 0 ) ) != checked.end() ) { | 833 | if ( checked.find( i->text( 0 ) ) != checked.end() ) { |
668 | i->setOn( TRUE ); | 834 | i->setOn( TRUE ); |
669 | // make sure it is showing at least one checked item | 835 | // make sure it is showing at least one checked item |
670 | if ( !showingChecked ) { | 836 | if ( !showingChecked ) { |
671 | ensureItemVisible( i ); | 837 | ensureItemVisible( i ); |
672 | showingChecked = TRUE; | 838 | showingChecked = TRUE; |
673 | } | 839 | } |
674 | } | 840 | } |
675 | else | 841 | else |
676 | i->setOn( FALSE ); | 842 | i->setOn( FALSE ); |
677 | } | 843 | } |
844 | |||
845 | /*! \fn Categories &Categories::operator= ( const Categories &c ) | ||
846 | |||
847 | Performs deep copy. | ||
848 | */ | ||
849 | |||
850 | |||
851 | /*! \fn QStringList Categories::labels( const QString & app, const QArray<int> &catids ) const | ||
852 | |||
853 | Returns list of labels associated with the application and catids | ||
854 | */ | ||
855 | |||
856 | /*! \fn QStringList Categories::globalCategories() const | ||
857 | |||
858 | Returns list of all global category labels | ||
859 | */ | ||
860 | |||
861 | /*! \fn const QMap<QString, CategoryGroup> &Categories::appGroupMap() const | ||
862 | |||
863 | Returns a map of application names to CategoryGroup. The CategoryGroup | ||
864 | class defines a map of ids to category labels and category labels to ids. | ||
865 | */ | ||
866 | |||
867 | /*! \fn const CategoryGroup &Categories::globalGroup() const | ||
868 | |||
869 | Returns the global CategoryGroup. The CategoryGroup | ||
870 | class defines a map of ids to category labels and category labels to ids. | ||
871 | */ | ||
872 | |||
873 | /*! \fn void Categories::categoryAdded( const Categories &cats, const QString &appname, int uid) | ||
874 | |||
875 | Emitted if a category is added. | ||
876 | |||
877 | \a cats is a const reference to this object | ||
878 | \a appname is the CategoryGroup application name that the category was added to or QString::null if it was global | ||
879 | \a uid is the unique identifier associated with the added category | ||
880 | */ | ||
881 | |||
882 | /*! \fn void Categories::categoryRemoved( const Categories &cats, const QString &appname, | ||
883 | int uid) | ||
884 | |||
885 | Emitted if removed category is removed. | ||
886 | |||
887 | \a cats is a const reference to this object | ||
888 | \a appname is the CategoryGroup application name that the category was removed from or QString::null if it was the global CategoryGroup | ||
889 | \a uid is the unique identifier associated with the removed category | ||
890 | */ | ||
891 | |||
892 | |||
893 | /*! \fn void Categories::categoryRenamed( const Categories &cats, const QString &appname, | ||
894 | int uid) | ||
895 | |||
896 | Emitted if \a uid in the \a appname CategoryGroup is renamed in \a cats | ||
897 | object. | ||
898 | |||
899 | \a cats is a const reference to this object | ||
900 | \a appname is the CategoryGroup application name that the category was renamed in or QString::null if it was the global CategoryGroup | ||
901 | \a uid is the unique identifier associated with the renamed category | ||
902 | */ | ||
903 | |||
904 | /*! \fn Categories::Categories( QObject *parent=0, const char *name = 0 ) | ||
905 | |||
906 | Constructor for an empty Categories object. | ||
907 | */ | ||
908 | |||
909 | /*! \fn Categories::Categories( const Categories ©From ) | ||
910 | |||
911 | Deep copy constructor | ||
912 | */ | ||
913 | |||
914 | /*! \fn Categories::~Categories() | ||
915 | |||
916 | Empty destructor. Call save() before destruction if there are changes | ||
917 | that need to be saved. | ||
918 | */ | ||
919 | |||
920 | /*! \fn CategoryGroup::clear() | ||
921 | \internal | ||
922 | */ | ||
923 | |||
924 | /*! \fn const QMap<int, QString> &CategoryGroup::idMap() const | ||
925 | |||
926 | Returns a const reference to the id to label QMap | ||
927 | */ | ||
928 | |||
929 | /*! \fn CategoryGroup::CategoryGroup() | ||
930 | \internal | ||
931 | */ | ||
932 | |||
933 | /*! \fn CategoryGroup::CategoryGroup(const CategoryGroup &c) | ||
934 | \internal | ||
935 | */ | ||
936 | |||
diff --git a/library/backend/contact.cpp b/library/backend/contact.cpp index b10b19a..3f4934a 100644 --- a/library/backend/contact.cpp +++ b/library/backend/contact.cpp | |||
@@ -1,924 +1,1408 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2001 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. |
3 | ** | 3 | ** |
4 | ** This file is part of Qtopia Environment. | 4 | ** This file is part of the Qtopia Environment. |
5 | ** | 5 | ** |
6 | ** This file may be distributed and/or modified under the terms of the | 6 | ** This file may be distributed and/or modified under the terms of the |
7 | ** GNU General Public License version 2 as published by the Free Software | 7 | ** GNU General Public License version 2 as published by the Free Software |
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** packaging of this file. | 9 | ** packaging of this file. |
10 | ** | 10 | ** |
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | 11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
13 | ** | 13 | ** |
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
15 | ** | 15 | ** |
16 | ** Contact info@trolltech.com if any conditions of this licensing are | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
17 | ** not clear to you. | 17 | ** not clear to you. |
18 | ** | 18 | ** |
19 | **********************************************************************/ | 19 | **********************************************************************/ |
20 | 20 | ||
21 | #define QTOPIA_INTERNAL_CONTACT_MRE | 21 | #define QTOPIA_INTERNAL_CONTACT_MRE |
22 | 22 | ||
23 | #include "contact.h" | 23 | #include "contact.h" |
24 | #include "vobject_p.h" | 24 | #include "vobject_p.h" |
25 | #include "qfiledirect_p.h" | 25 | #include "qfiledirect_p.h" |
26 | 26 | ||
27 | #include <qpe/stringutil.h> | 27 | #include <qpe/stringutil.h> |
28 | #include <qpe/timeconversion.h> | 28 | #include <qpe/timeconversion.h> |
29 | 29 | ||
30 | #include <qobject.h> | 30 | #include <qobject.h> |
31 | #include <qregexp.h> | 31 | #include <qregexp.h> |
32 | #include <qstylesheet.h> | 32 | #include <qstylesheet.h> |
33 | #include <qfileinfo.h> | 33 | #include <qfileinfo.h> |
34 | 34 | ||
35 | #include <stdio.h> | 35 | #include <stdio.h> |
36 | 36 | ||
37 | /*! | ||
38 | \class Contact contact.h | ||
39 | \brief The Contact class holds the data of an address book entry. | ||
40 | |||
41 | This data includes information the name of the person, contact | ||
42 | information, and business information such as deparment and job title. | ||
43 | |||
44 | \ingroup qtopiaemb | ||
45 | \ingroup qtopiadesktop | ||
46 | */ | ||
47 | |||
37 | Qtopia::UidGen Contact::sUidGen( Qtopia::UidGen::Qtopia ); | 48 | Qtopia::UidGen Contact::sUidGen( Qtopia::UidGen::Qtopia ); |
38 | 49 | ||
50 | /*! | ||
51 | Creates a new, empty contact. | ||
52 | */ | ||
39 | Contact::Contact() | 53 | Contact::Contact() |
40 | : Record(), mMap(), d( 0 ) | 54 | : Record(), mMap(), d( 0 ) |
41 | { | 55 | { |
42 | } | 56 | } |
43 | 57 | ||
58 | /*! | ||
59 | \internal | ||
60 | Creates a new contact. The properties of the contact are | ||
61 | set from \a fromMap. | ||
62 | */ | ||
44 | Contact::Contact( const QMap<int, QString> &fromMap ) : | 63 | Contact::Contact( const QMap<int, QString> &fromMap ) : |
45 | Record(), mMap( fromMap ), d( 0 ) | 64 | Record(), mMap( fromMap ), d( 0 ) |
46 | { | 65 | { |
47 | QString cats = mMap[ Qtopia::AddressCategory ]; | 66 | QString cats = mMap[ Qtopia::AddressCategory ]; |
48 | if ( !cats.isEmpty() ) | 67 | if ( !cats.isEmpty() ) |
49 | setCategories( idsFromString( cats ) ); | 68 | setCategories( idsFromString( cats ) ); |
50 | QString uidStr = find( Qtopia::AddressUid ); | 69 | QString uidStr = find( Qtopia::AddressUid ); |
70 | |||
51 | if ( uidStr.isEmpty() ) | 71 | if ( uidStr.isEmpty() ) |
52 | setUid( uidGen().generate() ); | 72 | setUid( uidGen().generate() ); |
53 | else | 73 | else |
54 | setUid( uidStr.toInt() ); | 74 | setUid( uidStr.toInt() ); |
75 | |||
76 | if ( !uidStr.isEmpty() ) | ||
77 | setUid( uidStr.toInt() ); | ||
55 | } | 78 | } |
56 | 79 | ||
80 | /*! | ||
81 | Destroys a contact. | ||
82 | */ | ||
57 | Contact::~Contact() | 83 | Contact::~Contact() |
58 | { | 84 | { |
59 | } | 85 | } |
60 | 86 | ||
87 | /*! \fn void Contact::setTitle( const QString &str ) | ||
88 | Sets the title of the contact to \a str. | ||
89 | */ | ||
90 | |||
91 | /*! \fn void Contact::setFirstName( const QString &str ) | ||
92 | Sets the first name of the contact to \a str. | ||
93 | */ | ||
94 | |||
95 | /*! \fn void Contact::setMiddleName( const QString &str ) | ||
96 | Sets the middle name of the contact to \a str. | ||
97 | */ | ||
98 | |||
99 | /*! \fn void Contact::setLastName( const QString &str ) | ||
100 | Sets the last name of the contact to \a str. | ||
101 | */ | ||
102 | |||
103 | /*! \fn void Contact::setSuffix( const QString &str ) | ||
104 | Sets the suffix of the contact to \a str. | ||
105 | */ | ||
106 | |||
107 | /*! \fn void Contact::setFileAs( const QString &str ) | ||
108 | Sets the contact to filed as \a str. | ||
109 | */ | ||
110 | |||
111 | /*! \fn void Contact::setDefaultEmail( const QString &str ) | ||
112 | Sets the default email of the contact to \a str. | ||
113 | */ | ||
114 | |||
115 | /*! \fn void Contact::setHomeStreet( const QString &str ) | ||
116 | Sets the home street address of the contact to \a str. | ||
117 | */ | ||
118 | |||
119 | /*! \fn void Contact::setHomeCity( const QString &str ) | ||
120 | Sets the home city of the contact to \a str. | ||
121 | */ | ||
122 | |||
123 | /*! \fn void Contact::setHomeState( const QString &str ) | ||
124 | Sets the home state of the contact to \a str. | ||
125 | */ | ||
126 | |||
127 | /*! \fn void Contact::setHomeZip( const QString &str ) | ||
128 | Sets the home zip code of the contact to \a str. | ||
129 | */ | ||
130 | |||
131 | /*! \fn void Contact::setHomeCountry( const QString &str ) | ||
132 | Sets the home country of the contact to \a str. | ||
133 | */ | ||
134 | |||
135 | /*! \fn void Contact::setHomePhone( const QString &str ) | ||
136 | Sets the home phone number of the contact to \a str. | ||
137 | */ | ||
138 | |||
139 | /*! \fn void Contact::setHomeFax( const QString &str ) | ||
140 | Sets the home fax number of the contact to \a str. | ||
141 | */ | ||
142 | |||
143 | /*! \fn void Contact::setHomeMobile( const QString &str ) | ||
144 | Sets the home mobile phone number of the contact to \a str. | ||
145 | */ | ||
146 | |||
147 | /*! \fn void Contact::setHomeWebpage( const QString &str ) | ||
148 | Sets the home webpage of the contact to \a str. | ||
149 | */ | ||
150 | |||
151 | /*! \fn void Contact::setCompany( const QString &str ) | ||
152 | Sets the company for contact to \a str. | ||
153 | */ | ||
154 | |||
155 | /*! \fn void Contact::setJobTitle( const QString &str ) | ||
156 | Sets the job title of the contact to \a str. | ||
157 | */ | ||
158 | |||
159 | /*! \fn void Contact::setDepartment( const QString &str ) | ||
160 | Sets the department for contact to \a str. | ||
161 | */ | ||
162 | |||
163 | /*! \fn void Contact::setOffice( const QString &str ) | ||
164 | Sets the office for contact to \a str. | ||
165 | */ | ||
166 | |||
167 | /*! \fn void Contact::setBusinessStreet( const QString &str ) | ||
168 | Sets the business street address of the contact to \a str. | ||
169 | */ | ||
170 | |||
171 | /*! \fn void Contact::setBusinessCity( const QString &str ) | ||
172 | Sets the business city of the contact to \a str. | ||
173 | */ | ||
174 | |||
175 | /*! \fn void Contact::setBusinessState( const QString &str ) | ||
176 | Sets the business state of the contact to \a str. | ||
177 | */ | ||
178 | |||
179 | /*! \fn void Contact::setBusinessZip( const QString &str ) | ||
180 | Sets the business zip code of the contact to \a str. | ||
181 | */ | ||
182 | |||
183 | /*! \fn void Contact::setBusinessCountry( const QString &str ) | ||
184 | Sets the business country of the contact to \a str. | ||
185 | */ | ||
186 | |||
187 | /*! \fn void Contact::setBusinessPhone( const QString &str ) | ||
188 | Sets the business phone number of the contact to \a str. | ||
189 | */ | ||
190 | |||
191 | /*! \fn void Contact::setBusinessFax( const QString &str ) | ||
192 | Sets the business fax number of the contact to \a str. | ||
193 | */ | ||
194 | |||
195 | /*! \fn void Contact::setBusinessMobile( const QString &str ) | ||
196 | Sets the business mobile phone number of the contact to \a str. | ||
197 | */ | ||
198 | |||
199 | /*! \fn void Contact::setBusinessPager( const QString &str ) | ||
200 | Sets the business pager number of the contact to \a str. | ||
201 | */ | ||
202 | |||
203 | /*! \fn void Contact::setBusinessWebpage( const QString &str ) | ||
204 | Sets the business webpage of the contact to \a str. | ||
205 | */ | ||
206 | |||
207 | /*! \fn void Contact::setProfession( const QString &str ) | ||
208 | Sets the profession of the contact to \a str. | ||
209 | */ | ||
210 | |||
211 | /*! \fn void Contact::setAssistant( const QString &str ) | ||
212 | Sets the assistant of the contact to \a str. | ||
213 | */ | ||
214 | |||
215 | /*! \fn void Contact::setManager( const QString &str ) | ||
216 | Sets the manager of the contact to \a str. | ||
217 | */ | ||
218 | |||
219 | /*! \fn void Contact::setSpouse( const QString &str ) | ||
220 | Sets the spouse of the contact to \a str. | ||
221 | */ | ||
222 | |||
223 | /*! \fn void Contact::setGender( const QString &str ) | ||
224 | Sets the gender of the contact to \a str. | ||
225 | */ | ||
226 | |||
227 | /*! \fn void Contact::setBirthday( const QString &str ) | ||
228 | Sets the birthday for the contact to \a str. | ||
229 | */ | ||
230 | |||
231 | /*! \fn void Contact::setAnniversary( const QString &str ) | ||
232 | Sets the anniversary of the contact to \a str. | ||
233 | */ | ||
234 | |||
235 | /*! \fn void Contact::setNickname( const QString &str ) | ||
236 | Sets the nickname of the contact to \a str. | ||
237 | */ | ||
238 | |||
239 | /*! \fn void Contact::setNotes( const QString &str ) | ||
240 | Sets the notes about the contact to \a str. | ||
241 | */ | ||
242 | |||
243 | /*! \fn QString Contact::title() const | ||
244 | Returns the title of the contact. | ||
245 | */ | ||
246 | |||
247 | /*! \fn QString Contact::firstName() const | ||
248 | Returns the first name of the contact. | ||
249 | */ | ||
250 | |||
251 | /*! \fn QString Contact::middleName() const | ||
252 | Returns the middle name of the contact. | ||
253 | */ | ||
254 | |||
255 | /*! \fn QString Contact::lastName() const | ||
256 | Returns the last name of the contact. | ||
257 | */ | ||
258 | |||
259 | /*! \fn QString Contact::suffix() const | ||
260 | Returns the suffix of the contact. | ||
261 | */ | ||
262 | |||
263 | /*! \fn QString Contact::fileAs() const | ||
264 | Returns the string the contact is filed as. | ||
265 | */ | ||
266 | |||
267 | /*! \fn QString Contact::defaultEmail() const | ||
268 | Returns the default email address of the contact. | ||
269 | */ | ||
270 | |||
271 | /*! \fn QString Contact::emails() const | ||
272 | Returns the list of email address for a contact separated by ';'s in a single | ||
273 | string. | ||
274 | */ | ||
275 | |||
276 | /*! \fn QString Contact::homeStreet() const | ||
277 | Returns the home street address of the contact. | ||
278 | */ | ||
279 | |||
280 | /*! \fn QString Contact::homeCity() const | ||
281 | Returns the home city of the contact. | ||
282 | */ | ||
283 | |||
284 | /*! \fn QString Contact::homeState() const | ||
285 | Returns the home state of the contact. | ||
286 | */ | ||
287 | |||
288 | /*! \fn QString Contact::homeZip() const | ||
289 | Returns the home zip of the contact. | ||
290 | */ | ||
291 | |||
292 | /*! \fn QString Contact::homeCountry() const | ||
293 | Returns the home country of the contact. | ||
294 | */ | ||
295 | |||
296 | /*! \fn QString Contact::homePhone() const | ||
297 | Returns the home phone number of the contact. | ||
298 | */ | ||
299 | |||
300 | /*! \fn QString Contact::homeFax() const | ||
301 | Returns the home fax number of the contact. | ||
302 | */ | ||
303 | |||
304 | /*! \fn QString Contact::homeMobile() const | ||
305 | Returns the home mobile number of the contact. | ||
306 | */ | ||
307 | |||
308 | /*! \fn QString Contact::homeWebpage() const | ||
309 | Returns the home webpage of the contact. | ||
310 | */ | ||
311 | |||
312 | /*! \fn QString Contact::company() const | ||
313 | Returns the company for the contact. | ||
314 | */ | ||
315 | |||
316 | /*! \fn QString Contact::department() const | ||
317 | Returns the department for the contact. | ||
318 | */ | ||
319 | |||
320 | /*! \fn QString Contact::office() const | ||
321 | Returns the office for the contact. | ||
322 | */ | ||
323 | |||
324 | /*! \fn QString Contact::jobTitle() const | ||
325 | Returns the job title of the contact. | ||
326 | */ | ||
327 | |||
328 | /*! \fn QString Contact::profession() const | ||
329 | Returns the profession of the contact. | ||
330 | */ | ||
331 | |||
332 | /*! \fn QString Contact::assistant() const | ||
333 | Returns the assistant of the contact. | ||
334 | */ | ||
335 | |||
336 | /*! \fn QString Contact::manager() const | ||
337 | Returns the manager of the contact. | ||
338 | */ | ||
339 | |||
340 | /*! \fn QString Contact::businessStreet() const | ||
341 | Returns the business street address of the contact. | ||
342 | */ | ||
343 | |||
344 | /*! \fn QString Contact::businessCity() const | ||
345 | Returns the business city of the contact. | ||
346 | */ | ||
347 | |||
348 | /*! \fn QString Contact::businessState() const | ||
349 | Returns the business state of the contact. | ||
350 | */ | ||
351 | |||
352 | /*! \fn QString Contact::businessZip() const | ||
353 | Returns the business zip of the contact. | ||
354 | */ | ||
355 | |||
356 | /*! \fn QString Contact::businessCountry() const | ||
357 | Returns the business country of the contact. | ||
358 | */ | ||
359 | |||
360 | /*! \fn QString Contact::businessPhone() const | ||
361 | Returns the business phone number of the contact. | ||
362 | */ | ||
363 | |||
364 | /*! \fn QString Contact::businessFax() const | ||
365 | Returns the business fax number of the contact. | ||
366 | */ | ||
367 | |||
368 | /*! \fn QString Contact::businessMobile() const | ||
369 | Returns the business mobile number of the contact. | ||
370 | */ | ||
371 | |||
372 | /*! \fn QString Contact::businessPager() const | ||
373 | Returns the business pager number of the contact. | ||
374 | */ | ||
375 | |||
376 | /*! \fn QString Contact::businessWebpage() const | ||
377 | Returns the business webpage of the contact. | ||
378 | */ | ||
379 | |||
380 | /*! \fn QString Contact::spouse() const | ||
381 | Returns the spouse of the contact. | ||
382 | */ | ||
383 | |||
384 | /*! \fn QString Contact::gender() const | ||
385 | Returns the gender of the contact. | ||
386 | */ | ||
387 | |||
388 | /*! \fn QString Contact::birthday() const | ||
389 | Returns the birthday of the contact. | ||
390 | */ | ||
391 | |||
392 | /*! \fn QString Contact::anniversary() const | ||
393 | Returns the anniversary of the contact. | ||
394 | */ | ||
395 | |||
396 | /*! \fn QString Contact::nickname() const | ||
397 | Returns the nickname of the contact. | ||
398 | */ | ||
399 | |||
400 | /*! \fn QString Contact::children() const | ||
401 | Returns the children of the contact. | ||
402 | */ | ||
403 | |||
404 | /*! \fn QString Contact::notes() const | ||
405 | Returns the notes relating to the the contact. | ||
406 | */ | ||
407 | |||
408 | /*! \fn QString Contact::groups() const | ||
409 | \internal | ||
410 | Returns the groups for the contact. | ||
411 | */ | ||
412 | |||
413 | /*! \fn QStringList Contact::groupList() const | ||
414 | \internal | ||
415 | */ | ||
416 | |||
417 | /*! \fn QString Contact::field(int) const | ||
418 | \internal | ||
419 | */ | ||
420 | |||
421 | /*! \fn void Contact::saveJournal( journal_action, const QString & = QString::null ) | ||
422 | \internal | ||
423 | */ | ||
424 | |||
425 | /*! \fn void Contact::setUid( int id ) | ||
426 | \internal | ||
427 | Sets the uid for this record to \a id. | ||
428 | */ | ||
429 | |||
430 | /*! \enum Contact::journal_action | ||
431 | \internal | ||
432 | */ | ||
433 | |||
434 | /*! | ||
435 | \internal | ||
436 | */ | ||
61 | QMap<int, QString> Contact::toMap() const | 437 | QMap<int, QString> Contact::toMap() const |
62 | { | 438 | { |
63 | QMap<int, QString> map = mMap; | 439 | QMap<int, QString> map = mMap; |
64 | map.insert( Qtopia::AddressCategory, idsToString( categories() )); | 440 | QString cats = idsToString( categories() ); |
441 | if ( !cats.isEmpty() ) | ||
442 | map.insert( Qtopia::AddressCategory, cats ); | ||
65 | return map; | 443 | return map; |
66 | } | 444 | } |
67 | 445 | ||
68 | /*! | 446 | /*! |
69 | Returns a rich text formatted QString of the Contact. | 447 | Returns a rich text formatted QString representing the contents the contact. |
70 | */ | 448 | */ |
71 | QString Contact::toRichText() const | 449 | QString Contact::toRichText() const |
72 | { | 450 | { |
73 | QString text; | 451 | QString text; |
74 | QString value, comp, state; | 452 | QString value, comp, state; |
75 | 453 | ||
76 | // name, jobtitle and company | 454 | // name, jobtitle and company |
77 | if ( !(value = fullName()).isEmpty() ) | 455 | if ( !(value = fullName()).isEmpty() ) |
78 | text += "<b>" + Qtopia::escapeString(value) + "</b><br>"; | 456 | text += "<b>" + Qtopia::escapeString(value) + "</b><br>"; |
79 | if ( !(value = jobTitle()).isEmpty() ) | 457 | if ( !(value = jobTitle()).isEmpty() ) |
80 | text += Qtopia::escapeString(value) + "<br>"; | 458 | text += Qtopia::escapeString(value) + "<br>"; |
81 | 459 | ||
82 | comp = company(); | 460 | comp = company(); |
83 | if ( !(value = department()).isEmpty() ) { | 461 | if ( !(value = department()).isEmpty() ) { |
84 | text += Qtopia::escapeString(value); | 462 | text += Qtopia::escapeString(value); |
85 | if ( comp ) | 463 | if ( comp ) |
86 | text += ", "; | 464 | text += ", "; |
87 | else | 465 | else |
88 | text += "<br>"; | 466 | text += "<br>"; |
89 | } | 467 | } |
90 | if ( !comp.isEmpty() ) | 468 | if ( !comp.isEmpty() ) |
91 | text += Qtopia::escapeString(comp) + "<br>"; | 469 | text += Qtopia::escapeString(comp) + "<br>"; |
92 | 470 | ||
93 | // business address | 471 | // business address |
94 | if ( !businessStreet().isEmpty() || !businessCity().isEmpty() || | 472 | if ( !businessStreet().isEmpty() || !businessCity().isEmpty() || |
95 | !businessZip().isEmpty() || !businessCountry().isEmpty() ) { | 473 | !businessZip().isEmpty() || !businessCountry().isEmpty() ) { |
96 | text += "<br>"; | 474 | text += "<br>"; |
97 | text += QObject::tr( "<b>Work Address:</b>" ); | 475 | text += QObject::tr( "<b>Work Address:</b>" ); |
98 | text += "<br>"; | 476 | text += "<br>"; |
99 | } | 477 | } |
100 | 478 | ||
101 | if ( !(value = businessStreet()).isEmpty() ) | 479 | if ( !(value = businessStreet()).isEmpty() ) |
102 | text += Qtopia::escapeString(value) + "<br>"; | 480 | text += Qtopia::escapeString(value) + "<br>"; |
103 | state = businessState(); | 481 | state = businessState(); |
104 | if ( !(value = businessCity()).isEmpty() ) { | 482 | if ( !(value = businessCity()).isEmpty() ) { |
105 | text += Qtopia::escapeString(value); | 483 | text += Qtopia::escapeString(value); |
106 | if ( state ) | 484 | if ( state ) |
107 | text += ", " + Qtopia::escapeString(state); | 485 | text += ", " + Qtopia::escapeString(state); |
108 | text += "<br>"; | 486 | text += "<br>"; |
109 | } else if ( !state.isEmpty() ) | 487 | } else if ( !state.isEmpty() ) |
110 | text += Qtopia::escapeString(state) + "<br>"; | 488 | text += Qtopia::escapeString(state) + "<br>"; |
111 | if ( !(value = businessZip()).isEmpty() ) | 489 | if ( !(value = businessZip()).isEmpty() ) |
112 | text += Qtopia::escapeString(value) + "<br>"; | 490 | text += Qtopia::escapeString(value) + "<br>"; |
113 | if ( !(value = businessCountry()).isEmpty() ) | 491 | if ( !(value = businessCountry()).isEmpty() ) |
114 | text += Qtopia::escapeString(value) + "<br>"; | 492 | text += Qtopia::escapeString(value) + "<br>"; |
115 | 493 | ||
116 | // home address | 494 | // home address |
117 | if ( !homeStreet().isEmpty() || !homeCity().isEmpty() || | 495 | if ( !homeStreet().isEmpty() || !homeCity().isEmpty() || |
118 | !homeZip().isEmpty() || !homeCountry().isEmpty() ) { | 496 | !homeZip().isEmpty() || !homeCountry().isEmpty() ) { |
119 | text += "<br>"; | 497 | text += "<br>"; |
120 | text += QObject::tr( "<b>Home Address:</b>" ); | 498 | text += QObject::tr( "<b>Home Address:</b>" ); |
121 | text += "<br>"; | 499 | text += "<br>"; |
122 | } | 500 | } |
123 | 501 | ||
124 | if ( !(value = homeStreet()).isEmpty() ) | 502 | if ( !(value = homeStreet()).isEmpty() ) |
125 | text += Qtopia::escapeString(value) + "<br>"; | 503 | text += Qtopia::escapeString(value) + "<br>"; |
126 | state = homeState(); | 504 | state = homeState(); |
127 | if ( !(value = homeCity()).isEmpty() ) { | 505 | if ( !(value = homeCity()).isEmpty() ) { |
128 | text += Qtopia::escapeString(value); | 506 | text += Qtopia::escapeString(value); |
129 | if ( !state.isEmpty() ) | 507 | if ( !state.isEmpty() ) |
130 | text += ", " + Qtopia::escapeString(state); | 508 | text += ", " + Qtopia::escapeString(state); |
131 | text += "<br>"; | 509 | text += "<br>"; |
132 | } else if (!state.isEmpty()) | 510 | } else if (!state.isEmpty()) |
133 | text += Qtopia::escapeString(state) + "<br>"; | 511 | text += Qtopia::escapeString(state) + "<br>"; |
134 | if ( !(value = homeZip()).isEmpty() ) | 512 | if ( !(value = homeZip()).isEmpty() ) |
135 | text += Qtopia::escapeString(value) + "<br>"; | 513 | text += Qtopia::escapeString(value) + "<br>"; |
136 | if ( !(value = homeCountry()).isEmpty() ) | 514 | if ( !(value = homeCountry()).isEmpty() ) |
137 | text += Qtopia::escapeString(value) + "<br>"; | 515 | text += Qtopia::escapeString(value) + "<br>"; |
138 | 516 | ||
139 | // the others... | 517 | // the others... |
140 | QString str; | 518 | QString str; |
141 | str = emails(); | 519 | str = emails(); |
142 | if ( !str.isEmpty() ) | 520 | if ( !str.isEmpty() ) |
143 | text += "<b>" + QObject::tr("Email Addresses: ") + "</b>" | 521 | text += "<b>" + QObject::tr("Email Addresses: ") + "</b>" |
144 | + Qtopia::escapeString(str) + "<br>"; | 522 | + Qtopia::escapeString(str) + "<br>"; |
145 | str = homePhone(); | 523 | str = homePhone(); |
146 | if ( !str.isEmpty() ) | 524 | if ( !str.isEmpty() ) |
147 | text += "<b>" + QObject::tr("Home Phone: ") + "</b>" | 525 | text += "<b>" + QObject::tr("Home Phone: ") + "</b>" |
148 | + Qtopia::escapeString(str) + "<br>"; | 526 | + Qtopia::escapeString(str) + "<br>"; |
149 | str = homeFax(); | 527 | str = homeFax(); |
150 | if ( !str.isEmpty() ) | 528 | if ( !str.isEmpty() ) |
151 | text += "<b>" + QObject::tr("Home Fax: ") + "</b>" | 529 | text += "<b>" + QObject::tr("Home Fax: ") + "</b>" |
152 | + Qtopia::escapeString(str) + "<br>"; | 530 | + Qtopia::escapeString(str) + "<br>"; |
153 | str = homeMobile(); | 531 | str = homeMobile(); |
154 | if ( !str.isEmpty() ) | 532 | if ( !str.isEmpty() ) |
155 | text += "<b>" + QObject::tr("Home Mobile: ") + "</b>" | 533 | text += "<b>" + QObject::tr("Home Mobile: ") + "</b>" |
156 | + Qtopia::escapeString(str) + "<br>"; | 534 | + Qtopia::escapeString(str) + "<br>"; |
157 | str = homeWebpage(); | 535 | str = homeWebpage(); |
158 | if ( !str.isEmpty() ) | 536 | if ( !str.isEmpty() ) |
159 | text += "<b>" + QObject::tr("Home Web Page: ") + "</b>" | 537 | text += "<b>" + QObject::tr("Home Web Page: ") + "</b>" |
160 | + Qtopia::escapeString(str) + "<br>"; | 538 | + Qtopia::escapeString(str) + "<br>"; |
161 | str = businessWebpage(); | 539 | str = businessWebpage(); |
162 | if ( !str.isEmpty() ) | 540 | if ( !str.isEmpty() ) |
163 | text += "<b>" + QObject::tr("Business Web Page: ") + "</b>" | 541 | text += "<b>" + QObject::tr("Business Web Page: ") + "</b>" |
164 | + Qtopia::escapeString(str) + "<br>"; | 542 | + Qtopia::escapeString(str) + "<br>"; |
165 | str = office(); | 543 | str = office(); |
166 | if ( !str.isEmpty() ) | 544 | if ( !str.isEmpty() ) |
167 | text += "<b>" + QObject::tr("Office: ") + "</b>" | 545 | text += "<b>" + QObject::tr("Office: ") + "</b>" |
168 | + Qtopia::escapeString(str) + "<br>"; | 546 | + Qtopia::escapeString(str) + "<br>"; |
169 | str = businessPhone(); | 547 | str = businessPhone(); |
170 | if ( !str.isEmpty() ) | 548 | if ( !str.isEmpty() ) |
171 | text += "<b>" + QObject::tr("Business Phone: ") + "</b>" | 549 | text += "<b>" + QObject::tr("Business Phone: ") + "</b>" |
172 | + Qtopia::escapeString(str) + "<br>"; | 550 | + Qtopia::escapeString(str) + "<br>"; |
173 | str = businessFax(); | 551 | str = businessFax(); |
174 | if ( !str.isEmpty() ) | 552 | if ( !str.isEmpty() ) |
175 | text += "<b>" + QObject::tr("Business Fax: ") + "</b>" | 553 | text += "<b>" + QObject::tr("Business Fax: ") + "</b>" |
176 | + Qtopia::escapeString(str) + "<br>"; | 554 | + Qtopia::escapeString(str) + "<br>"; |
177 | str = businessMobile(); | 555 | str = businessMobile(); |
178 | if ( !str.isEmpty() ) | 556 | if ( !str.isEmpty() ) |
179 | text += "<b>" + QObject::tr("Business Mobile: ") + "</b>" | 557 | text += "<b>" + QObject::tr("Business Mobile: ") + "</b>" |
180 | + Qtopia::escapeString(str) + "<br>"; | 558 | + Qtopia::escapeString(str) + "<br>"; |
181 | str = businessPager(); | 559 | str = businessPager(); |
182 | if ( !str.isEmpty() ) | 560 | if ( !str.isEmpty() ) |
183 | text += "<b>" + QObject::tr("Business Pager: ") + "</b>" | 561 | text += "<b>" + QObject::tr("Business Pager: ") + "</b>" |
184 | + Qtopia::escapeString(str) + "<br>"; | 562 | + Qtopia::escapeString(str) + "<br>"; |
185 | str = profession(); | 563 | str = profession(); |
186 | if ( !str.isEmpty() ) | 564 | if ( !str.isEmpty() ) |
187 | text += "<b>" + QObject::tr("Profession: ") + "</b>" | 565 | text += "<b>" + QObject::tr("Profession: ") + "</b>" |
188 | + Qtopia::escapeString(str) + "<br>"; | 566 | + Qtopia::escapeString(str) + "<br>"; |
189 | str = assistant(); | 567 | str = assistant(); |
190 | if ( !str.isEmpty() ) | 568 | if ( !str.isEmpty() ) |
191 | text += "<b>" + QObject::tr("Assistant: ") + "</b>" | 569 | text += "<b>" + QObject::tr("Assistant: ") + "</b>" |
192 | + Qtopia::escapeString(str) + "<br>"; | 570 | + Qtopia::escapeString(str) + "<br>"; |
193 | str = manager(); | 571 | str = manager(); |
194 | if ( !str.isEmpty() ) | 572 | if ( !str.isEmpty() ) |
195 | text += "<b>" + QObject::tr("Manager: ") + "</b>" | 573 | text += "<b>" + QObject::tr("Manager: ") + "</b>" |
196 | + Qtopia::escapeString(str) + "<br>"; | 574 | + Qtopia::escapeString(str) + "<br>"; |
197 | str = gender(); | 575 | str = gender(); |
198 | if ( !str.isEmpty() && str.toInt() != 0 ) { | 576 | if ( !str.isEmpty() && str.toInt() != 0 ) { |
199 | if ( str.toInt() == 1 ) | 577 | if ( str.toInt() == 1 ) |
200 | str = QObject::tr( "Male" ); | 578 | str = QObject::tr( "Male" ); |
201 | else if ( str.toInt() == 2 ) | 579 | else if ( str.toInt() == 2 ) |
202 | str = QObject::tr( "Female" ); | 580 | str = QObject::tr( "Female" ); |
203 | text += "<b>" + QObject::tr("Gender: ") + "</b>" + str + "<br>"; | 581 | text += "<b>" + QObject::tr("Gender: ") + "</b>" + str + "<br>"; |
204 | } | 582 | } |
205 | str = spouse(); | 583 | str = spouse(); |
206 | if ( !str.isEmpty() ) | 584 | if ( !str.isEmpty() ) |
207 | text += "<b>" + QObject::tr("Spouse: ") + "</b>" | 585 | text += "<b>" + QObject::tr("Spouse: ") + "</b>" |
208 | + Qtopia::escapeString(str) + "<br>"; | 586 | + Qtopia::escapeString(str) + "<br>"; |
209 | str = birthday(); | 587 | str = birthday(); |
210 | if ( !str.isEmpty() ) | 588 | if ( !str.isEmpty() ) |
211 | text += "<b>" + QObject::tr("Birthday: ") + "</b>" | 589 | text += "<b>" + QObject::tr("Birthday: ") + "</b>" |
212 | + Qtopia::escapeString(str) + "<br>"; | 590 | + Qtopia::escapeString(str) + "<br>"; |
213 | str = anniversary(); | 591 | str = anniversary(); |
214 | if ( !str.isEmpty() ) | 592 | if ( !str.isEmpty() ) |
215 | text += "<b>" + QObject::tr("Anniversary: ") + "</b>" | 593 | text += "<b>" + QObject::tr("Anniversary: ") + "</b>" |
216 | + Qtopia::escapeString(str) + "<br>"; | 594 | + Qtopia::escapeString(str) + "<br>"; |
217 | str = nickname(); | 595 | str = nickname(); |
218 | if ( !str.isEmpty() ) | 596 | if ( !str.isEmpty() ) |
219 | text += "<b>" + QObject::tr("Nickname: ") + "</b>" | 597 | text += "<b>" + QObject::tr("Nickname: ") + "</b>" |
220 | + Qtopia::escapeString(str) + "<br>"; | 598 | + Qtopia::escapeString(str) + "<br>"; |
221 | 599 | ||
222 | // notes last | 600 | // notes last |
223 | if ( (value = notes()) ) { | 601 | if ( (value = notes()) ) { |
224 | QRegExp reg("\n"); | 602 | QRegExp reg("\n"); |
225 | 603 | ||
226 | //QString tmp = Qtopia::escapeString(value); | 604 | //QString tmp = Qtopia::escapeString(value); |
227 | QString tmp = QStyleSheet::convertFromPlainText(value); | 605 | QString tmp = QStyleSheet::convertFromPlainText(value); |
228 | //tmp.replace( reg, "<br>" ); | 606 | //tmp.replace( reg, "<br>" ); |
229 | text += "<br>" + tmp + "<br>"; | 607 | text += "<br>" + tmp + "<br>"; |
230 | } | 608 | } |
231 | return text; | 609 | return text; |
232 | } | 610 | } |
233 | 611 | ||
612 | /*! | ||
613 | \internal | ||
614 | */ | ||
234 | void Contact::insert( int key, const QString &v ) | 615 | void Contact::insert( int key, const QString &v ) |
235 | { | 616 | { |
236 | QString value = v.stripWhiteSpace(); | 617 | QString value = v.stripWhiteSpace(); |
237 | if ( value.isEmpty() ) | 618 | if ( value.isEmpty() ) |
238 | mMap.remove( key ); | 619 | mMap.remove( key ); |
239 | else | 620 | else |
240 | mMap.insert( key, value ); | 621 | mMap.insert( key, value ); |
241 | } | 622 | } |
242 | 623 | ||
624 | /*! | ||
625 | \internal | ||
626 | */ | ||
243 | void Contact::replace( int key, const QString & v ) | 627 | void Contact::replace( int key, const QString & v ) |
244 | { | 628 | { |
245 | QString value = v.stripWhiteSpace(); | 629 | QString value = v.stripWhiteSpace(); |
246 | if ( value.isEmpty() ) | 630 | if ( value.isEmpty() ) |
247 | mMap.remove( key ); | 631 | mMap.remove( key ); |
248 | else | 632 | else |
249 | mMap.replace( key, value ); | 633 | mMap.replace( key, value ); |
250 | } | 634 | } |
251 | 635 | ||
636 | /*! | ||
637 | \internal | ||
638 | */ | ||
252 | QString Contact::find( int key ) const | 639 | QString Contact::find( int key ) const |
253 | { | 640 | { |
254 | return mMap[key]; | 641 | return mMap[key]; |
255 | } | 642 | } |
256 | 643 | ||
644 | /*! | ||
645 | \internal | ||
646 | */ | ||
257 | QString Contact::displayAddress( const QString &street, | 647 | QString Contact::displayAddress( const QString &street, |
258 | const QString &city, | 648 | const QString &city, |
259 | const QString &state, | 649 | const QString &state, |
260 | const QString &zip, | 650 | const QString &zip, |
261 | const QString &country ) const | 651 | const QString &country ) const |
262 | { | 652 | { |
263 | QString s = street; | 653 | QString s = street; |
264 | if ( !street.isEmpty() ) | 654 | if ( !street.isEmpty() ) |
265 | s+= "\n"; | 655 | s+= "\n"; |
266 | s += city; | 656 | s += city; |
267 | if ( !city.isEmpty() && !state.isEmpty() ) | 657 | if ( !city.isEmpty() && !state.isEmpty() ) |
268 | s += ", "; | 658 | s += ", "; |
269 | s += state; | 659 | s += state; |
270 | if ( !state.isEmpty() && !zip.isEmpty() ) | 660 | if ( !state.isEmpty() && !zip.isEmpty() ) |
271 | s += " "; | 661 | s += " "; |
272 | s += zip; | 662 | s += zip; |
273 | if ( !country.isEmpty() && !s.isEmpty() ) | 663 | if ( !country.isEmpty() && !s.isEmpty() ) |
274 | s += "\n"; | 664 | s += "\n"; |
275 | s += country; | 665 | s += country; |
276 | return s; | 666 | return s; |
277 | } | 667 | } |
278 | 668 | ||
669 | /*! | ||
670 | \internal | ||
671 | */ | ||
279 | QString Contact::displayBusinessAddress() const | 672 | QString Contact::displayBusinessAddress() const |
280 | { | 673 | { |
281 | return displayAddress( businessStreet(), businessCity(), | 674 | return displayAddress( businessStreet(), businessCity(), |
282 | businessState(), businessZip(), | 675 | businessState(), businessZip(), |
283 | businessCountry() ); | 676 | businessCountry() ); |
284 | } | 677 | } |
285 | 678 | ||
679 | /*! | ||
680 | \internal | ||
681 | */ | ||
286 | QString Contact::displayHomeAddress() const | 682 | QString Contact::displayHomeAddress() const |
287 | { | 683 | { |
288 | return displayAddress( homeStreet(), homeCity(), | 684 | return displayAddress( homeStreet(), homeCity(), |
289 | homeState(), homeZip(), | 685 | homeState(), homeZip(), |
290 | homeCountry() ); | 686 | homeCountry() ); |
291 | } | 687 | } |
292 | 688 | ||
689 | /*! | ||
690 | Returns the full name of the contact | ||
691 | */ | ||
293 | QString Contact::fullName() const | 692 | QString Contact::fullName() const |
294 | { | 693 | { |
295 | QString title = find( Qtopia::Title ); | 694 | QString title = find( Qtopia::Title ); |
296 | QString firstName = find( Qtopia::FirstName ); | 695 | QString firstName = find( Qtopia::FirstName ); |
297 | QString middleName = find( Qtopia::MiddleName ); | 696 | QString middleName = find( Qtopia::MiddleName ); |
298 | QString lastName = find( Qtopia::LastName ); | 697 | QString lastName = find( Qtopia::LastName ); |
299 | QString suffix = find( Qtopia::Suffix ); | 698 | QString suffix = find( Qtopia::Suffix ); |
300 | 699 | ||
301 | QString name = title; | 700 | QString name = title; |
302 | if ( !firstName.isEmpty() ) { | 701 | if ( !firstName.isEmpty() ) { |
303 | if ( !name.isEmpty() ) | 702 | if ( !name.isEmpty() ) |
304 | name += " "; | 703 | name += " "; |
305 | name += firstName; | 704 | name += firstName; |
306 | } | 705 | } |
307 | if ( !middleName.isEmpty() ) { | 706 | if ( !middleName.isEmpty() ) { |
308 | if ( !name.isEmpty() ) | 707 | if ( !name.isEmpty() ) |
309 | name += " "; | 708 | name += " "; |
310 | name += middleName; | 709 | name += middleName; |
311 | } | 710 | } |
312 | if ( !lastName.isEmpty() ) { | 711 | if ( !lastName.isEmpty() ) { |
313 | if ( !name.isEmpty() ) | 712 | if ( !name.isEmpty() ) |
314 | name += " "; | 713 | name += " "; |
315 | name += lastName; | 714 | name += lastName; |
316 | } | 715 | } |
317 | if ( !suffix.isEmpty() ) { | 716 | if ( !suffix.isEmpty() ) { |
318 | if ( !name.isEmpty() ) | 717 | if ( !name.isEmpty() ) |
319 | name += " "; | 718 | name += " "; |
320 | name += suffix; | 719 | name += suffix; |
321 | } | 720 | } |
322 | return name.simplifyWhiteSpace(); | 721 | return name.simplifyWhiteSpace(); |
323 | } | 722 | } |
324 | 723 | ||
724 | /*! | ||
725 | Returns a list of the names of the children of the contact. | ||
726 | */ | ||
325 | QStringList Contact::childrenList() const | 727 | QStringList Contact::childrenList() const |
326 | { | 728 | { |
327 | return QStringList::split( " ", find( Qtopia::Children ) ); | 729 | return QStringList::split( " ", find( Qtopia::Children ) ); |
328 | } | 730 | } |
329 | 731 | ||
732 | /*! \fn void Contact::insertEmail( const QString &email ) | ||
733 | |||
734 | Insert \a email into the email list. Ensures \a email can only be added | ||
735 | once. If there is no default email address set, it sets it to the \a email. | ||
736 | */ | ||
737 | |||
738 | /*! \fn void Contact::removeEmail( const QString &email ) | ||
739 | |||
740 | Removes the \a email from the email list. If the default email was \a email, | ||
741 | then the default email address is assigned to the first email in the | ||
742 | email list | ||
743 | */ | ||
744 | |||
745 | /*! \fn void Contact::clearEmails() | ||
746 | |||
747 | Clears the email list. | ||
748 | */ | ||
749 | |||
750 | /*! \fn void Contact::insertEmails( const QStringList &emailList ) | ||
751 | |||
752 | Appends the \a emailList to the exiting email list | ||
753 | */ | ||
754 | |||
755 | /*! | ||
756 | Returns a list of email addresses belonging to the contact, including | ||
757 | the default email address. | ||
758 | */ | ||
330 | QStringList Contact::emailList() const | 759 | QStringList Contact::emailList() const |
331 | { | 760 | { |
332 | return QStringList::split( ";", find( Qtopia::Emails ) ); | 761 | QString emailStr = emails(); |
762 | |||
763 | QStringList r; | ||
764 | if ( !emailStr.isEmpty() ) { | ||
765 | qDebug(" emailstr "); | ||
766 | QStringList l = QStringList::split( emailSeparator(), emailStr ); | ||
767 | for ( QStringList::ConstIterator it = l.begin();it != l.end();++it ) | ||
768 | r += (*it).simplifyWhiteSpace(); | ||
769 | } | ||
770 | |||
771 | return r; | ||
333 | } | 772 | } |
334 | 773 | ||
774 | /*! | ||
775 | \overload | ||
776 | |||
777 | Generates the string for the contact to be filed as from the first, | ||
778 | middle and last name of the contact. | ||
779 | */ | ||
335 | void Contact::setFileAs() | 780 | void Contact::setFileAs() |
336 | { | 781 | { |
337 | QString lastName, firstName, middleName, fileas; | 782 | QString lastName, firstName, middleName, fileas; |
338 | 783 | ||
339 | lastName = find( Qtopia::LastName ); | 784 | lastName = find( Qtopia::LastName ); |
340 | firstName = find( Qtopia::FirstName ); | 785 | firstName = find( Qtopia::FirstName ); |
341 | middleName = find( Qtopia::MiddleName ); | 786 | middleName = find( Qtopia::MiddleName ); |
342 | if ( !lastName.isEmpty() && !firstName.isEmpty() | 787 | if ( !lastName.isEmpty() && !firstName.isEmpty() |
343 | && !middleName.isEmpty() ) | 788 | && !middleName.isEmpty() ) |
344 | fileas = lastName + ", " + firstName + " " + middleName; | 789 | fileas = lastName + ", " + firstName + " " + middleName; |
345 | else if ( !lastName.isEmpty() && !firstName.isEmpty() ) | 790 | else if ( !lastName.isEmpty() && !firstName.isEmpty() ) |
346 | fileas = lastName + ", " + firstName; | 791 | fileas = lastName + ", " + firstName; |
347 | else if ( !lastName.isEmpty() || !firstName.isEmpty() || | 792 | else if ( !lastName.isEmpty() || !firstName.isEmpty() || |
348 | !middleName.isEmpty() ) | 793 | !middleName.isEmpty() ) |
349 | fileas = firstName + ( firstName.isEmpty() ? "" : " " ) | 794 | fileas = firstName + ( firstName.isEmpty() ? "" : " " ) |
350 | + middleName + ( middleName.isEmpty() ? "" : " " ) | 795 | + middleName + ( middleName.isEmpty() ? "" : " " ) |
351 | + lastName; | 796 | + lastName; |
352 | 797 | ||
353 | replace( Qtopia::FileAs, fileas ); | 798 | replace( Qtopia::FileAs, fileas ); |
354 | } | 799 | } |
355 | 800 | ||
801 | /*! | ||
802 | \internal | ||
803 | Appends the contact information to \a buf. | ||
804 | */ | ||
356 | void Contact::save( QString &buf ) const | 805 | void Contact::save( QString &buf ) const |
357 | { | 806 | { |
358 | static const QStringList SLFIELDS = fields(); | 807 | static const QStringList SLFIELDS = fields(); |
359 | // I'm expecting "<Contact " in front of this... | 808 | // I'm expecting "<Contact " in front of this... |
360 | for ( QMap<int, QString>::ConstIterator it = mMap.begin(); | 809 | for ( QMap<int, QString>::ConstIterator it = mMap.begin(); |
361 | it != mMap.end(); ++it ) { | 810 | it != mMap.end(); ++it ) { |
362 | const QString &value = it.data(); | 811 | const QString &value = it.data(); |
363 | int key = it.key(); | 812 | int key = it.key(); |
364 | if ( !value.isEmpty() ) { | 813 | if ( !value.isEmpty() ) { |
365 | if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid) | 814 | if ( key == Qtopia::AddressCategory || key == Qtopia::AddressUid) |
366 | continue; | 815 | continue; |
367 | 816 | ||
368 | key -= Qtopia::AddressCategory+1; | 817 | key -= Qtopia::AddressCategory+1; |
369 | buf += SLFIELDS[key]; | 818 | buf += SLFIELDS[key]; |
370 | buf += "=\"" + Qtopia::escapeString(value) + "\" "; | 819 | buf += "=\"" + Qtopia::escapeString(value) + "\" "; |
371 | } | 820 | } |
372 | } | 821 | } |
373 | buf += customToXml(); | 822 | buf += customToXml(); |
374 | if ( categories().count() > 0 ) | 823 | if ( categories().count() > 0 ) |
375 | buf += "Categories=\"" + idsToString( categories() ) + "\" "; | 824 | buf += "Categories=\"" + idsToString( categories() ) + "\" "; |
376 | buf += "Uid=\"" + QString::number( uid() ) + "\" "; | 825 | buf += "Uid=\"" + QString::number( uid() ) + "\" "; |
377 | // You need to close this yourself | 826 | // You need to close this yourself |
378 | } | 827 | } |
379 | 828 | ||
829 | /*! | ||
830 | \internal | ||
831 | Returns the list of fields belonging to a contact | ||
832 | */ | ||
380 | QStringList Contact::fields() | 833 | QStringList Contact::fields() |
381 | { | 834 | { |
382 | QStringList list; | 835 | QStringList list; |
383 | 836 | ||
384 | list.append( "Title" ); // Not Used! | 837 | list.append( "Title" ); // Not Used! |
385 | list.append( "FirstName" ); | 838 | list.append( "FirstName" ); |
386 | list.append( "MiddleName" ); | 839 | list.append( "MiddleName" ); |
387 | list.append( "LastName" ); | 840 | list.append( "LastName" ); |
388 | list.append( "Suffix" ); | 841 | list.append( "Suffix" ); |
389 | list.append( "FileAs" ); | 842 | list.append( "FileAs" ); |
390 | 843 | ||
391 | list.append( "JobTitle" ); | 844 | list.append( "JobTitle" ); |
392 | list.append( "Department" ); | 845 | list.append( "Department" ); |
393 | list.append( "Company" ); | 846 | list.append( "Company" ); |
394 | list.append( "BusinessPhone" ); | 847 | list.append( "BusinessPhone" ); |
395 | list.append( "BusinessFax" ); | 848 | list.append( "BusinessFax" ); |
396 | list.append( "BusinessMobile" ); | 849 | list.append( "BusinessMobile" ); |
397 | 850 | ||
398 | list.append( "DefaultEmail" ); | 851 | list.append( "DefaultEmail" ); |
399 | list.append( "Emails" ); | 852 | list.append( "Emails" ); |
400 | 853 | ||
401 | list.append( "HomePhone" ); | 854 | list.append( "HomePhone" ); |
402 | list.append( "HomeFax" ); | 855 | list.append( "HomeFax" ); |
403 | list.append( "HomeMobile" ); | 856 | list.append( "HomeMobile" ); |
404 | 857 | ||
405 | list.append( "BusinessStreet" ); | 858 | list.append( "BusinessStreet" ); |
406 | list.append( "BusinessCity" ); | 859 | list.append( "BusinessCity" ); |
407 | list.append( "BusinessState" ); | 860 | list.append( "BusinessState" ); |
408 | list.append( "BusinessZip" ); | 861 | list.append( "BusinessZip" ); |
409 | list.append( "BusinessCountry" ); | 862 | list.append( "BusinessCountry" ); |
410 | list.append( "BusinessPager" ); | 863 | list.append( "BusinessPager" ); |
411 | list.append( "BusinessWebPage" ); | 864 | list.append( "BusinessWebPage" ); |
412 | 865 | ||
413 | list.append( "Office" ); | 866 | list.append( "Office" ); |
414 | list.append( "Profession" ); | 867 | list.append( "Profession" ); |
415 | list.append( "Assistant" ); | 868 | list.append( "Assistant" ); |
416 | list.append( "Manager" ); | 869 | list.append( "Manager" ); |
417 | 870 | ||
418 | list.append( "HomeStreet" ); | 871 | list.append( "HomeStreet" ); |
419 | list.append( "HomeCity" ); | 872 | list.append( "HomeCity" ); |
420 | list.append( "HomeState" ); | 873 | list.append( "HomeState" ); |
421 | list.append( "HomeZip" ); | 874 | list.append( "HomeZip" ); |
422 | list.append( "HomeCountry" ); | 875 | list.append( "HomeCountry" ); |
423 | list.append( "HomeWebPage" ); | 876 | list.append( "HomeWebPage" ); |
424 | 877 | ||
425 | list.append( "Spouse" ); | 878 | list.append( "Spouse" ); |
426 | list.append( "Gender" ); | 879 | list.append( "Gender" ); |
427 | list.append( "Birthday" ); | 880 | list.append( "Birthday" ); |
428 | list.append( "Anniversary" ); | 881 | list.append( "Anniversary" ); |
429 | list.append( "Nickname" ); | 882 | list.append( "Nickname" ); |
430 | list.append( "Children" ); | 883 | list.append( "Children" ); |
431 | 884 | ||
432 | list.append( "Notes" ); | 885 | list.append( "Notes" ); |
433 | list.append( "Groups" ); | 886 | list.append( "Groups" ); |
434 | 887 | ||
435 | return list; | 888 | return list; |
436 | } | 889 | } |
437 | 890 | ||
891 | /*! | ||
892 | \internal | ||
893 | Returns a translated list of field names for a contact. | ||
894 | */ | ||
438 | QStringList Contact::trfields() | 895 | QStringList Contact::trfields() |
439 | { | 896 | { |
440 | QStringList list; | 897 | QStringList list; |
441 | 898 | ||
442 | list.append( QObject::tr( "Name Title") ); | 899 | list.append( QObject::tr( "Name Title") ); |
443 | list.append( QObject::tr( "First Name" ) ); | 900 | list.append( QObject::tr( "First Name" ) ); |
444 | list.append( QObject::tr( "Middle Name" ) ); | 901 | list.append( QObject::tr( "Middle Name" ) ); |
445 | list.append( QObject::tr( "Last Name" ) ); | 902 | list.append( QObject::tr( "Last Name" ) ); |
446 | list.append( QObject::tr( "Suffix" ) ); | 903 | list.append( QObject::tr( "Suffix" ) ); |
447 | list.append( QObject::tr( "File As" ) ); | 904 | list.append( QObject::tr( "File As" ) ); |
448 | 905 | ||
449 | list.append( QObject::tr( "Job Title" ) ); | 906 | list.append( QObject::tr( "Job Title" ) ); |
450 | list.append( QObject::tr( "Department" ) ); | 907 | list.append( QObject::tr( "Department" ) ); |
451 | list.append( QObject::tr( "Company" ) ); | 908 | list.append( QObject::tr( "Company" ) ); |
452 | list.append( QObject::tr( "Business Phone" ) ); | 909 | list.append( QObject::tr( "Business Phone" ) ); |
453 | list.append( QObject::tr( "Business Fax" ) ); | 910 | list.append( QObject::tr( "Business Fax" ) ); |
454 | list.append( QObject::tr( "Business Mobile" ) ); | 911 | list.append( QObject::tr( "Business Mobile" ) ); |
455 | 912 | ||
456 | list.append( QObject::tr( "Default Email" ) ); | 913 | list.append( QObject::tr( "Default Email" ) ); |
457 | list.append( QObject::tr( "Emails" ) ); | 914 | list.append( QObject::tr( "Emails" ) ); |
458 | 915 | ||
459 | list.append( QObject::tr( "Home Phone" ) ); | 916 | list.append( QObject::tr( "Home Phone" ) ); |
460 | list.append( QObject::tr( "Home Fax" ) ); | 917 | list.append( QObject::tr( "Home Fax" ) ); |
461 | list.append( QObject::tr( "Home Mobile" ) ); | 918 | list.append( QObject::tr( "Home Mobile" ) ); |
462 | 919 | ||
463 | list.append( QObject::tr( "Business Street" ) ); | 920 | list.append( QObject::tr( "Business Street" ) ); |
464 | list.append( QObject::tr( "Business City" ) ); | 921 | list.append( QObject::tr( "Business City" ) ); |
465 | list.append( QObject::tr( "Business State" ) ); | 922 | list.append( QObject::tr( "Business State" ) ); |
466 | list.append( QObject::tr( "Business Zip" ) ); | 923 | list.append( QObject::tr( "Business Zip" ) ); |
467 | list.append( QObject::tr( "Business Country" ) ); | 924 | list.append( QObject::tr( "Business Country" ) ); |
468 | list.append( QObject::tr( "Business Pager" ) ); | 925 | list.append( QObject::tr( "Business Pager" ) ); |
469 | list.append( QObject::tr( "Business WebPage" ) ); | 926 | list.append( QObject::tr( "Business WebPage" ) ); |
470 | 927 | ||
471 | list.append( QObject::tr( "Office" ) ); | 928 | list.append( QObject::tr( "Office" ) ); |
472 | list.append( QObject::tr( "Profession" ) ); | 929 | list.append( QObject::tr( "Profession" ) ); |
473 | list.append( QObject::tr( "Assistant" ) ); | 930 | list.append( QObject::tr( "Assistant" ) ); |
474 | list.append( QObject::tr( "Manager" ) ); | 931 | list.append( QObject::tr( "Manager" ) ); |
475 | 932 | ||
476 | list.append( QObject::tr( "Home Street" ) ); | 933 | list.append( QObject::tr( "Home Street" ) ); |
477 | list.append( QObject::tr( "Home City" ) ); | 934 | list.append( QObject::tr( "Home City" ) ); |
478 | list.append( QObject::tr( "Home State" ) ); | 935 | list.append( QObject::tr( "Home State" ) ); |
479 | list.append( QObject::tr( "Home Zip" ) ); | 936 | list.append( QObject::tr( "Home Zip" ) ); |
480 | list.append( QObject::tr( "Home Country" ) ); | 937 | list.append( QObject::tr( "Home Country" ) ); |
481 | list.append( QObject::tr( "Home Web Page" ) ); | 938 | list.append( QObject::tr( "Home Web Page" ) ); |
482 | 939 | ||
483 | list.append( QObject::tr( "Spouse" ) ); | 940 | list.append( QObject::tr( "Spouse" ) ); |
484 | list.append( QObject::tr( "Gender" ) ); | 941 | list.append( QObject::tr( "Gender" ) ); |
485 | list.append( QObject::tr( "Birthday" ) ); | 942 | list.append( QObject::tr( "Birthday" ) ); |
486 | list.append( QObject::tr( "Anniversary" ) ); | 943 | list.append( QObject::tr( "Anniversary" ) ); |
487 | list.append( QObject::tr( "Nickname" ) ); | 944 | list.append( QObject::tr( "Nickname" ) ); |
488 | list.append( QObject::tr( "Children" ) ); | 945 | list.append( QObject::tr( "Children" ) ); |
489 | 946 | ||
490 | list.append( QObject::tr( "Notes" ) ); | 947 | list.append( QObject::tr( "Notes" ) ); |
491 | list.append( QObject::tr( "Groups" ) ); | 948 | list.append( QObject::tr( "Groups" ) ); |
492 | 949 | ||
493 | return list; | 950 | return list; |
494 | } | 951 | } |
495 | 952 | ||
496 | void Contact::setEmails( const QString &v ) | 953 | /*! |
954 | Sets the list of email address for contact to those contained in \a str. | ||
955 | Email address should be separated by ';'s. | ||
956 | */ | ||
957 | void Contact::setEmails( const QString &str ) | ||
497 | { | 958 | { |
498 | replace( Qtopia::Emails, v ); | 959 | replace( Qtopia::Emails, str ); |
499 | if ( v.isEmpty() ) | 960 | if ( str.isEmpty() ) |
500 | setDefaultEmail( QString::null ); | 961 | setDefaultEmail( QString::null ); |
501 | } | 962 | } |
502 | 963 | ||
503 | void Contact::setChildren( const QString &v ) | 964 | /*! |
965 | Sets the list of children for the contact to those contained in \a str. | ||
966 | */ | ||
967 | void Contact::setChildren( const QString &str ) | ||
504 | { | 968 | { |
505 | replace( Qtopia::Children, v ); | 969 | replace( Qtopia::Children, str ); |
506 | } | 970 | } |
507 | 971 | ||
508 | // vcard conversion code | 972 | // vcard conversion code |
973 | /*! | ||
974 | \internal | ||
975 | */ | ||
509 | static inline VObject *safeAddPropValue( VObject *o, const char *prop, const QString &value ) | 976 | static inline VObject *safeAddPropValue( VObject *o, const char *prop, const QString &value ) |
510 | { | 977 | { |
511 | VObject *ret = 0; | 978 | VObject *ret = 0; |
512 | if ( o && !value.isEmpty() ) | 979 | if ( o && !value.isEmpty() ) |
513 | ret = addPropValue( o, prop, value.latin1() ); | 980 | ret = addPropValue( o, prop, value.latin1() ); |
514 | return ret; | 981 | return ret; |
515 | } | 982 | } |
516 | 983 | ||
984 | /*! | ||
985 | \internal | ||
986 | */ | ||
517 | static inline VObject *safeAddProp( VObject *o, const char *prop) | 987 | static inline VObject *safeAddProp( VObject *o, const char *prop) |
518 | { | 988 | { |
519 | VObject *ret = 0; | 989 | VObject *ret = 0; |
520 | if ( o ) | 990 | if ( o ) |
521 | ret = addProp( o, prop ); | 991 | ret = addProp( o, prop ); |
522 | return ret; | 992 | return ret; |
523 | } | 993 | } |
524 | 994 | ||
995 | /*! | ||
996 | \internal | ||
997 | */ | ||
525 | static VObject *createVObject( const Contact &c ) | 998 | static VObject *createVObject( const Contact &c ) |
526 | { | 999 | { |
527 | VObject *vcard = newVObject( VCCardProp ); | 1000 | VObject *vcard = newVObject( VCCardProp ); |
528 | safeAddPropValue( vcard, VCVersionProp, "2.1" ); | 1001 | safeAddPropValue( vcard, VCVersionProp, "2.1" ); |
529 | safeAddPropValue( vcard, VCLastRevisedProp, TimeConversion::toISO8601( QDateTime::currentDateTime() ) ); | 1002 | safeAddPropValue( vcard, VCLastRevisedProp, TimeConversion::toISO8601( QDateTime::currentDateTime() ) ); |
530 | safeAddPropValue( vcard, VCUniqueStringProp, QString::number(c.uid()) ); | 1003 | safeAddPropValue( vcard, VCUniqueStringProp, QString::number(c.uid()) ); |
531 | 1004 | ||
532 | // full name | 1005 | // full name |
533 | safeAddPropValue( vcard, VCFullNameProp, c.fullName() ); | 1006 | safeAddPropValue( vcard, VCFullNameProp, c.fullName() ); |
534 | 1007 | ||
535 | // name properties | 1008 | // name properties |
536 | VObject *name = safeAddProp( vcard, VCNameProp ); | 1009 | VObject *name = safeAddProp( vcard, VCNameProp ); |
537 | safeAddPropValue( name, VCFamilyNameProp, c.lastName() ); | 1010 | safeAddPropValue( name, VCFamilyNameProp, c.lastName() ); |
538 | safeAddPropValue( name, VCGivenNameProp, c.firstName() ); | 1011 | safeAddPropValue( name, VCGivenNameProp, c.firstName() ); |
539 | safeAddPropValue( name, VCAdditionalNamesProp, c.middleName() ); | 1012 | safeAddPropValue( name, VCAdditionalNamesProp, c.middleName() ); |
540 | safeAddPropValue( name, VCNamePrefixesProp, c.title() ); | 1013 | safeAddPropValue( name, VCNamePrefixesProp, c.title() ); |
541 | safeAddPropValue( name, VCNameSuffixesProp, c.suffix() ); | 1014 | safeAddPropValue( name, VCNameSuffixesProp, c.suffix() ); |
542 | 1015 | ||
543 | // home properties | 1016 | // home properties |
544 | VObject *home_adr= safeAddProp( vcard, VCAdrProp ); | 1017 | VObject *home_adr= safeAddProp( vcard, VCAdrProp ); |
545 | safeAddProp( home_adr, VCHomeProp ); | 1018 | safeAddProp( home_adr, VCHomeProp ); |
546 | safeAddPropValue( home_adr, VCStreetAddressProp, c.homeStreet() ); | 1019 | safeAddPropValue( home_adr, VCStreetAddressProp, c.homeStreet() ); |
547 | safeAddPropValue( home_adr, VCCityProp, c.homeCity() ); | 1020 | safeAddPropValue( home_adr, VCCityProp, c.homeCity() ); |
548 | safeAddPropValue( home_adr, VCRegionProp, c.homeState() ); | 1021 | safeAddPropValue( home_adr, VCRegionProp, c.homeState() ); |
549 | safeAddPropValue( home_adr, VCPostalCodeProp, c.homeZip() ); | 1022 | safeAddPropValue( home_adr, VCPostalCodeProp, c.homeZip() ); |
550 | safeAddPropValue( home_adr, VCCountryNameProp, c.homeCountry() ); | 1023 | safeAddPropValue( home_adr, VCCountryNameProp, c.homeCountry() ); |
551 | 1024 | ||
552 | VObject *home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homePhone() ); | 1025 | VObject *home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homePhone() ); |
553 | safeAddProp( home_phone, VCHomeProp ); | 1026 | safeAddProp( home_phone, VCHomeProp ); |
554 | home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeMobile() ); | 1027 | home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeMobile() ); |
555 | safeAddProp( home_phone, VCHomeProp ); | 1028 | safeAddProp( home_phone, VCHomeProp ); |
556 | safeAddProp( home_phone, VCCellularProp ); | 1029 | safeAddProp( home_phone, VCCellularProp ); |
557 | home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeFax() ); | 1030 | home_phone = safeAddPropValue( vcard, VCTelephoneProp, c.homeFax() ); |
558 | safeAddProp( home_phone, VCHomeProp ); | 1031 | safeAddProp( home_phone, VCHomeProp ); |
559 | safeAddProp( home_phone, VCFaxProp ); | 1032 | safeAddProp( home_phone, VCFaxProp ); |
560 | 1033 | ||
561 | VObject *url = safeAddPropValue( vcard, VCURLProp, c.homeWebpage() ); | 1034 | VObject *url = safeAddPropValue( vcard, VCURLProp, c.homeWebpage() ); |
562 | safeAddProp( url, VCHomeProp ); | 1035 | safeAddProp( url, VCHomeProp ); |
563 | 1036 | ||
564 | // work properties | 1037 | // work properties |
565 | VObject *work_adr= safeAddProp( vcard, VCAdrProp ); | 1038 | VObject *work_adr= safeAddProp( vcard, VCAdrProp ); |
566 | safeAddProp( work_adr, VCWorkProp ); | 1039 | safeAddProp( work_adr, VCWorkProp ); |
567 | safeAddPropValue( work_adr, VCStreetAddressProp, c.businessStreet() ); | 1040 | safeAddPropValue( work_adr, VCStreetAddressProp, c.businessStreet() ); |
568 | safeAddPropValue( work_adr, VCCityProp, c.businessCity() ); | 1041 | safeAddPropValue( work_adr, VCCityProp, c.businessCity() ); |
569 | safeAddPropValue( work_adr, VCRegionProp, c.businessState() ); | 1042 | safeAddPropValue( work_adr, VCRegionProp, c.businessState() ); |
570 | safeAddPropValue( work_adr, VCPostalCodeProp, c.businessZip() ); | 1043 | safeAddPropValue( work_adr, VCPostalCodeProp, c.businessZip() ); |
571 | safeAddPropValue( work_adr, VCCountryNameProp, c.businessCountry() ); | 1044 | safeAddPropValue( work_adr, VCCountryNameProp, c.businessCountry() ); |
572 | 1045 | ||
573 | VObject *work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPhone() ); | 1046 | VObject *work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPhone() ); |
574 | safeAddProp( work_phone, VCWorkProp ); | 1047 | safeAddProp( work_phone, VCWorkProp ); |
575 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessMobile() ); | 1048 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessMobile() ); |
576 | safeAddProp( work_phone, VCWorkProp ); | 1049 | safeAddProp( work_phone, VCWorkProp ); |
577 | safeAddProp( work_phone, VCCellularProp ); | 1050 | safeAddProp( work_phone, VCCellularProp ); |
578 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessFax() ); | 1051 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessFax() ); |
579 | safeAddProp( work_phone, VCWorkProp ); | 1052 | safeAddProp( work_phone, VCWorkProp ); |
580 | safeAddProp( work_phone, VCFaxProp ); | 1053 | safeAddProp( work_phone, VCFaxProp ); |
581 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPager() ); | 1054 | work_phone = safeAddPropValue( vcard, VCTelephoneProp, c.businessPager() ); |
582 | safeAddProp( work_phone, VCWorkProp ); | 1055 | safeAddProp( work_phone, VCWorkProp ); |
583 | safeAddProp( work_phone, VCPagerProp ); | 1056 | safeAddProp( work_phone, VCPagerProp ); |
584 | 1057 | ||
585 | url = safeAddPropValue( vcard, VCURLProp, c.businessWebpage() ); | 1058 | url = safeAddPropValue( vcard, VCURLProp, c.businessWebpage() ); |
586 | safeAddProp( url, VCWorkProp ); | 1059 | safeAddProp( url, VCWorkProp ); |
587 | 1060 | ||
588 | VObject *title = safeAddPropValue( vcard, VCTitleProp, c.jobTitle() ); | 1061 | VObject *title = safeAddPropValue( vcard, VCTitleProp, c.jobTitle() ); |
589 | safeAddProp( title, VCWorkProp ); | 1062 | safeAddProp( title, VCWorkProp ); |
590 | 1063 | ||
591 | 1064 | ||
592 | QStringList emails = c.emailList(); | 1065 | QStringList emails = c.emailList(); |
593 | emails.prepend( c.defaultEmail() ); | 1066 | emails.prepend( c.defaultEmail() ); |
594 | for( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) { | 1067 | for( QStringList::Iterator it = emails.begin(); it != emails.end(); ++it ) { |
595 | VObject *email = safeAddPropValue( vcard, VCEmailAddressProp, *it ); | 1068 | VObject *email = safeAddPropValue( vcard, VCEmailAddressProp, *it ); |
596 | safeAddProp( email, VCInternetProp ); | 1069 | safeAddProp( email, VCInternetProp ); |
597 | } | 1070 | } |
598 | 1071 | ||
599 | safeAddPropValue( vcard, VCNoteProp, c.notes() ); | 1072 | safeAddPropValue( vcard, VCNoteProp, c.notes() ); |
600 | 1073 | ||
601 | safeAddPropValue( vcard, VCBirthDateProp, c.birthday() ); | 1074 | safeAddPropValue( vcard, VCBirthDateProp, c.birthday() ); |
602 | 1075 | ||
603 | if ( !c.company().isEmpty() || !c.department().isEmpty() || !c.office().isEmpty() ) { | 1076 | if ( !c.company().isEmpty() || !c.department().isEmpty() || !c.office().isEmpty() ) { |
604 | VObject *org = safeAddProp( vcard, VCOrgProp ); | 1077 | VObject *org = safeAddProp( vcard, VCOrgProp ); |
605 | safeAddPropValue( org, VCOrgNameProp, c.company() ); | 1078 | safeAddPropValue( org, VCOrgNameProp, c.company() ); |
606 | safeAddPropValue( org, VCOrgUnitProp, c.department() ); | 1079 | safeAddPropValue( org, VCOrgUnitProp, c.department() ); |
607 | safeAddPropValue( org, VCOrgUnit2Prop, c.office() ); | 1080 | safeAddPropValue( org, VCOrgUnit2Prop, c.office() ); |
608 | } | 1081 | } |
609 | 1082 | ||
610 | // some values we have to export as custom fields | 1083 | // some values we have to export as custom fields |
611 | safeAddPropValue( vcard, "X-Qtopia-Profession", c.profession() ); | 1084 | safeAddPropValue( vcard, "X-Qtopia-Profession", c.profession() ); |
612 | safeAddPropValue( vcard, "X-Qtopia-Manager", c.manager() ); | 1085 | safeAddPropValue( vcard, "X-Qtopia-Manager", c.manager() ); |
613 | safeAddPropValue( vcard, "X-Qtopia-Assistant", c.assistant() ); | 1086 | safeAddPropValue( vcard, "X-Qtopia-Assistant", c.assistant() ); |
614 | 1087 | ||
615 | safeAddPropValue( vcard, "X-Qtopia-Spouse", c.spouse() ); | 1088 | safeAddPropValue( vcard, "X-Qtopia-Spouse", c.spouse() ); |
616 | safeAddPropValue( vcard, "X-Qtopia-Gender", c.gender() ); | 1089 | safeAddPropValue( vcard, "X-Qtopia-Gender", c.gender() ); |
617 | safeAddPropValue( vcard, "X-Qtopia-Anniversary", c.anniversary() ); | 1090 | safeAddPropValue( vcard, "X-Qtopia-Anniversary", c.anniversary() ); |
618 | safeAddPropValue( vcard, "X-Qtopia-Nickname", c.nickname() ); | 1091 | safeAddPropValue( vcard, "X-Qtopia-Nickname", c.nickname() ); |
619 | safeAddPropValue( vcard, "X-Qtopia-Children", c.children() ); | 1092 | safeAddPropValue( vcard, "X-Qtopia-Children", c.children() ); |
620 | 1093 | ||
621 | return vcard; | 1094 | return vcard; |
622 | } | 1095 | } |
623 | 1096 | ||
624 | 1097 | ||
1098 | /*! | ||
1099 | \internal | ||
1100 | */ | ||
625 | static Contact parseVObject( VObject *obj ) | 1101 | static Contact parseVObject( VObject *obj ) |
626 | { | 1102 | { |
627 | Contact c; | 1103 | Contact c; |
628 | 1104 | ||
629 | bool haveDefaultEmail = FALSE; | ||
630 | |||
631 | VObjectIterator it; | 1105 | VObjectIterator it; |
632 | initPropIterator( &it, obj ); | 1106 | initPropIterator( &it, obj ); |
633 | while( moreIteration( &it ) ) { | 1107 | while( moreIteration( &it ) ) { |
634 | VObject *o = nextVObject( &it ); | 1108 | VObject *o = nextVObject( &it ); |
635 | QCString name = vObjectName( o ); | 1109 | QCString name = vObjectName( o ); |
636 | QCString value = vObjectStringZValue( o ); | 1110 | QCString value = vObjectStringZValue( o ); |
637 | if ( name == VCNameProp ) { | 1111 | if ( name == VCNameProp ) { |
638 | VObjectIterator nit; | 1112 | VObjectIterator nit; |
639 | initPropIterator( &nit, o ); | 1113 | initPropIterator( &nit, o ); |
640 | while( moreIteration( &nit ) ) { | 1114 | while( moreIteration( &nit ) ) { |
641 | VObject *o = nextVObject( &nit ); | 1115 | VObject *o = nextVObject( &nit ); |
642 | QCString name = vObjectTypeInfo( o ); | 1116 | QCString name = vObjectTypeInfo( o ); |
643 | QString value = vObjectStringZValue( o ); | 1117 | QString value = vObjectStringZValue( o ); |
644 | if ( name == VCNamePrefixesProp ) | 1118 | if ( name == VCNamePrefixesProp ) |
645 | c.setTitle( value ); | 1119 | c.setTitle( value ); |
646 | else if ( name == VCNameSuffixesProp ) | 1120 | else if ( name == VCNameSuffixesProp ) |
647 | c.setSuffix( value ); | 1121 | c.setSuffix( value ); |
648 | else if ( name == VCFamilyNameProp ) | 1122 | else if ( name == VCFamilyNameProp ) |
649 | c.setLastName( value ); | 1123 | c.setLastName( value ); |
650 | else if ( name == VCGivenNameProp ) | 1124 | else if ( name == VCGivenNameProp ) |
651 | c.setFirstName( value ); | 1125 | c.setFirstName( value ); |
652 | else if ( name == VCAdditionalNamesProp ) | 1126 | else if ( name == VCAdditionalNamesProp ) |
653 | c.setMiddleName( value ); | 1127 | c.setMiddleName( value ); |
654 | } | 1128 | } |
655 | } | 1129 | } |
656 | else if ( name == VCAdrProp ) { | 1130 | else if ( name == VCAdrProp ) { |
657 | bool work = TRUE; // default address is work address | 1131 | bool work = TRUE; // default address is work address |
658 | QString street; | 1132 | QString street; |
659 | QString city; | 1133 | QString city; |
660 | QString region; | 1134 | QString region; |
661 | QString postal; | 1135 | QString postal; |
662 | QString country; | 1136 | QString country; |
663 | 1137 | ||
664 | VObjectIterator nit; | 1138 | VObjectIterator nit; |
665 | initPropIterator( &nit, o ); | 1139 | initPropIterator( &nit, o ); |
666 | while( moreIteration( &nit ) ) { | 1140 | while( moreIteration( &nit ) ) { |
667 | VObject *o = nextVObject( &nit ); | 1141 | VObject *o = nextVObject( &nit ); |
668 | QCString name = vObjectName( o ); | 1142 | QCString name = vObjectName( o ); |
669 | QString value = vObjectStringZValue( o ); | 1143 | QString value = vObjectStringZValue( o ); |
670 | if ( name == VCHomeProp ) | 1144 | if ( name == VCHomeProp ) |
671 | work = FALSE; | 1145 | work = FALSE; |
672 | else if ( name == VCWorkProp ) | 1146 | else if ( name == VCWorkProp ) |
673 | work = TRUE; | 1147 | work = TRUE; |
674 | else if ( name == VCStreetAddressProp ) | 1148 | else if ( name == VCStreetAddressProp ) |
675 | street = value; | 1149 | street = value; |
676 | else if ( name == VCCityProp ) | 1150 | else if ( name == VCCityProp ) |
677 | city = value; | 1151 | city = value; |
678 | else if ( name == VCRegionProp ) | 1152 | else if ( name == VCRegionProp ) |
679 | region = value; | 1153 | region = value; |
680 | else if ( name == VCPostalCodeProp ) | 1154 | else if ( name == VCPostalCodeProp ) |
681 | postal = value; | 1155 | postal = value; |
682 | else if ( name == VCCountryNameProp ) | 1156 | else if ( name == VCCountryNameProp ) |
683 | country = value; | 1157 | country = value; |
684 | } | 1158 | } |
685 | if ( work ) { | 1159 | if ( work ) { |
686 | c.setBusinessStreet( street ); | 1160 | c.setBusinessStreet( street ); |
687 | c.setBusinessCity( city ); | 1161 | c.setBusinessCity( city ); |
688 | c.setBusinessCountry( country ); | 1162 | c.setBusinessCountry( country ); |
689 | c.setBusinessZip( postal ); | 1163 | c.setBusinessZip( postal ); |
690 | c.setBusinessState( region ); | 1164 | c.setBusinessState( region ); |
691 | } else { | 1165 | } else { |
692 | c.setHomeStreet( street ); | 1166 | c.setHomeStreet( street ); |
693 | c.setHomeCity( city ); | 1167 | c.setHomeCity( city ); |
694 | c.setHomeCountry( country ); | 1168 | c.setHomeCountry( country ); |
695 | c.setHomeZip( postal ); | 1169 | c.setHomeZip( postal ); |
696 | c.setHomeState( region ); | 1170 | c.setHomeState( region ); |
697 | } | 1171 | } |
698 | } | 1172 | } |
699 | else if ( name == VCTelephoneProp ) { | 1173 | else if ( name == VCTelephoneProp ) { |
700 | enum { | 1174 | enum { |
701 | HOME = 0x01, | 1175 | HOME = 0x01, |
702 | WORK = 0x02, | 1176 | WORK = 0x02, |
703 | VOICE = 0x04, | 1177 | VOICE = 0x04, |
704 | CELL = 0x08, | 1178 | CELL = 0x08, |
705 | FAX = 0x10, | 1179 | FAX = 0x10, |
706 | PAGER = 0x20, | 1180 | PAGER = 0x20, |
707 | UNKNOWN = 0x80 | 1181 | UNKNOWN = 0x80 |
708 | }; | 1182 | }; |
709 | int type = 0; | 1183 | int type = 0; |
710 | 1184 | ||
711 | VObjectIterator nit; | 1185 | VObjectIterator nit; |
712 | initPropIterator( &nit, o ); | 1186 | initPropIterator( &nit, o ); |
713 | while( moreIteration( &nit ) ) { | 1187 | while( moreIteration( &nit ) ) { |
714 | VObject *o = nextVObject( &nit ); | 1188 | VObject *o = nextVObject( &nit ); |
715 | QCString name = vObjectTypeInfo( o ); | 1189 | QCString name = vObjectTypeInfo( o ); |
716 | if ( name == VCHomeProp ) | 1190 | if ( name == VCHomeProp ) |
717 | type |= HOME; | 1191 | type |= HOME; |
718 | else if ( name == VCWorkProp ) | 1192 | else if ( name == VCWorkProp ) |
719 | type |= WORK; | 1193 | type |= WORK; |
720 | else if ( name == VCVoiceProp ) | 1194 | else if ( name == VCVoiceProp ) |
721 | type |= VOICE; | 1195 | type |= VOICE; |
722 | else if ( name == VCCellularProp ) | 1196 | else if ( name == VCCellularProp ) |
723 | type |= CELL; | 1197 | type |= CELL; |
724 | else if ( name == VCFaxProp ) | 1198 | else if ( name == VCFaxProp ) |
725 | type |= FAX; | 1199 | type |= FAX; |
726 | else if ( name == VCPagerProp ) | 1200 | else if ( name == VCPagerProp ) |
727 | type |= PAGER; | 1201 | type |= PAGER; |
728 | else if ( name == VCPreferredProp ) | 1202 | else if ( name == VCPreferredProp ) |
729 | ; | 1203 | ; |
730 | else | 1204 | else |
731 | type |= UNKNOWN; | 1205 | type |= UNKNOWN; |
732 | } | 1206 | } |
733 | if ( (type & UNKNOWN) != UNKNOWN ) { | 1207 | if ( (type & UNKNOWN) != UNKNOWN ) { |
734 | if ( ( type & (HOME|WORK) ) == 0 ) // default | 1208 | if ( ( type & (HOME|WORK) ) == 0 ) // default |
735 | type |= HOME; | 1209 | type |= HOME; |
736 | if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default | 1210 | if ( ( type & (VOICE|CELL|FAX|PAGER) ) == 0 ) // default |
737 | type |= VOICE; | 1211 | type |= VOICE; |
738 | 1212 | ||
739 | if ( (type & (VOICE|HOME) ) == (VOICE|HOME) ) | 1213 | if ( (type & (VOICE|HOME) ) == (VOICE|HOME) ) |
740 | c.setHomePhone( value ); | 1214 | c.setHomePhone( value ); |
741 | if ( ( type & (FAX|HOME) ) == (FAX|HOME) ) | 1215 | if ( ( type & (FAX|HOME) ) == (FAX|HOME) ) |
742 | c.setHomeFax( value ); | 1216 | c.setHomeFax( value ); |
743 | if ( ( type & (CELL|HOME) ) == (CELL|HOME) ) | 1217 | if ( ( type & (CELL|HOME) ) == (CELL|HOME) ) |
744 | c.setHomeMobile( value ); | 1218 | c.setHomeMobile( value ); |
745 | if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) ) | 1219 | if ( ( type & (VOICE|WORK) ) == (VOICE|WORK) ) |
746 | c.setBusinessPhone( value ); | 1220 | c.setBusinessPhone( value ); |
747 | if ( ( type & (FAX|WORK) ) == (FAX|WORK) ) | 1221 | if ( ( type & (FAX|WORK) ) == (FAX|WORK) ) |
748 | c.setBusinessFax( value ); | 1222 | c.setBusinessFax( value ); |
749 | if ( ( type & (CELL|WORK) ) == (CELL|WORK) ) | 1223 | if ( ( type & (CELL|WORK) ) == (CELL|WORK) ) |
750 | c.setBusinessMobile( value ); | 1224 | c.setBusinessMobile( value ); |
751 | if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) ) | 1225 | if ( ( type & (PAGER|WORK) ) == (PAGER|WORK) ) |
752 | c.setBusinessPager( value ); | 1226 | c.setBusinessPager( value ); |
753 | } | 1227 | } |
754 | } | 1228 | } |
755 | else if ( name == VCEmailAddressProp ) { | 1229 | else if ( name == VCEmailAddressProp ) { |
756 | QString email = vObjectStringZValue( o ); | 1230 | QString email = vObjectStringZValue( o ); |
757 | bool valid = TRUE; | 1231 | bool valid = TRUE; |
758 | VObjectIterator nit; | 1232 | VObjectIterator nit; |
759 | initPropIterator( &nit, o ); | 1233 | initPropIterator( &nit, o ); |
760 | while( moreIteration( &nit ) ) { | 1234 | while( moreIteration( &nit ) ) { |
761 | VObject *o = nextVObject( &nit ); | 1235 | VObject *o = nextVObject( &nit ); |
762 | QCString name = vObjectTypeInfo( o ); | 1236 | QCString name = vObjectTypeInfo( o ); |
763 | if ( name != VCInternetProp && name != VCHomeProp && | 1237 | if ( name != VCInternetProp && name != VCHomeProp && |
764 | name != VCWorkProp && | 1238 | name != VCWorkProp && |
765 | name != VCPreferredProp ) | 1239 | name != VCPreferredProp ) |
766 | // ### preffered should map to default email | 1240 | // ### preffered should map to default email |
767 | valid = FALSE; | 1241 | valid = FALSE; |
768 | } | 1242 | } |
769 | if ( valid ) { | 1243 | if ( valid ) { |
770 | if ( haveDefaultEmail ) { | 1244 | c.insertEmail( email ); |
771 | QString str = c.emails(); | ||
772 | if ( !str.isEmpty() ) | ||
773 | str += ","+email; | ||
774 | c.setEmails( str ); | ||
775 | } else { | ||
776 | c.setDefaultEmail( email ); | ||
777 | } | ||
778 | } | 1245 | } |
779 | } | 1246 | } |
780 | else if ( name == VCURLProp ) { | 1247 | else if ( name == VCURLProp ) { |
781 | VObjectIterator nit; | 1248 | VObjectIterator nit; |
782 | initPropIterator( &nit, o ); | 1249 | initPropIterator( &nit, o ); |
783 | while( moreIteration( &nit ) ) { | 1250 | while( moreIteration( &nit ) ) { |
784 | VObject *o = nextVObject( &nit ); | 1251 | VObject *o = nextVObject( &nit ); |
785 | QCString name = vObjectTypeInfo( o ); | 1252 | QCString name = vObjectTypeInfo( o ); |
786 | if ( name == VCHomeProp ) | 1253 | if ( name == VCHomeProp ) |
787 | c.setHomeWebpage( value ); | 1254 | c.setHomeWebpage( value ); |
788 | else if ( name == VCWorkProp ) | 1255 | else if ( name == VCWorkProp ) |
789 | c.setBusinessWebpage( value ); | 1256 | c.setBusinessWebpage( value ); |
790 | } | 1257 | } |
791 | } | 1258 | } |
792 | else if ( name == VCOrgProp ) { | 1259 | else if ( name == VCOrgProp ) { |
793 | VObjectIterator nit; | 1260 | VObjectIterator nit; |
794 | initPropIterator( &nit, o ); | 1261 | initPropIterator( &nit, o ); |
795 | while( moreIteration( &nit ) ) { | 1262 | while( moreIteration( &nit ) ) { |
796 | VObject *o = nextVObject( &nit ); | 1263 | VObject *o = nextVObject( &nit ); |
797 | QCString name = vObjectName( o ); | 1264 | QCString name = vObjectName( o ); |
798 | QString value = vObjectStringZValue( o ); | 1265 | QString value = vObjectStringZValue( o ); |
799 | if ( name == VCOrgNameProp ) | 1266 | if ( name == VCOrgNameProp ) |
800 | c.setCompany( value ); | 1267 | c.setCompany( value ); |
801 | else if ( name == VCOrgUnitProp ) | 1268 | else if ( name == VCOrgUnitProp ) |
802 | c.setDepartment( value ); | 1269 | c.setDepartment( value ); |
803 | else if ( name == VCOrgUnit2Prop ) | 1270 | else if ( name == VCOrgUnit2Prop ) |
804 | c.setOffice( value ); | 1271 | c.setOffice( value ); |
805 | } | 1272 | } |
806 | } | 1273 | } |
807 | else if ( name == VCTitleProp ) { | 1274 | else if ( name == VCTitleProp ) { |
808 | c.setJobTitle( value ); | 1275 | c.setJobTitle( value ); |
809 | } | 1276 | } |
810 | else if ( name == "X-Qtopia-Profession" ) { | 1277 | else if ( name == "X-Qtopia-Profession" ) { |
811 | c.setProfession( value ); | 1278 | c.setProfession( value ); |
812 | } | 1279 | } |
813 | else if ( name == "X-Qtopia-Manager" ) { | 1280 | else if ( name == "X-Qtopia-Manager" ) { |
814 | c.setManager( value ); | 1281 | c.setManager( value ); |
815 | } | 1282 | } |
816 | else if ( name == "X-Qtopia-Assistant" ) { | 1283 | else if ( name == "X-Qtopia-Assistant" ) { |
817 | c.setAssistant( value ); | 1284 | c.setAssistant( value ); |
818 | } | 1285 | } |
819 | else if ( name == "X-Qtopia-Spouse" ) { | 1286 | else if ( name == "X-Qtopia-Spouse" ) { |
820 | c.setSpouse( value ); | 1287 | c.setSpouse( value ); |
821 | } | 1288 | } |
822 | else if ( name == "X-Qtopia-Gender" ) { | 1289 | else if ( name == "X-Qtopia-Gender" ) { |
823 | c.setGender( value ); | 1290 | c.setGender( value ); |
824 | } | 1291 | } |
825 | else if ( name == "X-Qtopia-Anniversary" ) { | 1292 | else if ( name == "X-Qtopia-Anniversary" ) { |
826 | c.setAnniversary( value ); | 1293 | c.setAnniversary( value ); |
827 | } | 1294 | } |
828 | else if ( name == "X-Qtopia-Nickname" ) { | 1295 | else if ( name == "X-Qtopia-Nickname" ) { |
829 | c.setNickname( value ); | 1296 | c.setNickname( value ); |
830 | } | 1297 | } |
831 | else if ( name == "X-Qtopia-Children" ) { | 1298 | else if ( name == "X-Qtopia-Children" ) { |
832 | c.setChildren( value ); | 1299 | c.setChildren( value ); |
833 | } | 1300 | } |
834 | 1301 | ||
835 | 1302 | ||
836 | #if 0 | 1303 | #if 0 |
837 | else { | 1304 | else { |
838 | printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) ); | 1305 | printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) ); |
839 | VObjectIterator nit; | 1306 | VObjectIterator nit; |
840 | initPropIterator( &nit, o ); | 1307 | initPropIterator( &nit, o ); |
841 | while( moreIteration( &nit ) ) { | 1308 | while( moreIteration( &nit ) ) { |
842 | VObject *o = nextVObject( &nit ); | 1309 | VObject *o = nextVObject( &nit ); |
843 | QCString name = vObjectName( o ); | 1310 | QCString name = vObjectName( o ); |
844 | QString value = vObjectStringZValue( o ); | 1311 | QString value = vObjectStringZValue( o ); |
845 | printf(" subprop: %s = %s\n", name.data(), value.latin1() ); | 1312 | printf(" subprop: %s = %s\n", name.data(), value.latin1() ); |
846 | } | 1313 | } |
847 | } | 1314 | } |
848 | #endif | 1315 | #endif |
849 | } | 1316 | } |
850 | c.setFileAs(); | 1317 | c.setFileAs(); |
851 | return c; | 1318 | return c; |
852 | } | 1319 | } |
853 | 1320 | ||
1321 | /*! | ||
1322 | Writes the list of \a contacts as a set of VCards to the file \a filename. | ||
1323 | */ | ||
854 | void Contact::writeVCard( const QString &filename, const QValueList<Contact> &contacts) | 1324 | void Contact::writeVCard( const QString &filename, const QValueList<Contact> &contacts) |
855 | { | 1325 | { |
856 | QFileDirect f( filename.utf8().data() ); | 1326 | QFileDirect f( filename.utf8().data() ); |
857 | if ( !f.open( IO_WriteOnly ) ) { | 1327 | if ( !f.open( IO_WriteOnly ) ) { |
858 | qWarning("Unable to open vcard write"); | 1328 | qWarning("Unable to open vcard write"); |
859 | return; | 1329 | return; |
860 | } | 1330 | } |
861 | 1331 | ||
862 | QValueList<Contact>::ConstIterator it; | 1332 | QValueList<Contact>::ConstIterator it; |
863 | for( it = contacts.begin(); it != contacts.end(); ++it ) { | 1333 | for( it = contacts.begin(); it != contacts.end(); ++it ) { |
864 | VObject *obj = createVObject( *it ); | 1334 | VObject *obj = createVObject( *it ); |
865 | writeVObject(f.directHandle() , obj ); | 1335 | writeVObject(f.directHandle() , obj ); |
866 | cleanVObject( obj ); | 1336 | cleanVObject( obj ); |
867 | } | 1337 | } |
868 | cleanStrTbl(); | 1338 | cleanStrTbl(); |
869 | } | 1339 | } |
870 | 1340 | ||
1341 | /*! | ||
1342 | writes \a contact as a VCard to the file \a filename. | ||
1343 | */ | ||
871 | void Contact::writeVCard( const QString &filename, const Contact &contact) | 1344 | void Contact::writeVCard( const QString &filename, const Contact &contact) |
872 | { | 1345 | { |
873 | QFileDirect f( filename.utf8().data() ); | 1346 | QFileDirect f( filename.utf8().data() ); |
874 | if ( !f.open( IO_WriteOnly ) ) { | 1347 | if ( !f.open( IO_WriteOnly ) ) { |
875 | qWarning("Unable to open vcard write"); | 1348 | qWarning("Unable to open vcard write"); |
876 | return; | 1349 | return; |
877 | } | 1350 | } |
878 | 1351 | ||
879 | VObject *obj = createVObject( contact ); | 1352 | VObject *obj = createVObject( contact ); |
880 | writeVObject( f.directHandle() , obj ); | 1353 | writeVObject( f.directHandle() , obj ); |
881 | cleanVObject( obj ); | 1354 | cleanVObject( obj ); |
882 | 1355 | ||
883 | cleanStrTbl(); | 1356 | cleanStrTbl(); |
884 | } | 1357 | } |
885 | 1358 | ||
886 | 1359 | /*! | |
1360 | Returns the set of contacts read as VCards from the file \a filename. | ||
1361 | */ | ||
887 | QValueList<Contact> Contact::readVCard( const QString &filename ) | 1362 | QValueList<Contact> Contact::readVCard( const QString &filename ) |
888 | { | 1363 | { |
889 | qDebug("trying to open %s, exists=%d", filename.utf8().data(), QFileInfo( filename.utf8().data() ).size() ); | 1364 | qDebug("trying to open %s, exists=%d", filename.utf8().data(), QFileInfo( filename.utf8().data() ).size() ); |
890 | VObject *obj = Parse_MIME_FromFileName( (char *)filename.utf8().data() ); | 1365 | VObject *obj = Parse_MIME_FromFileName( (char *)filename.utf8().data() ); |
891 | 1366 | ||
892 | qDebug("vobject = %p", obj ); | 1367 | qDebug("vobject = %p", obj ); |
893 | 1368 | ||
894 | QValueList<Contact> contacts; | 1369 | QValueList<Contact> contacts; |
895 | 1370 | ||
896 | while ( obj ) { | 1371 | while ( obj ) { |
897 | contacts.append( parseVObject( obj ) ); | 1372 | contacts.append( parseVObject( obj ) ); |
898 | 1373 | ||
899 | VObject *t = obj; | 1374 | VObject *t = obj; |
900 | obj = nextVObjectInList(obj); | 1375 | obj = nextVObjectInList(obj); |
901 | cleanVObject( t ); | 1376 | cleanVObject( t ); |
902 | } | 1377 | } |
903 | 1378 | ||
904 | return contacts; | 1379 | return contacts; |
905 | } | 1380 | } |
906 | 1381 | ||
1382 | /*! | ||
1383 | Returns TRUE if the contact matches the regular expression \a regexp. | ||
1384 | Otherwise returns FALSE. | ||
1385 | */ | ||
907 | bool Contact::match( const QString ®exp ) const | 1386 | bool Contact::match( const QString ®exp ) const |
908 | { | 1387 | { |
909 | return match(QRegExp(regexp)); | 1388 | return match(QRegExp(regexp)); |
910 | } | 1389 | } |
911 | 1390 | ||
1391 | /*! | ||
1392 | \overload | ||
1393 | Returns TRUE if the contact matches the regular expression \a regexp. | ||
1394 | Otherwise returns FALSE. | ||
1395 | */ | ||
912 | bool Contact::match( const QRegExp &r ) const | 1396 | bool Contact::match( const QRegExp &r ) const |
913 | { | 1397 | { |
914 | bool match; | 1398 | bool match; |
915 | match = false; | 1399 | match = false; |
916 | QMap<int, QString>::ConstIterator it; | 1400 | QMap<int, QString>::ConstIterator it; |
917 | for ( it = mMap.begin(); it != mMap.end(); ++it ) { | 1401 | for ( it = mMap.begin(); it != mMap.end(); ++it ) { |
918 | if ( (*it).find( r ) > -1 ) { | 1402 | if ( (*it).find( r ) > -1 ) { |
919 | match = true; | 1403 | match = true; |
920 | break; | 1404 | break; |
921 | } | 1405 | } |
922 | } | 1406 | } |
923 | return match; | 1407 | return match; |
924 | } | 1408 | } |
diff --git a/library/backend/contact.h b/library/backend/contact.h index a74cbbe..4999430 100644 --- a/library/backend/contact.h +++ b/library/backend/contact.h | |||
@@ -1,222 +1,306 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2001 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. |
3 | ** | 3 | ** |
4 | ** This file is part of Qtopia Environment. | 4 | ** This file is part of the Qtopia Environment. |
5 | ** | 5 | ** |
6 | ** This file may be distributed and/or modified under the terms of the | 6 | ** This file may be distributed and/or modified under the terms of the |
7 | ** GNU General Public License version 2 as published by the Free Software | 7 | ** GNU General Public License version 2 as published by the Free Software |
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** packaging of this file. | 9 | ** packaging of this file. |
10 | ** | 10 | ** |
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | 11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
13 | ** | 13 | ** |
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
15 | ** | 15 | ** |
16 | ** Contact info@trolltech.com if any conditions of this licensing are | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
17 | ** not clear to you. | 17 | ** not clear to you. |
18 | ** | 18 | ** |
19 | **********************************************************************/ | 19 | **********************************************************************/ |
20 | 20 | ||
21 | #ifndef __CONTACT_H__ | 21 | #ifndef __CONTACT_H__ |
22 | #define __CONTACT_H__ | 22 | #define __CONTACT_H__ |
23 | 23 | ||
24 | #include <qpe/palmtoprecord.h> | 24 | #include <qtopia/private/palmtoprecord.h> |
25 | #include <qpe/recordfields.h> | 25 | #include <qtopia/private/recordfields.h> |
26 | 26 | ||
27 | #include <qstringlist.h> | 27 | #include <qstringlist.h> |
28 | 28 | ||
29 | #if defined(QPC_TEMPLATEDLL) | 29 | #if defined(QPC_TEMPLATEDLL) |
30 | // MOC_SKIP_BEGIN | 30 | // MOC_SKIP_BEGIN |
31 | template class QPC_EXPORT QMap<int, QString>; | 31 | QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<int, QString>; |
32 | // MOC_SKIP_END | 32 | // MOC_SKIP_END |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | class ContactPrivate; | 35 | class ContactPrivate; |
36 | class QPC_EXPORT Contact : public Qtopia::Record | 36 | class QPC_EXPORT Contact : public Qtopia::Record |
37 | { | 37 | { |
38 | friend class DataSet; | 38 | friend class DataSet; |
39 | public: | 39 | public: |
40 | Contact(); | 40 | Contact(); |
41 | Contact( const QMap<int, QString> &fromMap ); | 41 | Contact( const QMap<int, QString> &fromMap ); |
42 | virtual ~Contact(); | 42 | virtual ~Contact(); |
43 | 43 | ||
44 | static void writeVCard( const QString &filename, const QValueList<Contact> &contacts); | 44 | static void writeVCard( const QString &filename, const QValueList<Contact> &contacts); |
45 | static void writeVCard( const QString &filename, const Contact &c ); | 45 | static void writeVCard( const QString &filename, const Contact &c ); |
46 | static QValueList<Contact> readVCard( const QString &filename ); | 46 | static QValueList<Contact> readVCard( const QString &filename ); |
47 | 47 | ||
48 | enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; | 48 | enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE }; |
49 | 49 | ||
50 | void setTitle( const QString &v ) { replace( Qtopia::Title, v ); } | 50 | void setTitle( const QString &v ) { replace( Qtopia::Title, v ); } |
51 | void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); } | 51 | void setFirstName( const QString &v ) { replace( Qtopia::FirstName, v ); } |
52 | void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); } | 52 | void setMiddleName( const QString &v ) { replace( Qtopia::MiddleName, v ); } |
53 | void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); } | 53 | void setLastName( const QString &v ) { replace( Qtopia::LastName, v ); } |
54 | void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); } | 54 | void setSuffix( const QString &v ) { replace( Qtopia::Suffix, v ); } |
55 | void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); } | 55 | void setFileAs( const QString &v ) { replace( Qtopia::FileAs, v ); } |
56 | void setFileAs(); | 56 | void setFileAs(); |
57 | 57 | ||
58 | // default email address | 58 | // default email address |
59 | void setDefaultEmail( const QString &v ) { replace( Qtopia::DefaultEmail, v ); } | 59 | void setDefaultEmail( const QString &v ); |
60 | // the emails should be seperated by a semicolon | 60 | // inserts email to list and ensure's doesn't already exist |
61 | void setEmails( const QString &v ); | 61 | void insertEmail( const QString &v ); |
62 | void removeEmail( const QString &v ); | ||
63 | void clearEmails(); | ||
64 | void insertEmails( const QStringList &v ); | ||
62 | 65 | ||
63 | // home | 66 | // home |
64 | void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); } | 67 | void setHomeStreet( const QString &v ) { replace( Qtopia::HomeStreet, v ); } |
65 | void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); } | 68 | void setHomeCity( const QString &v ) { replace( Qtopia::HomeCity, v ); } |
66 | void setHomeState( const QString &v ) { replace( Qtopia::HomeState, v ); } | 69 | void setHomeState( const QString &v ) { replace( Qtopia::HomeState, v ); } |
67 | void setHomeZip( const QString &v ) { replace( Qtopia::HomeZip, v ); } | 70 | void setHomeZip( const QString &v ) { replace( Qtopia::HomeZip, v ); } |
68 | void setHomeCountry( const QString &v ) { replace( Qtopia::HomeCountry, v ); } | 71 | void setHomeCountry( const QString &v ) { replace( Qtopia::HomeCountry, v ); } |
69 | void setHomePhone( const QString &v ) { replace( Qtopia::HomePhone, v ); } | 72 | void setHomePhone( const QString &v ) { replace( Qtopia::HomePhone, v ); } |
70 | void setHomeFax( const QString &v ) { replace( Qtopia::HomeFax, v ); } | 73 | void setHomeFax( const QString &v ) { replace( Qtopia::HomeFax, v ); } |
71 | void setHomeMobile( const QString &v ) { replace( Qtopia::HomeMobile, v ); } | 74 | void setHomeMobile( const QString &v ) { replace( Qtopia::HomeMobile, v ); } |
72 | void setHomeWebpage( const QString &v ) { replace( Qtopia::HomeWebPage, v ); } | 75 | void setHomeWebpage( const QString &v ) { replace( Qtopia::HomeWebPage, v ); } |
73 | 76 | ||
74 | // business | 77 | // business |
75 | void setCompany( const QString &v ) { replace( Qtopia::Company, v ); } | 78 | void setCompany( const QString &v ) { replace( Qtopia::Company, v ); } |
76 | void setBusinessStreet( const QString &v ) { replace( Qtopia::BusinessStreet, v ); } | 79 | void setBusinessStreet( const QString &v ) { replace( Qtopia::BusinessStreet, v ); } |
77 | void setBusinessCity( const QString &v ) { replace( Qtopia::BusinessCity, v ); } | 80 | void setBusinessCity( const QString &v ) { replace( Qtopia::BusinessCity, v ); } |
78 | void setBusinessState( const QString &v ) { replace( Qtopia::BusinessState, v ); } | 81 | void setBusinessState( const QString &v ) { replace( Qtopia::BusinessState, v ); } |
79 | void setBusinessZip( const QString &v ) { replace( Qtopia::BusinessZip, v ); } | 82 | void setBusinessZip( const QString &v ) { replace( Qtopia::BusinessZip, v ); } |
80 | void setBusinessCountry( const QString &v ) { replace( Qtopia::BusinessCountry, v ); } | 83 | void setBusinessCountry( const QString &v ) { replace( Qtopia::BusinessCountry, v ); } |
81 | void setBusinessWebpage( const QString &v ) { replace( Qtopia::BusinessWebPage, v ); } | 84 | void setBusinessWebpage( const QString &v ) { replace( Qtopia::BusinessWebPage, v ); } |
82 | void setJobTitle( const QString &v ) { replace( Qtopia::JobTitle, v ); } | 85 | void setJobTitle( const QString &v ) { replace( Qtopia::JobTitle, v ); } |
83 | void setDepartment( const QString &v ) { replace( Qtopia::Department, v ); } | 86 | void setDepartment( const QString &v ) { replace( Qtopia::Department, v ); } |
84 | void setOffice( const QString &v ) { replace( Qtopia::Office, v ); } | 87 | void setOffice( const QString &v ) { replace( Qtopia::Office, v ); } |
85 | void setBusinessPhone( const QString &v ) { replace( Qtopia::BusinessPhone, v ); } | 88 | void setBusinessPhone( const QString &v ) { replace( Qtopia::BusinessPhone, v ); } |
86 | void setBusinessFax( const QString &v ) { replace( Qtopia::BusinessFax, v ); } | 89 | void setBusinessFax( const QString &v ) { replace( Qtopia::BusinessFax, v ); } |
87 | void setBusinessMobile( const QString &v ) { replace( Qtopia::BusinessMobile, v ); } | 90 | void setBusinessMobile( const QString &v ) { replace( Qtopia::BusinessMobile, v ); } |
88 | void setBusinessPager( const QString &v ) { replace( Qtopia::BusinessPager, v ); } | 91 | void setBusinessPager( const QString &v ) { replace( Qtopia::BusinessPager, v ); } |
89 | void setProfession( const QString &v ) { replace( Qtopia::Profession, v ); } | 92 | void setProfession( const QString &v ) { replace( Qtopia::Profession, v ); } |
90 | void setAssistant( const QString &v ) { replace( Qtopia::Assistant, v ); } | 93 | void setAssistant( const QString &v ) { replace( Qtopia::Assistant, v ); } |
91 | void setManager( const QString &v ) { replace( Qtopia::Manager, v ); } | 94 | void setManager( const QString &v ) { replace( Qtopia::Manager, v ); } |
92 | 95 | ||
93 | // personal | 96 | // personal |
94 | void setSpouse( const QString &v ) { replace( Qtopia::Spouse, v ); } | 97 | void setSpouse( const QString &v ) { replace( Qtopia::Spouse, v ); } |
95 | void setGender( const QString &v ) { replace( Qtopia::Gender, v ); } | 98 | void setGender( const QString &v ) { replace( Qtopia::Gender, v ); } |
96 | void setBirthday( const QString &v ) { replace( Qtopia::Birthday, v ); } | 99 | void setBirthday( const QString &v ) { replace( Qtopia::Birthday, v ); } |
97 | void setAnniversary( const QString &v ) { replace( Qtopia::Anniversary, v ); } | 100 | void setAnniversary( const QString &v ) { replace( Qtopia::Anniversary, v ); } |
98 | void setNickname( const QString &v ) { replace( Qtopia::Nickname, v ); } | 101 | void setNickname( const QString &v ) { replace( Qtopia::Nickname, v ); } |
99 | void setChildren( const QString &v ); | 102 | void setChildren( const QString &v ); |
100 | 103 | ||
101 | // other | 104 | // other |
102 | void setNotes( const QString &v ) { replace( Qtopia::Notes, v); } | 105 | void setNotes( const QString &v ) { replace( Qtopia::Notes, v); } |
103 | 106 | ||
104 | bool match( const QString ®exp ) const; | 107 | bool match( const QString ®exp ) const; |
105 | 108 | ||
106 | // DON'T ATTEMPT TO USE THIS | 109 | // DON'T ATTEMPT TO USE THIS |
107 | #ifdef QTOPIA_INTERNAL_CONTACT_MRE | 110 | #ifdef QTOPIA_INTERNAL_CONTACT_MRE |
108 | bool match( const QRegExp ®exp ) const; | 111 | bool match( const QRegExp ®exp ) const; |
109 | #endif | 112 | #endif |
110 | 113 | ||
111 | // // custom | 114 | // // custom |
112 | // void setCustomField( const QString &key, const QString &v ) | 115 | // void setCustomField( const QString &key, const QString &v ) |
113 | // { replace(Custom- + key, v ); } | 116 | // { replace(Custom- + key, v ); } |
114 | 117 | ||
115 | // name | 118 | // name |
116 | QString fullName() const; | 119 | QString fullName() const; |
117 | QString title() const { return find( Qtopia::Title ); } | 120 | QString title() const { return find( Qtopia::Title ); } |
118 | QString firstName() const { return find( Qtopia::FirstName ); } | 121 | QString firstName() const { return find( Qtopia::FirstName ); } |
119 | QString middleName() const { return find( Qtopia::MiddleName ); } | 122 | QString middleName() const { return find( Qtopia::MiddleName ); } |
120 | QString lastName() const { return find( Qtopia::LastName ); } | 123 | QString lastName() const { return find( Qtopia::LastName ); } |
121 | QString suffix() const { return find( Qtopia::Suffix ); } | 124 | QString suffix() const { return find( Qtopia::Suffix ); } |
122 | QString fileAs() const { return find( Qtopia::FileAs ); } | 125 | QString fileAs() const { return find( Qtopia::FileAs ); } |
123 | 126 | ||
124 | 127 | ||
125 | QString defaultEmail() const { return find( Qtopia::DefaultEmail ); } | 128 | QString defaultEmail() const { return find( Qtopia::DefaultEmail ); } |
126 | QString emails() const { return find( Qtopia::Emails ); } | ||
127 | QStringList emailList() const; | 129 | QStringList emailList() const; |
128 | 130 | ||
129 | // home | 131 | // home |
130 | QString homeStreet() const { return find( Qtopia::HomeStreet ); } | 132 | QString homeStreet() const { return find( Qtopia::HomeStreet ); } |
131 | QString homeCity() const { return find( Qtopia::HomeCity ); } | 133 | QString homeCity() const { return find( Qtopia::HomeCity ); } |
132 | QString homeState() const { return find( Qtopia::HomeState ); } | 134 | QString homeState() const { return find( Qtopia::HomeState ); } |
133 | QString homeZip() const { return find( Qtopia::HomeZip ); } | 135 | QString homeZip() const { return find( Qtopia::HomeZip ); } |
134 | QString homeCountry() const { return find( Qtopia::HomeCountry ); } | 136 | QString homeCountry() const { return find( Qtopia::HomeCountry ); } |
135 | QString homePhone() const { return find( Qtopia::HomePhone ); } | 137 | QString homePhone() const { return find( Qtopia::HomePhone ); } |
136 | QString homeFax() const { return find( Qtopia::HomeFax ); } | 138 | QString homeFax() const { return find( Qtopia::HomeFax ); } |
137 | QString homeMobile() const { return find( Qtopia::HomeMobile ); } | 139 | QString homeMobile() const { return find( Qtopia::HomeMobile ); } |
138 | QString homeWebpage() const { return find( Qtopia::HomeWebPage ); } | 140 | QString homeWebpage() const { return find( Qtopia::HomeWebPage ); } |
139 | /** Multi line string containing all non-empty address info in the form | 141 | /** Multi line string containing all non-empty address info in the form |
140 | * Street | 142 | * Street |
141 | * City, State Zip | 143 | * City, State Zip |
142 | * Country | 144 | * Country |
143 | */ | 145 | */ |
144 | QString displayHomeAddress() const; | 146 | QString displayHomeAddress() const; |
145 | 147 | ||
146 | // business | 148 | // business |
147 | QString company() const { return find( Qtopia::Company ); } | 149 | QString company() const { return find( Qtopia::Company ); } |
148 | QString businessStreet() const { return find( Qtopia::BusinessStreet ); } | 150 | QString businessStreet() const { return find( Qtopia::BusinessStreet ); } |
149 | QString businessCity() const { return find( Qtopia::BusinessCity ); } | 151 | QString businessCity() const { return find( Qtopia::BusinessCity ); } |
150 | QString businessState() const { return find( Qtopia::BusinessState ); } | 152 | QString businessState() const { return find( Qtopia::BusinessState ); } |
151 | QString businessZip() const { return find( Qtopia::BusinessZip ); } | 153 | QString businessZip() const { return find( Qtopia::BusinessZip ); } |
152 | QString businessCountry() const { return find( Qtopia::BusinessCountry ); } | 154 | QString businessCountry() const { return find( Qtopia::BusinessCountry ); } |
153 | QString businessWebpage() const { return find( Qtopia::BusinessWebPage ); } | 155 | QString businessWebpage() const { return find( Qtopia::BusinessWebPage ); } |
154 | QString jobTitle() const { return find( Qtopia::JobTitle ); } | 156 | QString jobTitle() const { return find( Qtopia::JobTitle ); } |
155 | QString department() const { return find( Qtopia::Department ); } | 157 | QString department() const { return find( Qtopia::Department ); } |
156 | QString office() const { return find( Qtopia::Office ); } | 158 | QString office() const { return find( Qtopia::Office ); } |
157 | QString businessPhone() const { return find( Qtopia::BusinessPhone ); } | 159 | QString businessPhone() const { return find( Qtopia::BusinessPhone ); } |
158 | QString businessFax() const { return find( Qtopia::BusinessFax ); } | 160 | QString businessFax() const { return find( Qtopia::BusinessFax ); } |
159 | QString businessMobile() const { return find( Qtopia::BusinessMobile ); } | 161 | QString businessMobile() const { return find( Qtopia::BusinessMobile ); } |
160 | QString businessPager() const { return find( Qtopia::BusinessPager ); } | 162 | QString businessPager() const { return find( Qtopia::BusinessPager ); } |
161 | QString profession() const { return find( Qtopia::Profession ); } | 163 | QString profession() const { return find( Qtopia::Profession ); } |
162 | QString assistant() const { return find( Qtopia::Assistant ); } | 164 | QString assistant() const { return find( Qtopia::Assistant ); } |
163 | QString manager() const { return find( Qtopia::Manager ); } | 165 | QString manager() const { return find( Qtopia::Manager ); } |
164 | /** Multi line string containing all non-empty address info in the form | 166 | /** Multi line string containing all non-empty address info in the form |
165 | * Street | 167 | * Street |
166 | * City, State Zip | 168 | * City, State Zip |
167 | * Country | 169 | * Country |
168 | */ | 170 | */ |
169 | QString displayBusinessAddress() const; | 171 | QString displayBusinessAddress() const; |
170 | 172 | ||
171 | //personal | 173 | //personal |
172 | QString spouse() const { return find( Qtopia::Spouse ); } | 174 | QString spouse() const { return find( Qtopia::Spouse ); } |
173 | QString gender() const { return find( Qtopia::Gender ); } | 175 | QString gender() const { return find( Qtopia::Gender ); } |
174 | QString birthday() const { return find( Qtopia::Birthday ); } | 176 | QString birthday() const { return find( Qtopia::Birthday ); } |
175 | QString anniversary() const { return find( Qtopia::Anniversary ); } | 177 | QString anniversary() const { return find( Qtopia::Anniversary ); } |
176 | QString nickname() const { return find( Qtopia::Nickname ); } | 178 | QString nickname() const { return find( Qtopia::Nickname ); } |
177 | QString children() const { return find( Qtopia::Children ); } | 179 | QString children() const { return find( Qtopia::Children ); } |
178 | QStringList childrenList() const; | 180 | QStringList childrenList() const; |
179 | 181 | ||
180 | // other | 182 | // other |
181 | QString notes() const { return find( Qtopia::Notes ); } | 183 | QString notes() const { return find( Qtopia::Notes ); } |
182 | QString groups() const { return find( Qtopia::Groups ); } | 184 | QString groups() const { return find( Qtopia::Groups ); } |
183 | QStringList groupList() const; | 185 | QStringList groupList() const; |
184 | 186 | ||
185 | // // custom | 187 | // // custom |
186 | // const QString &customField( const QString &key ) | 188 | // const QString &customField( const QString &key ) |
187 | // { return find( Custom- + key ); } | 189 | // { return find( Custom- + key ); } |
188 | 190 | ||
189 | static QStringList fields(); | 191 | static QStringList fields(); |
190 | static QStringList trfields(); | 192 | static QStringList trfields(); |
191 | 193 | ||
192 | QString toRichText() const; | 194 | QString toRichText() const; |
193 | QMap<int, QString> toMap() const; | 195 | QMap<int, QString> toMap() const; |
194 | QString field( int key ) const { return find( key ); } | 196 | QString field( int key ) const { return find( key ); } |
195 | 197 | ||
196 | 198 | ||
197 | // journaling... | 199 | // journaling... |
198 | void saveJournal( journal_action action, const QString &key = QString::null ); | 200 | void saveJournal( journal_action action, const QString &key = QString::null ); |
199 | void save( QString &buf ) const; | 201 | void save( QString &buf ) const; |
200 | 202 | ||
201 | void setUid( int i ) | 203 | void setUid( int i ) |
202 | { Record::setUid(i); replace( Qtopia::AddressUid , QString::number(i)); } | 204 | { Record::setUid(i); replace( Qtopia::AddressUid , QString::number(i)); } |
203 | 205 | ||
204 | private: | 206 | private: |
207 | friend class AbEditor; | ||
205 | friend class AbTable; | 208 | friend class AbTable; |
209 | friend class AddressBookAccessPrivate; | ||
210 | friend class XMLIO; | ||
211 | |||
212 | QString emailSeparator() const { return " "; } | ||
213 | // the emails should be seperated by a comma | ||
214 | void setEmails( const QString &v ); | ||
215 | QString emails() const { return find( Qtopia::Emails ); } | ||
216 | |||
206 | void insert( int key, const QString &value ); | 217 | void insert( int key, const QString &value ); |
207 | void replace( int key, const QString &value ); | 218 | void replace( int key, const QString &value ); |
208 | QString find( int key ) const; | 219 | QString find( int key ) const; |
209 | 220 | ||
210 | QString displayAddress( const QString &street, | 221 | QString displayAddress( const QString &street, |
211 | const QString &city, | 222 | const QString &city, |
212 | const QString &state, | 223 | const QString &state, |
213 | const QString &zip, | 224 | const QString &zip, |
214 | const QString &country ) const; | 225 | const QString &country ) const; |
215 | 226 | ||
216 | Qtopia::UidGen &uidGen() { return sUidGen; } | 227 | Qtopia::UidGen &uidGen() { return sUidGen; } |
217 | static Qtopia::UidGen sUidGen; | 228 | static Qtopia::UidGen sUidGen; |
218 | QMap<int, QString> mMap; | 229 | QMap<int, QString> mMap; |
219 | ContactPrivate *d; | 230 | ContactPrivate *d; |
220 | }; | 231 | }; |
221 | 232 | ||
233 | // these methods are inlined to keep binary compatability with Qtopia 1.5 | ||
234 | inline void Contact::insertEmail( const QString &v ) | ||
235 | { | ||
236 | //qDebug("insertEmail %s", v.latin1()); | ||
237 | QString e = v.simplifyWhiteSpace(); | ||
238 | QString def = defaultEmail(); | ||
239 | |||
240 | // if no default, set it as the default email and don't insert | ||
241 | if ( def.isEmpty() ) { | ||
242 | setDefaultEmail( e ); // will insert into the list for us | ||
243 | return; | ||
244 | } | ||
245 | |||
246 | // otherwise, insert assuming doesn't already exist | ||
247 | QString emailsStr = find( Qtopia::Emails ); | ||
248 | if ( emailsStr.contains( e )) | ||
249 | return; | ||
250 | if ( !emailsStr.isEmpty() ) | ||
251 | emailsStr += emailSeparator(); | ||
252 | emailsStr += e; | ||
253 | replace( Qtopia::Emails, emailsStr ); | ||
254 | } | ||
255 | |||
256 | inline void Contact::removeEmail( const QString &v ) | ||
257 | { | ||
258 | QString e = v.simplifyWhiteSpace(); | ||
259 | QString def = defaultEmail(); | ||
260 | QString emailsStr = find( Qtopia::Emails ); | ||
261 | QStringList emails = emailList(); | ||
262 | |||
263 | // otherwise, must first contain it | ||
264 | if ( !emailsStr.contains( e ) ) | ||
265 | return; | ||
266 | |||
267 | // remove it | ||
268 | //qDebug(" removing email from list %s", e.latin1()); | ||
269 | emails.remove( e ); | ||
270 | // reset the string | ||
271 | emailsStr = emails.join(emailSeparator()); // Sharp's brain dead separator | ||
272 | replace( Qtopia::Emails, emailsStr ); | ||
273 | |||
274 | // if default, then replace the default email with the first one | ||
275 | if ( def == e ) { | ||
276 | //qDebug("removeEmail is default; setting new default"); | ||
277 | if ( !emails.count() ) | ||
278 | clearEmails(); | ||
279 | else // setDefaultEmail will remove e from the list | ||
280 | setDefaultEmail( emails.first() ); | ||
281 | } | ||
282 | } | ||
283 | inline void Contact::clearEmails() | ||
284 | { | ||
285 | mMap.remove( Qtopia::DefaultEmail ); | ||
286 | mMap.remove( Qtopia::Emails ); | ||
287 | } | ||
288 | inline void Contact::setDefaultEmail( const QString &v ) | ||
289 | { | ||
290 | QString e = v.simplifyWhiteSpace(); | ||
291 | |||
292 | //qDebug("Contact::setDefaultEmail %s", e.latin1()); | ||
293 | replace( Qtopia::DefaultEmail, e ); | ||
294 | |||
295 | if ( !e.isEmpty() ) | ||
296 | insertEmail( e ); | ||
297 | |||
298 | } | ||
299 | |||
300 | inline void Contact::insertEmails( const QStringList &v ) | ||
301 | { | ||
302 | for ( QStringList::ConstIterator it = v.begin(); it != v.end(); ++it ) | ||
303 | insertEmail( *it ); | ||
304 | } | ||
305 | |||
222 | #endif | 306 | #endif |
diff --git a/library/backend/event.cpp b/library/backend/event.cpp index 50a663d..7110717 100644 --- a/library/backend/event.cpp +++ b/library/backend/event.cpp | |||
@@ -1,830 +1,1315 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2001 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. |
3 | ** | 3 | ** |
4 | ** This file is part of Qtopia Environment. | 4 | ** This file is part of the Qtopia Environment. |
5 | ** | 5 | ** |
6 | ** This file may be distributed and/or modified under the terms of the | 6 | ** This file may be distributed and/or modified under the terms of the |
7 | ** GNU General Public License version 2 as published by the Free Software | 7 | ** GNU General Public License version 2 as published by the Free Software |
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** packaging of this file. | 9 | ** packaging of this file. |
10 | ** | 10 | ** |
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | 11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
13 | ** | 13 | ** |
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
15 | ** | 15 | ** |
16 | ** Contact info@trolltech.com if any conditions of this licensing are | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
17 | ** not clear to you. | 17 | ** not clear to you. |
18 | ** | 18 | ** |
19 | **********************************************************************/ | 19 | **********************************************************************/ |
20 | 20 | ||
21 | #include "event.h" | 21 | #include "event.h" |
22 | #include "qfiledirect_p.h" | 22 | #include "qfiledirect_p.h" |
23 | #include <qpe/timeconversion.h> | 23 | #include <qtopia/timeconversion.h> |
24 | #include <qpe/stringutil.h> | 24 | #include <qtopia/stringutil.h> |
25 | #include <qpe/recordfields.h> | 25 | #include <qtopia/private/recordfields.h> |
26 | #include <qbuffer.h> | 26 | #include <qbuffer.h> |
27 | #include <time.h> | 27 | #include <time.h> |
28 | #include "vobject_p.h" | 28 | #include "vobject_p.h" |
29 | 29 | ||
30 | #include <stdio.h> | 30 | #include <stdio.h> |
31 | 31 | ||
32 | using namespace Qtopia; | 32 | using namespace Qtopia; |
33 | 33 | ||
34 | static void write( QString& buf, const Event::RepeatPattern &r ) | 34 | static void write( QString& buf, const Event::RepeatPattern &r ) |
35 | { | 35 | { |
36 | buf += " rtype=\""; | 36 | buf += " rtype=\""; |
37 | switch ( r.type ) { | 37 | switch ( r.type ) { |
38 | case Event::Daily: | 38 | case Event::Daily: |
39 | buf += "Daily"; | 39 | buf += "Daily"; |
40 | break; | 40 | break; |
41 | case Event::Weekly: | 41 | case Event::Weekly: |
42 | buf += "Weekly"; | 42 | buf += "Weekly"; |
43 | break; | 43 | break; |
44 | case Event::MonthlyDay: | 44 | case Event::MonthlyDay: |
45 | buf += "MonthlyDay"; | 45 | buf += "MonthlyDay"; |
46 | break; | 46 | break; |
47 | case Event::MonthlyDate: | 47 | case Event::MonthlyDate: |
48 | buf += "MonthlyDate"; | 48 | buf += "MonthlyDate"; |
49 | break; | 49 | break; |
50 | case Event::Yearly: | 50 | case Event::Yearly: |
51 | buf += "Yearly"; | 51 | buf += "Yearly"; |
52 | break; | 52 | break; |
53 | default: | 53 | default: |
54 | buf += "NoRepeat"; | 54 | buf += "NoRepeat"; |
55 | break; | 55 | break; |
56 | } | 56 | } |
57 | buf += "\""; | 57 | buf += "\""; |
58 | if ( r.days > 0 ) | 58 | if ( r.days > 0 ) |
59 | buf += " rweekdays=\"" + QString::number( static_cast<int>( r.days ) ) + "\""; | 59 | buf += " rweekdays=\"" + QString::number( static_cast<int>( r.days ) ) + "\""; |
60 | if ( r.position != 0 ) | 60 | if ( r.position != 0 ) |
61 | buf += " rposition=\"" + QString::number( r.position ) + "\""; | 61 | buf += " rposition=\"" + QString::number( r.position ) + "\""; |
62 | 62 | ||
63 | buf += " rfreq=\"" + QString::number( r.frequency ) + "\""; | 63 | buf += " rfreq=\"" + QString::number( r.frequency ) + "\""; |
64 | buf += " rhasenddate=\"" + QString::number( static_cast<int>( r.hasEndDate ) ) + "\""; | 64 | buf += " rhasenddate=\"" + QString::number( static_cast<int>( r.hasEndDate ) ) + "\""; |
65 | if ( r.hasEndDate ) | 65 | if ( r.hasEndDate ) |
66 | buf += " enddt=\"" | 66 | buf += " enddt=\"" |
67 | + QString::number( r.endDateUTC ? r.endDateUTC : time( 0 ) ) | 67 | + QString::number( r.endDateUTC ? r.endDateUTC : time( 0 ) ) |
68 | + "\""; | 68 | + "\""; |
69 | buf += " created=\"" + QString::number( r.createTime ) + "\""; | 69 | buf += " created=\"" + QString::number( r.createTime ) + "\""; |
70 | } | 70 | } |
71 | 71 | ||
72 | Qtopia::UidGen Event::sUidGen( Qtopia::UidGen::Qtopia ); | 72 | Qtopia::UidGen Event::sUidGen( Qtopia::UidGen::Qtopia ); |
73 | 73 | ||
74 | /*! | ||
75 | \class Event event.h | ||
76 | \brief The Event class holds the data of a calendar event. | ||
77 | |||
78 | This data includes descriptive data of the event and schedualing information. | ||
79 | |||
80 | \ingroup qtopiaemb | ||
81 | \ingroup qtopiadesktop | ||
82 | */ | ||
83 | |||
84 | /*! | ||
85 | \class Event::RepeatPattern | ||
86 | \class The Event::RepeatPattern class is internal. | ||
87 | \internal | ||
88 | */ | ||
89 | |||
90 | /*! | ||
91 | \enum Event::Days | ||
92 | \internal | ||
93 | */ | ||
94 | |||
95 | /*! | ||
96 | \enum Event::Type | ||
97 | \internal | ||
98 | */ | ||
99 | |||
100 | /*! | ||
101 | \enum Event::SoundTypeChoice | ||
102 | |||
103 | This enum type defines what kind of sound is made when an alarm occurs | ||
104 | for an event. The currently defined types are: | ||
105 | |||
106 | <ul> | ||
107 | <li>\c Silent - No sound is produced. | ||
108 | <li>\c Loud - A loud sound is produced. | ||
109 | </ul> | ||
110 | */ | ||
111 | |||
112 | /*! | ||
113 | \fn bool Event::operator<( const Event & ) const | ||
114 | \internal | ||
115 | */ | ||
116 | |||
117 | /*! | ||
118 | \fn bool Event::operator<=( const Event & ) const | ||
119 | \internal | ||
120 | */ | ||
121 | |||
122 | /*! | ||
123 | \fn bool Event::operator!=( const Event & ) const | ||
124 | \internal | ||
125 | */ | ||
126 | |||
127 | /*! | ||
128 | \fn bool Event::operator>( const Event & ) const | ||
129 | \internal | ||
130 | */ | ||
131 | |||
132 | /*! | ||
133 | \fn bool Event::operator>=( const Event & ) const | ||
134 | \internal | ||
135 | */ | ||
136 | |||
137 | /*! | ||
138 | \enum Event::RepeatType | ||
139 | |||
140 | This enum defines how a event will repeat, if at all. | ||
141 | |||
142 | <ul> | ||
143 | <li>\c NoRepeat - Event does not repeat. | ||
144 | <li>\c Daily - Event occurs every n days. | ||
145 | <li>\c Weekly - Event occurs every n weeks. | ||
146 | <li>\c MonthlyDay - Event occurs every n months. Event will always occur in | ||
147 | the same week and same day of week as the first event. | ||
148 | <li>\c MonthlyDate - Event occurs every n months. Event will always occur | ||
149 | on the same day of the month as the first event. | ||
150 | <li>\c Yearly - Event occurs every n years. | ||
151 | </ul> | ||
152 | */ | ||
153 | |||
154 | /*! | ||
155 | \fn bool Event::isAllDay() const | ||
156 | |||
157 | Returns TRUE if the event is an all day event. Otherwise returns FALSE. | ||
158 | */ | ||
159 | |||
160 | /*! | ||
161 | \fn void Event::setAllDay(bool allday) | ||
162 | |||
163 | If \a allday is TRUE, will set the event to be an all day event. | ||
164 | Otherwise sets the event to not be an all day event. | ||
165 | |||
166 | \warning This function may affect the start and end times of the event. | ||
167 | */ | ||
168 | |||
169 | /*! | ||
170 | \fn QDateTime Event::start() const | ||
171 | |||
172 | Returns the start date and time of the first occurance of the event. | ||
173 | */ | ||
174 | |||
175 | /*! | ||
176 | \fn QDateTime Event::end() const | ||
177 | |||
178 | Returns the end date and time of the first occurance of the event. | ||
179 | */ | ||
180 | |||
181 | /*! | ||
182 | \fn time_t Event::startTime() const | ||
183 | \internal | ||
184 | */ | ||
185 | |||
186 | /*! | ||
187 | \fn time_t Event::endTime() const | ||
188 | \internal | ||
189 | */ | ||
190 | |||
191 | /*! | ||
192 | \fn void Event::setAlarm(int delay, SoundTypeChoice s) | ||
193 | |||
194 | Sets the alarm delay of the event to \a delay and the sound type of the | ||
195 | alarm to \a s. | ||
196 | */ | ||
197 | |||
198 | /*! | ||
199 | \fn void Event::clearAlarm() | ||
200 | |||
201 | Clears the alarm for the event. | ||
202 | */ | ||
203 | |||
204 | /*! | ||
205 | \fn int Event::alarmDelay() const | ||
206 | |||
207 | Returns the delay in minutes between the alarm for an event and the | ||
208 | start of the event. | ||
209 | */ | ||
210 | |||
211 | /*! | ||
212 | \fn Event::RepeatType Event::repeatType() const | ||
213 | |||
214 | Returns the repeat pattern type for the event. | ||
215 | |||
216 | \sa frequency() | ||
217 | */ | ||
218 | |||
219 | /*! | ||
220 | \fn int Event::weekOffset() const | ||
221 | |||
222 | Returns the number of weeks from the start of the month that this event | ||
223 | occurs. | ||
224 | */ | ||
225 | |||
226 | /*! | ||
227 | \fn QDate Event::repeatTill() const | ||
228 | |||
229 | Returns the date that the event will continue to repeat until. If the event | ||
230 | repeats forever the value returned is undefined. | ||
231 | |||
232 | \sa repeatForever() | ||
233 | */ | ||
234 | |||
235 | /*! | ||
236 | \fn bool Event::repeatForever() const | ||
237 | |||
238 | Returns FALSE if there is a date set for the event to continue until. | ||
239 | Otherwise returns TRUE. | ||
240 | */ | ||
241 | |||
242 | /*! | ||
243 | \fn bool Event::doRepeat() const | ||
244 | \internal | ||
245 | */ | ||
246 | |||
247 | /*! | ||
248 | \fn bool Event::repeatOnWeekDay(int day) const | ||
249 | |||
250 | Returns TRUE if the event has a RepeatType of Weekly and is set to occur on | ||
251 | \a day each week. Otherwise returns FALSE. | ||
252 | |||
253 | \sa QDate::dayName() | ||
254 | */ | ||
255 | |||
256 | /*! | ||
257 | \fn void Event::setRepeatOnWeekDay(int day, bool enable) | ||
258 | |||
259 | If \a enable is TRUE then sets the event to occur on \a day each week. | ||
260 | Otherwise sets the event not to occur on \a day. | ||
261 | |||
262 | \warning this function is only relavent for a event with RepeatType of | ||
263 | Weekly. | ||
264 | |||
265 | \sa QDate::dayName() | ||
266 | */ | ||
267 | |||
268 | /*! | ||
269 | \fn int Event::frequency() const | ||
270 | |||
271 | Returns how often the event repeats. | ||
272 | |||
273 | \sa repeatType() | ||
274 | */ | ||
275 | |||
276 | /*! | ||
277 | \fn void Event::setRepeatType(RepeatType t) | ||
278 | |||
279 | Sets the repeat pattern type of the event to \a t. | ||
280 | |||
281 | \sa setFrequency() | ||
282 | */ | ||
283 | |||
284 | /*! | ||
285 | \fn void Event::setFrequency(int n) | ||
286 | |||
287 | Sets how often the event occurs with in its repeat pattern. | ||
288 | |||
289 | \sa setRepeatType() | ||
290 | */ | ||
291 | |||
292 | /*! | ||
293 | \fn void Event::setRepeatTill(const QDate &d) | ||
294 | |||
295 | Sets the event to repeat until \a d. | ||
296 | */ | ||
297 | |||
298 | /*! | ||
299 | \fn void Event::setRepeatForever(bool enable) | ||
300 | |||
301 | If \a enable is TRUE, sets the event to repeat forever. Otherwise | ||
302 | sets the event to stop repeating at some date. | ||
303 | |||
304 | \warning This function may affect the specific date the event will repeat | ||
305 | till. | ||
306 | */ | ||
307 | |||
308 | /*! | ||
309 | \fn bool Event::match(const QRegExp &r) const | ||
310 | |||
311 | Returns TRUE if the event matches the regular expression \a r. | ||
312 | Otherwise returns FALSE. | ||
313 | */ | ||
314 | |||
315 | /*! | ||
316 | \fn char Event::day(int) | ||
317 | \internal | ||
318 | */ | ||
319 | |||
320 | /*! | ||
321 | Creates a new, empty event. | ||
322 | */ | ||
74 | Event::Event() : Record() | 323 | Event::Event() : Record() |
75 | { | 324 | { |
76 | startUTC = endUTC = time( 0 ); | 325 | startUTC = endUTC = time( 0 ); |
77 | typ = Normal; | 326 | typ = Normal; |
78 | hAlarm = FALSE; | 327 | hAlarm = FALSE; |
79 | hRepeat = FALSE; | 328 | hRepeat = FALSE; |
80 | aMinutes = 0; | 329 | aMinutes = 0; |
81 | aSound = Silent; | 330 | aSound = Silent; |
82 | pattern.type = NoRepeat; | 331 | pattern.type = NoRepeat; |
83 | pattern.frequency = -1; | 332 | pattern.frequency = -1; |
84 | } | 333 | } |
85 | 334 | ||
335 | /*! | ||
336 | \internal | ||
337 | */ | ||
86 | Event::Event( const QMap<int, QString> &map ) | 338 | Event::Event( const QMap<int, QString> &map ) |
87 | { | 339 | { |
88 | setDescription( map[DatebookDescription] ); | 340 | setDescription( map[DatebookDescription] ); |
89 | setLocation( map[Location] ); | 341 | setLocation( map[Location] ); |
90 | setCategories( idsFromString( map[DatebookCategory] ) ); | 342 | setCategories( idsFromString( map[DatebookCategory] ) ); |
91 | setTimeZone( map[TimeZone] ); | 343 | setTimeZone( map[TimeZone] ); |
92 | setNotes( map[Note] ); | 344 | setNotes( map[Note] ); |
93 | setStart( TimeConversion::fromUTC( map[StartDateTime].toUInt() ) ); | 345 | setStart( TimeConversion::fromUTC( map[StartDateTime].toUInt() ) ); |
94 | setEnd( TimeConversion::fromUTC( map[EndDateTime].toUInt() ) ); | 346 | setEnd( TimeConversion::fromUTC( map[EndDateTime].toUInt() ) ); |
95 | setType( (Event::Type) map[DatebookType].toInt() ); | 347 | setType( (Event::Type) map[DatebookType].toInt() ); |
96 | setAlarm( ( map[HasAlarm] == "1" ? TRUE : FALSE ), map[AlarmTime].toInt(), (Event::SoundTypeChoice)map[SoundType].toInt() ); | 348 | setAlarm( ( map[HasAlarm] == "1" ? TRUE : FALSE ), map[AlarmTime].toInt(), (Event::SoundTypeChoice)map[SoundType].toInt() ); |
97 | Event::RepeatPattern p; | 349 | Event::RepeatPattern p; |
98 | p.type = (Event::RepeatType) map[ RepeatPatternType ].toInt(); | 350 | p.type = (Event::RepeatType) map[ RepeatPatternType ].toInt(); |
99 | p.frequency = map[ RepeatPatternFrequency ].toInt(); | 351 | p.frequency = map[ RepeatPatternFrequency ].toInt(); |
100 | p.position = map[ RepeatPatternPosition ].toInt(); | 352 | p.position = map[ RepeatPatternPosition ].toInt(); |
101 | p.days = map[ RepeatPatternDays ].toInt(); | 353 | p.days = map[ RepeatPatternDays ].toInt(); |
102 | p.hasEndDate = map[ RepeatPatternHasEndDate ].toInt(); | 354 | p.hasEndDate = map[ RepeatPatternHasEndDate ].toInt(); |
103 | p.endDateUTC = map[ RepeatPatternEndDate ].toUInt(); | 355 | p.endDateUTC = map[ RepeatPatternEndDate ].toUInt(); |
104 | setRepeat( p ); | 356 | setRepeat( p ); |
105 | 357 | ||
106 | setUid( map[ DatebookUid ].toInt() ); | 358 | setUid( map[ DatebookUid ].toInt() ); |
107 | } | 359 | } |
108 | 360 | ||
361 | /*! | ||
362 | Destroys an event. | ||
363 | */ | ||
109 | Event::~Event() | 364 | Event::~Event() |
110 | { | 365 | { |
111 | } | 366 | } |
112 | 367 | ||
368 | /*! | ||
369 | \internal | ||
370 | */ | ||
113 | int Event::week( const QDate& date ) | 371 | int Event::week( const QDate& date ) |
114 | { | 372 | { |
115 | // Calculates the week this date is in within that | 373 | // Calculates the week this date is in within that |
116 | // month. Equals the "row" is is in in the month view | 374 | // month. Equals the "row" is is in in the month view |
117 | int week = 1; | 375 | int week = 1; |
118 | QDate tmp( date.year(), date.month(), 1 ); | 376 | QDate tmp( date.year(), date.month(), 1 ); |
119 | 377 | ||
120 | if ( date.dayOfWeek() < tmp.dayOfWeek() ) | 378 | if ( date.dayOfWeek() < tmp.dayOfWeek() ) |
121 | ++week; | 379 | ++week; |
122 | 380 | ||
123 | week += ( date.day() - 1 ) / 7; | 381 | week += ( date.day() - 1 ) / 7; |
124 | return week; | 382 | return week; |
125 | } | 383 | } |
126 | 384 | ||
385 | /*! | ||
386 | \internal | ||
387 | */ | ||
127 | int Event::occurrence( const QDate& date ) | 388 | int Event::occurrence( const QDate& date ) |
128 | { | 389 | { |
129 | // calculates the number of occurrances of this day of the | 390 | // calculates the number of occurrances of this day of the |
130 | // week till the given date (e.g 3rd Wednesday of the month) | 391 | // week till the given date (e.g 3rd Wednesday of the month) |
131 | return ( date.day() - 1 ) / 7 + 1; | 392 | return ( date.day() - 1 ) / 7 + 1; |
132 | } | 393 | } |
133 | 394 | ||
395 | /*! | ||
396 | \internal | ||
397 | */ | ||
134 | int Event::dayOfWeek( char day ) | 398 | int Event::dayOfWeek( char day ) |
135 | { | 399 | { |
136 | int dayOfWeek = 1; | 400 | int dayOfWeek = 1; |
137 | char i = Event::MON; | 401 | char i = Event::MON; |
138 | while ( !( i & day ) && i <= Event::SUN ) { | 402 | while ( !( i & day ) && i <= Event::SUN ) { |
139 | i <<= 1; | 403 | i <<= 1; |
140 | ++dayOfWeek; | 404 | ++dayOfWeek; |
141 | } | 405 | } |
142 | return dayOfWeek; | 406 | return dayOfWeek; |
143 | } | 407 | } |
144 | 408 | ||
409 | /*! | ||
410 | \internal | ||
411 | */ | ||
145 | int Event::monthDiff( const QDate& first, const QDate& second ) | 412 | int Event::monthDiff( const QDate& first, const QDate& second ) |
146 | { | 413 | { |
147 | return ( second.year() - first.year() ) * 12 + | 414 | return ( second.year() - first.year() ) * 12 + |
148 | second.month() - first.month(); | 415 | second.month() - first.month(); |
149 | } | 416 | } |
150 | 417 | ||
418 | /*! | ||
419 | \internal | ||
420 | */ | ||
151 | QMap<int, QString> Event::toMap() const | 421 | QMap<int, QString> Event::toMap() const |
152 | { | 422 | { |
153 | QMap<int, QString> m; | 423 | QMap<int, QString> m; |
154 | m.insert( DatebookDescription, description() ); | 424 | |
155 | m.insert ( Location, location() ); | 425 | if ( !description().isEmpty() ) |
156 | m.insert ( DatebookCategory, idsToString( categories() ) ); | 426 | m.insert( DatebookDescription, description() ); |
157 | m.insert ( TimeZone, timeZone() ); | 427 | if ( !location().isEmpty() ) |
158 | m.insert ( Note, notes() ); | 428 | m.insert ( Location, location() ); |
429 | if ( categories().count() ) | ||
430 | m.insert ( DatebookCategory, idsToString( categories() ) ); | ||
431 | if ( !timeZone().isEmpty() ) | ||
432 | m.insert ( TimeZone, timeZone() ); | ||
433 | if ( !notes().isEmpty() ) | ||
434 | m.insert ( Note, notes() ); | ||
435 | |||
159 | m.insert ( StartDateTime, QString::number( TimeConversion::toUTC( start() ) ) ); | 436 | m.insert ( StartDateTime, QString::number( TimeConversion::toUTC( start() ) ) ); |
160 | m.insert ( EndDateTime, QString::number( TimeConversion::toUTC( end() ) ) ); | 437 | m.insert ( EndDateTime, QString::number( TimeConversion::toUTC( end() ) ) ); |
161 | m.insert ( DatebookType, QString::number( (int)type() ) ); | 438 | m.insert ( DatebookType, QString::number( (int)type() ) ); |
162 | m.insert ( HasAlarm, ( hasAlarm() ? "1" : "0" ) ); | 439 | m.insert ( HasAlarm, ( hasAlarm() ? "1" : "0" ) ); |
163 | m.insert ( SoundType, QString::number( (int)alarmSound() ) ); | 440 | m.insert ( SoundType, QString::number( (int)alarmSound() ) ); |
164 | m.insert ( AlarmTime, QString::number( alarmTime() ) ); | 441 | m.insert ( AlarmTime, QString::number( alarmTime() ) ); |
165 | m.insert ( RepeatPatternType, QString::number( static_cast<int>( repeatPattern().type ) ) ); | 442 | m.insert ( RepeatPatternType, QString::number( static_cast<int>( repeatPattern().type ) ) ); |
166 | m.insert ( RepeatPatternFrequency, QString::number( repeatPattern().frequency ) ); | 443 | m.insert ( RepeatPatternFrequency, QString::number( repeatPattern().frequency ) ); |
167 | m.insert ( RepeatPatternPosition, QString::number( repeatPattern().position ) ); | 444 | m.insert ( RepeatPatternPosition, QString::number( repeatPattern().position ) ); |
168 | m.insert ( RepeatPatternDays, QString::number( repeatPattern().days ) ); | 445 | m.insert ( RepeatPatternDays, QString::number( repeatPattern().days ) ); |
169 | m.insert ( RepeatPatternHasEndDate, QString::number( static_cast<int>( repeatPattern().hasEndDate ) ) ); | 446 | m.insert ( RepeatPatternHasEndDate, QString::number( static_cast<int>( repeatPattern().hasEndDate ) ) ); |
170 | m.insert ( RepeatPatternEndDate, QString::number( repeatPattern().endDateUTC ) ); | 447 | m.insert ( RepeatPatternEndDate, QString::number( repeatPattern().endDateUTC ) ); |
171 | 448 | ||
172 | m.insert( DatebookUid, QString::number( uid()) ); | 449 | m.insert( DatebookUid, QString::number( uid()) ); |
173 | 450 | ||
174 | return m; | 451 | return m; |
175 | } | 452 | } |
176 | 453 | ||
454 | /*! | ||
455 | \internal | ||
456 | */ | ||
177 | void Event::setRepeat( const RepeatPattern &p ) | 457 | void Event::setRepeat( const RepeatPattern &p ) |
178 | { | 458 | { |
179 | setRepeat( p.type != NoRepeat, p ); | 459 | setRepeat( p.type != NoRepeat, p ); |
180 | } | 460 | } |
181 | 461 | ||
462 | /*! | ||
463 | Sets the description of the event to \a s. | ||
464 | */ | ||
182 | void Event::setDescription( const QString &s ) | 465 | void Event::setDescription( const QString &s ) |
183 | { | 466 | { |
184 | descript = s; | 467 | descript = s; |
185 | } | 468 | } |
186 | 469 | ||
470 | /*! | ||
471 | Sets the location of the event to \a s. | ||
472 | */ | ||
187 | void Event::setLocation( const QString &s ) | 473 | void Event::setLocation( const QString &s ) |
188 | { | 474 | { |
189 | locat = s; | 475 | locat = s; |
190 | } | 476 | } |
191 | 477 | ||
192 | // void Event::setCategory( const QString &s ) | 478 | // void Event::setCategory( const QString &s ) |
193 | // { | 479 | // { |
194 | // categ = s; | 480 | // categ = s; |
195 | // } | 481 | // } |
196 | 482 | ||
483 | /*! | ||
484 | \internal | ||
485 | */ | ||
197 | void Event::setType( Type t ) | 486 | void Event::setType( Type t ) |
198 | { | 487 | { |
199 | typ = t; | 488 | typ = t; |
200 | } | 489 | } |
201 | 490 | ||
491 | /*! | ||
492 | Sets the start date and time of the first or only occurance of this event | ||
493 | to the date and time \a d. \a d should be in local time. | ||
494 | */ | ||
202 | void Event::setStart( const QDateTime &d ) | 495 | void Event::setStart( const QDateTime &d ) |
203 | { | 496 | { |
204 | startUTC = TimeConversion::toUTC( d ); | 497 | startUTC = TimeConversion::toUTC( d ); |
205 | } | 498 | } |
206 | 499 | ||
500 | /*! | ||
501 | \internal | ||
502 | */ | ||
207 | void Event::setStart( time_t time ) | 503 | void Event::setStart( time_t time ) |
208 | { | 504 | { |
209 | startUTC = time; | 505 | startUTC = time; |
210 | } | 506 | } |
211 | 507 | ||
508 | /*! | ||
509 | Sets the end date and time of the first or only occurance of this event | ||
510 | to the date and time \a d. \a d should be in local time. | ||
511 | */ | ||
212 | void Event::setEnd( const QDateTime &d ) | 512 | void Event::setEnd( const QDateTime &d ) |
213 | { | 513 | { |
214 | endUTC = TimeConversion::toUTC( d ); | 514 | endUTC = TimeConversion::toUTC( d ); |
215 | } | 515 | } |
216 | 516 | ||
517 | /*! | ||
518 | \internal | ||
519 | */ | ||
217 | void Event::setEnd( time_t time ) | 520 | void Event::setEnd( time_t time ) |
218 | { | 521 | { |
219 | endUTC = time; | 522 | endUTC = time; |
220 | } | 523 | } |
221 | 524 | ||
525 | /*! | ||
526 | \internal | ||
527 | */ | ||
222 | void Event::setTimeZone( const QString &z ) | 528 | void Event::setTimeZone( const QString &z ) |
223 | { | 529 | { |
224 | tz = z; | 530 | tz = z; |
225 | } | 531 | } |
226 | 532 | ||
533 | /*! | ||
534 | \internal | ||
535 | */ | ||
227 | void Event::setAlarm( bool b, int minutes, SoundTypeChoice s ) | 536 | void Event::setAlarm( bool b, int minutes, SoundTypeChoice s ) |
228 | { | 537 | { |
229 | hAlarm = b; | 538 | hAlarm = b; |
230 | aMinutes = minutes; | 539 | aMinutes = minutes; |
231 | aSound = s; | 540 | aSound = s; |
232 | } | 541 | } |
233 | 542 | ||
543 | /*! | ||
544 | \internal | ||
545 | */ | ||
234 | void Event::setRepeat( bool b, const RepeatPattern &p ) | 546 | void Event::setRepeat( bool b, const RepeatPattern &p ) |
235 | { | 547 | { |
236 | hRepeat = b; | 548 | hRepeat = b; |
237 | pattern = p; | 549 | pattern = p; |
238 | } | 550 | } |
239 | 551 | ||
552 | /*! | ||
553 | Sets the notes for the event to \a n. | ||
554 | */ | ||
240 | void Event::setNotes( const QString &n ) | 555 | void Event::setNotes( const QString &n ) |
241 | { | 556 | { |
242 | note = n; | 557 | note = n; |
243 | } | 558 | } |
244 | 559 | ||
560 | /*! | ||
561 | Returns the description of the event. | ||
562 | */ | ||
245 | const QString &Event::description() const | 563 | const QString &Event::description() const |
246 | { | 564 | { |
247 | return descript; | 565 | return descript; |
248 | } | 566 | } |
249 | 567 | ||
568 | /*! | ||
569 | Returns the location of the event. | ||
570 | */ | ||
250 | const QString &Event::location() const | 571 | const QString &Event::location() const |
251 | { | 572 | { |
252 | return locat; | 573 | return locat; |
253 | } | 574 | } |
254 | 575 | ||
255 | // QString Event::category() const | 576 | // QString Event::category() const |
256 | // { | 577 | // { |
257 | // return categ; | 578 | // return categ; |
258 | // } | 579 | // } |
259 | 580 | ||
581 | /*! | ||
582 | \internal | ||
583 | */ | ||
260 | Event::Type Event::type() const | 584 | Event::Type Event::type() const |
261 | { | 585 | { |
262 | return typ; | 586 | return typ; |
263 | } | 587 | } |
264 | 588 | ||
589 | /*! | ||
590 | \internal | ||
591 | */ | ||
265 | QDateTime Event::start( bool actual ) const | 592 | QDateTime Event::start( bool actual ) const |
266 | { | 593 | { |
267 | QDateTime dt = (startUTC > 0) ? TimeConversion::fromUTC( startUTC ) : QDateTime::currentDateTime(); | 594 | QDateTime dt = (startUTC > 0) ? TimeConversion::fromUTC( startUTC ) : QDateTime::currentDateTime(); |
268 | 595 | ||
269 | if ( actual && typ == AllDay ) { | 596 | if ( actual && typ == AllDay ) { |
270 | QTime t = dt.time(); | 597 | QTime t = dt.time(); |
271 | t.setHMS( 0, 0, 0 ); | 598 | t.setHMS( 0, 0, 0 ); |
272 | dt.setTime( t ); | 599 | dt.setTime( t ); |
273 | } | 600 | } |
274 | return dt; | 601 | return dt; |
275 | } | 602 | } |
276 | 603 | ||
604 | /*! | ||
605 | \internal | ||
606 | */ | ||
277 | QDateTime Event::end( bool actual ) const | 607 | QDateTime Event::end( bool actual ) const |
278 | { | 608 | { |
279 | QDateTime dt = (endUTC > 0) ? TimeConversion::fromUTC( endUTC ) : QDateTime::currentDateTime(); | 609 | QDateTime dt = (endUTC > 0) ? TimeConversion::fromUTC( endUTC ) : QDateTime::currentDateTime(); |
280 | 610 | ||
281 | if ( actual && typ == AllDay ) { | 611 | if ( actual && typ == AllDay ) { |
282 | QTime t = dt.time(); | 612 | QTime t = dt.time(); |
283 | t.setHMS( 23, 59, 59 ); | 613 | t.setHMS( 23, 59, 59 ); |
284 | dt.setTime( t ); | 614 | dt.setTime( t ); |
285 | } | 615 | } |
286 | return dt; | 616 | return dt; |
287 | } | 617 | } |
288 | 618 | ||
619 | /*! | ||
620 | \internal | ||
621 | */ | ||
289 | const QString &Event::timeZone() const | 622 | const QString &Event::timeZone() const |
290 | { | 623 | { |
291 | return tz; | 624 | return tz; |
292 | } | 625 | } |
293 | 626 | ||
627 | /*! | ||
628 | \internal | ||
629 | */ | ||
294 | bool Event::hasAlarm() const | 630 | bool Event::hasAlarm() const |
295 | { | 631 | { |
296 | return hAlarm; | 632 | return hAlarm; |
297 | } | 633 | } |
298 | 634 | ||
635 | /*! | ||
636 | \internal | ||
637 | */ | ||
299 | int Event::alarmTime() const | 638 | int Event::alarmTime() const |
300 | { | 639 | { |
301 | return aMinutes; | 640 | return aMinutes; |
302 | } | 641 | } |
303 | 642 | ||
643 | /*! | ||
644 | Returns the sound type for the alarm of this event. | ||
645 | */ | ||
304 | Event::SoundTypeChoice Event::alarmSound() const | 646 | Event::SoundTypeChoice Event::alarmSound() const |
305 | { | 647 | { |
306 | return aSound; | 648 | return aSound; |
307 | } | 649 | } |
308 | 650 | ||
651 | /*! | ||
652 | \internal | ||
653 | */ | ||
309 | bool Event::hasRepeat() const | 654 | bool Event::hasRepeat() const |
310 | { | 655 | { |
311 | return doRepeat(); | 656 | return doRepeat(); |
312 | } | 657 | } |
313 | 658 | ||
659 | /*! | ||
660 | \internal | ||
661 | */ | ||
314 | const Event::RepeatPattern &Event::repeatPattern() const | 662 | const Event::RepeatPattern &Event::repeatPattern() const |
315 | { | 663 | { |
316 | return pattern; | 664 | return pattern; |
317 | } | 665 | } |
318 | 666 | ||
667 | /*! | ||
668 | \internal | ||
669 | */ | ||
319 | Event::RepeatPattern &Event::repeatPattern() | 670 | Event::RepeatPattern &Event::repeatPattern() |
320 | { | 671 | { |
321 | return pattern; | 672 | return pattern; |
322 | } | 673 | } |
323 | 674 | ||
675 | /*! | ||
676 | Returns the notes for the event. | ||
677 | */ | ||
324 | const QString &Event::notes() const | 678 | const QString &Event::notes() const |
325 | { | 679 | { |
326 | return note; | 680 | return note; |
327 | } | 681 | } |
328 | 682 | ||
683 | /*! | ||
684 | \internal | ||
685 | */ | ||
329 | bool Event::operator==( const Event &e ) const | 686 | bool Event::operator==( const Event &e ) const |
330 | { | 687 | { |
688 | if ( uid() && e.uid() == uid() ) | ||
689 | return TRUE; | ||
331 | return ( e.descript == descript && | 690 | return ( e.descript == descript && |
332 | e.locat == locat && | 691 | e.locat == locat && |
333 | e.categ == categ && | 692 | e.categ == categ && |
334 | e.typ == typ && | 693 | e.typ == typ && |
335 | e.startUTC == startUTC && | 694 | e.startUTC == startUTC && |
336 | e.endUTC == endUTC && | 695 | e.endUTC == endUTC && |
337 | e.tz == tz && | 696 | e.tz == tz && |
338 | e.hAlarm == hAlarm && | 697 | e.hAlarm == hAlarm && |
339 | e.aMinutes == aMinutes && | 698 | e.aMinutes == aMinutes && |
340 | e.aSound == aSound && | 699 | e.aSound == aSound && |
341 | e.hRepeat == hRepeat && | 700 | e.hRepeat == hRepeat && |
342 | e.pattern == pattern && | 701 | e.pattern == pattern && |
343 | e.note == note ); | 702 | e.note == note ); |
344 | } | 703 | } |
345 | 704 | ||
705 | /*! | ||
706 | \internal | ||
707 | Appends the contact information to \a buf. | ||
708 | */ | ||
346 | void Event::save( QString& buf ) | 709 | void Event::save( QString& buf ) |
347 | { | 710 | { |
348 | buf += " description=\"" + Qtopia::escapeString(descript) + "\""; | 711 | buf += " description=\"" + Qtopia::escapeString(descript) + "\""; |
349 | if ( !locat.isEmpty() ) | 712 | if ( !locat.isEmpty() ) |
350 | buf += " location=\"" + Qtopia::escapeString(locat) + "\""; | 713 | buf += " location=\"" + Qtopia::escapeString(locat) + "\""; |
351 | // save the categoies differently.... | 714 | // save the categoies differently.... |
352 | QString strCats = idsToString( categories() ); | 715 | QString strCats = idsToString( categories() ); |
353 | buf += " categories=\"" + Qtopia::escapeString(strCats) + "\""; | 716 | buf += " categories=\"" + Qtopia::escapeString(strCats) + "\""; |
354 | buf += " uid=\"" + QString::number( uid() ) + "\""; | 717 | buf += " uid=\"" + QString::number( uid() ) + "\""; |
355 | if ( (Type)typ != Normal ) | 718 | if ( (Type)typ != Normal ) |
356 | buf += " type=\"AllDay\""; | 719 | buf += " type=\"AllDay\""; |
357 | if ( hAlarm ) { | 720 | if ( hAlarm ) { |
358 | buf += " alarm=\"" + QString::number( aMinutes ) + "\" sound=\""; | 721 | buf += " alarm=\"" + QString::number( aMinutes ) + "\" sound=\""; |
359 | if ( aSound == Event::Loud ) | 722 | if ( aSound == Event::Loud ) |
360 | buf += "loud"; | 723 | buf += "loud"; |
361 | else | 724 | else |
362 | buf += "silent"; | 725 | buf += "silent"; |
363 | buf += "\""; | 726 | buf += "\""; |
364 | } | 727 | } |
365 | if ( hRepeat ) | 728 | if ( hRepeat ) |
366 | write( buf, pattern ); | 729 | write( buf, pattern ); |
367 | 730 | ||
368 | buf += " start=\"" | 731 | buf += " start=\"" |
369 | + QString::number( startUTC ) | 732 | + QString::number( startUTC ) |
370 | + "\""; | 733 | + "\""; |
371 | 734 | ||
372 | buf += " end=\"" | 735 | buf += " end=\"" |
373 | + QString::number( endUTC ) | 736 | + QString::number( endUTC ) |
374 | + "\""; | 737 | + "\""; |
375 | 738 | ||
376 | if ( !note.isEmpty() ) | 739 | if ( !note.isEmpty() ) |
377 | buf += " note=\"" + Qtopia::escapeString( note ) + "\""; | 740 | buf += " note=\"" + Qtopia::escapeString( note ) + "\""; |
378 | buf += customToXml(); | 741 | buf += customToXml(); |
379 | } | 742 | } |
380 | 743 | ||
744 | /*! | ||
745 | \internal | ||
746 | */ | ||
381 | bool Event::RepeatPattern::operator==( const Event::RepeatPattern &right ) const | 747 | bool Event::RepeatPattern::operator==( const Event::RepeatPattern &right ) const |
382 | { | 748 | { |
383 | // *sigh* | 749 | // *sigh* |
384 | return ( type == right.type | 750 | return ( type == right.type |
385 | && frequency == right.frequency | 751 | && frequency == right.frequency |
386 | && position == right.position | 752 | && position == right.position |
387 | && days == right.days | 753 | && days == right.days |
388 | && hasEndDate == right.hasEndDate | 754 | && hasEndDate == right.hasEndDate |
389 | && endDateUTC == right.endDateUTC | 755 | && endDateUTC == right.endDateUTC |
390 | && createTime == right.createTime ); | 756 | && createTime == right.createTime ); |
391 | } | 757 | } |
392 | 758 | ||
759 | /*! | ||
760 | \class EffectiveEvent | ||
761 | \brief The EffectiveEvent class the data for a single occurance of an event. | ||
762 | |||
763 | This class describes the event for a single occurance of it. For example if | ||
764 | an Event occurs every week, the effective event might represent the third | ||
765 | occurance of this Event. | ||
766 | |||
767 | \ingroup qtopiaemb | ||
768 | \ingroup qtopiadesktop | ||
769 | \warning This class will be phased out in Qtopia 3.x | ||
770 | */ | ||
771 | |||
772 | /*! | ||
773 | \enum EffectiveEvent::Position | ||
774 | \internal | ||
775 | */ | ||
776 | |||
777 | /*! | ||
778 | \fn EffectiveEvent &EffectiveEvent::operator=(const EffectiveEvent &) | ||
779 | \internal | ||
780 | */ | ||
393 | 781 | ||
394 | class EffectiveEventPrivate | 782 | class EffectiveEventPrivate |
395 | { | 783 | { |
396 | public: | 784 | public: |
397 | //currently the existence of the d pointer means multi-day repeating, | 785 | //currently the existence of the d pointer means multi-day repeating, |
398 | //msut be changed if we use the d pointer for anything else. | 786 | //msut be changed if we use the d pointer for anything else. |
399 | QDate startDate; | 787 | QDate startDate; |
400 | QDate endDate; | 788 | QDate endDate; |
401 | }; | 789 | }; |
402 | 790 | ||
403 | 791 | /*! | |
792 | \internal | ||
793 | */ | ||
404 | EffectiveEvent::EffectiveEvent() | 794 | EffectiveEvent::EffectiveEvent() |
405 | { | 795 | { |
406 | mDate = QDate::currentDate(); | 796 | mDate = QDate::currentDate(); |
407 | mStart = mEnd = QTime::currentTime(); | 797 | mStart = mEnd = QTime::currentTime(); |
408 | d = 0; | 798 | d = 0; |
409 | } | 799 | } |
410 | 800 | ||
801 | /*! | ||
802 | \internal | ||
803 | */ | ||
411 | EffectiveEvent::EffectiveEvent( const Event &e, const QDate &date, Position pos ) | 804 | EffectiveEvent::EffectiveEvent( const Event &e, const QDate &date, Position pos ) |
412 | { | 805 | { |
413 | mEvent = e; | 806 | mEvent = e; |
414 | mDate = date; | 807 | mDate = date; |
415 | if ( pos & Start ) | 808 | if ( pos & Start ) |
416 | mStart = e.start( TRUE ).time(); | 809 | mStart = e.start( TRUE ).time(); |
417 | else | 810 | else |
418 | mStart = QTime( 0, 0, 0 ); | 811 | mStart = QTime( 0, 0, 0 ); |
419 | 812 | ||
420 | if ( pos & End ) | 813 | if ( pos & End ) |
421 | mEnd = e.end( TRUE ).time(); | 814 | mEnd = e.end( TRUE ).time(); |
422 | else | 815 | else |
423 | mEnd = QTime( 23, 59, 59 ); | 816 | mEnd = QTime( 23, 59, 59 ); |
424 | d = 0; | 817 | d = 0; |
425 | } | 818 | } |
426 | 819 | ||
820 | /*! | ||
821 | \internal | ||
822 | */ | ||
427 | EffectiveEvent::~EffectiveEvent() | 823 | EffectiveEvent::~EffectiveEvent() |
428 | { | 824 | { |
429 | delete d; | 825 | delete d; |
430 | } | 826 | } |
431 | 827 | ||
828 | /*! | ||
829 | \internal | ||
830 | */ | ||
432 | EffectiveEvent::EffectiveEvent( const EffectiveEvent &e ) | 831 | EffectiveEvent::EffectiveEvent( const EffectiveEvent &e ) |
433 | { | 832 | { |
434 | d = 0; | 833 | d = 0; |
435 | *this = e; | 834 | *this = e; |
436 | } | 835 | } |
437 | 836 | ||
438 | EffectiveEvent& EffectiveEvent::operator=( const EffectiveEvent & e ) | 837 | EffectiveEvent& EffectiveEvent::operator=( const EffectiveEvent & e ) |
439 | { | 838 | { |
440 | if ( &e == this ) | 839 | if ( &e == this ) |
441 | return *this; | 840 | return *this; |
442 | delete d; | 841 | delete d; |
443 | if ( e.d ) { | 842 | if ( e.d ) { |
444 | d = new EffectiveEventPrivate; | 843 | d = new EffectiveEventPrivate; |
445 | d->startDate = e.d->startDate; | 844 | d->startDate = e.d->startDate; |
446 | d->endDate = e.d->endDate; | 845 | d->endDate = e.d->endDate; |
447 | } else { | 846 | } else { |
448 | d = 0; | 847 | d = 0; |
449 | } | 848 | } |
450 | mEvent = e.mEvent; | 849 | mEvent = e.mEvent; |
451 | mDate = e.mDate; | 850 | mDate = e.mDate; |
452 | mStart = e.mStart; | 851 | mStart = e.mStart; |
453 | mEnd = e.mEnd; | 852 | mEnd = e.mEnd; |
454 | 853 | ||
455 | return *this; | 854 | return *this; |
456 | 855 | ||
457 | } | 856 | } |
458 | 857 | ||
459 | // QString EffectiveEvent::category() const | 858 | // QString EffectiveEvent::category() const |
460 | // { | 859 | // { |
461 | // return mEvent.category(); | 860 | // return mEvent.category(); |
462 | // } | 861 | // } |
463 | 862 | ||
863 | /*! | ||
864 | Returns the description of the event for this effective event. | ||
865 | */ | ||
464 | const QString &EffectiveEvent::description( ) const | 866 | const QString &EffectiveEvent::description( ) const |
465 | { | 867 | { |
466 | return mEvent.description(); | 868 | return mEvent.description(); |
467 | } | 869 | } |
468 | 870 | ||
871 | /*! | ||
872 | \internal | ||
873 | */ | ||
469 | const QString &EffectiveEvent::location( ) const | 874 | const QString &EffectiveEvent::location( ) const |
470 | { | 875 | { |
471 | return mEvent.location(); | 876 | return mEvent.location(); |
472 | } | 877 | } |
473 | 878 | ||
879 | /*! | ||
880 | \internal | ||
881 | */ | ||
474 | const QString &EffectiveEvent::notes() const | 882 | const QString &EffectiveEvent::notes() const |
475 | { | 883 | { |
476 | return mEvent.notes(); | 884 | return mEvent.notes(); |
477 | } | 885 | } |
478 | 886 | ||
887 | /*! | ||
888 | Returns the event associated with this effective event. | ||
889 | */ | ||
479 | const Event &EffectiveEvent::event() const | 890 | const Event &EffectiveEvent::event() const |
480 | { | 891 | { |
481 | return mEvent; | 892 | return mEvent; |
482 | } | 893 | } |
483 | 894 | ||
895 | /*! | ||
896 | \internal | ||
897 | */ | ||
484 | const QTime &EffectiveEvent::end() const | 898 | const QTime &EffectiveEvent::end() const |
485 | { | 899 | { |
486 | return mEnd; | 900 | return mEnd; |
487 | } | 901 | } |
488 | 902 | ||
903 | /*! | ||
904 | \internal | ||
905 | */ | ||
489 | const QTime &EffectiveEvent::start() const | 906 | const QTime &EffectiveEvent::start() const |
490 | { | 907 | { |
491 | return mStart; | 908 | return mStart; |
492 | } | 909 | } |
493 | 910 | ||
911 | /*! | ||
912 | Returns the date the effective event occurs on. | ||
913 | */ | ||
494 | const QDate &EffectiveEvent::date() const | 914 | const QDate &EffectiveEvent::date() const |
495 | { | 915 | { |
496 | return mDate; | 916 | return mDate; |
497 | } | 917 | } |
498 | 918 | ||
919 | /*! | ||
920 | \internal | ||
921 | */ | ||
499 | int EffectiveEvent::length() const | 922 | int EffectiveEvent::length() const |
500 | { | 923 | { |
501 | return (mEnd.hour() * 60 - mStart.hour() * 60) | 924 | return (mEnd.hour() * 60 - mStart.hour() * 60) |
502 | + QABS(mStart.minute() - mEnd.minute() ); | 925 | + QABS(mStart.minute() - mEnd.minute() ); |
503 | } | 926 | } |
504 | 927 | ||
928 | /*! | ||
929 | \internal | ||
930 | */ | ||
505 | void EffectiveEvent::setDate( const QDate &dt ) | 931 | void EffectiveEvent::setDate( const QDate &dt ) |
506 | { | 932 | { |
507 | mDate = dt; | 933 | mDate = dt; |
508 | } | 934 | } |
509 | 935 | ||
936 | /*! | ||
937 | \internal | ||
938 | */ | ||
510 | void EffectiveEvent::setStart( const QTime &start ) | 939 | void EffectiveEvent::setStart( const QTime &start ) |
511 | { | 940 | { |
512 | mStart = start; | 941 | mStart = start; |
513 | } | 942 | } |
514 | 943 | ||
944 | /*! | ||
945 | \internal | ||
946 | */ | ||
515 | void EffectiveEvent::setEnd( const QTime &end ) | 947 | void EffectiveEvent::setEnd( const QTime &end ) |
516 | { | 948 | { |
517 | mEnd = end; | 949 | mEnd = end; |
518 | } | 950 | } |
519 | 951 | ||
952 | /*! | ||
953 | \internal | ||
954 | */ | ||
520 | void EffectiveEvent::setEvent( Event e ) | 955 | void EffectiveEvent::setEvent( Event e ) |
521 | { | 956 | { |
522 | mEvent = e; | 957 | mEvent = e; |
523 | } | 958 | } |
524 | 959 | ||
960 | /*! | ||
961 | \internal | ||
962 | */ | ||
525 | bool EffectiveEvent::operator<( const EffectiveEvent &e ) const | 963 | bool EffectiveEvent::operator<( const EffectiveEvent &e ) const |
526 | { | 964 | { |
527 | if ( mDate < e.date() ) | 965 | if ( mDate < e.date() ) |
528 | return TRUE; | 966 | return TRUE; |
529 | if ( mDate == e.date() ) | 967 | if ( mDate == e.date() ) |
530 | return ( mStart < e.start() ); | 968 | return ( mStart < e.start() ); |
531 | else | 969 | else |
532 | return FALSE; | 970 | return FALSE; |
533 | } | 971 | } |
534 | 972 | ||
973 | /*! | ||
974 | \internal | ||
975 | */ | ||
535 | bool EffectiveEvent::operator<=( const EffectiveEvent &e ) const | 976 | bool EffectiveEvent::operator<=( const EffectiveEvent &e ) const |
536 | { | 977 | { |
537 | return (mDate <= e.date() ); | 978 | return (mDate <= e.date() ); |
538 | } | 979 | } |
539 | 980 | ||
981 | /*! | ||
982 | \internal | ||
983 | */ | ||
540 | bool EffectiveEvent::operator==( const EffectiveEvent &e ) const | 984 | bool EffectiveEvent::operator==( const EffectiveEvent &e ) const |
541 | { | 985 | { |
542 | return ( mDate == e.date() | 986 | return ( mDate == e.date() |
543 | && mStart == e.start() | 987 | && mStart == e.start() |
544 | && mEnd == e.end() | 988 | && mEnd == e.end() |
545 | && mEvent == e.event() ); | 989 | && mEvent == e.event() ); |
546 | } | 990 | } |
547 | 991 | ||
992 | /*! | ||
993 | \internal | ||
994 | */ | ||
548 | bool EffectiveEvent::operator!=( const EffectiveEvent &e ) const | 995 | bool EffectiveEvent::operator!=( const EffectiveEvent &e ) const |
549 | { | 996 | { |
550 | return !(*this == e); | 997 | return !(*this == e); |
551 | } | 998 | } |
552 | 999 | ||
1000 | /*! | ||
1001 | \internal | ||
1002 | */ | ||
553 | bool EffectiveEvent::operator>( const EffectiveEvent &e ) const | 1003 | bool EffectiveEvent::operator>( const EffectiveEvent &e ) const |
554 | { | 1004 | { |
555 | return !(*this <= e ); | 1005 | return !(*this <= e ); |
556 | } | 1006 | } |
557 | 1007 | ||
1008 | /*! | ||
1009 | \internal | ||
1010 | */ | ||
558 | bool EffectiveEvent::operator>=(const EffectiveEvent &e) const | 1011 | bool EffectiveEvent::operator>=(const EffectiveEvent &e) const |
559 | { | 1012 | { |
560 | return !(*this < e); | 1013 | return !(*this < e); |
561 | } | 1014 | } |
562 | 1015 | ||
1016 | /*! | ||
1017 | \internal | ||
1018 | */ | ||
563 | void EffectiveEvent::setEffectiveDates( const QDate &from, const QDate &to ) | 1019 | void EffectiveEvent::setEffectiveDates( const QDate &from, const QDate &to ) |
564 | { | 1020 | { |
565 | if ( !from.isValid() ) { | 1021 | if ( !from.isValid() ) { |
566 | delete d; | 1022 | delete d; |
567 | d = 0; | 1023 | d = 0; |
568 | return; | 1024 | return; |
569 | } | 1025 | } |
570 | if ( !d ) | 1026 | if ( !d ) |
571 | d = new EffectiveEventPrivate; | 1027 | d = new EffectiveEventPrivate; |
572 | d->startDate = from; | 1028 | d->startDate = from; |
573 | d->endDate = to; | 1029 | d->endDate = to; |
574 | } | 1030 | } |
575 | 1031 | ||
1032 | /*! | ||
1033 | \internal | ||
1034 | */ | ||
576 | QDate EffectiveEvent::startDate() const | 1035 | QDate EffectiveEvent::startDate() const |
577 | { | 1036 | { |
578 | if ( d ) | 1037 | if ( d ) |
579 | return d->startDate; | 1038 | return d->startDate; |
580 | else if ( mEvent.hasRepeat() ) | 1039 | else if ( mEvent.hasRepeat() ) |
581 | return mDate; // single day, since multi-day should have a d pointer | 1040 | return mDate; // single day, since multi-day should have a d pointer |
582 | else | 1041 | else |
583 | return mEvent.start().date(); | 1042 | return mEvent.start().date(); |
584 | } | 1043 | } |
585 | 1044 | ||
1045 | /*! | ||
1046 | \internal | ||
1047 | */ | ||
586 | QDate EffectiveEvent::endDate() const | 1048 | QDate EffectiveEvent::endDate() const |
587 | { | 1049 | { |
588 | if ( d ) | 1050 | if ( d ) |
589 | return d->endDate; | 1051 | return d->endDate; |
590 | else if ( mEvent.hasRepeat() ) | 1052 | else if ( mEvent.hasRepeat() ) |
591 | return mDate; // single day, since multi-day should have a d pointer | 1053 | return mDate; // single day, since multi-day should have a d pointer |
592 | else | 1054 | else |
593 | return mEvent.end().date(); | 1055 | return mEvent.end().date(); |
594 | } | 1056 | } |
595 | 1057 | ||
1058 | /*! | ||
1059 | \internal | ||
1060 | */ | ||
596 | int EffectiveEvent::size() const | 1061 | int EffectiveEvent::size() const |
597 | { | 1062 | { |
598 | return ( mEnd.hour() - mStart.hour() ) * 3600 | 1063 | return ( mEnd.hour() - mStart.hour() ) * 3600 |
599 | + (mEnd.minute() - mStart.minute() * 60 | 1064 | + (mEnd.minute() - mStart.minute() * 60 |
600 | + mEnd.second() - mStart.second() ); | 1065 | + mEnd.second() - mStart.second() ); |
601 | } | 1066 | } |
602 | 1067 | ||
603 | 1068 | ||
604 | // vcal conversion code | 1069 | // vcal conversion code |
605 | static inline VObject *safeAddPropValue( VObject *o, const char *prop, const QString &value ) | 1070 | static inline VObject *safeAddPropValue( VObject *o, const char *prop, const QString &value ) |
606 | { | 1071 | { |
607 | VObject *ret = 0; | 1072 | VObject *ret = 0; |
608 | if ( o && !value.isEmpty() ) | 1073 | if ( o && !value.isEmpty() ) |
609 | ret = addPropValue( o, prop, value.latin1() ); | 1074 | ret = addPropValue( o, prop, value.latin1() ); |
610 | return ret; | 1075 | return ret; |
611 | } | 1076 | } |
612 | 1077 | ||
613 | static inline VObject *safeAddProp( VObject *o, const char *prop) | 1078 | static inline VObject *safeAddProp( VObject *o, const char *prop) |
614 | { | 1079 | { |
615 | VObject *ret = 0; | 1080 | VObject *ret = 0; |
616 | if ( o ) | 1081 | if ( o ) |
617 | ret = addProp( o, prop ); | 1082 | ret = addProp( o, prop ); |
618 | return ret; | 1083 | return ret; |
619 | } | 1084 | } |
620 | 1085 | ||
621 | static VObject *createVObject( const Event &e ) | 1086 | static VObject *createVObject( const Event &e ) |
622 | { | 1087 | { |
623 | VObject *vcal = newVObject( VCCalProp ); | 1088 | VObject *vcal = newVObject( VCCalProp ); |
624 | safeAddPropValue( vcal, VCVersionProp, "1.0" ); | 1089 | safeAddPropValue( vcal, VCVersionProp, "1.0" ); |
625 | VObject *event = safeAddProp( vcal, VCEventProp ); | 1090 | VObject *event = safeAddProp( vcal, VCEventProp ); |
626 | 1091 | ||
627 | safeAddPropValue( event, VCDTstartProp, TimeConversion::toISO8601( e.start() ) ); | 1092 | safeAddPropValue( event, VCDTstartProp, TimeConversion::toISO8601( e.start() ) ); |
628 | safeAddPropValue( event, VCDTendProp, TimeConversion::toISO8601( e.end() ) ); | 1093 | safeAddPropValue( event, VCDTendProp, TimeConversion::toISO8601( e.end() ) ); |
629 | safeAddPropValue( event, "X-Qtopia-NOTES", e.description() ); | 1094 | safeAddPropValue( event, "X-Qtopia-NOTES", e.description() ); |
630 | safeAddPropValue( event, VCDescriptionProp, e.description() ); | 1095 | safeAddPropValue( event, VCDescriptionProp, e.description() ); |
631 | safeAddPropValue( event, VCLocationProp, e.location() ); | 1096 | safeAddPropValue( event, VCLocationProp, e.location() ); |
632 | 1097 | ||
633 | if ( e.hasAlarm() ) { | 1098 | if ( e.hasAlarm() ) { |
634 | VObject *alarm = safeAddProp( event, VCAAlarmProp ); | 1099 | VObject *alarm = safeAddProp( event, VCAAlarmProp ); |
635 | QDateTime dt = e.start(); | 1100 | QDateTime dt = e.start(); |
636 | dt = dt.addSecs( -e.alarmTime()*60 ); | 1101 | dt = dt.addSecs( -e.alarmTime()*60 ); |
637 | safeAddPropValue( alarm, VCRunTimeProp, TimeConversion::toISO8601( dt ) ); | 1102 | safeAddPropValue( alarm, VCRunTimeProp, TimeConversion::toISO8601( dt ) ); |
638 | safeAddPropValue( alarm, VCAudioContentProp, | 1103 | safeAddPropValue( alarm, VCAudioContentProp, |
639 | (e.alarmSound() == Event::Silent ? "silent" : "alarm" ) ); | 1104 | (e.alarmSound() == Event::Silent ? "silent" : "alarm" ) ); |
640 | } | 1105 | } |
641 | 1106 | ||
642 | safeAddPropValue( event, "X-Qtopia-TIMEZONE", e.timeZone() ); | 1107 | safeAddPropValue( event, "X-Qtopia-TIMEZONE", e.timeZone() ); |
643 | 1108 | ||
644 | if ( e.type() == Event::AllDay ) | 1109 | if ( e.type() == Event::AllDay ) |
645 | safeAddPropValue( event, "X-Qtopia-AllDay", e.timeZone() ); | 1110 | safeAddPropValue( event, "X-Qtopia-AllDay", e.timeZone() ); |
646 | 1111 | ||
647 | // ### repeat missing | 1112 | // ### repeat missing |
648 | 1113 | ||
649 | // ### categories missing | 1114 | // ### categories missing |
650 | 1115 | ||
651 | return vcal; | 1116 | return vcal; |
652 | } | 1117 | } |
653 | 1118 | ||
654 | 1119 | ||
655 | static Event parseVObject( VObject *obj ) | 1120 | static Event parseVObject( VObject *obj ) |
656 | { | 1121 | { |
657 | Event e; | 1122 | Event e; |
658 | 1123 | ||
659 | bool haveAlarm = FALSE; | 1124 | bool haveAlarm = FALSE; |
660 | bool haveStart = FALSE; | 1125 | bool haveStart = FALSE; |
661 | bool haveEnd = FALSE; | 1126 | bool haveEnd = FALSE; |
662 | QDateTime alarmTime; | 1127 | QDateTime alarmTime; |
663 | Event::SoundTypeChoice soundType = Event::Silent; | 1128 | Event::SoundTypeChoice soundType = Event::Silent; |
664 | 1129 | ||
665 | VObjectIterator it; | 1130 | VObjectIterator it; |
666 | initPropIterator( &it, obj ); | 1131 | initPropIterator( &it, obj ); |
667 | while( moreIteration( &it ) ) { | 1132 | while( moreIteration( &it ) ) { |
668 | VObject *o = nextVObject( &it ); | 1133 | VObject *o = nextVObject( &it ); |
669 | QCString name = vObjectName( o ); | 1134 | QCString name = vObjectName( o ); |
670 | QCString value = vObjectStringZValue( o ); | 1135 | QCString value = vObjectStringZValue( o ); |
671 | if ( name == VCDTstartProp ) { | 1136 | if ( name == VCDTstartProp ) { |
672 | e.setStart( TimeConversion::fromISO8601( value ) ); | 1137 | e.setStart( TimeConversion::fromISO8601( value ) ); |
673 | haveStart = TRUE; | 1138 | haveStart = TRUE; |
674 | } | 1139 | } |
675 | else if ( name == VCDTendProp ) { | 1140 | else if ( name == VCDTendProp ) { |
676 | e.setEnd( TimeConversion::fromISO8601( value ) ); | 1141 | e.setEnd( TimeConversion::fromISO8601( value ) ); |
677 | haveEnd = TRUE; | 1142 | haveEnd = TRUE; |
678 | } | 1143 | } |
679 | else if ( name == "X-Qtopia-NOTES" ) { | 1144 | else if ( name == "X-Qtopia-NOTES" ) { |
680 | e.setNotes( value ); | 1145 | e.setNotes( value ); |
681 | } | 1146 | } |
682 | else if ( name == VCDescriptionProp ) { | 1147 | else if ( name == VCDescriptionProp ) { |
683 | e.setDescription( value ); | 1148 | e.setDescription( value ); |
684 | } | 1149 | } |
685 | else if ( name == VCLocationProp ) { | 1150 | else if ( name == VCLocationProp ) { |
686 | e.setLocation( value ); | 1151 | e.setLocation( value ); |
687 | } | 1152 | } |
688 | else if ( name == VCAudioContentProp ) { | 1153 | else if ( name == VCAudioContentProp ) { |
689 | haveAlarm = TRUE; | 1154 | haveAlarm = TRUE; |
690 | VObjectIterator nit; | 1155 | VObjectIterator nit; |
691 | initPropIterator( &nit, o ); | 1156 | initPropIterator( &nit, o ); |
692 | while( moreIteration( &nit ) ) { | 1157 | while( moreIteration( &nit ) ) { |
693 | VObject *o = nextVObject( &nit ); | 1158 | VObject *o = nextVObject( &nit ); |
694 | QCString name = vObjectName( o ); | 1159 | QCString name = vObjectName( o ); |
695 | QCString value = vObjectStringZValue( o ); | 1160 | QCString value = vObjectStringZValue( o ); |
696 | if ( name == VCRunTimeProp ) | 1161 | if ( name == VCRunTimeProp ) |
697 | alarmTime = TimeConversion::fromISO8601( value ); | 1162 | alarmTime = TimeConversion::fromISO8601( value ); |
698 | else if ( name == VCAudioContentProp ) { | 1163 | else if ( name == VCAudioContentProp ) { |
699 | if ( value == "silent" ) | 1164 | if ( value == "silent" ) |
700 | soundType = Event::Silent; | 1165 | soundType = Event::Silent; |
701 | else | 1166 | else |
702 | soundType = Event::Loud; | 1167 | soundType = Event::Loud; |
703 | } | 1168 | } |
704 | } | 1169 | } |
705 | } | 1170 | } |
706 | else if ( name == "X-Qtopia-TIMEZONE") { | 1171 | else if ( name == "X-Qtopia-TIMEZONE") { |
707 | e.setTimeZone( value ); | 1172 | e.setTimeZone( value ); |
708 | } | 1173 | } |
709 | else if ( name == "X-Qtopia-AllDay" ) { | 1174 | else if ( name == "X-Qtopia-AllDay" ) { |
710 | e.setType( Event::AllDay ); | 1175 | e.setType( Event::AllDay ); |
711 | } | 1176 | } |
712 | #if 0 | 1177 | #if 0 |
713 | else { | 1178 | else { |
714 | printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) ); | 1179 | printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) ); |
715 | VObjectIterator nit; | 1180 | VObjectIterator nit; |
716 | initPropIterator( &nit, o ); | 1181 | initPropIterator( &nit, o ); |
717 | while( moreIteration( &nit ) ) { | 1182 | while( moreIteration( &nit ) ) { |
718 | VObject *o = nextVObject( &nit ); | 1183 | VObject *o = nextVObject( &nit ); |
719 | QCString name = vObjectName( o ); | 1184 | QCString name = vObjectName( o ); |
720 | QString value = vObjectStringZValue( o ); | 1185 | QString value = vObjectStringZValue( o ); |
721 | printf(" subprop: %s = %s\n", name.data(), value.latin1() ); | 1186 | printf(" subprop: %s = %s\n", name.data(), value.latin1() ); |
722 | } | 1187 | } |
723 | } | 1188 | } |
724 | #endif | 1189 | #endif |
725 | } | 1190 | } |
726 | 1191 | ||
727 | if ( !haveStart && !haveEnd ) | 1192 | if ( !haveStart && !haveEnd ) |
728 | e.setStart( QDateTime::currentDateTime() ); | 1193 | e.setStart( QDateTime::currentDateTime() ); |
729 | 1194 | ||
730 | if ( !haveEnd ) { | 1195 | if ( !haveEnd ) { |
731 | e.setType( Event::AllDay ); | 1196 | e.setType( Event::AllDay ); |
732 | e.setEnd( e.start() ); | 1197 | e.setEnd( e.start() ); |
733 | } | 1198 | } |
734 | 1199 | ||
735 | if ( haveAlarm ) { | 1200 | if ( haveAlarm ) { |
736 | int minutes = alarmTime.secsTo( e.start() ) / 60; | 1201 | int minutes = alarmTime.secsTo( e.start() ) / 60; |
737 | e.setAlarm( TRUE, minutes, soundType ); | 1202 | e.setAlarm( TRUE, minutes, soundType ); |
738 | } | 1203 | } |
739 | return e; | 1204 | return e; |
740 | } | 1205 | } |
741 | 1206 | ||
742 | 1207 | ||
743 | 1208 | /*! | |
1209 | Writes the list of \a events as a set of VCards to the file \a filename. | ||
1210 | */ | ||
744 | void Event::writeVCalendar( const QString &filename, const QValueList<Event> &events) | 1211 | void Event::writeVCalendar( const QString &filename, const QValueList<Event> &events) |
745 | { | 1212 | { |
746 | QFileDirect f( filename.utf8().data() ); | 1213 | |
747 | if ( !f.open( IO_WriteOnly ) ) { | 1214 | QFileDirect f( filename.utf8().data() ); |
748 | qWarning("Unable to open vcard write"); | 1215 | |
749 | return; | 1216 | if ( !f.open( IO_WriteOnly ) ) { |
750 | } | 1217 | |
1218 | qWarning("Unable to open vcard write"); | ||
1219 | |||
1220 | return; | ||
1221 | |||
1222 | } | ||
1223 | |||
751 | 1224 | ||
752 | QValueList<Event>::ConstIterator it; | 1225 | QValueList<Event>::ConstIterator it; |
753 | for( it = events.begin(); it != events.end(); ++it ) { | 1226 | for( it = events.begin(); it != events.end(); ++it ) { |
754 | VObject *obj = createVObject( *it ); | 1227 | VObject *obj = createVObject( *it ); |
755 | writeVObject( f.directHandle() , obj ); | 1228 | writeVObject( f.directHandle() , obj ); |
756 | cleanVObject( obj ); | 1229 | cleanVObject( obj ); |
757 | } | 1230 | } |
1231 | |||
758 | 1232 | ||
759 | cleanStrTbl(); | 1233 | cleanStrTbl(); |
760 | } | 1234 | } |
761 | 1235 | ||
1236 | /*! | ||
1237 | Writes \a event as a VCard to the file \a filename. | ||
1238 | */ | ||
762 | void Event::writeVCalendar( const QString &filename, const Event &event) | 1239 | void Event::writeVCalendar( const QString &filename, const Event &event) |
763 | { | 1240 | { |
764 | QFileDirect f( filename.utf8().data() ); | 1241 | |
765 | if ( !f.open( IO_WriteOnly ) ) { | 1242 | QFileDirect f( filename.utf8().data() ); |
766 | qWarning("Unable to open vcard write"); | 1243 | |
767 | return; | 1244 | if ( !f.open( IO_WriteOnly ) ) { |
768 | } | 1245 | |
1246 | qWarning("Unable to open vcard write"); | ||
1247 | |||
1248 | return; | ||
1249 | |||
1250 | } | ||
1251 | |||
769 | 1252 | ||
770 | VObject *obj = createVObject( event ); | 1253 | VObject *obj = createVObject( event ); |
771 | writeVObject( f.directHandle() , obj ); | 1254 | writeVObject( f.directHandle() , obj ); |
772 | cleanVObject( obj ); | 1255 | cleanVObject( obj ); |
773 | 1256 | ||
774 | cleanStrTbl(); | 1257 | cleanStrTbl(); |
775 | } | 1258 | } |
776 | 1259 | ||
777 | 1260 | /*! | |
1261 | Returns the set of events read as VCards from the file \a filename. | ||
1262 | */ | ||
778 | QValueList<Event> Event::readVCalendar( const QString &filename ) | 1263 | QValueList<Event> Event::readVCalendar( const QString &filename ) |
779 | { | 1264 | { |
780 | VObject *obj = Parse_MIME_FromFileName( (char *)filename.utf8().data() ); | 1265 | VObject *obj = Parse_MIME_FromFileName( (char *)filename.utf8().data() ); |
781 | 1266 | ||
782 | QValueList<Event> events; | 1267 | QValueList<Event> events; |
783 | 1268 | ||
784 | while ( obj ) { | 1269 | while ( obj ) { |
785 | QCString name = vObjectName( obj ); | 1270 | QCString name = vObjectName( obj ); |
786 | if ( name == VCCalProp ) { | 1271 | if ( name == VCCalProp ) { |
787 | VObjectIterator nit; | 1272 | VObjectIterator nit; |
788 | initPropIterator( &nit, obj ); | 1273 | initPropIterator( &nit, obj ); |
789 | while( moreIteration( &nit ) ) { | 1274 | while( moreIteration( &nit ) ) { |
790 | VObject *o = nextVObject( &nit ); | 1275 | VObject *o = nextVObject( &nit ); |
791 | QCString name = vObjectName( o ); | 1276 | QCString name = vObjectName( o ); |
792 | if ( name == VCEventProp ) | 1277 | if ( name == VCEventProp ) |
793 | events.append( parseVObject( o ) ); | 1278 | events.append( parseVObject( o ) ); |
794 | } | 1279 | } |
795 | } else if ( name == VCEventProp ) { | 1280 | } else if ( name == VCEventProp ) { |
796 | // shouldn't happen, but just to be sure | 1281 | // shouldn't happen, but just to be sure |
797 | events.append( parseVObject( obj ) ); | 1282 | events.append( parseVObject( obj ) ); |
798 | } | 1283 | } |
799 | VObject *t = obj; | 1284 | VObject *t = obj; |
800 | obj = nextVObjectInList(obj); | 1285 | obj = nextVObjectInList(obj); |
801 | cleanVObject( t ); | 1286 | cleanVObject( t ); |
802 | } | 1287 | } |
803 | 1288 | ||
804 | return events; | 1289 | return events; |
805 | } | 1290 | } |
806 | 1291 | ||
807 | bool Event::match( const QRegExp &r ) const | 1292 | bool Event::match( const QRegExp &r ) const |
808 | { | 1293 | { |
809 | bool returnMe; | 1294 | bool returnMe; |
810 | returnMe = false; | 1295 | returnMe = false; |
811 | 1296 | ||
812 | if ( descript.find( r ) > -1 ) | 1297 | if ( descript.find( r ) > -1 ) |
813 | returnMe = true; | 1298 | returnMe = true; |
814 | else if ( locat.find( r ) > -1 ) | 1299 | else if ( locat.find( r ) > -1 ) |
815 | returnMe = true; | 1300 | returnMe = true; |
816 | else if ( TimeConversion::fromUTC( startUTC ).toString().find( r ) > -1 ) | 1301 | else if ( TimeConversion::fromUTC( startUTC ).toString().find( r ) > -1 ) |
817 | returnMe = true; | 1302 | returnMe = true; |
818 | else if ( TimeConversion::fromUTC( endUTC ).toString().find( r ) > -1 ) | 1303 | else if ( TimeConversion::fromUTC( endUTC ).toString().find( r ) > -1 ) |
819 | returnMe = true; | 1304 | returnMe = true; |
820 | else if ( tz.find( r ) > -1 ) | 1305 | else if ( tz.find( r ) > -1 ) |
821 | returnMe = true; | 1306 | returnMe = true; |
822 | else if ( note.find( r ) > -1 ) | 1307 | else if ( note.find( r ) > -1 ) |
823 | returnMe = true; | 1308 | returnMe = true; |
824 | else if ( doRepeat() ) { | 1309 | else if ( doRepeat() ) { |
825 | if ( pattern.hasEndDate ) | 1310 | if ( pattern.hasEndDate ) |
826 | if ( TimeConversion::fromUTC( pattern.endDateUTC ).toString().find(r) > -1 ) | 1311 | if ( TimeConversion::fromUTC( pattern.endDateUTC ).toString().find(r) > -1 ) |
827 | returnMe = true; | 1312 | returnMe = true; |
828 | } | 1313 | } |
829 | return returnMe; | 1314 | return returnMe; |
830 | } | 1315 | } |
diff --git a/library/backend/event.h b/library/backend/event.h index 277aadd..7fe41a5 100644 --- a/library/backend/event.h +++ b/library/backend/event.h | |||
@@ -1,234 +1,375 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2001 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. |
3 | ** | 3 | ** |
4 | ** This file is part of Qtopia Environment. | 4 | ** This file is part of the Qtopia Environment. |
5 | ** | 5 | ** |
6 | ** This file may be distributed and/or modified under the terms of the | 6 | ** This file may be distributed and/or modified under the terms of the |
7 | ** GNU General Public License version 2 as published by the Free Software | 7 | ** GNU General Public License version 2 as published by the Free Software |
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** packaging of this file. | 9 | ** packaging of this file. |
10 | ** | 10 | ** |
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | 11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
13 | ** | 13 | ** |
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
15 | ** | 15 | ** |
16 | ** Contact info@trolltech.com if any conditions of this licensing are | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
17 | ** not clear to you. | 17 | ** not clear to you. |
18 | ** | 18 | ** |
19 | **********************************************************************/ | 19 | **********************************************************************/ |
20 | 20 | ||
21 | #ifndef __EVENT_H__ | 21 | #ifndef __EVENT_H__ |
22 | #define __EVENT_H__ | 22 | #define __EVENT_H__ |
23 | 23 | ||
24 | #include <qdatetime.h> | 24 | #include <qdatetime.h> |
25 | #include <qvaluelist.h> | 25 | #include <qvaluelist.h> |
26 | #include <qcolor.h> | ||
26 | 27 | ||
27 | #ifdef PALMTOPCENTER | 28 | #ifdef PALMTOPCENTER |
28 | #include <qpc/qsorter.h> | 29 | #include <qpc/qsorter.h> |
29 | #endif | 30 | #endif |
30 | #include <qpe/palmtoprecord.h> | 31 | #include <qtopia/private/palmtoprecord.h> |
31 | 32 | ||
32 | #include <qpe/timeconversion.h> | 33 | #include <qpe/timeconversion.h> |
33 | 34 | ||
35 | static const QColor colorNormal = QColor(255, 0 , 0 ); | ||
36 | static const QColor colorRepeat = QColor(0 , 0 , 255); | ||
37 | static const QColor colorNormalLight = QColor(255, 220, 220); | ||
38 | static const QColor colorRepeatLight = QColor(200, 200, 255); | ||
39 | |||
34 | class EventPrivate; | 40 | class EventPrivate; |
35 | class QPC_EXPORT Event : public Qtopia::Record | 41 | class QPC_EXPORT Event : public Qtopia::Record |
36 | { | 42 | { |
37 | public: | 43 | public: |
38 | enum RepeatType { NoRepeat = -1, Daily, Weekly, MonthlyDay, | 44 | enum RepeatType { NoRepeat = -1, Daily, Weekly, MonthlyDay, |
39 | MonthlyDate, Yearly }; | 45 | MonthlyDate, Yearly }; |
46 | |||
47 | // Don't use this. | ||
40 | enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, | 48 | enum Days { MON = 0x01, TUE = 0x02, WED = 0x04, THU = 0x08, |
41 | FRI = 0x10, SAT = 0x20, SUN = 0x40 }; | 49 | FRI = 0x10, SAT = 0x20, SUN = 0x40 }; |
50 | // Don't use this. | ||
42 | struct QPC_EXPORT RepeatPattern | 51 | struct QPC_EXPORT RepeatPattern |
43 | { | 52 | { |
44 | RepeatPattern() { | 53 | RepeatPattern() { |
45 | type = NoRepeat; frequency = -1; days = 0; position = 0; createTime = -1; | 54 | type = NoRepeat; frequency = -1; days = 0; position = 0; createTime = -1; |
46 | hasEndDate = FALSE; endDateUTC = 0; } | 55 | hasEndDate = FALSE; endDateUTC = 0; } |
47 | bool operator ==( const RepeatPattern &right ) const; | 56 | bool operator ==( const RepeatPattern &right ) const; |
48 | 57 | ||
49 | RepeatType type; | 58 | RepeatType type; |
50 | int frequency; | 59 | int frequency; |
51 | int position;// the posistion in the month (e.g. the first sunday, etc) positive, count from the front negative count from the end... | 60 | int position;// the posistion in the month (e.g. the first sunday, etc) positive, count from the front negative count from the end... |
52 | char days; // a mask for days OR in your days! | 61 | char days; // a mask for days OR in your days! |
53 | bool hasEndDate; | 62 | bool hasEndDate; |
54 | QDate endDate() const { return TimeConversion::fromUTC( endDateUTC ).date(); } | 63 | QDate endDate() const { return TimeConversion::fromUTC( endDateUTC ).date(); } |
55 | void setEndDate( const QDate &dt ) { endDateUTC = TimeConversion::toUTC( dt ); } | 64 | void setEndDate( const QDate &dt ) { endDateUTC = TimeConversion::toUTC( dt ); } |
56 | time_t endDateUTC; | 65 | time_t endDateUTC; |
57 | time_t createTime; | 66 | time_t createTime; |
58 | }; | 67 | }; |
59 | 68 | ||
60 | Event(); | 69 | Event(); |
61 | Event( const QMap<int, QString > & map ); | 70 | Event( const QMap<int, QString > & map ); |
62 | virtual ~Event(); | 71 | virtual ~Event(); |
63 | 72 | ||
64 | QMap<int, QString> toMap() const; | 73 | QMap<int, QString> toMap() const; |
65 | 74 | ||
66 | static void writeVCalendar( const QString &filename, const QValueList<Event> &events); | 75 | static void writeVCalendar( const QString &filename, const QValueList<Event> &events); |
67 | static void writeVCalendar( const QString &filename, const Event &event); | 76 | static void writeVCalendar( const QString &filename, const Event &event); |
68 | static QValueList<Event> readVCalendar( const QString &filename ); | 77 | static QValueList<Event> readVCalendar( const QString &filename ); |
69 | 78 | ||
70 | enum Type { Normal, AllDay }; | 79 | enum Type { Normal, AllDay }; |
71 | enum SoundTypeChoice { Silent, Loud }; | 80 | enum SoundTypeChoice { Silent, Loud }; |
72 | 81 | ||
82 | // Don't use these, there are essentially meaningless. | ||
73 | bool operator<( const Event &e1) const { return start() < e1.start(); }; | 83 | bool operator<( const Event &e1) const { return start() < e1.start(); }; |
74 | bool operator<=( const Event &e1 ) const { return start() <= e1.start(); }; | 84 | bool operator<=( const Event &e1 ) const { return start() <= e1.start(); }; |
75 | bool operator!=( const Event &e1 ) const { return !( *this == e1 ); }; | 85 | bool operator!=( const Event &e1 ) const { return !( *this == e1 ); }; |
76 | bool operator>( const Event &e1 ) const { return start() > e1.start(); }; | 86 | bool operator>( const Event &e1 ) const { return start() > e1.start(); }; |
77 | bool operator>=(const Event &e1 ) const { return start() >= e1.start(); }; | 87 | bool operator>=(const Event &e1 ) const { return start() >= e1.start(); }; |
78 | bool operator==( const Event &e ) const; | 88 | bool operator==( const Event &e ) const; |
79 | 89 | ||
80 | void setDescription( const QString &s ); | 90 | void setDescription( const QString &s ); |
81 | const QString &description() const; | 91 | const QString &description() const; |
82 | 92 | ||
83 | void setLocation( const QString &s ); | 93 | void setLocation( const QString &s ); |
84 | const QString &location() const; | 94 | const QString &location() const; |
85 | 95 | ||
86 | void setType( Type t ); | 96 | void setNotes( const QString &n ); |
87 | Type type() const; | 97 | const QString ¬es() const; |
98 | |||
99 | void setType( Type t ); // Don't use me. | ||
100 | Type type() const; // Don't use me. | ||
101 | |||
102 | void setAllDay(bool); | ||
103 | bool isAllDay() const; | ||
104 | |||
88 | void setStart( const QDateTime &d ); | 105 | void setStart( const QDateTime &d ); |
89 | void setStart( time_t time ); | 106 | void setStart( time_t time ); // don't use me. |
90 | QDateTime start( bool actual = FALSE ) const; | 107 | QDateTime start( ) const; |
91 | time_t startTime() const { return startUTC; } | 108 | QDateTime start( bool actual ) const; // don't use me. |
109 | time_t startTime() const { return startUTC; } // don't use me. | ||
92 | void setEnd( const QDateTime &e ); | 110 | void setEnd( const QDateTime &e ); |
93 | void setEnd( time_t time ); | 111 | void setEnd( time_t time ); // don't use me |
94 | QDateTime end( bool actual = FALSE ) const; | 112 | QDateTime end( ) const; |
95 | time_t endTime() const { return endUTC; } | 113 | QDateTime end( bool actual ) const; // don't use me. |
114 | time_t endTime() const { return endUTC; } // don't use me. | ||
96 | void setTimeZone( const QString & ); | 115 | void setTimeZone( const QString & ); |
97 | const QString &timeZone() const; | 116 | const QString &timeZone() const; |
98 | void setAlarm( bool b, int minutes, SoundTypeChoice ); | 117 | void setAlarm( int minutes, SoundTypeChoice ); |
118 | void clearAlarm(); | ||
119 | void setAlarm( bool b, int minutes, SoundTypeChoice ); // Don't use me. | ||
99 | bool hasAlarm() const; | 120 | bool hasAlarm() const; |
100 | int alarmTime() const; | 121 | int alarmDelay() const; |
122 | int alarmTime() const; // Don't use me. | ||
101 | SoundTypeChoice alarmSound() const; | 123 | SoundTypeChoice alarmSound() const; |
124 | |||
125 | RepeatType repeatType() const; | ||
126 | int frequency() const; | ||
127 | int weekOffset() const; | ||
128 | QDate repeatTill() const; | ||
129 | bool repeatForever() const; | ||
130 | bool repeatOnWeekDay(int day) const; | ||
131 | |||
132 | void setRepeatType(RepeatType); | ||
133 | void setFrequency(int); | ||
134 | void setRepeatTill(const QDate &); | ||
135 | void setRepeatForever(bool); | ||
136 | void setRepeatOnWeekDay(int day, bool enable); | ||
137 | |||
138 | // Don't use any of these. | ||
102 | void setRepeat( bool b, const RepeatPattern &p ); | 139 | void setRepeat( bool b, const RepeatPattern &p ); |
103 | void setRepeat( const RepeatPattern &p ); | 140 | void setRepeat( const RepeatPattern &p ); |
104 | bool hasRepeat() const; | 141 | bool hasRepeat() const; |
105 | const RepeatPattern &repeatPattern() const; | 142 | const RepeatPattern &repeatPattern() const; |
106 | RepeatPattern &repeatPattern(); | 143 | RepeatPattern &repeatPattern(); |
107 | void setNotes( const QString &n ); | ||
108 | const QString ¬es() const; | ||
109 | bool doRepeat() const { return pattern.type != NoRepeat; } | 144 | bool doRepeat() const { return pattern.type != NoRepeat; } |
110 | 145 | ||
111 | void save( QString& buf ); | 146 | void save( QString& buf ); |
112 | //void load( Node *n ); | 147 | //void load( Node *n ); |
113 | 148 | ||
149 | bool match( const QRegExp &r ) const; | ||
150 | |||
151 | // Don't use these either. Functionality will be moved elsewhere. | ||
152 | |||
114 | // helper function to calculate the week of the given date | 153 | // helper function to calculate the week of the given date |
115 | static int week( const QDate& date ); | 154 | static int week( const QDate& date ); |
116 | // calculates the number of occurrences of the week day of | 155 | // calculates the number of occurrences of the week day of |
117 | // the given date from the start of the month | 156 | // the given date from the start of the month |
118 | static int occurrence( const QDate& date ); | 157 | static int occurrence( const QDate& date ); |
119 | // returns a proper days-char for a given dayOfWeek() | 158 | // returns a proper days-char for a given dayOfWeek() |
120 | static char day( int dayOfWeek ) { return 1 << ( dayOfWeek - 1 ); } | 159 | static char day( int dayOfWeek ) { return 1 << ( dayOfWeek - 1 ); } |
121 | // returns the dayOfWeek for the *first* day it finds (ignores | 160 | // returns the dayOfWeek for the *first* day it finds (ignores |
122 | // any further days!). Returns 1 (Monday) if there isn't any day found | 161 | // any further days!). Returns 1 (Monday) if there isn't any day found |
123 | static int dayOfWeek( char day ); | 162 | static int dayOfWeek( char day ); |
124 | // returns the difference of months from first to second. | 163 | // returns the difference of months from first to second. |
125 | static int monthDiff( const QDate& first, const QDate& second ); | 164 | static int monthDiff( const QDate& first, const QDate& second ); |
126 | bool match( const QRegExp &r ) const; | ||
127 | 165 | ||
128 | private: | 166 | private: |
129 | Qtopia::UidGen &uidGen() { return sUidGen; } | 167 | Qtopia::UidGen &uidGen() { return sUidGen; } |
130 | static Qtopia::UidGen sUidGen; | 168 | static Qtopia::UidGen sUidGen; |
131 | 169 | ||
132 | QString descript, locat, categ; | 170 | QString descript, locat, categ; |
133 | Type typ : 4; | 171 | Type typ : 4; |
134 | bool startTimeDirty : 1; | 172 | bool startTimeDirty : 1; |
135 | bool endTimeDirty : 1; | 173 | bool endTimeDirty : 1; |
136 | time_t startUTC, endUTC; | 174 | time_t startUTC, endUTC; |
137 | QString tz; | 175 | QString tz; |
138 | bool hAlarm, hRepeat; | 176 | bool hAlarm, hRepeat; |
139 | int aMinutes; | 177 | int aMinutes; |
140 | SoundTypeChoice aSound; | 178 | SoundTypeChoice aSound; |
141 | RepeatPattern pattern; | 179 | RepeatPattern pattern; |
142 | QString note; | 180 | QString note; |
143 | // ADDITION | 181 | // ADDITION |
144 | int mRid;// Recode ID | 182 | int mRid;// Recode ID |
145 | int mRinfo;// Recode Info | 183 | int mRinfo;// Recode Info |
146 | // | 184 | // |
147 | EventPrivate *d; | 185 | EventPrivate *d; |
148 | 186 | ||
149 | }; | 187 | }; |
150 | 188 | ||
151 | // Since an event spans multiple day, it is better to have this | 189 | // Since an event spans multiple day, it is better to have this |
152 | // class to represent a day instead of creating many | 190 | // class to represent a day instead of creating many |
153 | // dummy events... | 191 | // dummy events... |
154 | 192 | ||
155 | class EffectiveEventPrivate; | 193 | class EffectiveEventPrivate; |
156 | class QPC_EXPORT EffectiveEvent | 194 | class QPC_EXPORT EffectiveEvent |
157 | { | 195 | { |
158 | public: | 196 | public: |
159 | // If we calculate the effective event of a multi-day event | 197 | // If we calculate the effective event of a multi-day event |
160 | // we have to figure out whether we are at the first day, | 198 | // we have to figure out whether we are at the first day, |
161 | // at the end, or anywhere else ("middle"). This is important | 199 | // at the end, or anywhere else ("middle"). This is important |
162 | // for the start/end times (00:00/23:59) | 200 | // for the start/end times (00:00/23:59) |
163 | // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi- | 201 | // MidWay: 00:00 -> 23:59, as we are "in the middle" of a multi- |
164 | // day event | 202 | // day event |
165 | // Start: start time -> 23:59 | 203 | // Start: start time -> 23:59 |
166 | // End: 00:00 -> end time | 204 | // End: 00:00 -> end time |
167 | // Start | End == StartEnd: for single-day events (default) | 205 | // Start | End == StartEnd: for single-day events (default) |
168 | // here we draw start time -> end time | 206 | // here we draw start time -> end time |
169 | enum Position { MidWay = 0, Start = 1, End = 2, StartEnd = 3 }; | 207 | enum Position { MidWay = 0, Start = 1, End = 2, StartEnd = 3 }; |
170 | 208 | ||
171 | EffectiveEvent(); | 209 | EffectiveEvent(); |
172 | EffectiveEvent( const Event &event, const QDate &startDate, Position pos = StartEnd ); | 210 | EffectiveEvent( const Event &event, const QDate &startDate, Position pos = StartEnd ); |
173 | EffectiveEvent( const EffectiveEvent & ); | 211 | EffectiveEvent( const EffectiveEvent & ); |
174 | EffectiveEvent& operator=( const EffectiveEvent & ); | 212 | EffectiveEvent& operator=( const EffectiveEvent & ); |
175 | ~EffectiveEvent(); | 213 | ~EffectiveEvent(); |
176 | 214 | ||
177 | 215 | ||
178 | bool operator<( const EffectiveEvent &e ) const; | 216 | bool operator<( const EffectiveEvent &e ) const; |
179 | bool operator<=( const EffectiveEvent &e ) const; | 217 | bool operator<=( const EffectiveEvent &e ) const; |
180 | bool operator==( const EffectiveEvent &e ) const; | 218 | bool operator==( const EffectiveEvent &e ) const; |
181 | bool operator!=( const EffectiveEvent &e ) const; | 219 | bool operator!=( const EffectiveEvent &e ) const; |
182 | bool operator>( const EffectiveEvent &e ) const; | 220 | bool operator>( const EffectiveEvent &e ) const; |
183 | bool operator>= ( const EffectiveEvent &e ) const; | 221 | bool operator>= ( const EffectiveEvent &e ) const; |
184 | 222 | ||
185 | void setStart( const QTime &start ); | 223 | void setStart( const QTime &start ); |
186 | void setEnd( const QTime &end ); | 224 | void setEnd( const QTime &end ); |
187 | void setEvent( Event e ); | 225 | void setEvent( Event e ); |
188 | void setDate( const QDate &date ); | 226 | void setDate( const QDate &date ); |
189 | void setEffectiveDates( const QDate &from, const QDate &to ); | 227 | void setEffectiveDates( const QDate &from, const QDate &to ); |
190 | 228 | ||
191 | // QString category() const; | 229 | // QString category() const; |
192 | const QString &description() const; | 230 | const QString &description() const; |
193 | const QString &location() const; | 231 | const QString &location() const; |
194 | const QString ¬es() const; | 232 | const QString ¬es() const; |
195 | const Event &event() const; | 233 | const Event &event() const; |
196 | const QTime &start() const; | 234 | const QTime &start() const; |
197 | const QTime &end() const; | 235 | const QTime &end() const; |
198 | const QDate &date() const; | 236 | const QDate &date() const; |
199 | int length() const; | 237 | int length() const; |
200 | int size() const; | 238 | int size() const; |
201 | 239 | ||
202 | QDate startDate() const; | 240 | QDate startDate() const; |
203 | QDate endDate() const; | 241 | QDate endDate() const; |
204 | 242 | ||
205 | private: | 243 | private: |
206 | class EffectiveEventPrivate *d; | 244 | class EffectiveEventPrivate *d; |
207 | Event mEvent; | 245 | Event mEvent; |
208 | QDate mDate; | 246 | QDate mDate; |
209 | QTime mStart, | 247 | QTime mStart, |
210 | mEnd; | 248 | mEnd; |
211 | 249 | ||
212 | }; | 250 | }; |
213 | 251 | ||
252 | inline void Event::setAlarm( int minutes, SoundTypeChoice s ) | ||
253 | { | ||
254 | setAlarm(TRUE, minutes, s); | ||
255 | } | ||
256 | |||
257 | inline void Event::clearAlarm() | ||
258 | { | ||
259 | setAlarm(FALSE, 0, Silent); | ||
260 | } | ||
261 | |||
262 | inline int Event::alarmDelay() const | ||
263 | { | ||
264 | return alarmTime(); | ||
265 | } | ||
266 | |||
267 | inline void Event::setAllDay(bool enable) | ||
268 | { | ||
269 | if (enable) | ||
270 | setType(AllDay); | ||
271 | else | ||
272 | setType(Normal); | ||
273 | }; | ||
274 | |||
275 | inline bool Event::isAllDay() const | ||
276 | { | ||
277 | return type() == AllDay; | ||
278 | } | ||
279 | |||
280 | inline Event::RepeatType Event::repeatType() const | ||
281 | { | ||
282 | return repeatPattern().type; | ||
283 | } | ||
284 | |||
285 | inline int Event::frequency() const | ||
286 | { | ||
287 | return repeatPattern().frequency; | ||
288 | } | ||
289 | |||
290 | inline int Event::weekOffset() const | ||
291 | { | ||
292 | if (start().date().day() == 1) | ||
293 | return 1; | ||
294 | return (start().date().day() - 1) / 7 + 1; | ||
295 | } | ||
296 | |||
297 | inline QDate Event::repeatTill() const | ||
298 | { | ||
299 | return repeatPattern().endDate(); | ||
300 | } | ||
301 | |||
302 | inline bool Event::repeatForever() const | ||
303 | { | ||
304 | return !repeatPattern().hasEndDate; | ||
305 | } | ||
306 | |||
307 | inline void Event::setRepeatType(RepeatType t) | ||
308 | { | ||
309 | pattern.type = t; | ||
310 | } | ||
311 | |||
312 | inline void Event::setFrequency(int f) | ||
313 | { | ||
314 | pattern.frequency = f; | ||
315 | } | ||
316 | |||
317 | inline void Event::setRepeatTill(const QDate &d) | ||
318 | { | ||
319 | pattern.setEndDate(d); | ||
320 | pattern.hasEndDate = TRUE; | ||
321 | } | ||
322 | |||
323 | inline void Event::setRepeatForever(bool b) | ||
324 | { | ||
325 | if (!b == pattern.hasEndDate) | ||
326 | return; | ||
327 | if (!b && !pattern.hasEndDate) | ||
328 | pattern.setEndDate(end().date()); | ||
329 | pattern.hasEndDate = !b; | ||
330 | } | ||
331 | |||
332 | inline bool Event::repeatOnWeekDay(int day) const | ||
333 | { | ||
334 | if (pattern.type != Weekly) | ||
335 | return FALSE; | ||
336 | return ( (1 << (day - 1)) & pattern.days ) != 0; | ||
337 | } | ||
338 | |||
339 | inline void Event::setRepeatOnWeekDay(int day, bool enable) | ||
340 | { | ||
341 | if ( repeatOnWeekDay( day ) != enable ) | ||
342 | pattern.days ^= 1 << (day - 1); | ||
343 | } | ||
344 | |||
345 | inline QDateTime Event::start( ) const | ||
346 | { | ||
347 | return start(FALSE); | ||
348 | } | ||
349 | |||
350 | inline QDateTime Event::end( ) const | ||
351 | { | ||
352 | return end(FALSE); | ||
353 | } | ||
354 | |||
214 | #ifdef PALMTOPCENTER | 355 | #ifdef PALMTOPCENTER |
215 | class QPC_EXPORT EffectiveEventSizeSorter : public QSorter<EffectiveEvent> | 356 | class QPC_EXPORT EffectiveEventSizeSorter : public QSorter<EffectiveEvent> |
216 | { | 357 | { |
217 | public: | 358 | public: |
218 | int compare( const EffectiveEvent& a, const EffectiveEvent& b ) const | 359 | int compare( const EffectiveEvent& a, const EffectiveEvent& b ) const |
219 | { | 360 | { |
220 | return a.size() - b.size(); | 361 | return a.size() - b.size(); |
221 | } | 362 | } |
222 | }; | 363 | }; |
223 | 364 | ||
224 | class QPC_EXPORT EffectiveEventTimeSorter : public QSorter<EffectiveEvent> | 365 | class QPC_EXPORT EffectiveEventTimeSorter : public QSorter<EffectiveEvent> |
225 | { | 366 | { |
226 | public: | 367 | public: |
227 | int compare( const EffectiveEvent& a, const EffectiveEvent& b ) const | 368 | int compare( const EffectiveEvent& a, const EffectiveEvent& b ) const |
228 | { | 369 | { |
229 | return a.start().secsTo( b.start() ); | 370 | return a.start().secsTo( b.start() ); |
230 | } | 371 | } |
231 | }; | 372 | }; |
232 | #endif | 373 | #endif |
233 | 374 | ||
234 | #endif | 375 | #endif |
diff --git a/library/backend/palmtoprecord.cpp b/library/backend/palmtoprecord.cpp index 0d57699..3cfa874 100644 --- a/library/backend/palmtoprecord.cpp +++ b/library/backend/palmtoprecord.cpp | |||
@@ -1,127 +1,141 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. |
3 | ** | 3 | ** |
4 | ** This file is part of Qtopia Environment. | 4 | ** This file is part of the Qtopia Environment. |
5 | ** | 5 | ** |
6 | ** This file may be distributed and/or modified under the terms of the | 6 | ** This file may be distributed and/or modified under the terms of the |
7 | ** GNU General Public License version 2 as published by the Free | 7 | ** GNU General Public License version 2 as published by the Free Software |
8 | ** Software Foundation and appearing in the file LICENSE.GPL included | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** in the packaging of this file. | 9 | ** packaging of this file. |
10 | ** | 10 | ** |
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING | 11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
12 | ** THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
13 | ** PARTICULAR PURPOSE. | ||
14 | ** | 13 | ** |
15 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
16 | ** | 15 | ** |
17 | ** Contact info@trolltech.com if any conditions of this licensing are | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
18 | ** not clear to you. | 17 | ** not clear to you. |
19 | ** | 18 | ** |
20 | **********************************************************************/ | 19 | **********************************************************************/ |
21 | #include "palmtoprecord.h" | 20 | #include <qtopia/private/palmtoprecord.h> |
22 | #include "stringutil.h" | 21 | #include <qtopia/stringutil.h> |
23 | #include <qstringlist.h> | 22 | #include <qstringlist.h> |
24 | 23 | ||
24 | /*! \class Qtopia::PalmtopRecord palmtoprecord.h | ||
25 | \brief The Qtopia::PalmtopRecord class is the base class for all PIM records. | ||
26 | |||
27 | Provides unique id and category support for all PIM records. | ||
28 | |||
29 | \ingroup qtopiaemb | ||
30 | \ingroup qtopiadesktop | ||
31 | */ | ||
32 | |||
33 | |||
25 | namespace Qtopia { | 34 | namespace Qtopia { |
26 | 35 | ||
36 | |||
37 | |||
27 | Record &Record::operator=( const Record &c ) | 38 | Record &Record::operator=( const Record &c ) |
28 | { | 39 | { |
29 | mUid = c.mUid; | 40 | mUid = c.mUid; |
30 | mCats = c.mCats; | 41 | mCats = c.mCats; |
31 | customMap = c.customMap; | 42 | customMap = c.customMap; |
32 | return *this; | 43 | return *this; |
33 | } | 44 | } |
34 | 45 | ||
35 | void Record::setCategories( int single ) | 46 | void Record::setCategories( int single ) |
36 | { | 47 | { |
37 | if ( single == 0 ) | 48 | if ( single == 0 ) |
38 | return; | 49 | return; |
39 | mCats.resize(1); | 50 | mCats.resize(1); |
40 | mCats[0] = single; | 51 | mCats[0] = single; |
41 | } | 52 | } |
42 | 53 | ||
43 | // convenience methods provided for loading and saving to xml | 54 | // convenience methods provided for loading and saving to xml |
44 | QString Record::idsToString( const QArray<int> &cats ) | 55 | QString Record::idsToString( const QArray<int> &catsUnsorted ) |
45 | { | 56 | { |
57 | QArray<int> cats = catsUnsorted; | ||
58 | cats.sort(); | ||
59 | |||
46 | QString str; | 60 | QString str; |
47 | for ( uint i = 0; i < cats.size(); i++ ) | 61 | for ( uint i = 0; i < cats.size(); i++ ) |
48 | if ( i == 0 ) | 62 | if ( i == 0 ) |
49 | str = QString::number( cats[int(i)] ); | 63 | str = QString::number( cats[int(i)] ); |
50 | else | 64 | else |
51 | str += ";" + QString::number( cats[int(i)] ); | 65 | str += ";" + QString::number( cats[int(i)] ); |
52 | 66 | ||
53 | return str; | 67 | return str; |
54 | } | 68 | } |
55 | 69 | ||
56 | // convenience methods provided for loading and saving to xml | 70 | // convenience methods provided for loading and saving to xml |
57 | QArray<int> Record::idsFromString( const QString &str ) | 71 | QArray<int> Record::idsFromString( const QString &str ) |
58 | { | 72 | { |
59 | QStringList catStrs = QStringList::split( ";", str ); | 73 | QStringList catStrs = QStringList::split( ";", str ); |
60 | QArray<int> cats( catStrs.count() ); | 74 | QArray<int> cats( catStrs.count() ); |
61 | uint i = 0; | 75 | uint i = 0; |
62 | for ( QStringList::ConstIterator it = catStrs.begin(); | 76 | for ( QStringList::ConstIterator it = catStrs.begin(); |
63 | it != catStrs.end(); ++it ) { | 77 | it != catStrs.end(); ++it ) { |
64 | cats[int(i)] = (*it).toInt(); | 78 | cats[int(i)] = (*it).toInt(); |
65 | i++; | 79 | i++; |
66 | } | 80 | } |
67 | return cats; | 81 | return cats; |
68 | } | 82 | } |
69 | 83 | ||
70 | /*! | 84 | /*! |
71 | Returns the string stored for the custom field \a key. | 85 | Returns the string stored for the custom field \a key. |
72 | Returns a null string if the field does not exist. | 86 | Returns a null string if the field does not exist. |
73 | */ | 87 | */ |
74 | QString Record::customField( const QString &key) const | 88 | QString Record::customField( const QString &key) const |
75 | { | 89 | { |
76 | if (customMap.contains(key)) | 90 | if (customMap.contains(key)) |
77 | return customMap[key]; | 91 | return customMap[key]; |
78 | 92 | ||
79 | return QString::null; | 93 | return QString::null; |
80 | } | 94 | } |
81 | 95 | ||
82 | /*! | 96 | /*! |
83 | Sets the string stored for the custom field \a key to \a value. | 97 | Sets the string stored for the custom field \a key to \a value. |
84 | */ | 98 | */ |
85 | void Record::setCustomField( const QString &key, const QString &value) | 99 | void Record::setCustomField( const QString &key, const QString &value) |
86 | { | 100 | { |
87 | qWarning("setting custom " + key + " to " + value); | 101 | // qWarning("setting custom " + key + " to " + value); |
88 | if (customMap.contains(key)) | 102 | if (customMap.contains(key)) |
89 | customMap.replace(key, value); | 103 | customMap.replace(key, value); |
90 | else | 104 | else |
91 | customMap.insert(key, value); | 105 | customMap.insert(key, value); |
92 | 106 | ||
93 | qWarning(QString("custom size %1").arg(customMap.count())); | 107 | // qWarning(QString("custom size %1").arg(customMap.count())); |
94 | } | 108 | } |
95 | 109 | ||
96 | /*! | 110 | /*! |
97 | Removes the custom field \a key. | 111 | Removes the custom field \a key. |
98 | */ | 112 | */ |
99 | void Record::removeCustomField(const QString &key) | 113 | void Record::removeCustomField(const QString &key) |
100 | { | 114 | { |
101 | customMap.remove(key); | 115 | customMap.remove(key); |
102 | } | 116 | } |
103 | 117 | ||
104 | QString Record::customToXml() const | 118 | QString Record::customToXml() const |
105 | { | 119 | { |
106 | //qWarning(QString("writing custom %1").arg(customMap.count())); | 120 | //qWarning(QString("writing custom %1").arg(customMap.count())); |
107 | QString buf(" "); | 121 | QString buf(" "); |
108 | for ( QMap<QString, QString>::ConstIterator cit = customMap.begin(); | 122 | for ( QMap<QString, QString>::ConstIterator cit = customMap.begin(); |
109 | cit != customMap.end(); ++cit) { | 123 | cit != customMap.end(); ++cit) { |
110 | qWarning(".ITEM."); | 124 | // qWarning(".ITEM."); |
111 | buf += cit.key(); | 125 | buf += cit.key(); |
112 | buf += "=\""; | 126 | buf += "=\""; |
113 | buf += escapeString(cit.data()); | 127 | buf += escapeString(cit.data()); |
114 | buf += "\" "; | 128 | buf += "\" "; |
115 | } | 129 | } |
116 | return buf; | 130 | return buf; |
117 | } | 131 | } |
118 | 132 | ||
119 | void Record::dump( const QMap<int, QString> &map ) | 133 | void Record::dump( const QMap<int, QString> &map ) |
120 | { | 134 | { |
121 | QMap<int, QString>::ConstIterator it; | 135 | QMap<int, QString>::ConstIterator it; |
122 | for( it = map.begin(); it != map.end(); ++it ) | 136 | for( it = map.begin(); it != map.end(); ++it ) |
123 | qDebug("%d : %s", it.key(), it.data().local8Bit().data() ); | 137 | qDebug("%d : %s", it.key(), it.data().local8Bit().data() ); |
124 | } | 138 | } |
125 | 139 | ||
126 | } | 140 | } |
127 | 141 | ||
diff --git a/library/backend/palmtoprecord.h b/library/backend/palmtoprecord.h index 0372011..72f7d1c 100644 --- a/library/backend/palmtoprecord.h +++ b/library/backend/palmtoprecord.h | |||
@@ -1,94 +1,95 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. |
3 | ** | 3 | ** |
4 | ** This file is part of Qtopia Environment. | 4 | ** This file is part of the Qtopia Environment. |
5 | ** | 5 | ** |
6 | ** This file may be distributed and/or modified under the terms of the | 6 | ** This file may be distributed and/or modified under the terms of the |
7 | ** GNU General Public License version 2 as published by the Free | 7 | ** GNU General Public License version 2 as published by the Free Software |
8 | ** Software Foundation and appearing in the file LICENSE.GPL included | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** in the packaging of this file. | 9 | ** packaging of this file. |
10 | ** | 10 | ** |
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING | 11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
12 | ** THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
13 | ** PARTICULAR PURPOSE. | ||
14 | ** | 13 | ** |
15 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
16 | ** | 15 | ** |
17 | ** Contact info@trolltech.com if any conditions of this licensing are | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
18 | ** not clear to you. | 17 | ** not clear to you. |
19 | ** | 18 | ** |
20 | **********************************************************************/ | 19 | **********************************************************************/ |
21 | |||
22 | #ifndef QTPALMTOP_RECORD_H | 20 | #ifndef QTPALMTOP_RECORD_H |
23 | #define QTPALMTOP_RECORD_H | 21 | #define QTPALMTOP_RECORD_H |
24 | |||
25 | #include <qglobal.h> | 22 | #include <qglobal.h> |
26 | #include "qpcglobal.h" | 23 | #include "qpcglobal.h" |
27 | #include "palmtopuidgen.h" | 24 | #include "palmtopuidgen.h" |
28 | #include <qarray.h> | 25 | #include <qarray.h> |
29 | #include <qmap.h> | 26 | #include <qmap.h> |
30 | 27 | ||
31 | #if defined(QPC_TEMPLATEDLL) | 28 | #if defined(QPC_TEMPLATEDLL) |
32 | // MOC_SKIP_BEGIN | 29 | // MOC_SKIP_BEGIN |
33 | template class QPC_EXPORT QMap<QString, QString>; | 30 | QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<QString, QString>; |
34 | // MOC_SKIP_END | 31 | // MOC_SKIP_END |
35 | #endif | 32 | #endif |
36 | 33 | ||
37 | class QRegExp; | 34 | class QRegExp; |
38 | namespace Qtopia { | 35 | namespace Qtopia { |
39 | 36 | ||
40 | class RecordPrivate; | 37 | class RecordPrivate; |
41 | class QPC_EXPORT Record | 38 | class QPC_EXPORT Record |
42 | { | 39 | { |
43 | public: | 40 | public: |
44 | Record() : mUid(0), mCats() { } | 41 | Record() : mUid(0), mCats() { } |
45 | Record( const Record &c ) :mUid( c.mUid ), mCats ( c.mCats ), customMap(c.customMap) { } | 42 | Record( const Record &c ) :mUid( c.mUid ), mCats ( c.mCats ), customMap(c.customMap) { } |
46 | virtual ~Record() { } | 43 | virtual ~Record() { } |
47 | 44 | ||
48 | Record &operator=( const Record &c ); | 45 | Record &operator=( const Record &c ); |
49 | 46 | ||
50 | virtual bool match( const QRegExp & ) const { return FALSE; } | 47 | virtual bool match( const QRegExp & ) const { return FALSE; } |
51 | 48 | ||
52 | void setCategories( const QArray<int> &v ) { mCats = v; } | 49 | void setCategories( const QArray<int> &v ) { mCats = v; mCats.sort(); } |
53 | void setCategories( int single ); | 50 | void setCategories( int single ); |
54 | const QArray<int> &categories() const { return mCats; } | 51 | const QArray<int> &categories() const { return mCats; } |
55 | 52 | ||
53 | void reassignCategoryId( int oldId, int newId ) | ||
54 | { | ||
55 | int index = mCats.find( oldId ); | ||
56 | if ( index >= 0 ) | ||
57 | mCats[index] = newId; | ||
58 | } | ||
59 | |||
56 | int uid() const { return mUid; }; | 60 | int uid() const { return mUid; }; |
57 | virtual void setUid( int i ) { mUid = i; uidGen().store( mUid ); } | 61 | virtual void setUid( int i ) { mUid = i; uidGen().store( mUid ); } |
58 | bool isValidUid() const { return mUid != 0; } | 62 | bool isValidUid() const { return mUid != 0; } |
59 | void assignUid() { setUid( uidGen().generate() ); } | 63 | void assignUid() { setUid( uidGen().generate() ); } |
60 | 64 | ||
61 | virtual QString customField(const QString &) const; | 65 | virtual QString customField(const QString &) const; |
62 | virtual void setCustomField(const QString &, const QString &); | 66 | virtual void setCustomField(const QString &, const QString &); |
63 | virtual void removeCustomField(const QString &); | 67 | virtual void removeCustomField(const QString &); |
64 | 68 | ||
65 | virtual bool operator == ( const Record &r ) const | 69 | virtual bool operator == ( const Record &r ) const |
66 | { return mUid == r.mUid; } | 70 | { return mUid == r.mUid; } |
67 | virtual bool operator != ( const Record &r ) const | 71 | virtual bool operator != ( const Record &r ) const |
68 | { return mUid != r.mUid; } | 72 | { return mUid != r.mUid; } |
69 | 73 | ||
70 | // convenience methods provided for loading and saving to xml | 74 | // convenience methods provided for loading and saving to xml |
71 | static QString idsToString( const QArray<int> &ids ); | 75 | static QString idsToString( const QArray<int> &ids ); |
72 | // convenience methods provided for loading and saving to xml | 76 | // convenience methods provided for loading and saving to xml |
73 | static QArray<int> idsFromString( const QString &str ); | 77 | static QArray<int> idsFromString( const QString &str ); |
74 | 78 | ||
75 | // for debugging | 79 | // for debugging |
76 | static void dump( const QMap<int, QString> &map ); | 80 | static void dump( const QMap<int, QString> &map ); |
77 | 81 | ||
78 | protected: | 82 | protected: |
79 | virtual UidGen &uidGen() = 0; | 83 | virtual UidGen &uidGen() = 0; |
80 | |||
81 | virtual QString customToXml() const; | 84 | virtual QString customToXml() const; |
82 | |||
83 | private: | 85 | private: |
84 | int mUid; | 86 | int mUid; |
85 | QArray<int> mCats; | 87 | QArray<int> mCats; |
86 | |||
87 | QMap<QString, QString> customMap; | 88 | QMap<QString, QString> customMap; |
88 | |||
89 | RecordPrivate *d; | 89 | RecordPrivate *d; |
90 | }; | 90 | }; |
91 | 91 | ||
92 | } | 92 | } |
93 | 93 | ||
94 | #endif | 94 | #endif |
95 | |||
diff --git a/library/backend/palmtopuidgen.h b/library/backend/palmtopuidgen.h index 1a16681..c3fbcb9 100644 --- a/library/backend/palmtopuidgen.h +++ b/library/backend/palmtopuidgen.h | |||
@@ -1,83 +1,83 @@ | |||
1 | #ifndef QTPALMTOP_UIDGEN_H | ||
2 | #define QTPALMTOP_UIDGEN_H | ||
3 | /********************************************************************** | 1 | /********************************************************************** |
4 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. |
5 | ** | 3 | ** |
6 | ** This file is part of Qtopia Environment. | 4 | ** This file is part of the Qtopia Environment. |
7 | ** | 5 | ** |
8 | ** Licensees holding valid Qtopia Developer license may use this | 6 | ** This file may be distributed and/or modified under the terms of the |
9 | ** file in accordance with the Qtopia Developer License Agreement | 7 | ** GNU General Public License version 2 as published by the Free Software |
10 | ** provided with the Software. | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** packaging of this file. | ||
11 | ** | 10 | ** |
12 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING | 11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
13 | ** THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
14 | ** PURPOSE. | ||
15 | ** | 13 | ** |
16 | ** email sales@trolltech.com for information about Qtopia License | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
17 | ** Agreements. | ||
18 | ** | 15 | ** |
19 | ** Contact info@trolltech.com if any conditions of this licensing are | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
20 | ** not clear to you. | 17 | ** not clear to you. |
21 | ** | 18 | ** |
22 | **********************************************************************/ | 19 | **********************************************************************/ |
23 | 20 | ||
21 | #ifndef QTPALMTOP_UIDGEN_H | ||
22 | #define QTPALMTOP_UIDGEN_H | ||
23 | |||
24 | #include <time.h> | 24 | #include <time.h> |
25 | #include <qmap.h> | 25 | #include <qmap.h> |
26 | #include "qpcglobal.h" | 26 | #include "qpcglobal.h" |
27 | 27 | ||
28 | #if defined(QPC_TEMPLATEDLL) | 28 | #if defined(QPC_TEMPLATEDLL) |
29 | // MOC_SKIP_BEGIN | 29 | // MOC_SKIP_BEGIN |
30 | template class QPC_EXPORT QMap< int, bool >; | 30 | QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap< int, bool >; |
31 | // MOC_SKIP_END | 31 | // MOC_SKIP_END |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | namespace Qtopia { | 34 | namespace Qtopia { |
35 | 35 | ||
36 | 36 | ||
37 | class QPC_EXPORT UidGen | 37 | class QPC_EXPORT UidGen |
38 | { | 38 | { |
39 | public: | 39 | public: |
40 | enum Type { Qtopia, PalmtopCenter }; | 40 | enum Type { Qtopia, PalmtopCenter }; |
41 | 41 | ||
42 | UidGen() : type( Qtopia ), sign( -1 ), ids() | 42 | UidGen() : type( Qtopia ), sign( -1 ), ids() |
43 | { | 43 | { |
44 | #ifdef PALMTOPCENTER | 44 | #ifdef PALMTOPCENTER |
45 | type = PalmtopCenter; | 45 | type = PalmtopCenter; |
46 | sign = 1; | 46 | sign = 1; |
47 | #endif | 47 | #endif |
48 | } | 48 | } |
49 | UidGen( Type t ) : type(t), sign(1), ids() | 49 | UidGen( Type t ) : type(t), sign(1), ids() |
50 | { | 50 | { |
51 | if ( t == Qtopia ) | 51 | if ( t == Qtopia ) |
52 | sign = -1; | 52 | sign = -1; |
53 | } | 53 | } |
54 | 54 | ||
55 | virtual ~UidGen() { } | 55 | virtual ~UidGen() { } |
56 | 56 | ||
57 | int generate() const | 57 | int generate() const |
58 | { | 58 | { |
59 | int id = sign * (int) ::time(NULL); | 59 | int id = sign * (int) ::time(NULL); |
60 | while ( ids.contains( id ) ) { | 60 | while ( ids.contains( id ) ) { |
61 | id += sign; | 61 | id += sign; |
62 | 62 | ||
63 | // check for overflow cases; if so, wrap back to beginning of | 63 | // check for overflow cases; if so, wrap back to beginning of |
64 | // set ( -1 or 1 ) | 64 | // set ( -1 or 1 ) |
65 | if ( sign == -1 && id > 0 || sign == 1 && id < 0 ) | 65 | if ( sign == -1 && id > 0 || sign == 1 && id < 0 ) |
66 | id = sign; | 66 | id = sign; |
67 | } | 67 | } |
68 | return id; | 68 | return id; |
69 | } | 69 | } |
70 | 70 | ||
71 | void store(int id) { ids.insert(id, TRUE); } | 71 | void store(int id) { ids.insert(id, TRUE); } |
72 | bool isUnique(int id) const { return (!ids.contains(id)); } | 72 | bool isUnique(int id) const { return (!ids.contains(id)); } |
73 | 73 | ||
74 | private: | 74 | private: |
75 | Type type; | 75 | Type type; |
76 | int sign; | 76 | int sign; |
77 | QMap<int, bool> ids; | 77 | QMap<int, bool> ids; |
78 | 78 | ||
79 | }; | 79 | }; |
80 | 80 | ||
81 | } | 81 | } |
82 | 82 | ||
83 | #endif | 83 | #endif |
diff --git a/library/backend/qfiledirect_p.h b/library/backend/qfiledirect_p.h index 3ade622..976c69f 100644 --- a/library/backend/qfiledirect_p.h +++ b/library/backend/qfiledirect_p.h | |||
@@ -1,37 +1,35 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2001 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. |
3 | ** | 3 | ** |
4 | ** This file is part of the Qtopia Environment. | 4 | ** This file is part of the Qtopia Environment. |
5 | ** | 5 | ** |
6 | ** Licensees holding valid Qtopia Developer license may use this | 6 | ** This file may be distributed and/or modified under the terms of the |
7 | ** file in accordance with the Qtopia Developer License Agreement | 7 | ** GNU General Public License version 2 as published by the Free Software |
8 | ** provided with the Software. | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** | 9 | ** packaging of this file. |
10 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING | 10 | ** |
11 | ** THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
12 | ** PURPOSE. | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
13 | ** | 13 | ** |
14 | ** email sales@trolltech.com for information about Qtopia License | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
15 | ** Agreements. | 15 | ** |
16 | ** | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
17 | ** Contact info@trolltech.com if any conditions of this licensing are | 17 | ** not clear to you. |
18 | ** not clear to you. | 18 | ** |
19 | ** | 19 | **********************************************************************/ |
20 | **********************************************************************/ | 20 | |
21 | 21 | #ifndef QFILE_DIRECT_H | |
22 | #ifndef QFILE_DIRECT_H | 22 | #define QFILE_DIRECT_H |
23 | #define QFILE_DIRECT_H | 23 | #include <qfile.h> |
24 | #include <qfile.h> | 24 | #include <qtopia/private/qpcglobal.h> |
25 | #include <qpe/qpcglobal.h> | 25 | |
26 | 26 | class QPC_EXPORT QFileDirect : public QFile | |
27 | class QPC_EXPORT QFileDirect : public QFile | 27 | { |
28 | { | 28 | public: |
29 | public: | 29 | QFileDirect() : QFile() { } |
30 | QFileDirect() : QFile() { } | 30 | QFileDirect( const QString &name ) : QFile(name) { } |
31 | QFileDirect( const QString &name ) : QFile(name) { } | 31 | |
32 | 32 | FILE *directHandle() { return fh; } | |
33 | FILE *directHandle() { return fh; } | 33 | }; |
34 | }; | 34 | |
35 | 35 | #endif | |
36 | #endif | ||
37 | |||
diff --git a/library/backend/qpcglobal.h b/library/backend/qpcglobal.h index 0d60272..7b71f06 100644 --- a/library/backend/qpcglobal.h +++ b/library/backend/qpcglobal.h | |||
@@ -1,50 +1,53 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. |
3 | ** | 3 | ** |
4 | ** This file is part of Qtopia Environment. | 4 | ** This file is part of the Qtopia Environment. |
5 | ** | 5 | ** |
6 | ** Licensees holding valid Qtopia Developer license may use this | 6 | ** Licensees holding valid Qtopia Developer license may use this |
7 | ** file in accordance with the Qtopia Developer License Agreement | 7 | ** file in accordance with the Qtopia Developer License Agreement |
8 | ** provided with the Software. | 8 | ** provided with the Software. |
9 | ** | 9 | ** |
10 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING | 10 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING |
11 | ** THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 11 | ** THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
12 | ** PURPOSE. | 12 | ** PURPOSE. |
13 | ** | 13 | ** |
14 | ** email sales@trolltech.com for information about Qtopia License | 14 | ** email sales@trolltech.com for information about Qtopia License |
15 | ** Agreements. | 15 | ** Agreements. |
16 | ** | 16 | ** |
17 | ** Contact info@trolltech.com if any conditions of this licensing are | 17 | ** Contact info@trolltech.com if any conditions of this licensing are |
18 | ** not clear to you. | 18 | ** not clear to you. |
19 | ** | 19 | ** |
20 | **********************************************************************/ | 20 | **********************************************************************/ |
21 | 21 | ||
22 | #ifndef QPC_GLOBAL_H | 22 | #ifndef QPC_GLOBAL_H |
23 | #define QPC_GLOBAL_H | 23 | #define QPC_GLOBAL_H |
24 | 24 | ||
25 | #if ( defined(Q_OS_WIN32) || defined(Q_OS_WIN64) ) && defined(PALMTOPCENTER) | ||
26 | #include <qglobal.h> | 25 | #include <qglobal.h> |
26 | |||
27 | #if ( defined(Q_OS_WIN32) || defined(Q_OS_WIN64) ) && defined(PALMTOPCENTER) | ||
27 | // # if defined(QT_NODLL) | 28 | // # if defined(QT_NODLL) |
28 | //# undef QPC_MAKEDLL | 29 | //# undef QPC_MAKEDLL |
29 | //# undef QPC_DLL | 30 | //# undef QPC_DLL |
30 | # if defined(QPC_MAKEDLL)/* create a Qt DLL library */ | 31 | # if defined(QPC_MAKEDLL)/* create a Qt DLL library */ |
31 | # if defined(QPC_DLL) | 32 | # if defined(QPC_DLL) |
32 | # undef QPC_DLL | 33 | # undef QPC_DLL |
33 | # endif | 34 | # endif |
34 | # define QPC_EXPORT __declspec(dllexport) | 35 | # define QPC_EXPORT __declspec(dllexport) |
36 | # define QPC_TEMPLATEEXTERN | ||
35 | # define QPC_TEMPLATEDLL | 37 | # define QPC_TEMPLATEDLL |
36 | # undef QPC_DISABLE_COPY/* avoid unresolved externals */ | 38 | # undef QPC_DISABLE_COPY/* avoid unresolved externals */ |
37 | # elif defined(QPC_DLL) /* use a Qt DLL library */ | 39 | # elif defined(QPC_DLL) /* use a Qt DLL library */ |
38 | # define QPC_EXPORT __declspec(dllimport) | 40 | # define QPC_EXPORT __declspec(dllimport) |
41 | # define QPC_TEMPLATEEXTERN extern | ||
39 | # define QPC_TEMPLATEDLL | 42 | # define QPC_TEMPLATEDLL |
40 | # undef QPC_DISABLE_COPY/* avoid unresolved externals */ | 43 | # undef QPC_DISABLE_COPY/* avoid unresolved externals */ |
41 | # endif | 44 | # endif |
42 | #else | 45 | #else |
43 | # undef QPC_MAKEDLL /* ignore these for other platforms */ | 46 | # undef QPC_MAKEDLL /* ignore these for other platforms */ |
44 | # undef QPC_DLL | 47 | # undef QPC_DLL |
45 | #endif | 48 | #endif |
46 | #endif | 49 | #endif |
47 | 50 | ||
48 | #ifndef QPC_EXPORT | 51 | #ifndef QPC_EXPORT |
49 | # define QPC_EXPORT | 52 | # define QPC_EXPORT |
50 | #endif | 53 | #endif |
diff --git a/library/backend/recordfields.h b/library/backend/recordfields.h index 4196c8b..1167ed3 100644 --- a/library/backend/recordfields.h +++ b/library/backend/recordfields.h | |||
@@ -1,149 +1,149 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. |
3 | ** | 3 | ** |
4 | ** This file is part of Qtopia Environment. | 4 | ** This file is part of the Qtopia Environment. |
5 | ** | 5 | ** |
6 | ** Licensees holding valid Qtopia Developer license may use this | 6 | ** This file may be distributed and/or modified under the terms of the |
7 | ** file in accordance with the Qtopia Developer License Agreement | 7 | ** GNU General Public License version 2 as published by the Free Software |
8 | ** provided with the Software. | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** packaging of this file. | ||
9 | ** | 10 | ** |
10 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING | 11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
11 | ** THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
12 | ** PURPOSE. | ||
13 | ** | 13 | ** |
14 | ** email sales@trolltech.com for information about Qtopia License | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
15 | ** Agreements. | ||
16 | ** | 15 | ** |
17 | ** Contact info@trolltech.com if any conditions of this licensing are | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
18 | ** not clear to you. | 17 | ** not clear to you. |
19 | ** | 18 | ** |
20 | **********************************************************************/ | 19 | **********************************************************************/ |
21 | #ifndef QPC_RECORD_FIELDS_H | 20 | #ifndef QPC_RECORD_FIELDS_H |
22 | #define QPC_RECORD_FIELDS_H | 21 | #define QPC_RECORD_FIELDS_H |
23 | #include "qpcglobal.h" | 22 | #include "qpcglobal.h" |
24 | 23 | ||
25 | // dataset = "addressbook" | 24 | // dataset = "addressbook" |
26 | namespace Qtopia | 25 | namespace Qtopia |
27 | { | 26 | { |
28 | static const int UID_ID = 0; | 27 | static const int UID_ID = 0; |
29 | static const int CATEGORY_ID = 1; | 28 | static const int CATEGORY_ID = 1; |
30 | 29 | ||
31 | enum AddressBookFields { | 30 | enum AddressBookFields { |
32 | AddressUid = UID_ID, | 31 | AddressUid = UID_ID, |
33 | AddressCategory = CATEGORY_ID, | 32 | AddressCategory = CATEGORY_ID, |
34 | 33 | ||
35 | // NOTE: Order of fields dependency in backend/contact.cpp | 34 | // NOTE: Order of fields dependency in backend/contact.cpp |
36 | 35 | ||
37 | Title, | 36 | Title, |
38 | FirstName, | 37 | FirstName, |
39 | MiddleName, | 38 | MiddleName, |
40 | LastName, | 39 | LastName, |
41 | Suffix, | 40 | Suffix, |
42 | FileAs, | 41 | FileAs, |
43 | 42 | ||
44 | JobTitle, | 43 | JobTitle, |
45 | Department, | 44 | Department, |
46 | Company, | 45 | Company, |
47 | BusinessPhone, | 46 | BusinessPhone, |
48 | BusinessFax, | 47 | BusinessFax, |
49 | BusinessMobile, | 48 | BusinessMobile, |
50 | 49 | ||
51 | 50 | ||
52 | DefaultEmail, | 51 | DefaultEmail, |
53 | Emails, | 52 | Emails, |
54 | 53 | ||
55 | HomePhone, | 54 | HomePhone, |
56 | HomeFax, | 55 | HomeFax, |
57 | HomeMobile, | 56 | HomeMobile, |
58 | 57 | ||
59 | // business | 58 | // business |
60 | BusinessStreet, | 59 | BusinessStreet, |
61 | BusinessCity, | 60 | BusinessCity, |
62 | BusinessState, | 61 | BusinessState, |
63 | BusinessZip, | 62 | BusinessZip, |
64 | BusinessCountry, | 63 | BusinessCountry, |
65 | BusinessPager, | 64 | BusinessPager, |
66 | BusinessWebPage, | 65 | BusinessWebPage, |
67 | 66 | ||
68 | Office, | 67 | Office, |
69 | Profession, | 68 | Profession, |
70 | Assistant, | 69 | Assistant, |
71 | Manager, | 70 | Manager, |
72 | 71 | ||
73 | // home | 72 | // home |
74 | HomeStreet, | 73 | HomeStreet, |
75 | HomeCity, | 74 | HomeCity, |
76 | HomeState, | 75 | HomeState, |
77 | HomeZip, | 76 | HomeZip, |
78 | HomeCountry, | 77 | HomeCountry, |
79 | HomeWebPage, | 78 | HomeWebPage, |
80 | 79 | ||
81 | //personal | 80 | //personal |
82 | Spouse, | 81 | Spouse, |
83 | Gender, | 82 | Gender, |
84 | Birthday, | 83 | Birthday, |
85 | Anniversary, | 84 | Anniversary, |
86 | Nickname, | 85 | Nickname, |
87 | Children, | 86 | Children, |
88 | 87 | ||
89 | // other | 88 | // other |
90 | Notes, | 89 | Notes, |
91 | Groups | ||
92 | 90 | ||
93 | ,rid, | 91 | // used for internal record keeping, not for end user. |
92 | Groups, | ||
93 | rid, | ||
94 | rinfo | 94 | rinfo |
95 | }; | 95 | }; |
96 | 96 | ||
97 | // dataset = "todolist" | 97 | // dataset = "todolist" |
98 | enum TaskFields { | 98 | enum TaskFields { |
99 | TaskUid = UID_ID, | 99 | TaskUid = UID_ID, |
100 | TaskCategory = CATEGORY_ID, | 100 | TaskCategory = CATEGORY_ID, |
101 | 101 | ||
102 | HasDate, | 102 | HasDate, |
103 | Completed, | 103 | Completed, |
104 | TaskDescription, | 104 | TaskDescription, |
105 | Priority, | 105 | Priority, |
106 | Date, | 106 | Date, |
107 | 107 | ||
108 | TaskRid, | 108 | TaskRid, |
109 | TaskRinfo | 109 | TaskRinfo |
110 | }; | 110 | }; |
111 | 111 | ||
112 | // dataset = "categories" for todos | 112 | // dataset = "categories" for todos |
113 | enum CategoryFields { | 113 | enum CategoryFields { |
114 | CatUid = UID_ID, | 114 | CatUid = UID_ID, |
115 | CatName, | 115 | CatName, |
116 | CatAppGroup | 116 | CatAppGroup |
117 | }; | 117 | }; |
118 | 118 | ||
119 | 119 | ||
120 | // dataset = "datebook" | 120 | // dataset = "datebook" |
121 | enum DatebookFields { | 121 | enum DatebookFields { |
122 | DatebookUid = UID_ID, | 122 | DatebookUid = UID_ID, |
123 | DatebookCategory = CATEGORY_ID, | 123 | DatebookCategory = CATEGORY_ID, |
124 | 124 | ||
125 | DatebookDescription, | 125 | DatebookDescription, |
126 | Location, | 126 | Location, |
127 | TimeZone, | 127 | TimeZone, |
128 | Note, | 128 | Note, |
129 | StartDateTime, | 129 | StartDateTime, |
130 | EndDateTime, | 130 | EndDateTime, |
131 | DatebookType, | 131 | DatebookType, |
132 | HasAlarm, | 132 | HasAlarm, |
133 | SoundType, | 133 | SoundType, |
134 | AlarmTime, | 134 | AlarmTime, |
135 | 135 | ||
136 | RepeatPatternType, | 136 | RepeatPatternType, |
137 | RepeatPatternFrequency, | 137 | RepeatPatternFrequency, |
138 | RepeatPatternPosition, | 138 | RepeatPatternPosition, |
139 | RepeatPatternDays, | 139 | RepeatPatternDays, |
140 | RepeatPatternHasEndDate, | 140 | RepeatPatternHasEndDate, |
141 | RepeatPatternEndDate, | 141 | RepeatPatternEndDate, |
142 | 142 | ||
143 | DateBookRid, | 143 | DateBookRid, |
144 | DateBookRinfo | 144 | DateBookRinfo |
145 | }; | 145 | }; |
146 | }; | 146 | }; |
147 | 147 | ||
148 | 148 | ||
149 | #endif | 149 | #endif |
diff --git a/library/backend/stringutil.cpp b/library/backend/stringutil.cpp deleted file mode 100644 index df58f54..0000000 --- a/library/backend/stringutil.cpp +++ b/dev/null | |||
@@ -1,415 +0,0 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free | ||
8 | ** Software Foundation and appearing in the file LICENSE.GPL included | ||
9 | ** in the packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING | ||
12 | ** THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A | ||
13 | ** PARTICULAR PURPOSE. | ||
14 | ** | ||
15 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
16 | ** | ||
17 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
18 | ** not clear to you. | ||
19 | ** | ||
20 | **********************************************************************/ | ||
21 | |||
22 | #include "stringutil.h" | ||
23 | #include <qregexp.h> | ||
24 | #include <qstringlist.h> | ||
25 | |||
26 | namespace Qtopia | ||
27 | { | ||
28 | |||
29 | |||
30 | |||
31 | /* | ||
32 | Very, very simple Latin-1 only collation guaranteed to displease anyone | ||
33 | who actually uses the non-ASCII characters. | ||
34 | */ | ||
35 | |||
36 | static const char collationHack[] = { | ||
37 | 0x00, //C-@ | ||
38 | 0x01, //C-A | ||
39 | 0x02, //C-B | ||
40 | 0x03, //C-C | ||
41 | 0x04, //C-D | ||
42 | 0x05, //C-E | ||
43 | 0x06, //C-F | ||
44 | 0x07, //C-G | ||
45 | 0x08, //C-H | ||
46 | 0x09, //C-I | ||
47 | 0x0a, //C-J | ||
48 | 0x0b, //C-K | ||
49 | 0x0c, //C-L | ||
50 | 0x0d, //C-M | ||
51 | 0x0e, //C-N | ||
52 | 0x0f, //C-O | ||
53 | 0x10, //C-P | ||
54 | 0x11, //C-Q | ||
55 | 0x12, //C-R | ||
56 | 0x13, //C-S | ||
57 | 0x14, //C-T | ||
58 | 0x15, //C-U | ||
59 | 0x16, //C-V | ||
60 | 0x17, //C-W | ||
61 | 0x18, //C-X | ||
62 | 0x19, //C-Y | ||
63 | 0x1a, //C-Z | ||
64 | 0x1b, //C-[ | ||
65 | 0x1c, //C-\ | ||
66 | 0x1d, //C-] | ||
67 | 0x1e, //C-^ | ||
68 | 0x1f, //C-_ | ||
69 | ' ', // | ||
70 | '!', //! | ||
71 | '"', //" | ||
72 | '#', //# | ||
73 | '$', //$ | ||
74 | '%', //% | ||
75 | '&', //& | ||
76 | '\'', //' | ||
77 | '(', //( | ||
78 | ')', //) | ||
79 | '*', //* | ||
80 | '+', //+ | ||
81 | ',', //, | ||
82 | '-', //- | ||
83 | '.', //. | ||
84 | '/', /// | ||
85 | 0x80, //0 | ||
86 | 0x81, //1 | ||
87 | 0x82, //2 | ||
88 | 0x83, //3 | ||
89 | 0x84, //4 | ||
90 | 0x85, //5 | ||
91 | 0x86, //6 | ||
92 | 0x87, //7 | ||
93 | 0x88, //8 | ||
94 | 0x89, //9 | ||
95 | ':', //: | ||
96 | ';', //; | ||
97 | '<', //< | ||
98 | '=', //= | ||
99 | '>', //> | ||
100 | '?', //? | ||
101 | '@', //@ | ||
102 | 'A', //A | ||
103 | 'B', //B | ||
104 | 'C', //C | ||
105 | 'D', //D | ||
106 | 'E', //E | ||
107 | 'F', //F | ||
108 | 'G', //G | ||
109 | 'H', //H | ||
110 | 'I', //I | ||
111 | 'J', //J | ||
112 | 'K', //K | ||
113 | 'L', //L | ||
114 | 'M', //M | ||
115 | 'N', //N | ||
116 | 'O', //O | ||
117 | 'P', //P | ||
118 | 'Q', //Q | ||
119 | 'R', //R | ||
120 | 'S', //S | ||
121 | 'T', //T | ||
122 | 'U', //U | ||
123 | 'V', //V | ||
124 | 'W', //W | ||
125 | 'X', //X | ||
126 | 'Y', //Y | ||
127 | 'Z', //Z | ||
128 | '[', //[ | ||
129 | '\\', //\ | ||
130 | ']', //] | ||
131 | '^', //^ | ||
132 | '_', //_ | ||
133 | '`', //` | ||
134 | 'A', //a | ||
135 | 'B', //b | ||
136 | 'C', //c | ||
137 | 'D', //d | ||
138 | 'E', //e | ||
139 | 'F', //f | ||
140 | 'G', //g | ||
141 | 'H', //h | ||
142 | 'I', //i | ||
143 | 'J', //j | ||
144 | 'K', //k | ||
145 | 'L', //l | ||
146 | 'M', //m | ||
147 | 'N', //n | ||
148 | 'O', //o | ||
149 | 'P', //p | ||
150 | 'Q', //q | ||
151 | 'R', //r | ||
152 | 'S', //s | ||
153 | 'T', //t | ||
154 | 'U', //u | ||
155 | 'V', //v | ||
156 | 'W', //w | ||
157 | 'X', //x | ||
158 | 'Y', //y | ||
159 | 'Z', //z | ||
160 | '{', //{ | ||
161 | '|', //| | ||
162 | '}', //} | ||
163 | '~', //~ | ||
164 | '', // | ||
165 | 0x80, //C-M-@ | ||
166 | 0x81, //C-M-A | ||
167 | 0x82, //C-M-B | ||
168 | 0x83, //C-M-C | ||
169 | 0x84, //C-M-D | ||
170 | 0x85, //C-M-E | ||
171 | 0x86, //C-M-F | ||
172 | 0x87, //C-M-G | ||
173 | 0x88, //C-M-H | ||
174 | 0x89, //C-M-I | ||
175 | 0x8a, //C-M-J | ||
176 | 0x8b, //C-M-K | ||
177 | 0x8c, //C-M-L | ||
178 | 0x8d, //C-M-M | ||
179 | 0x8e, //C-M-N | ||
180 | 0x8f, //C-M-O | ||
181 | 0x90, //C-M-P | ||
182 | 0x91, //C-M-Q | ||
183 | 0x92, //C-M-R | ||
184 | 0x93, //C-M-S | ||
185 | 0x94, //C-M-T | ||
186 | 0x95, //C-M-U | ||
187 | 0x96, //C-M-V | ||
188 | 0x97, //C-M-W | ||
189 | 0x98, //C-M-X | ||
190 | 0x99, //C-M-Y | ||
191 | 0x9a, //C-M-Z | ||
192 | 0x9b, //C-M-[ | ||
193 | 0x9c, //C-M-\ | ||
194 | 0x9d, //C-M-] | ||
195 | 0x9e, //C-M-^ | ||
196 | 0x9f, //C-M-_ | ||
197 | ' ', // | ||
198 | '¡', //¡ | ||
199 | '¢', //¢ | ||
200 | '£', //£ | ||
201 | '¤', //¤ | ||
202 | '¥', //¥ | ||
203 | '¦', //¦ | ||
204 | '§', //§ | ||
205 | '¨', //¨ | ||
206 | '©', //© | ||
207 | 'A', //ª | ||
208 | '«', //« | ||
209 | '¬', //¬ | ||
210 | '', // | ||
211 | '®', //® | ||
212 | '¯', //¯ | ||
213 | 'O', //° | ||
214 | '±', //± | ||
215 | '²', //² | ||
216 | '³', //³ | ||
217 | '´', //´ | ||
218 | 'µ', //µ | ||
219 | 'P', //¶ | ||
220 | '·', //· | ||
221 | '¸', //¸ | ||
222 | '¹', //¹ | ||
223 | 'O', //º | ||
224 | '»', //» | ||
225 | '¼', //¼ | ||
226 | '½', //½ | ||
227 | '¾', //¾ | ||
228 | '¿', //¿ | ||
229 | 'A', //À | ||
230 | 'A', //Á | ||
231 | 'A', //Â | ||
232 | 'A', //Ã | ||
233 | 'A', //Ä | ||
234 | 'A', //Å | ||
235 | 'A', //Æ | ||
236 | 'C', //Ç | ||
237 | 'E', //È | ||
238 | 'E', //É | ||
239 | 'E', //Ê | ||
240 | 'E', //Ë | ||
241 | 'I', //Ì | ||
242 | 'I', //Í | ||
243 | 'I', //Î | ||
244 | 'I', //Ï | ||
245 | 'D', //Ð | ||
246 | 'N', //Ñ | ||
247 | 'O', //Ò | ||
248 | 'O', //Ó | ||
249 | 'O', //Ô | ||
250 | 'O', //Õ | ||
251 | 'O', //Ö | ||
252 | '×', //× | ||
253 | 'O', //Ø | ||
254 | 'U', //Ù | ||
255 | 'U', //Ú | ||
256 | 'U', //Û | ||
257 | 'U', //Ü | ||
258 | 'Y', //Ý | ||
259 | 'T', //Þ | ||
260 | 'S', //ß | ||
261 | 'A', //à | ||
262 | 'A', //á | ||
263 | 'A', //â | ||
264 | 'A', //ã | ||
265 | 'A', //ä | ||
266 | 'A', //å | ||
267 | 'A', //æ | ||
268 | 'C', //ç | ||
269 | 'E', //è | ||
270 | 'E', //é | ||
271 | 'E', //ê | ||
272 | 'E', //ë | ||
273 | 'I', //ì | ||
274 | 'I', //í | ||
275 | 'I', //î | ||
276 | 'I', //ï | ||
277 | 'D', //ð | ||
278 | 'N', //ñ | ||
279 | 'O', //ò | ||
280 | 'O', //ó | ||
281 | 'O', //ô | ||
282 | 'O', //õ | ||
283 | 'O', //ö | ||
284 | '÷', //÷ | ||
285 | 'O', //ø | ||
286 | 'U', //ù | ||
287 | 'U', //ú | ||
288 | 'U', //û | ||
289 | 'U', //ü | ||
290 | 'Y', //ý | ||
291 | 'T', //þ | ||
292 | 'Y', //ÿ | ||
293 | }; | ||
294 | |||
295 | |||
296 | |||
297 | |||
298 | |||
299 | static void hackString ( QString &s ) | ||
300 | { | ||
301 | int len = s.length(); | ||
302 | const QChar* uc = s.unicode(); | ||
303 | for ( int i = 0; i < len; i++ ) { | ||
304 | if ( !uc++->row() ) | ||
305 | s[i] = collationHack[s[i].cell()]; | ||
306 | } | ||
307 | } | ||
308 | |||
309 | QString buildSortKey( const QString & s ) | ||
310 | { | ||
311 | QString res = s; | ||
312 | hackString( res ); | ||
313 | return res; | ||
314 | } | ||
315 | |||
316 | QString buildSortKey( const QString & s1, const QString & s2 ) | ||
317 | { | ||
318 | QString res = s1 + QChar( '\0' ) + s2; | ||
319 | hackString( res ); | ||
320 | return res; | ||
321 | } | ||
322 | |||
323 | QString buildSortKey( const QString & s1, const QString & s2, | ||
324 | const QString & s3 ) | ||
325 | { | ||
326 | QString res = s1 + QChar( '\0' ) + s2 + QChar( '\0' ) + s3; | ||
327 | hackString( res ); | ||
328 | return res; | ||
329 | } | ||
330 | |||
331 | static inline QChar coll( QChar u ) | ||
332 | { | ||
333 | return u.row() ? u : QChar(collationHack[ u.cell() ]); | ||
334 | } | ||
335 | |||
336 | |||
337 | int compare( const QString & s1, const QString & s2 ) | ||
338 | { | ||
339 | const QChar* u1 = s1.unicode(); | ||
340 | const QChar* u2 = s2.unicode(); | ||
341 | |||
342 | if ( u1 == u2 ) | ||
343 | return 0; | ||
344 | if ( u1 == 0 ) | ||
345 | return 1; | ||
346 | if ( u2 == 0 ) | ||
347 | return -1; | ||
348 | int l=QMIN(s1.length(),s2.length()); | ||
349 | while ( l-- && coll(*u1) == coll(*u2) ) | ||
350 | u1++,u2++; | ||
351 | if ( l==-1 ) | ||
352 | return ( s1.length()-s2.length() ); | ||
353 | return u1->unicode() - u2->unicode(); | ||
354 | } | ||
355 | |||
356 | QString simplifyMultiLineSpace( const QString &multiLine ) | ||
357 | { | ||
358 | QString result; | ||
359 | QStringList lines = QStringList::split("\n", multiLine); | ||
360 | for ( QStringList::Iterator it = lines.begin(); it != lines.end(); ++it ) { | ||
361 | if ( it != lines.begin() ) | ||
362 | result += "\n"; | ||
363 | result += (*it).simplifyWhiteSpace(); | ||
364 | } | ||
365 | return result; | ||
366 | } | ||
367 | |||
368 | QString escapeString( const QString& plain ) | ||
369 | { | ||
370 | QString tmp(plain); | ||
371 | int pos = tmp.length(); | ||
372 | const QChar *uc = plain.unicode(); | ||
373 | while ( pos-- ) { | ||
374 | unsigned char ch = uc[pos].latin1(); | ||
375 | if ( ch == '&' ) | ||
376 | tmp.replace( pos, 1, "&" ); | ||
377 | else if ( ch == '<' ) | ||
378 | tmp.replace( pos, 1, "<" ); | ||
379 | else if ( ch == '>' ) | ||
380 | tmp.replace( pos, 1, ">" ); | ||
381 | else if ( ch == '\"' ) | ||
382 | tmp.replace( pos, 1, """ ); | ||
383 | } | ||
384 | return tmp; | ||
385 | } | ||
386 | |||
387 | QString plainString( const char* escaped, unsigned int length ) | ||
388 | { | ||
389 | return plainString( QString::fromUtf8( escaped, length ) ); | ||
390 | } | ||
391 | |||
392 | QString plainString( const QCString& string ) | ||
393 | { | ||
394 | // We first have to pass it through a ::fromUtf8() | ||
395 | return plainString( string.data(), string.length() ); | ||
396 | } | ||
397 | |||
398 | QString plainString( const QString& string ) | ||
399 | { | ||
400 | QString tmp( string ); | ||
401 | int pos = -1; | ||
402 | while ( (pos = tmp.find( "&", pos +1 ) ) != -1 ) { | ||
403 | if ( tmp.find( "&", pos ) == pos ) | ||
404 | tmp.replace( pos, 5, "&" ); | ||
405 | else if ( tmp.find( "<", pos ) == pos ) | ||
406 | tmp.replace( pos, 4, "<" ); | ||
407 | else if( tmp.find( ">", pos ) == pos ) | ||
408 | tmp.replace( pos, 4, ">" ); | ||
409 | else if ( tmp.find( """, pos ) == pos ) | ||
410 | tmp.replace( pos, 6, "\"" ); | ||
411 | } | ||
412 | return tmp; | ||
413 | } | ||
414 | |||
415 | } // namespace QPC | ||
diff --git a/library/backend/stringutil.h b/library/backend/stringutil.h deleted file mode 100644 index e9daf70..0000000 --- a/library/backend/stringutil.h +++ b/dev/null | |||
@@ -1,57 +0,0 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free | ||
8 | ** Software Foundation and appearing in the file LICENSE.GPL included | ||
9 | ** in the packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING | ||
12 | ** THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A | ||
13 | ** PARTICULAR PURPOSE. | ||
14 | ** | ||
15 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
16 | ** | ||
17 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
18 | ** not clear to you. | ||
19 | ** | ||
20 | **********************************************************************/ | ||
21 | |||
22 | |||
23 | #ifndef QTPALMTOP_stringutil_h__ | ||
24 | #define QTPALMTOP_stringutil_h__ | ||
25 | |||
26 | #include <qstring.h> | ||
27 | #include "qpcglobal.h" | ||
28 | |||
29 | namespace Qtopia | ||
30 | { | ||
31 | |||
32 | // Simplifies white space within each line but keeps the new line characters | ||
33 | QString QPC_EXPORT simplifyMultiLineSpace( const QString &multiLine ); | ||
34 | |||
35 | // Creates a QString which doesn't contain any "dangerous" | ||
36 | // characters (i.e. <, >, &, ") | ||
37 | QString QPC_EXPORT escapeString( const QString& plain ); | ||
38 | |||
39 | // Takes a UTF-8!! string and removes all the XML thingies (entities?) | ||
40 | // from the string and also calls fromUtf8() on it... so make sure | ||
41 | // to pass a QCString/const char* with UTF-8 data only | ||
42 | QString QPC_EXPORT plainString( const char* escaped, unsigned int length ); | ||
43 | QString QPC_EXPORT plainString( const QCString& string ); | ||
44 | |||
45 | QString QPC_EXPORT plainString( const QString& string ); | ||
46 | |||
47 | |||
48 | // collation functions | ||
49 | int compare( const QString & s1, const QString & s2 ); | ||
50 | QString buildSortKey( const QString & s ); | ||
51 | QString buildSortKey( const QString & s1, const QString & s2 ); | ||
52 | QString buildSortKey( const QString & s1, const QString & s2, | ||
53 | const QString & s3 ); | ||
54 | |||
55 | } | ||
56 | |||
57 | #endif | ||
diff --git a/library/backend/task.cpp b/library/backend/task.cpp index f0a38f1..a00adb3 100644 --- a/library/backend/task.cpp +++ b/library/backend/task.cpp | |||
@@ -1,272 +1,409 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2001 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. |
3 | ** | 3 | ** |
4 | ** This file is part of Qtopia Environment. | 4 | ** This file is part of the Qtopia Environment. |
5 | ** | 5 | ** |
6 | ** This file may be distributed and/or modified under the terms of the | 6 | ** This file may be distributed and/or modified under the terms of the |
7 | ** GNU General Public License version 2 as published by the Free Software | 7 | ** GNU General Public License version 2 as published by the Free Software |
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** packaging of this file. | 9 | ** packaging of this file. |
10 | ** | 10 | ** |
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | 11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
13 | ** | 13 | ** |
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
15 | ** | 15 | ** |
16 | ** Contact info@trolltech.com if any conditions of this licensing are | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
17 | ** not clear to you. | 17 | ** not clear to you. |
18 | ** | 18 | ** |
19 | **********************************************************************/ | 19 | **********************************************************************/ |
20 | 20 | ||
21 | #include <qpe/task.h> | 21 | #include "task.h" |
22 | #include <qregexp.h> | 22 | #include "recordfields.h" |
23 | #include <qstring.h> | ||
24 | #include <qpe/recordfields.h> | ||
25 | #include "vobject_p.h" | 23 | #include "vobject_p.h" |
26 | #include "timeconversion.h" | ||
27 | #include "qfiledirect_p.h" | 24 | #include "qfiledirect_p.h" |
28 | 25 | ||
26 | #include <qtopia/timeconversion.h> | ||
27 | |||
28 | #include <qregexp.h> | ||
29 | #include <qstring.h> | ||
30 | |||
29 | #include <stdio.h> | 31 | #include <stdio.h> |
30 | 32 | ||
31 | using namespace Qtopia; | 33 | using namespace Qtopia; |
32 | UidGen Task::sUidGen( UidGen::Qtopia ); | 34 | UidGen Task::sUidGen( UidGen::Qtopia ); |
33 | 35 | ||
36 | /*! | ||
37 | \class Task | ||
38 | \brief The Task class holds the data of a todo entry. | ||
39 | |||
40 | This data includes the priority of the task, a description, an optional due | ||
41 | date, and whether the task is completed or not. | ||
42 | |||
43 | \ingroup qtopiaemb | ||
44 | \ingroup qtopiadesktop | ||
45 | */ | ||
46 | |||
47 | /*! | ||
48 | Creates a new, empty task. | ||
49 | */ | ||
34 | Task::Task() : Record(), mDue( FALSE ), | 50 | Task::Task() : Record(), mDue( FALSE ), |
35 | mDueDate( QDate::currentDate() ), | 51 | mDueDate( QDate::currentDate() ), |
36 | mCompleted( FALSE ), mPriority( 3 ), mDesc() | 52 | mCompleted( FALSE ), mPriority( 3 ), mDesc() |
37 | { | 53 | { |
38 | } | 54 | } |
39 | 55 | ||
56 | /*! | ||
57 | \fn void Task::setPriority( int priority ) | ||
58 | |||
59 | Sets the priority of the task to \a priority. | ||
60 | */ | ||
61 | |||
62 | /*! | ||
63 | \fn int Task::priority() const | ||
64 | |||
65 | Returns the priority of the task. | ||
66 | */ | ||
67 | |||
68 | /*! | ||
69 | \fn void Task::setDescription( const QString &description ) | ||
70 | |||
71 | Sets the description of the task to \a description. | ||
72 | */ | ||
73 | |||
74 | /*! | ||
75 | \fn const QString &Task::description() const | ||
76 | |||
77 | Returns the description of the task. | ||
78 | */ | ||
79 | |||
80 | /*! | ||
81 | \fn void Task::setDueDate( const QDate &date, bool hasDue ) | ||
82 | |||
83 | \internal | ||
84 | If \a hasDue is TRUE sets the due date of the task to \a date. | ||
85 | Otherwise clears the due date of the task. | ||
86 | */ | ||
87 | |||
88 | /*! | ||
89 | \fn void Task::setDueDate( const QDate &date ) | ||
90 | |||
91 | Sets the due date of the task to \a date. | ||
92 | */ | ||
93 | |||
94 | /*! | ||
95 | \fn void Task::clearDueDate( ) | ||
96 | |||
97 | Clears the due date of the task. | ||
98 | */ | ||
99 | |||
100 | /*! | ||
101 | \fn void Task::setCompleted( bool b ) | ||
102 | |||
103 | If \a b is TRUE marks the task as completed. Otherwise marks the task as | ||
104 | uncompleted. | ||
105 | */ | ||
106 | |||
107 | /*! | ||
108 | \fn bool Task::isCompleted() const | ||
109 | |||
110 | Returns TRUE if the task is completed. Otherwise returns FALSE. | ||
111 | */ | ||
112 | |||
113 | /*! | ||
114 | \fn const QDate &Task::dueDate() const | ||
115 | |||
116 | Returns the due date of the task. | ||
117 | */ | ||
118 | |||
119 | /*! | ||
120 | \fn bool Task::hasDueDate() const | ||
121 | |||
122 | Returns TRUE if there is a due date set for the task. Otherwise returns | ||
123 | FALSE. | ||
124 | */ | ||
125 | |||
126 | /*! | ||
127 | \fn void Task::setHasDueDate( bool b ) | ||
128 | |||
129 | \internal | ||
130 | Just don't ask. I really can't justify the function. | ||
131 | */ | ||
132 | |||
133 | |||
134 | /*! | ||
135 | \internal | ||
136 | Creates a new task. The properties of the task are set from \a m. | ||
137 | */ | ||
138 | |||
40 | Task::Task( const QMap<int, QString> &m ) : Record(), mDue( FALSE ), | 139 | Task::Task( const QMap<int, QString> &m ) : Record(), mDue( FALSE ), |
41 | mDueDate( QDate::currentDate() ), mCompleted( FALSE ), mPriority( 3 ), mDesc() | 140 | mDueDate( QDate::currentDate() ), mCompleted( FALSE ), mPriority( 3 ), mDesc() |
42 | { | 141 | { |
43 | //qDebug("Task::Task fromMap"); | 142 | //qDebug("Task::Task fromMap"); |
44 | //dump( m ); | 143 | //dump( m ); |
45 | for ( QMap<int,QString>::ConstIterator it = m.begin(); it != m.end();++it ) | 144 | for ( QMap<int,QString>::ConstIterator it = m.begin(); it != m.end();++it ) |
46 | switch ( (TaskFields) it.key() ) { | 145 | switch ( (TaskFields) it.key() ) { |
47 | case HasDate: if ( *it == "1" ) mDue = TRUE; break; | 146 | case HasDate: if ( *it == "1" ) mDue = TRUE; break; |
48 | case Completed: setCompleted( *it == "1" ); break; | 147 | case Completed: setCompleted( *it == "1" ); break; |
49 | case TaskCategory: setCategories( idsFromString( *it ) ); break; | 148 | case TaskCategory: setCategories( idsFromString( *it ) ); break; |
50 | case TaskDescription: setDescription( *it ); break; | 149 | case TaskDescription: setDescription( *it ); break; |
51 | case Priority: setPriority( (*it).toInt() ); break; | 150 | case Priority: setPriority( (*it).toInt() ); break; |
52 | case Date: mDueDate = TimeConversion::fromString( (*it) ); break; | 151 | case Date: mDueDate = TimeConversion::fromString( (*it) ); break; |
53 | case TaskUid: setUid( (*it).toInt() ); break; | 152 | case TaskUid: setUid( (*it).toInt() ); break; |
54 | default: break; | 153 | case TaskRid: |
154 | case TaskRinfo: | ||
155 | break; | ||
55 | } | 156 | } |
56 | } | 157 | } |
57 | 158 | ||
159 | /*! | ||
160 | Destroys a task. | ||
161 | */ | ||
58 | Task::~Task() | 162 | Task::~Task() |
59 | { | 163 | { |
60 | } | 164 | } |
61 | 165 | ||
166 | /*! | ||
167 | \internal | ||
168 | Returns the task as a map of field ids to property values. | ||
169 | */ | ||
62 | QMap<int, QString> Task::toMap() const | 170 | QMap<int, QString> Task::toMap() const |
63 | { | 171 | { |
64 | QMap<int, QString> m; | 172 | QMap<int, QString> m; |
65 | m.insert( HasDate, hasDueDate() ? "1" : "0" ); | 173 | m.insert( HasDate, hasDueDate() ? "1" : "0" ); |
66 | m.insert( Completed, isCompleted() ? "1" : "0" ); | 174 | m.insert( Completed, isCompleted() ? "1" : "0" ); |
67 | m.insert( TaskCategory, idsToString( categories() ) ); | 175 | if ( categories().count() ) |
68 | m.insert( TaskDescription, description() ); | 176 | m.insert( TaskCategory, idsToString( categories() ) ); |
177 | if ( !description().isEmpty() ) | ||
178 | m.insert( TaskDescription, description() ); | ||
69 | m.insert( Priority, QString::number( priority() ) ); | 179 | m.insert( Priority, QString::number( priority() ) ); |
70 | m.insert( Date, TimeConversion::toString( dueDate() ) ); | 180 | if ( hasDueDate() ) |
181 | m.insert( Date, TimeConversion::toString( dueDate() ) ); | ||
71 | m.insert( TaskUid, QString::number(uid()) ); | 182 | m.insert( TaskUid, QString::number(uid()) ); |
72 | 183 | ||
73 | //qDebug("Task::toMap"); | 184 | //qDebug("Task::toMap"); |
74 | //dump( m ); | 185 | //dump( m ); |
75 | return m; | 186 | return m; |
76 | } | 187 | } |
77 | 188 | ||
189 | /*! | ||
190 | \internal | ||
191 | Appends the task information to \a buf. | ||
192 | */ | ||
78 | void Task::save( QString& buf ) const | 193 | void Task::save( QString& buf ) const |
79 | { | 194 | { |
80 | buf += " Completed=\""; | 195 | buf += " Completed=\""; |
81 | // qDebug( "writing %d", complete ); | 196 | // qDebug( "writing %d", complete ); |
82 | buf += QString::number( (int)mCompleted ); | 197 | buf += QString::number( (int)mCompleted ); |
83 | buf += "\""; | 198 | buf += "\""; |
84 | buf += " HasDate=\""; | 199 | buf += " HasDate=\""; |
85 | // qDebug( "writing %d", ); | 200 | // qDebug( "writing %d", ); |
86 | buf += QString::number( (int)mDue ); | 201 | buf += QString::number( (int)mDue ); |
87 | buf += "\""; | 202 | buf += "\""; |
88 | buf += " Priority=\""; | 203 | buf += " Priority=\""; |
89 | // qDebug ("writing %d", prior ); | 204 | // qDebug ("writing %d", prior ); |
90 | buf += QString::number( mPriority ); | 205 | buf += QString::number( mPriority ); |
91 | buf += "\""; | 206 | buf += "\""; |
92 | buf += " Categories=\""; | 207 | buf += " Categories=\""; |
93 | buf += Qtopia::Record::idsToString( categories() ); | 208 | buf += Qtopia::Record::idsToString( categories() ); |
94 | buf += "\""; | 209 | buf += "\""; |
95 | buf += " Description=\""; | 210 | buf += " Description=\""; |
96 | // qDebug( "writing note %s", note.latin1() ); | 211 | // qDebug( "writing note %s", note.latin1() ); |
97 | buf += Qtopia::escapeString( mDesc ); | 212 | buf += Qtopia::escapeString( mDesc ); |
98 | buf += "\""; | 213 | buf += "\""; |
99 | if ( mDue ) { | 214 | if ( mDue ) { |
100 | // qDebug("saving ymd %d %d %d", mDueDate.year(), mDueDate.month(), | 215 | // qDebug("saving ymd %d %d %d", mDueDate.year(), mDueDate.month(), |
101 | // mDueDate.day() ); | 216 | // mDueDate.day() ); |
102 | buf += " DateYear=\""; | 217 | buf += " DateYear=\""; |
103 | buf += QString::number( mDueDate.year() ); | 218 | buf += QString::number( mDueDate.year() ); |
104 | buf += "\""; | 219 | buf += "\""; |
105 | buf += " DateMonth=\""; | 220 | buf += " DateMonth=\""; |
106 | buf += QString::number( mDueDate.month() ); | 221 | buf += QString::number( mDueDate.month() ); |
107 | buf += "\""; | 222 | buf += "\""; |
108 | buf += " DateDay=\""; | 223 | buf += " DateDay=\""; |
109 | buf += QString::number( mDueDate.day() ); | 224 | buf += QString::number( mDueDate.day() ); |
110 | buf += "\""; | 225 | buf += "\""; |
111 | } | 226 | } |
112 | buf += customToXml(); | 227 | buf += customToXml(); |
113 | // qDebug ("writing uid %d", uid() ); | 228 | // qDebug ("writing uid %d", uid() ); |
114 | buf += " Uid=\""; | 229 | buf += " Uid=\""; |
115 | buf += QString::number( uid() ); | 230 | buf += QString::number( uid() ); |
116 | // terminate it in the application... | 231 | // terminate it in the application... |
117 | buf += "\""; | 232 | buf += "\""; |
118 | } | 233 | } |
119 | 234 | ||
120 | bool Task::match ( const QRegExp &r ) const | 235 | /*! |
236 | Returns TRUE if the task matches the regular expressions \a regexp. | ||
237 | Otherwise returns FALSE. | ||
238 | */ | ||
239 | bool Task::match ( const QRegExp ®exp ) const | ||
121 | { | 240 | { |
122 | // match on priority, description on due date... | 241 | // match on priority, description on due date... |
123 | bool match; | 242 | bool match; |
124 | match = false; | 243 | match = false; |
125 | if ( QString::number( mPriority ).find( r ) > -1 ) | 244 | if ( QString::number( mPriority ).find( regexp ) > -1 ) |
126 | match = true; | 245 | match = true; |
127 | else if ( mDue && mDueDate.toString().find( r ) > -1 ) | 246 | else if ( mDue && mDueDate.toString().find( regexp ) > -1 ) |
128 | match = true; | 247 | match = true; |
129 | else if ( mDesc.find( r ) > -1 ) | 248 | else if ( mDesc.find( regexp ) > -1 ) |
130 | match = true; | 249 | match = true; |
131 | return match; | 250 | return match; |
132 | } | 251 | } |
133 | 252 | ||
253 | /*! | ||
254 | \internal | ||
255 | */ | ||
134 | static inline VObject *safeAddPropValue( VObject *o, const char *prop, const QString &value ) | 256 | static inline VObject *safeAddPropValue( VObject *o, const char *prop, const QString &value ) |
135 | { | 257 | { |
136 | VObject *ret = 0; | 258 | VObject *ret = 0; |
137 | if ( o && !value.isEmpty() ) | 259 | if ( o && !value.isEmpty() ) |
138 | ret = addPropValue( o, prop, value.latin1() ); | 260 | ret = addPropValue( o, prop, value.latin1() ); |
139 | return ret; | 261 | return ret; |
140 | } | 262 | } |
141 | 263 | ||
264 | /*! | ||
265 | \internal | ||
266 | */ | ||
142 | static inline VObject *safeAddProp( VObject *o, const char *prop) | 267 | static inline VObject *safeAddProp( VObject *o, const char *prop) |
143 | { | 268 | { |
144 | VObject *ret = 0; | 269 | VObject *ret = 0; |
145 | if ( o ) | 270 | if ( o ) |
146 | ret = addProp( o, prop ); | 271 | ret = addProp( o, prop ); |
147 | return ret; | 272 | return ret; |
148 | } | 273 | } |
149 | 274 | ||
150 | 275 | ||
276 | /*! | ||
277 | \internal | ||
278 | */ | ||
151 | static VObject *createVObject( const Task &t ) | 279 | static VObject *createVObject( const Task &t ) |
152 | { | 280 | { |
153 | VObject *vcal = newVObject( VCCalProp ); | 281 | VObject *vcal = newVObject( VCCalProp ); |
154 | safeAddPropValue( vcal, VCVersionProp, "1.0" ); | 282 | safeAddPropValue( vcal, VCVersionProp, "1.0" ); |
155 | VObject *task = safeAddProp( vcal, VCTodoProp ); | 283 | VObject *task = safeAddProp( vcal, VCTodoProp ); |
156 | 284 | ||
157 | if ( t.hasDueDate() ) | 285 | if ( t.hasDueDate() ) |
158 | safeAddPropValue( task, VCDueProp, TimeConversion::toISO8601( t.dueDate() ) ); | 286 | safeAddPropValue( task, VCDueProp, TimeConversion::toISO8601( t.dueDate() ) ); |
159 | safeAddPropValue( task, VCDescriptionProp, t.description() ); | 287 | safeAddPropValue( task, VCDescriptionProp, t.description() ); |
160 | if ( t.isCompleted() ) | 288 | if ( t.isCompleted() ) |
161 | safeAddPropValue( task, VCStatusProp, "COMPLETED" ); | 289 | safeAddPropValue( task, VCStatusProp, "COMPLETED" ); |
162 | safeAddPropValue( task, VCPriorityProp, QString::number( t.priority() ) ); | 290 | safeAddPropValue( task, VCPriorityProp, QString::number( t.priority() ) ); |
163 | 291 | ||
164 | return vcal; | 292 | return vcal; |
165 | } | 293 | } |
166 | 294 | ||
167 | 295 | /*! | |
296 | \internal | ||
297 | */ | ||
168 | static Task parseVObject( VObject *obj ) | 298 | static Task parseVObject( VObject *obj ) |
169 | { | 299 | { |
170 | Task t; | 300 | Task t; |
171 | 301 | ||
172 | VObjectIterator it; | 302 | VObjectIterator it; |
173 | initPropIterator( &it, obj ); | 303 | initPropIterator( &it, obj ); |
174 | while( moreIteration( &it ) ) { | 304 | while( moreIteration( &it ) ) { |
175 | VObject *o = nextVObject( &it ); | 305 | VObject *o = nextVObject( &it ); |
176 | QCString name = vObjectName( o ); | 306 | QCString name = vObjectName( o ); |
177 | QCString value = vObjectStringZValue( o ); | 307 | QCString value = vObjectStringZValue( o ); |
178 | if ( name == VCDueProp ) { | 308 | if ( name == VCDueProp ) { |
179 | t.setDueDate( TimeConversion::fromISO8601( value ).date(), TRUE ); | 309 | t.setDueDate( TimeConversion::fromISO8601( value ).date(), TRUE ); |
180 | } | 310 | } |
181 | else if ( name == VCDescriptionProp ) { | 311 | else if ( name == VCDescriptionProp ) { |
182 | t.setDescription( value ); | 312 | t.setDescription( value ); |
183 | } | 313 | } |
184 | else if ( name == VCStatusProp ) { | 314 | else if ( name == VCStatusProp ) { |
185 | if ( value == "COMPLETED" ) | 315 | if ( value == "COMPLETED" ) |
186 | t.setCompleted( TRUE ); | 316 | t.setCompleted( TRUE ); |
187 | } | 317 | } |
188 | else if ( name == VCPriorityProp ) { | 318 | else if ( name == VCPriorityProp ) { |
189 | t.setPriority( value.toInt() ); | 319 | t.setPriority( value.toInt() ); |
190 | } | 320 | } |
191 | #if 0 | 321 | #if 0 |
192 | else { | 322 | else { |
193 | printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) ); | 323 | printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) ); |
194 | VObjectIterator nit; | 324 | VObjectIterator nit; |
195 | initPropIterator( &nit, o ); | 325 | initPropIterator( &nit, o ); |
196 | while( moreIteration( &nit ) ) { | 326 | while( moreIteration( &nit ) ) { |
197 | VObject *o = nextVObject( &nit ); | 327 | VObject *o = nextVObject( &nit ); |
198 | QCString name = vObjectName( o ); | 328 | QCString name = vObjectName( o ); |
199 | QString value = vObjectStringZValue( o ); | 329 | QString value = vObjectStringZValue( o ); |
200 | printf(" subprop: %s = %s\n", name.data(), value.latin1() ); | 330 | printf(" subprop: %s = %s\n", name.data(), value.latin1() ); |
201 | } | 331 | } |
202 | } | 332 | } |
203 | #endif | 333 | #endif |
204 | } | 334 | } |
205 | 335 | ||
206 | return t; | 336 | return t; |
207 | } | 337 | } |
208 | 338 | ||
209 | 339 | ||
210 | 340 | /*! | |
341 | Writes the list of \a tasks as a set of VCards to the file \a filename. | ||
342 | */ | ||
211 | void Task::writeVCalendar( const QString &filename, const QValueList<Task> &tasks) | 343 | void Task::writeVCalendar( const QString &filename, const QValueList<Task> &tasks) |
212 | { | 344 | { |
213 | QFileDirect f( filename.utf8().data() ); | 345 | QFileDirect f( filename.utf8().data() ); |
214 | if ( !f.open( IO_WriteOnly ) ) { | 346 | if ( !f.open( IO_WriteOnly ) ) { |
215 | qWarning("Unable to open vcard write"); | 347 | qWarning("Unable to open vcard write"); |
216 | return; | 348 | return; |
217 | } | 349 | } |
218 | 350 | ||
219 | QValueList<Task>::ConstIterator it; | 351 | QValueList<Task>::ConstIterator it; |
220 | for( it = tasks.begin(); it != tasks.end(); ++it ) { | 352 | for( it = tasks.begin(); it != tasks.end(); ++it ) { |
221 | VObject *obj = createVObject( *it ); | 353 | VObject *obj = createVObject( *it ); |
222 | writeVObject(f.directHandle() , obj ); | 354 | writeVObject(f.directHandle() , obj ); |
223 | cleanVObject( obj ); | 355 | cleanVObject( obj ); |
224 | } | 356 | } |
225 | 357 | ||
226 | cleanStrTbl(); | 358 | cleanStrTbl(); |
227 | } | 359 | } |
228 | 360 | ||
361 | /*! | ||
362 | Writes \a task as a VCard to the file \a filename. | ||
363 | */ | ||
229 | void Task::writeVCalendar( const QString &filename, const Task &task) | 364 | void Task::writeVCalendar( const QString &filename, const Task &task) |
230 | { | 365 | { |
231 | QFileDirect f( filename.utf8().data() ); | 366 | QFileDirect f( filename.utf8().data() ); |
232 | if ( !f.open( IO_WriteOnly ) ) { | 367 | if ( !f.open( IO_WriteOnly ) ) { |
233 | qWarning("Unable to open vcard write"); | 368 | qWarning("Unable to open vcard write"); |
234 | return; | 369 | return; |
235 | } | 370 | } |
236 | 371 | ||
237 | VObject *obj = createVObject( task ); | 372 | VObject *obj = createVObject( task ); |
238 | writeVObject(f.directHandle() , obj ); | 373 | writeVObject(f.directHandle() , obj ); |
239 | cleanVObject( obj ); | 374 | cleanVObject( obj ); |
240 | 375 | ||
241 | cleanStrTbl(); | 376 | cleanStrTbl(); |
242 | } | 377 | } |
243 | 378 | ||
244 | 379 | /*! | |
380 | Returns the set of tasks read as VCards from the file \a filename. | ||
381 | */ | ||
245 | QValueList<Task> Task::readVCalendar( const QString &filename ) | 382 | QValueList<Task> Task::readVCalendar( const QString &filename ) |
246 | { | 383 | { |
247 | VObject *obj = Parse_MIME_FromFileName( (char *)filename.utf8().data() ); | 384 | VObject *obj = Parse_MIME_FromFileName( (char *)filename.utf8().data() ); |
248 | 385 | ||
249 | QValueList<Task> tasks; | 386 | QValueList<Task> tasks; |
250 | 387 | ||
251 | while ( obj ) { | 388 | while ( obj ) { |
252 | QCString name = vObjectName( obj ); | 389 | QCString name = vObjectName( obj ); |
253 | if ( name == VCCalProp ) { | 390 | if ( name == VCCalProp ) { |
254 | VObjectIterator nit; | 391 | VObjectIterator nit; |
255 | initPropIterator( &nit, obj ); | 392 | initPropIterator( &nit, obj ); |
256 | while( moreIteration( &nit ) ) { | 393 | while( moreIteration( &nit ) ) { |
257 | VObject *o = nextVObject( &nit ); | 394 | VObject *o = nextVObject( &nit ); |
258 | QCString name = vObjectName( o ); | 395 | QCString name = vObjectName( o ); |
259 | if ( name == VCTodoProp ) | 396 | if ( name == VCTodoProp ) |
260 | tasks.append( parseVObject( o ) ); | 397 | tasks.append( parseVObject( o ) ); |
261 | } | 398 | } |
262 | } else if ( name == VCTodoProp ) { | 399 | } else if ( name == VCTodoProp ) { |
263 | // shouldn't happen, but just to be sure | 400 | // shouldn't happen, but just to be sure |
264 | tasks.append( parseVObject( obj ) ); | 401 | tasks.append( parseVObject( obj ) ); |
265 | } | 402 | } |
266 | VObject *t = obj; | 403 | VObject *t = obj; |
267 | obj = nextVObjectInList(obj); | 404 | obj = nextVObjectInList(obj); |
268 | cleanVObject( t ); | 405 | cleanVObject( t ); |
269 | } | 406 | } |
270 | 407 | ||
271 | return tasks; | 408 | return tasks; |
272 | } | 409 | } |
diff --git a/library/backend/task.h b/library/backend/task.h index 6f383b8..091f2e9 100644 --- a/library/backend/task.h +++ b/library/backend/task.h | |||
@@ -1,81 +1,92 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2001 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. |
3 | ** | 3 | ** |
4 | ** This file is part of Qtopia Environment. | 4 | ** This file is part of the Qtopia Environment. |
5 | ** | 5 | ** |
6 | ** This file may be distributed and/or modified under the terms of the | 6 | ** This file may be distributed and/or modified under the terms of the |
7 | ** GNU General Public License version 2 as published by the Free Software | 7 | ** GNU General Public License version 2 as published by the Free Software |
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** packaging of this file. | 9 | ** packaging of this file. |
10 | ** | 10 | ** |
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | 11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
13 | ** | 13 | ** |
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
15 | ** | 15 | ** |
16 | ** Contact info@trolltech.com if any conditions of this licensing are | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
17 | ** not clear to you. | 17 | ** not clear to you. |
18 | ** | 18 | ** |
19 | **********************************************************************/ | 19 | **********************************************************************/ |
20 | #ifndef __TASK_H__ | 20 | #ifndef __TASK_H__ |
21 | #define __TASK_H__ | 21 | #define __TASK_H__ |
22 | 22 | ||
23 | #include <qpe/palmtoprecord.h> | 23 | #include <qtopia/private/palmtoprecord.h> |
24 | #include <qpe/stringutil.h> | 24 | #include <qtopia/stringutil.h> |
25 | 25 | ||
26 | #include <qvaluelist.h> | 26 | #include <qvaluelist.h> |
27 | #include <qdatetime.h> | 27 | #include <qdatetime.h> |
28 | 28 | ||
29 | class TaskPrivate; | 29 | class TaskPrivate; |
30 | class QPC_EXPORT Task : public Qtopia::Record | 30 | class QPC_EXPORT Task : public Qtopia::Record |
31 | { | 31 | { |
32 | public: | 32 | public: |
33 | Task(); | 33 | Task(); |
34 | Task( const QMap<int, QString> &fromMap ); | 34 | Task( const QMap<int, QString> &fromMap ); |
35 | ~Task(); | 35 | ~Task(); |
36 | 36 | ||
37 | QMap<int, QString> toMap() const; | 37 | QMap<int, QString> toMap() const; |
38 | 38 | ||
39 | static void writeVCalendar( const QString &filename, const QValueList<Task> &tasks); | 39 | static void writeVCalendar( const QString &filename, const QValueList<Task> &tasks); |
40 | static void writeVCalendar( const QString &filename, const Task &task); | 40 | static void writeVCalendar( const QString &filename, const Task &task); |
41 | static QValueList<Task> readVCalendar( const QString &filename ); | 41 | static QValueList<Task> readVCalendar( const QString &filename ); |
42 | 42 | ||
43 | enum PriorityValue { VeryHigh=1, High, Normal, Low, VeryLow }; | ||
44 | |||
43 | void setPriority( int priority ) { mPriority = priority; } | 45 | void setPriority( int priority ) { mPriority = priority; } |
44 | int priority() const { return mPriority; } | 46 | int priority() const { return mPriority; } |
45 | 47 | ||
46 | // void setCategory( const QString& category ) | 48 | // void setCategory( const QString& category ) |
47 | // { mCategory = category.stripWhiteSpace(); } | 49 | // { mCategory = category.stripWhiteSpace(); } |
48 | // const QString &category() const { return mCategory; } | 50 | // const QString &category() const { return mCategory; } |
49 | 51 | ||
50 | void setDescription( const QString& description ) | 52 | void setDescription( const QString& description ) |
51 | { mDesc = Qtopia::simplifyMultiLineSpace(description); } | 53 | { mDesc = Qtopia::simplifyMultiLineSpace(description); } |
52 | const QString &description() const { return mDesc; } | 54 | const QString &description() const { return mDesc; } |
53 | 55 | ||
56 | // Use THESE functions | ||
57 | void setDueDate( const QDate &date); | ||
58 | void clearDueDate(); | ||
59 | |||
60 | // Instead of these functions. | ||
54 | void setDueDate( const QDate& date, bool hasDue ) { mDueDate = date; mDue = hasDue; } | 61 | void setDueDate( const QDate& date, bool hasDue ) { mDueDate = date; mDue = hasDue; } |
62 | void setHasDueDate( bool b ) { mDue = b; } | ||
63 | |||
55 | const QDate &dueDate() const { return mDueDate; } | 64 | const QDate &dueDate() const { return mDueDate; } |
56 | bool hasDueDate() const { return mDue; } | 65 | bool hasDueDate() const { return mDue; } |
57 | void setHasDueDate( bool b ) { mDue = b; } | ||
58 | 66 | ||
59 | void setCompleted( bool b ) { mCompleted = b; } | 67 | void setCompleted( bool b ) { mCompleted = b; } |
60 | bool isCompleted() const { return mCompleted; } | 68 | bool isCompleted() const { return mCompleted; } |
61 | 69 | ||
62 | void save( QString& buf ) const; | 70 | void save( QString& buf ) const; |
63 | bool match( const QRegExp &r ) const; | 71 | bool match( const QRegExp &r ) const; |
64 | 72 | ||
65 | private: | 73 | private: |
66 | Qtopia::UidGen &uidGen() { return sUidGen; } | 74 | Qtopia::UidGen &uidGen() { return sUidGen; } |
67 | static Qtopia::UidGen sUidGen; | 75 | static Qtopia::UidGen sUidGen; |
68 | 76 | ||
69 | bool mDue; | 77 | bool mDue; |
70 | QDate mDueDate; | 78 | QDate mDueDate; |
71 | bool mCompleted; | 79 | bool mCompleted; |
72 | int mPriority; | 80 | int mPriority; |
73 | QString mDesc; | 81 | QString mDesc; |
74 | TaskPrivate *d; | 82 | TaskPrivate *d; |
75 | // ADDITION | 83 | // ADDITION |
76 | int recordId; | 84 | int recordId; |
77 | int recordInfo; | 85 | int recordInfo; |
78 | // | 86 | // |
79 | }; | 87 | }; |
80 | 88 | ||
89 | // MUST be inline. (forwards compatability). | ||
90 | inline void Task::setDueDate( const QDate &date) { setDueDate(date, date.isValid()); } | ||
91 | inline void Task::clearDueDate() { setHasDueDate( FALSE ); } | ||
81 | #endif | 92 | #endif |
diff --git a/library/backend/timeconversion.cpp b/library/backend/timeconversion.cpp deleted file mode 100644 index a4a2547..0000000 --- a/library/backend/timeconversion.cpp +++ b/dev/null | |||
@@ -1,237 +0,0 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #include <qglobal.h> | ||
22 | #include "timeconversion.h" | ||
23 | #include <qregexp.h> | ||
24 | #include <stdlib.h> | ||
25 | |||
26 | QString TimeConversion::toString( const QDate &d ) | ||
27 | { | ||
28 | QString r = QString::number( d.day() ) + "." + | ||
29 | QString::number( d.month() ) + "." + | ||
30 | QString::number( d.year() ); | ||
31 | //qDebug("TimeConversion::toString %s", r.latin1()); | ||
32 | return r; | ||
33 | } | ||
34 | |||
35 | QDate TimeConversion::fromString( const QString &datestr ) | ||
36 | { | ||
37 | int monthPos = datestr.find('.'); | ||
38 | int yearPos = datestr.find('.', monthPos+1 ); | ||
39 | if ( monthPos == -1 || yearPos == -1 ) { | ||
40 | qDebug("fromString didn't find . in str = %s; mpos = %d ypos = %d", datestr.latin1(), monthPos, yearPos ); | ||
41 | return QDate(); | ||
42 | } | ||
43 | int d = datestr.left( monthPos ).toInt(); | ||
44 | int m = datestr.mid( monthPos+1, yearPos - monthPos - 1 ).toInt(); | ||
45 | int y = datestr.mid( yearPos+1 ).toInt(); | ||
46 | QDate date ( y,m,d ); | ||
47 | //qDebug("TimeConversion::fromString ymd = %s => %d %d %d; mpos = %d ypos = %d", datestr.latin1(), y, m, d, monthPos, yearPos); | ||
48 | return date; | ||
49 | } | ||
50 | |||
51 | time_t TimeConversion::toUTC( const QDateTime& dt ) | ||
52 | { | ||
53 | time_t tmp; | ||
54 | struct tm *lt; | ||
55 | |||
56 | #if defined(_OS_WIN32) || defined (Q_OS_WIN32) || defined (Q_OS_WIN64) | ||
57 | _tzset(); | ||
58 | #else | ||
59 | tzset(); | ||
60 | #endif | ||
61 | |||
62 | // get a tm structure from the system to get the correct tz_name | ||
63 | tmp = time( 0 ); | ||
64 | lt = localtime( &tmp ); | ||
65 | |||
66 | lt->tm_sec = dt.time().second(); | ||
67 | lt->tm_min = dt.time().minute(); | ||
68 | lt->tm_hour = dt.time().hour(); | ||
69 | lt->tm_mday = dt.date().day(); | ||
70 | lt->tm_mon = dt.date().month() - 1; // 0-11 instead of 1-12 | ||
71 | lt->tm_year = dt.date().year() - 1900; // year - 1900 | ||
72 | //lt->tm_wday = dt.date().dayOfWeek(); ignored anyway | ||
73 | //lt->tm_yday = dt.date().dayOfYear(); ignored anyway | ||
74 | lt->tm_wday = -1; | ||
75 | lt->tm_yday = -1; | ||
76 | // tm_isdst negative -> mktime will find out about DST | ||
77 | lt->tm_isdst = -1; | ||
78 | // keep tm_zone and tm_gmtoff | ||
79 | tmp = mktime( lt ); | ||
80 | return tmp; | ||
81 | } | ||
82 | |||
83 | QDateTime TimeConversion::fromUTC( time_t time ) | ||
84 | { | ||
85 | struct tm *lt; | ||
86 | |||
87 | #if defined(_OS_WIN32) || defined (Q_OS_WIN32) || defined (Q_OS_WIN64) | ||
88 | _tzset(); | ||
89 | #else | ||
90 | tzset(); | ||
91 | #endif | ||
92 | lt = localtime( &time ); | ||
93 | QDateTime dt; | ||
94 | dt.setDate( QDate( lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday ) ); | ||
95 | dt.setTime( QTime( lt->tm_hour, lt->tm_min, lt->tm_sec ) ); | ||
96 | return dt; | ||
97 | } | ||
98 | |||
99 | |||
100 | int TimeConversion::secsTo( const QDateTime &from, const QDateTime &to ) | ||
101 | { | ||
102 | return toUTC( to ) - toUTC( from ); | ||
103 | } | ||
104 | |||
105 | QCString TimeConversion::toISO8601( const QDate &d ) | ||
106 | { | ||
107 | time_t tmp = toUTC( d ); | ||
108 | struct tm *utc = gmtime( &tmp ); | ||
109 | |||
110 | QCString str; | ||
111 | str.sprintf("%04d%02d%02d", (utc->tm_year + 1900), utc->tm_mon+1, utc->tm_mday ); | ||
112 | return str; | ||
113 | } | ||
114 | |||
115 | QCString TimeConversion::toISO8601( const QDateTime &dt ) | ||
116 | { | ||
117 | time_t tmp = toUTC( dt ); | ||
118 | struct tm *utc = gmtime( &tmp ); | ||
119 | |||
120 | QCString str; | ||
121 | str.sprintf("%04d%02d%02dT%02d%02d%02dZ", | ||
122 | (utc->tm_year + 1900), utc->tm_mon+1, utc->tm_mday, | ||
123 | utc->tm_hour, utc->tm_min, utc->tm_sec ); | ||
124 | return str; | ||
125 | } | ||
126 | |||
127 | QDateTime TimeConversion::fromISO8601( const QCString &s ) | ||
128 | { | ||
129 | |||
130 | #if defined(_OS_WIN32) || defined (Q_OS_WIN32) || defined (Q_OS_WIN64) | ||
131 | _tzset(); | ||
132 | #else | ||
133 | tzset(); | ||
134 | #endif | ||
135 | |||
136 | struct tm *thetime = new tm; | ||
137 | |||
138 | QCString str = s.copy(); | ||
139 | str.replace(QRegExp("-"), "" ); | ||
140 | str.replace(QRegExp(":"), "" ); | ||
141 | str.stripWhiteSpace(); | ||
142 | str = str.lower(); | ||
143 | |||
144 | int i = str.find( "t" ); | ||
145 | QCString date; | ||
146 | QCString timestr; | ||
147 | if ( i != -1 ) { | ||
148 | date = str.left( i ); | ||
149 | timestr = str.mid( i+1 ); | ||
150 | } else { | ||
151 | date = str; | ||
152 | } | ||
153 | |||
154 | // qDebug("--- parsing ISO time---"); | ||
155 | thetime->tm_year = 100; | ||
156 | thetime->tm_mon = 0; | ||
157 | thetime->tm_mday = 0; | ||
158 | thetime->tm_hour = 0; | ||
159 | thetime->tm_min = 0; | ||
160 | thetime->tm_sec = 0; | ||
161 | |||
162 | // qDebug("date = %s", date.data() ); | ||
163 | |||
164 | switch( date.length() ) { | ||
165 | case 8: | ||
166 | thetime->tm_mday = date.right( 2 ).toInt(); | ||
167 | case 6: | ||
168 | thetime->tm_mon = date.mid( 4, 2 ).toInt() - 1; | ||
169 | case 4: | ||
170 | thetime->tm_year = date.left( 4 ).toInt(); | ||
171 | thetime->tm_year -= 1900; | ||
172 | break; | ||
173 | default: | ||
174 | break; | ||
175 | } | ||
176 | |||
177 | int tzoff = 0; | ||
178 | bool inLocalTime = FALSE; | ||
179 | if ( timestr.find( 'z' ) == (int)timestr.length() - 1 ) | ||
180 | // UTC | ||
181 | timestr = timestr.left( timestr.length() -1 ); | ||
182 | else { | ||
183 | int plus = timestr.find( "+" ); | ||
184 | int minus = timestr.find( "-" ); | ||
185 | if ( plus != -1 || minus != -1 ) { | ||
186 | // have a timezone offset | ||
187 | plus = (plus != -1) ? plus : minus; | ||
188 | QCString off = timestr.mid( plus ); | ||
189 | timestr = timestr.left( plus ); | ||
190 | |||
191 | int tzoffhour = 0; | ||
192 | int tzoffmin = 0; | ||
193 | switch( off.length() ) { | ||
194 | case 5: | ||
195 | tzoffmin = off.mid(3).toInt(); | ||
196 | case 3: | ||
197 | tzoffhour = off.left(3).toInt(); | ||
198 | default: | ||
199 | break; | ||
200 | } | ||
201 | tzoff = 60*tzoffhour + tzoffmin; | ||
202 | } else | ||
203 | inLocalTime = TRUE; | ||
204 | } | ||
205 | |||
206 | // get the time: | ||
207 | switch( timestr.length() ) { | ||
208 | case 6: | ||
209 | thetime->tm_sec = timestr.mid( 4 ).toInt(); | ||
210 | case 4: | ||
211 | thetime->tm_min = timestr.mid( 2, 2 ).toInt(); | ||
212 | case 2: | ||
213 | thetime->tm_hour = timestr.left( 2 ).toInt(); | ||
214 | default: | ||
215 | break; | ||
216 | } | ||
217 | |||
218 | int tzloc = 0; | ||
219 | time_t tmp = time( 0 ); | ||
220 | if ( !inLocalTime ) { | ||
221 | // have to get the offset between gmt and local time | ||
222 | struct tm *lt = localtime( &tmp ); | ||
223 | tzloc = mktime( lt ); | ||
224 | struct tm *ut = gmtime( &tmp ); | ||
225 | tzloc -= mktime( ut ); | ||
226 | } | ||
227 | // qDebug("time: %d %d %d, tzloc=%d, tzoff=%d", thetime->tm_hour, thetime->tm_min, thetime->tm_sec, | ||
228 | // tzloc, tzoff ); | ||
229 | |||
230 | tmp = mktime( thetime ); | ||
231 | tmp += 60*(-tzloc + tzoff); | ||
232 | |||
233 | delete thetime; | ||
234 | |||
235 | return fromUTC( tmp ); | ||
236 | } | ||
237 | |||
diff --git a/library/backend/timeconversion.h b/library/backend/timeconversion.h deleted file mode 100644 index 1724812..0000000 --- a/library/backend/timeconversion.h +++ b/dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #ifndef __timeconversion_h__ | ||
22 | #define __timeconversion_h__ | ||
23 | |||
24 | #include <time.h> | ||
25 | #include <sys/types.h> | ||
26 | #include <qdatetime.h> | ||
27 | |||
28 | #include <qpe/qpcglobal.h> | ||
29 | |||
30 | class QPC_EXPORT TimeConversion | ||
31 | { | ||
32 | public: | ||
33 | static QString toString( const QDate &d ); | ||
34 | static QDate fromString( const QString &datestr ); | ||
35 | |||
36 | static time_t toUTC( const QDateTime& dt ); | ||
37 | static QDateTime fromUTC( time_t time ); | ||
38 | static int secsTo( const QDateTime &from, const QDateTime &to ); | ||
39 | |||
40 | static QCString toISO8601( const QDate & ); | ||
41 | static QCString toISO8601( const QDateTime & ); | ||
42 | static QDateTime fromISO8601( const QCString & ); | ||
43 | }; | ||
44 | |||
45 | #endif // __timeconversion_h__ | ||
diff --git a/library/backend/vcc.y b/library/backend/vcc.y index e326a64..5bcf0cb 100644 --- a/library/backend/vcc.y +++ b/library/backend/vcc.y | |||
@@ -1,1199 +1,1208 @@ | |||
1 | %{ | 1 | %{ |
2 | 2 | ||
3 | /*************************************************************************** | 3 | /*************************************************************************** |
4 | (C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International | 4 | (C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International |
5 | Business Machines Corporation and Siemens Rolm Communications Inc. | 5 | Business Machines Corporation and Siemens Rolm Communications Inc. |
6 | 6 | ||
7 | For purposes of this license notice, the term Licensors shall mean, | 7 | For purposes of this license notice, the term Licensors shall mean, |
8 | collectively, Apple Computer, Inc., AT&T Corp., International | 8 | collectively, Apple Computer, Inc., AT&T Corp., International |
9 | Business Machines Corporation and Siemens Rolm Communications Inc. | 9 | Business Machines Corporation and Siemens Rolm Communications Inc. |
10 | The term Licensor shall mean any of the Licensors. | 10 | The term Licensor shall mean any of the Licensors. |
11 | 11 | ||
12 | Subject to acceptance of the following conditions, permission is hereby | 12 | Subject to acceptance of the following conditions, permission is hereby |
13 | granted by Licensors without the need for written agreement and without | 13 | granted by Licensors without the need for written agreement and without |
14 | license or royalty fees, to use, copy, modify and distribute this | 14 | license or royalty fees, to use, copy, modify and distribute this |
15 | software for any purpose. | 15 | software for any purpose. |
16 | 16 | ||
17 | The above copyright notice and the following four paragraphs must be | 17 | The above copyright notice and the following four paragraphs must be |
18 | reproduced in all copies of this software and any software including | 18 | reproduced in all copies of this software and any software including |
19 | this software. | 19 | this software. |
20 | 20 | ||
21 | THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE | 21 | THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE |
22 | ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR | 22 | ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR |
23 | MODIFICATIONS. | 23 | MODIFICATIONS. |
24 | 24 | ||
25 | IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, | 25 | IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, |
26 | INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT | 26 | INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT |
27 | OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | 27 | OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
28 | DAMAGE. | 28 | DAMAGE. |
29 | 29 | ||
30 | EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, | 30 | EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, |
31 | INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE | 31 | INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE |
32 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 32 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
33 | PURPOSE. | 33 | PURPOSE. |
34 | 34 | ||
35 | The software is provided with RESTRICTED RIGHTS. Use, duplication, or | 35 | The software is provided with RESTRICTED RIGHTS. Use, duplication, or |
36 | disclosure by the government are subject to restrictions set forth in | 36 | disclosure by the government are subject to restrictions set forth in |
37 | DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. | 37 | DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. |
38 | 38 | ||
39 | ***************************************************************************/ | 39 | ***************************************************************************/ |
40 | 40 | ||
41 | /* | 41 | /* |
42 | * src: vcc.c | 42 | * src: vcc.c |
43 | * doc: Parser for vCard and vCalendar. Note that this code is | 43 | * doc: Parser for vCard and vCalendar. Note that this code is |
44 | * generated by a yacc parser generator. Generally it should not | 44 | * generated by a yacc parser generator. Generally it should not |
45 | * be edited by hand. The real source is vcc.y. The #line directives | 45 | * be edited by hand. The real source is vcc.y. The #line directives |
46 | * can be commented out here to make it easier to trace through | 46 | * can be commented out here to make it easier to trace through |
47 | * in a debugger. However, if a bug is found it should | 47 | * in a debugger. However, if a bug is found it should |
48 | * be fixed in vcc.y and this file regenerated. | 48 | * be fixed in vcc.y and this file regenerated. |
49 | */ | 49 | */ |
50 | 50 | ||
51 | 51 | ||
52 | /* debugging utilities */ | 52 | /* debugging utilities */ |
53 | #if __DEBUG | 53 | #if __DEBUG |
54 | #define DBG_(x) printf x | 54 | #define DBG_(x) printf x |
55 | #else | 55 | #else |
56 | #define DBG_(x) | 56 | #define DBG_(x) |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | /**** External Functions ****/ | 59 | /**** External Functions ****/ |
60 | 60 | ||
61 | /* assign local name to parser variables and functions so that | 61 | /* assign local name to parser variables and functions so that |
62 | we can use more than one yacc based parser. | 62 | we can use more than one yacc based parser. |
63 | */ | 63 | */ |
64 | 64 | ||
65 | #if 0 | 65 | #if 0 |
66 | #define yyparse mime_parse | 66 | #define yyparse mime_parse |
67 | #define yylex mime_lex | 67 | #define yylex mime_lex |
68 | #define yyerror mime_error | 68 | #define yyerror mime_error |
69 | #define yychar mime_char | 69 | #define yychar mime_char |
70 | /* #define p_yyval p_mime_val */ | 70 | /* #define p_yyval p_mime_val */ |
71 | #undef yyval | 71 | #undef yyval |
72 | #define yyval mime_yyval | 72 | #define yyval mime_yyval |
73 | /* #define p_yylval p_mime_lval */ | 73 | /* #define p_yylval p_mime_lval */ |
74 | #undef yylval | 74 | #undef yylval |
75 | #define yylval mime_yylval | 75 | #define yylval mime_yylval |
76 | #define yydebug mime_debug | 76 | #define yydebug mime_debug |
77 | #define yynerrs mime_nerrs | 77 | #define yynerrs mime_nerrs |
78 | #define yyerrflag mime_errflag | 78 | #define yyerrflag mime_errflag |
79 | #define yyss mime_ss | 79 | #define yyss mime_ss |
80 | #define yyssp mime_ssp | 80 | #define yyssp mime_ssp |
81 | #define yyvs mime_vs | 81 | #define yyvs mime_vs |
82 | #define yyvsp mime_vsp | 82 | #define yyvsp mime_vsp |
83 | #define yylhs mime_lhs | 83 | #define yylhs mime_lhs |
84 | #define yylen mime_len | 84 | #define yylen mime_len |
85 | #define yydefred mime_defred | 85 | #define yydefred mime_defred |
86 | #define yydgoto mime_dgoto | 86 | #define yydgoto mime_dgoto |
87 | #define yysindex mime_sindex | 87 | #define yysindex mime_sindex |
88 | #define yyrindex mime_rindex | 88 | #define yyrindex mime_rindex |
89 | #define yygindex mime_gindex | 89 | #define yygindex mime_gindex |
90 | #define yytable mime_table | 90 | #define yytable mime_table |
91 | #define yycheck mime_check | 91 | #define yycheck mime_check |
92 | #define yyname mime_name | 92 | #define yyname mime_name |
93 | #define yyrule mime_rule | 93 | #define yyrule mime_rule |
94 | #ifdef YYPREFIX | 94 | #ifdef YYPREFIX |
95 | #undef YYPREFIX | 95 | #undef YYPREFIX |
96 | #endif | 96 | #endif |
97 | #define YYPREFIX "mime_" | 97 | #define YYPREFIX "mime_" |
98 | #endif | 98 | #endif |
99 | 99 | ||
100 | 100 | ||
101 | #ifndef _NO_LINE_FOLDING | 101 | #ifndef _NO_LINE_FOLDING |
102 | #define _SUPPORT_LINE_FOLDING 1 | 102 | #define _SUPPORT_LINE_FOLDING 1 |
103 | #endif | 103 | #endif |
104 | 104 | ||
105 | /* undef below if compile with MFC */ | 105 | /* undef below if compile with MFC */ |
106 | /* #define INCLUDEMFC 1 */ | 106 | /* #define INCLUDEMFC 1 */ |
107 | 107 | ||
108 | #if defined(WIN32) || defined(_WIN32) | 108 | #if defined(WIN32) || defined(_WIN32) |
109 | #ifdef INCLUDEMFC | 109 | #ifdef INCLUDEMFC |
110 | #include <afx.h> | 110 | #include <afx.h> |
111 | #endif | 111 | #endif |
112 | #endif | 112 | #endif |
113 | 113 | ||
114 | #include <string.h> | 114 | #include <string.h> |
115 | #ifndef __MWERKS__ | 115 | #ifndef __MWERKS__ |
116 | #include <stdlib.h> | 116 | #include <stdlib.h> |
117 | #endif | 117 | #endif |
118 | #include <stdio.h> | 118 | #include <stdio.h> |
119 | #include <stdlib.h> | 119 | #include <stdlib.h> |
120 | #include <ctype.h> | 120 | #include <ctype.h> |
121 | 121 | ||
122 | //#ifdef PALMTOPCENTER | 122 | //#ifdef PALMTOPCENTER |
123 | //#include <qpe/vobject_p.h> | 123 | //#include <qpe/vobject_p.h> |
124 | //#else | 124 | //#else |
125 | #include "vobject_p.h" | 125 | #include "vobject_p.h" |
126 | //#endif | 126 | //#endif |
127 | 127 | ||
128 | /**** Types, Constants ****/ | 128 | /**** Types, Constants ****/ |
129 | 129 | ||
130 | #define YYDEBUG 0/* 1 to compile in some debugging code */ | 130 | #define YYDEBUG 0/* 1 to compile in some debugging code */ |
131 | #define MAXTOKEN 256/* maximum token (line) length */ | 131 | #define MAXTOKEN 256/* maximum token (line) length */ |
132 | #define YYSTACKSIZE 100// ~unref ? | 132 | #define YYSTACKSIZE 100// ~unref ? |
133 | #define MAXLEVEL 10/* max # of nested objects parseable */ | 133 | #define MAXLEVEL 10/* max # of nested objects parseable */ |
134 | /* (includes outermost) */ | 134 | /* (includes outermost) */ |
135 | 135 | ||
136 | 136 | ||
137 | /**** Global Variables ****/ | 137 | /**** Global Variables ****/ |
138 | int mime_lineNum, mime_numErrors; /* yyerror() can use these */ | 138 | int mime_lineNum, mime_numErrors; /* yyerror() can use these */ |
139 | static VObject* vObjList; | 139 | static VObject* vObjList; |
140 | static VObject *curProp; | 140 | static VObject *curProp; |
141 | static VObject *curObj; | 141 | static VObject *curObj; |
142 | static VObject* ObjStack[MAXLEVEL]; | 142 | static VObject* ObjStack[MAXLEVEL]; |
143 | static int ObjStackTop; | 143 | static int ObjStackTop; |
144 | 144 | ||
145 | 145 | ||
146 | /* A helpful utility for the rest of the app. */ | 146 | /* A helpful utility for the rest of the app. */ |
147 | #if __CPLUSPLUS__ | 147 | #if __CPLUSPLUS__ |
148 | extern "C" { | 148 | extern "C" { |
149 | #endif | 149 | #endif |
150 | 150 | ||
151 | extern void yyerror(char *s); | 151 | extern void yyerror(char *s); |
152 | 152 | ||
153 | #if __CPLUSPLUS__ | 153 | #if __CPLUSPLUS__ |
154 | }; | 154 | }; |
155 | #endif | 155 | #endif |
156 | 156 | ||
157 | int yyparse(); | 157 | int yyparse(); |
158 | 158 | ||
159 | enum LexMode { | 159 | enum LexMode { |
160 | L_NORMAL, | 160 | L_NORMAL, |
161 | L_VCARD, | 161 | L_VCARD, |
162 | L_VCAL, | 162 | L_VCAL, |
163 | L_VEVENT, | 163 | L_VEVENT, |
164 | L_VTODO, | 164 | L_VTODO, |
165 | L_VALUES, | 165 | L_VALUES, |
166 | L_BASE64, | 166 | L_BASE64, |
167 | L_QUOTED_PRINTABLE | 167 | L_QUOTED_PRINTABLE |
168 | }; | 168 | }; |
169 | 169 | ||
170 | /**** Private Forward Declarations ****/ | 170 | /**** Private Forward Declarations ****/ |
171 | static int pushVObject(const char *prop); | 171 | static int pushVObject(const char *prop); |
172 | static VObject* popVObject(); | 172 | static VObject* popVObject(); |
173 | static void lexPopMode(int top); | 173 | static void lexPopMode(int top); |
174 | static int lexWithinMode(enum LexMode mode); | 174 | static int lexWithinMode(enum LexMode mode); |
175 | static void lexPushMode(enum LexMode mode); | 175 | static void lexPushMode(enum LexMode mode); |
176 | static void enterProps(const char *s); | 176 | static void enterProps(const char *s); |
177 | static void enterAttr(const char *s1, const char *s2); | 177 | static void enterAttr(const char *s1, const char *s2); |
178 | static void enterValues(const char *value); | 178 | static void enterValues(const char *value); |
179 | #define mime_error yyerror | 179 | #define mime_error yyerror |
180 | void mime_error(char *s); | 180 | void mime_error(char *s); |
181 | void mime_error_(char *s); | 181 | void mime_error_(char *s); |
182 | 182 | ||
183 | %} | 183 | %} |
184 | 184 | ||
185 | /***************************************************************************/ | 185 | /***************************************************************************/ |
186 | /*** The grammar ****/ | 186 | /*** The grammar ****/ |
187 | /***************************************************************************/ | 187 | /***************************************************************************/ |
188 | 188 | ||
189 | %union { | 189 | %union { |
190 | char *str; | 190 | char *str; |
191 | VObject *vobj; | 191 | VObject *vobj; |
192 | } | 192 | } |
193 | 193 | ||
194 | %token | 194 | %token |
195 | EQ COLON DOT SEMICOLON SPACE HTAB LINESEP NEWLINE | 195 | EQ COLON DOT SEMICOLON SPACE HTAB LINESEP NEWLINE |
196 | BEGIN_VCARD END_VCARD BEGIN_VCAL END_VCAL | 196 | BEGIN_VCARD END_VCARD BEGIN_VCAL END_VCAL |
197 | BEGIN_VEVENT END_VEVENT BEGIN_VTODO END_VTODO | 197 | BEGIN_VEVENT END_VEVENT BEGIN_VTODO END_VTODO |
198 | ID | 198 | ID |
199 | 199 | ||
200 | /* | 200 | /* |
201 | * NEWLINE is the token that would occur outside a vCard, | 201 | * NEWLINE is the token that would occur outside a vCard, |
202 | * while LINESEP is the token that would occur inside a vCard. | 202 | * while LINESEP is the token that would occur inside a vCard. |
203 | */ | 203 | */ |
204 | 204 | ||
205 | %token <str> | 205 | %token <str> |
206 | STRING ID | 206 | STRING ID |
207 | 207 | ||
208 | %type <str> name value | 208 | %type <str> name value |
209 | 209 | ||
210 | %type <vobj> vcard vcal vobject | 210 | %type <vobj> vcard vcal vobject |
211 | 211 | ||
212 | %start mime | 212 | %start mime |
213 | 213 | ||
214 | %% | 214 | %% |
215 | 215 | ||
216 | 216 | ||
217 | mime: vobjects | 217 | mime: vobjects |
218 | ; | 218 | ; |
219 | 219 | ||
220 | vobjects: vobjects vobject | 220 | vobjects: vobjects vobject |
221 | { addList(&vObjList, $2); curObj = 0; } | 221 | { addList(&vObjList, $2); curObj = 0; } |
222 | | vobject | 222 | | vobject |
223 | { addList(&vObjList, $1); curObj = 0; } | 223 | { addList(&vObjList, $1); curObj = 0; } |
224 | ; | 224 | ; |
225 | 225 | ||
226 | vobject: vcard | 226 | vobject: vcard |
227 | | vcal | 227 | | vcal |
228 | ; | 228 | ; |
229 | 229 | ||
230 | vcard: | 230 | vcard: |
231 | BEGIN_VCARD | 231 | BEGIN_VCARD |
232 | { | 232 | { |
233 | lexPushMode(L_VCARD); | 233 | lexPushMode(L_VCARD); |
234 | if (!pushVObject(VCCardProp)) YYERROR; | 234 | if (!pushVObject(VCCardProp)) YYERROR; |
235 | } | 235 | } |
236 | items END_VCARD | 236 | items END_VCARD |
237 | { | 237 | { |
238 | lexPopMode(0); | 238 | lexPopMode(0); |
239 | $$ = popVObject(); | 239 | $$ = popVObject(); |
240 | } | 240 | } |
241 | | BEGIN_VCARD | 241 | | BEGIN_VCARD |
242 | { | 242 | { |
243 | lexPushMode(L_VCARD); | 243 | lexPushMode(L_VCARD); |
244 | if (!pushVObject(VCCardProp)) YYERROR; | 244 | if (!pushVObject(VCCardProp)) YYERROR; |
245 | } | 245 | } |
246 | END_VCARD | 246 | END_VCARD |
247 | { | 247 | { |
248 | lexPopMode(0); | 248 | lexPopMode(0); |
249 | $$ = popVObject(); | 249 | $$ = popVObject(); |
250 | } | 250 | } |
251 | ; | 251 | ; |
252 | 252 | ||
253 | items: items item | 253 | items: items item |
254 | | item | 254 | | item |
255 | ; | 255 | ; |
256 | 256 | ||
257 | item: prop COLON | 257 | item: prop COLON |
258 | { | 258 | { |
259 | lexPushMode(L_VALUES); | 259 | lexPushMode(L_VALUES); |
260 | } | 260 | } |
261 | values LINESEP | 261 | values LINESEP |
262 | { | 262 | { |
263 | if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE)) | 263 | if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE)) |
264 | lexPopMode(0); | 264 | lexPopMode(0); |
265 | lexPopMode(0); | 265 | lexPopMode(0); |
266 | } | 266 | } |
267 | | error | 267 | | error |
268 | ; | 268 | ; |
269 | 269 | ||
270 | prop: name | 270 | prop: name |
271 | { | 271 | { |
272 | enterProps($1); | 272 | enterProps($1); |
273 | } | 273 | } |
274 | attr_params | 274 | attr_params |
275 | | name | 275 | | name |
276 | { | 276 | { |
277 | enterProps($1); | 277 | enterProps($1); |
278 | } | 278 | } |
279 | ; | 279 | ; |
280 | 280 | ||
281 | attr_params: attr_params attr_param | 281 | attr_params: attr_params attr_param |
282 | | attr_param | 282 | | attr_param |
283 | ; | 283 | ; |
284 | 284 | ||
285 | attr_param: SEMICOLON attr | 285 | attr_param: SEMICOLON attr |
286 | ; | 286 | ; |
287 | 287 | ||
288 | attr: name | 288 | attr: name |
289 | { | 289 | { |
290 | enterAttr($1,0); | 290 | enterAttr($1,0); |
291 | } | 291 | } |
292 | | name EQ name | 292 | | name EQ name |
293 | { | 293 | { |
294 | enterAttr($1,$3); | 294 | enterAttr($1,$3); |
295 | 295 | ||
296 | } | 296 | } |
297 | ; | 297 | ; |
298 | 298 | ||
299 | name: ID | 299 | name: ID |
300 | ; | 300 | ; |
301 | 301 | ||
302 | values: value SEMICOLON { enterValues($1); } values | 302 | values: value SEMICOLON { enterValues($1); } values |
303 | | value | 303 | | value |
304 | { enterValues($1); } | 304 | { enterValues($1); } |
305 | ; | 305 | ; |
306 | 306 | ||
307 | value: STRING | 307 | value: STRING |
308 | | | 308 | | |
309 | { $$ = 0; } | 309 | { $$ = 0; } |
310 | ; | 310 | ; |
311 | 311 | ||
312 | vcal: | 312 | vcal: |
313 | BEGIN_VCAL | 313 | BEGIN_VCAL |
314 | { if (!pushVObject(VCCalProp)) YYERROR; } | 314 | { if (!pushVObject(VCCalProp)) YYERROR; } |
315 | calitems | 315 | calitems |
316 | END_VCAL | 316 | END_VCAL |
317 | { $$ = popVObject(); } | 317 | { $$ = popVObject(); } |
318 | | BEGIN_VCAL | 318 | | BEGIN_VCAL |
319 | { if (!pushVObject(VCCalProp)) YYERROR; } | 319 | { if (!pushVObject(VCCalProp)) YYERROR; } |
320 | END_VCAL | 320 | END_VCAL |
321 | { $$ = popVObject(); } | 321 | { $$ = popVObject(); } |
322 | ; | 322 | ; |
323 | 323 | ||
324 | calitems: calitems calitem | 324 | calitems: calitems calitem |
325 | | calitem | 325 | | calitem |
326 | ; | 326 | ; |
327 | 327 | ||
328 | calitem: | 328 | calitem: |
329 | eventitem | 329 | eventitem |
330 | | todoitem | 330 | | todoitem |
331 | | items | 331 | | items |
332 | ; | 332 | ; |
333 | 333 | ||
334 | eventitem: | 334 | eventitem: |
335 | BEGIN_VEVENT | 335 | BEGIN_VEVENT |
336 | { | 336 | { |
337 | lexPushMode(L_VEVENT); | 337 | lexPushMode(L_VEVENT); |
338 | if (!pushVObject(VCEventProp)) YYERROR; | 338 | if (!pushVObject(VCEventProp)) YYERROR; |
339 | } | 339 | } |
340 | items | 340 | items |
341 | END_VEVENT | 341 | END_VEVENT |
342 | { | 342 | { |
343 | lexPopMode(0); | 343 | lexPopMode(0); |
344 | popVObject(); | 344 | popVObject(); |
345 | } | 345 | } |
346 | | BEGIN_VEVENT | 346 | | BEGIN_VEVENT |
347 | { | 347 | { |
348 | lexPushMode(L_VEVENT); | 348 | lexPushMode(L_VEVENT); |
349 | if (!pushVObject(VCEventProp)) YYERROR; | 349 | if (!pushVObject(VCEventProp)) YYERROR; |
350 | } | 350 | } |
351 | END_VEVENT | 351 | END_VEVENT |
352 | { | 352 | { |
353 | lexPopMode(0); | 353 | lexPopMode(0); |
354 | popVObject(); | 354 | popVObject(); |
355 | } | 355 | } |
356 | ; | 356 | ; |
357 | 357 | ||
358 | todoitem: | 358 | todoitem: |
359 | BEGIN_VTODO | 359 | BEGIN_VTODO |
360 | { | 360 | { |
361 | lexPushMode(L_VTODO); | 361 | lexPushMode(L_VTODO); |
362 | if (!pushVObject(VCTodoProp)) YYERROR; | 362 | if (!pushVObject(VCTodoProp)) YYERROR; |
363 | } | 363 | } |
364 | items | 364 | items |
365 | END_VTODO | 365 | END_VTODO |
366 | { | 366 | { |
367 | lexPopMode(0); | 367 | lexPopMode(0); |
368 | popVObject(); | 368 | popVObject(); |
369 | } | 369 | } |
370 | | BEGIN_VTODO | 370 | | BEGIN_VTODO |
371 | { | 371 | { |
372 | lexPushMode(L_VTODO); | 372 | lexPushMode(L_VTODO); |
373 | if (!pushVObject(VCTodoProp)) YYERROR; | 373 | if (!pushVObject(VCTodoProp)) YYERROR; |
374 | } | 374 | } |
375 | END_VTODO | 375 | END_VTODO |
376 | { | 376 | { |
377 | lexPopMode(0); | 377 | lexPopMode(0); |
378 | popVObject(); | 378 | popVObject(); |
379 | } | 379 | } |
380 | ; | 380 | ; |
381 | 381 | ||
382 | %% | 382 | %% |
383 | /*------------------------------------*/ | 383 | /*------------------------------------*/ |
384 | static int pushVObject(const char *prop) | 384 | static int pushVObject(const char *prop) |
385 | { | 385 | { |
386 | VObject *newObj; | 386 | VObject *newObj; |
387 | if (ObjStackTop == MAXLEVEL) | 387 | if (ObjStackTop == MAXLEVEL) |
388 | return FALSE; | 388 | return FALSE; |
389 | 389 | ||
390 | ObjStack[++ObjStackTop] = curObj; | 390 | ObjStack[++ObjStackTop] = curObj; |
391 | 391 | ||
392 | if (curObj) { | 392 | if (curObj) { |
393 | newObj = addProp(curObj,prop); | 393 | newObj = addProp(curObj,prop); |
394 | curObj = newObj; | 394 | curObj = newObj; |
395 | } | 395 | } |
396 | else | 396 | else |
397 | curObj = newVObject(prop); | 397 | curObj = newVObject(prop); |
398 | 398 | ||
399 | return TRUE; | 399 | return TRUE; |
400 | } | 400 | } |
401 | 401 | ||
402 | 402 | ||
403 | /*---------------------------------------*/ | 403 | /*---------------------------------------*/ |
404 | /* This pops the recently built vCard off the stack and returns it. */ | 404 | /* This pops the recently built vCard off the stack and returns it. */ |
405 | static VObject* popVObject() | 405 | static VObject* popVObject() |
406 | { | 406 | { |
407 | VObject *oldObj; | 407 | VObject *oldObj; |
408 | if (ObjStackTop < 0) { | 408 | if (ObjStackTop < 0) { |
409 | yyerror("pop on empty Object Stack\n"); | 409 | yyerror("pop on empty Object Stack\n"); |
410 | return 0; | 410 | return 0; |
411 | } | 411 | } |
412 | oldObj = curObj; | 412 | oldObj = curObj; |
413 | curObj = ObjStack[ObjStackTop--]; | 413 | curObj = ObjStack[ObjStackTop--]; |
414 | 414 | ||
415 | return oldObj; | 415 | return oldObj; |
416 | } | 416 | } |
417 | 417 | ||
418 | 418 | ||
419 | static void enterValues(const char *value) | 419 | static void enterValues(const char *value) |
420 | { | 420 | { |
421 | if (fieldedProp && *fieldedProp) { | 421 | if (fieldedProp && *fieldedProp) { |
422 | if (value) { | 422 | if (value) { |
423 | addPropValue(curProp,*fieldedProp,value); | 423 | addPropValue(curProp,*fieldedProp,value); |
424 | } | 424 | } |
425 | /* else this field is empty, advance to next field */ | 425 | /* else this field is empty, advance to next field */ |
426 | fieldedProp++; | 426 | fieldedProp++; |
427 | } | 427 | } |
428 | else { | 428 | else { |
429 | if (value) { | 429 | if (value) { |
430 | setVObjectStringZValue_(curProp,strdup( value )); | 430 | setVObjectStringZValue_(curProp,strdup( value )); |
431 | } | 431 | } |
432 | } | 432 | } |
433 | deleteStr(value); | 433 | deleteStr(value); |
434 | } | 434 | } |
435 | 435 | ||
436 | static void enterProps(const char *s) | 436 | static void enterProps(const char *s) |
437 | { | 437 | { |
438 | curProp = addGroup(curObj,s); | 438 | curProp = addGroup(curObj,s); |
439 | deleteStr(s); | 439 | deleteStr(s); |
440 | } | 440 | } |
441 | 441 | ||
442 | static void enterAttr(const char *s1, const char *s2) | 442 | static void enterAttr(const char *s1, const char *s2) |
443 | { | 443 | { |
444 | const char *p1, *p2; | 444 | const char *p1, *p2; |
445 | p1 = lookupProp_(s1); | 445 | p1 = lookupProp_(s1); |
446 | if (s2) { | 446 | if (s2) { |
447 | VObject *a; | 447 | VObject *a; |
448 | p2 = lookupProp_(s2); | 448 | p2 = lookupProp_(s2); |
449 | a = addProp(curProp,p1); | 449 | a = addProp(curProp,p1); |
450 | setVObjectStringZValue(a,p2); | 450 | setVObjectStringZValue(a,p2); |
451 | } | 451 | } |
452 | else | 452 | else |
453 | addProp(curProp,p1); | 453 | addProp(curProp,p1); |
454 | if (qstricmp(p1,VCBase64Prop) == 0 || (s2 && qstricmp(p2,VCBase64Prop)==0)) | 454 | if (qstricmp(p1,VCBase64Prop) == 0 || (s2 && qstricmp(p2,VCBase64Prop)==0)) |
455 | lexPushMode(L_BASE64); | 455 | lexPushMode(L_BASE64); |
456 | else if (qstricmp(p1,VCQuotedPrintableProp) == 0 | 456 | else if (qstricmp(p1,VCQuotedPrintableProp) == 0 |
457 | || (s2 && qstricmp(p2,VCQuotedPrintableProp)==0)) | 457 | || (s2 && qstricmp(p2,VCQuotedPrintableProp)==0)) |
458 | lexPushMode(L_QUOTED_PRINTABLE); | 458 | lexPushMode(L_QUOTED_PRINTABLE); |
459 | deleteStr(s1); deleteStr(s2); | 459 | deleteStr(s1); deleteStr(s2); |
460 | } | 460 | } |
461 | 461 | ||
462 | 462 | ||
463 | #define MAX_LEX_LOOKAHEAD_0 32 | 463 | #define MAX_LEX_LOOKAHEAD_0 32 |
464 | #define MAX_LEX_LOOKAHEAD 64 | 464 | #define MAX_LEX_LOOKAHEAD 64 |
465 | #define MAX_LEX_MODE_STACK_SIZE 10 | 465 | #define MAX_LEX_MODE_STACK_SIZE 10 |
466 | #define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop]) | 466 | #define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop]) |
467 | 467 | ||
468 | struct LexBuf { | 468 | struct LexBuf { |
469 | /* input */ | 469 | /* input */ |
470 | #ifdef INCLUDEMFC | 470 | #ifdef INCLUDEMFC |
471 | CFile *inputFile; | 471 | CFile *inputFile; |
472 | #else | 472 | #else |
473 | FILE *inputFile; | 473 | FILE *inputFile; |
474 | #endif | 474 | #endif |
475 | char *inputString; | 475 | char *inputString; |
476 | unsigned long curPos; | 476 | unsigned long curPos; |
477 | unsigned long inputLen; | 477 | unsigned long inputLen; |
478 | /* lookahead buffer */ | 478 | /* lookahead buffer */ |
479 | /* -- lookahead buffer is short instead of char so that EOF | 479 | /* -- lookahead buffer is short instead of char so that EOF |
480 | / can be represented correctly. | 480 | / can be represented correctly. |
481 | */ | 481 | */ |
482 | unsigned long len; | 482 | unsigned long len; |
483 | short buf[MAX_LEX_LOOKAHEAD]; | 483 | short buf[MAX_LEX_LOOKAHEAD]; |
484 | unsigned long getPtr; | 484 | unsigned long getPtr; |
485 | /* context stack */ | 485 | /* context stack */ |
486 | unsigned long lexModeStackTop; | 486 | unsigned long lexModeStackTop; |
487 | enum LexMode lexModeStack[MAX_LEX_MODE_STACK_SIZE]; | 487 | enum LexMode lexModeStack[MAX_LEX_MODE_STACK_SIZE]; |
488 | /* token buffer */ | 488 | /* token buffer */ |
489 | unsigned long maxToken; | 489 | unsigned long maxToken; |
490 | char *strs; | 490 | char *strs; |
491 | unsigned long strsLen; | 491 | unsigned long strsLen; |
492 | } lexBuf; | 492 | } lexBuf; |
493 | 493 | ||
494 | static void lexPushMode(enum LexMode mode) | 494 | static void lexPushMode(enum LexMode mode) |
495 | { | 495 | { |
496 | if (lexBuf.lexModeStackTop == (MAX_LEX_MODE_STACK_SIZE-1)) | 496 | if (lexBuf.lexModeStackTop == (MAX_LEX_MODE_STACK_SIZE-1)) |
497 | yyerror("lexical context stack overflow"); | 497 | yyerror("lexical context stack overflow"); |
498 | else { | 498 | else { |
499 | lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode; | 499 | lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode; |
500 | } | 500 | } |
501 | } | 501 | } |
502 | 502 | ||
503 | static void lexPopMode(int top) | 503 | static void lexPopMode(int top) |
504 | { | 504 | { |
505 | /* special case of pop for ease of error recovery -- this | 505 | /* special case of pop for ease of error recovery -- this |
506 | version will never underflow */ | 506 | version will never underflow */ |
507 | if (top) | 507 | if (top) |
508 | lexBuf.lexModeStackTop = 0; | 508 | lexBuf.lexModeStackTop = 0; |
509 | else | 509 | else |
510 | if (lexBuf.lexModeStackTop > 0) lexBuf.lexModeStackTop--; | 510 | if (lexBuf.lexModeStackTop > 0) lexBuf.lexModeStackTop--; |
511 | } | 511 | } |
512 | 512 | ||
513 | static int lexWithinMode(enum LexMode mode) { | 513 | static int lexWithinMode(enum LexMode mode) { |
514 | unsigned long i; | 514 | unsigned long i; |
515 | for (i=0;i<lexBuf.lexModeStackTop;i++) | 515 | for (i=0;i<lexBuf.lexModeStackTop;i++) |
516 | if (mode == lexBuf.lexModeStack[i]) return 1; | 516 | if (mode == lexBuf.lexModeStack[i]) return 1; |
517 | return 0; | 517 | return 0; |
518 | } | 518 | } |
519 | 519 | ||
520 | static char lexGetc_() | 520 | static int lexGetc_() |
521 | { | 521 | { |
522 | /* get next char from input, no buffering. */ | 522 | /* get next char from input, no buffering. */ |
523 | if (lexBuf.curPos == lexBuf.inputLen) | 523 | if (lexBuf.curPos == lexBuf.inputLen) |
524 | return EOF; | 524 | return EOF; |
525 | else if (lexBuf.inputString) | 525 | else if (lexBuf.inputString) |
526 | return *(lexBuf.inputString + lexBuf.curPos++); | 526 | return *(lexBuf.inputString + lexBuf.curPos++); |
527 | else { | 527 | else { |
528 | #ifdef INCLUDEMFC | 528 | #ifdef INCLUDEMFC |
529 | char result; | 529 | char result; |
530 | return lexBuf.inputFile->Read(&result, 1) == 1 ? result : EOF; | 530 | return lexBuf.inputFile->Read(&result, 1) == 1 ? result : EOF; |
531 | #else | 531 | #else |
532 | return fgetc(lexBuf.inputFile); | 532 | return fgetc(lexBuf.inputFile); |
533 | #endif | 533 | #endif |
534 | } | 534 | } |
535 | } | 535 | } |
536 | 536 | ||
537 | static int lexGeta() | 537 | static int lexGeta() |
538 | { | 538 | { |
539 | ++lexBuf.len; | 539 | ++lexBuf.len; |
540 | return (lexBuf.buf[lexBuf.getPtr] = lexGetc_()); | 540 | return (lexBuf.buf[lexBuf.getPtr] = lexGetc_()); |
541 | } | 541 | } |
542 | 542 | ||
543 | static int lexGeta_(int i) | 543 | static int lexGeta_(int i) |
544 | { | 544 | { |
545 | ++lexBuf.len; | 545 | ++lexBuf.len; |
546 | return (lexBuf.buf[(lexBuf.getPtr+i)%MAX_LEX_LOOKAHEAD] = lexGetc_()); | 546 | return (lexBuf.buf[(lexBuf.getPtr+i)%MAX_LEX_LOOKAHEAD] = lexGetc_()); |
547 | } | 547 | } |
548 | 548 | ||
549 | static void lexSkipLookahead() { | 549 | static void lexSkipLookahead() { |
550 | if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) { | 550 | if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) { |
551 | /* don't skip EOF. */ | 551 | /* don't skip EOF. */ |
552 | lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD; | 552 | lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD; |
553 | lexBuf.len--; | 553 | lexBuf.len--; |
554 | } | 554 | } |
555 | } | 555 | } |
556 | 556 | ||
557 | static int lexLookahead() { | 557 | static int lexLookahead() { |
558 | int c = (lexBuf.len)? | 558 | int c = (lexBuf.len)? |
559 | lexBuf.buf[lexBuf.getPtr]: | 559 | lexBuf.buf[lexBuf.getPtr]: |
560 | lexGeta(); | 560 | lexGeta(); |
561 | /* do the \r\n -> \n or \r -> \n translation here */ | 561 | /* do the \r\n -> \n or \r -> \n translation here */ |
562 | if (c == '\r') { | 562 | if (c == '\r') { |
563 | int a = (lexBuf.len>1)? | 563 | int a = (lexBuf.len>1)? |
564 | lexBuf.buf[(lexBuf.getPtr+1)%MAX_LEX_LOOKAHEAD]: | 564 | lexBuf.buf[(lexBuf.getPtr+1)%MAX_LEX_LOOKAHEAD]: |
565 | lexGeta_(1); | 565 | lexGeta_(1); |
566 | if (a == '\n') { | 566 | if (a == '\n') { |
567 | lexSkipLookahead(); | 567 | lexSkipLookahead(); |
568 | } | 568 | } |
569 | lexBuf.buf[lexBuf.getPtr] = c = '\n'; | 569 | lexBuf.buf[lexBuf.getPtr] = c = '\n'; |
570 | } | 570 | } |
571 | else if (c == '\n') { | 571 | else if (c == '\n') { |
572 | int a = (lexBuf.len>1)? | 572 | int a = (lexBuf.len>1)? |
573 | lexBuf.buf[lexBuf.getPtr+1]: | 573 | lexBuf.buf[lexBuf.getPtr+1]: |
574 | lexGeta_(1); | 574 | lexGeta_(1); |
575 | if (a == '\r') { | 575 | if (a == '\r') { |
576 | lexSkipLookahead(); | 576 | lexSkipLookahead(); |
577 | } | 577 | } |
578 | lexBuf.buf[lexBuf.getPtr] = '\n'; | 578 | lexBuf.buf[lexBuf.getPtr] = '\n'; |
579 | } | 579 | } |
580 | return c; | 580 | return c; |
581 | } | 581 | } |
582 | 582 | ||
583 | static int lexGetc() { | 583 | static int lexGetc() { |
584 | int c = lexLookahead(); | 584 | int c = lexLookahead(); |
585 | if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) { | 585 | if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) { |
586 | /* EOF will remain in lookahead buffer */ | 586 | /* EOF will remain in lookahead buffer */ |
587 | lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD; | 587 | lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD; |
588 | lexBuf.len--; | 588 | lexBuf.len--; |
589 | } | 589 | } |
590 | return c; | 590 | return c; |
591 | } | 591 | } |
592 | 592 | ||
593 | static void lexSkipLookaheadWord() { | 593 | static void lexSkipLookaheadWord() { |
594 | if (lexBuf.strsLen <= lexBuf.len) { | 594 | if (lexBuf.strsLen <= lexBuf.len) { |
595 | lexBuf.len -= lexBuf.strsLen; | 595 | lexBuf.len -= lexBuf.strsLen; |
596 | lexBuf.getPtr = (lexBuf.getPtr + lexBuf.strsLen) % MAX_LEX_LOOKAHEAD; | 596 | lexBuf.getPtr = (lexBuf.getPtr + lexBuf.strsLen) % MAX_LEX_LOOKAHEAD; |
597 | } | 597 | } |
598 | } | 598 | } |
599 | 599 | ||
600 | static void lexClearToken() | 600 | static void lexClearToken() |
601 | { | 601 | { |
602 | lexBuf.strsLen = 0; | 602 | lexBuf.strsLen = 0; |
603 | } | 603 | } |
604 | 604 | ||
605 | static void lexAppendc(int c) | 605 | static void lexAppendc(int c) |
606 | { | 606 | { |
607 | lexBuf.strs[lexBuf.strsLen] = c; | 607 | lexBuf.strs[lexBuf.strsLen] = c; |
608 | /* append up to zero termination */ | 608 | /* append up to zero termination */ |
609 | if (c == 0) return; | 609 | if (c == 0) return; |
610 | lexBuf.strsLen++; | 610 | lexBuf.strsLen++; |
611 | if (lexBuf.strsLen > lexBuf.maxToken) { | 611 | if (lexBuf.strsLen > lexBuf.maxToken) { |
612 | /* double the token string size */ | 612 | /* double the token string size */ |
613 | lexBuf.maxToken <<= 1; | 613 | lexBuf.maxToken <<= 1; |
614 | lexBuf.strs = (char*) realloc(lexBuf.strs,(size_t)lexBuf.maxToken); | 614 | lexBuf.strs = (char*) realloc(lexBuf.strs,(size_t)lexBuf.maxToken); |
615 | } | 615 | } |
616 | } | 616 | } |
617 | 617 | ||
618 | static char* lexStr() { | 618 | static char* lexStr() { |
619 | return dupStr(lexBuf.strs,(size_t)lexBuf.strsLen+1); | 619 | return dupStr(lexBuf.strs,(size_t)lexBuf.strsLen+1); |
620 | } | 620 | } |
621 | 621 | ||
622 | static void lexSkipWhite() { | 622 | static void lexSkipWhite() { |
623 | int c = lexLookahead(); | 623 | int c = lexLookahead(); |
624 | while (c == ' ' || c == '\t') { | 624 | while (c == ' ' || c == '\t') { |
625 | lexSkipLookahead(); | 625 | lexSkipLookahead(); |
626 | c = lexLookahead(); | 626 | c = lexLookahead(); |
627 | } | 627 | } |
628 | } | 628 | } |
629 | 629 | ||
630 | static char* lexGetWord() { | 630 | static char* lexGetWord() { |
631 | int c; | 631 | int c; |
632 | lexSkipWhite(); | 632 | lexSkipWhite(); |
633 | lexClearToken(); | 633 | lexClearToken(); |
634 | c = lexLookahead(); | 634 | c = lexLookahead(); |
635 | while (c != EOF && !strchr("\t\n ;:=",c)) { | 635 | while (c != EOF && !strchr("\t\n ;:=",c)) { |
636 | lexAppendc(c); | 636 | lexAppendc(c); |
637 | lexSkipLookahead(); | 637 | lexSkipLookahead(); |
638 | c = lexLookahead(); | 638 | c = lexLookahead(); |
639 | } | 639 | } |
640 | lexAppendc(0); | 640 | lexAppendc(0); |
641 | return lexStr(); | 641 | return lexStr(); |
642 | } | 642 | } |
643 | 643 | ||
644 | static void lexPushLookaheadc(int c) { | 644 | static void lexPushLookaheadc(int c) { |
645 | int putptr; | 645 | int putptr; |
646 | /* can't putback EOF, because it never leaves lookahead buffer */ | 646 | /* can't putback EOF, because it never leaves lookahead buffer */ |
647 | if (c == EOF) return; | 647 | if (c == EOF) return; |
648 | putptr = (int)lexBuf.getPtr - 1; | 648 | putptr = (int)lexBuf.getPtr - 1; |
649 | if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD; | 649 | if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD; |
650 | lexBuf.getPtr = putptr; | 650 | lexBuf.getPtr = putptr; |
651 | lexBuf.buf[putptr] = c; | 651 | lexBuf.buf[putptr] = c; |
652 | lexBuf.len += 1; | 652 | lexBuf.len += 1; |
653 | } | 653 | } |
654 | 654 | ||
655 | static char* lexLookaheadWord() { | 655 | static char* lexLookaheadWord() { |
656 | /* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0 | 656 | /* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0 |
657 | / and thing bigger than that will stop the lookahead and return 0; | 657 | / and thing bigger than that will stop the lookahead and return 0; |
658 | / leading white spaces are not recoverable. | 658 | / leading white spaces are not recoverable. |
659 | */ | 659 | */ |
660 | int c; | 660 | int c; |
661 | int len = 0; | 661 | int len = 0; |
662 | int curgetptr = 0; | 662 | int curgetptr = 0; |
663 | lexSkipWhite(); | 663 | lexSkipWhite(); |
664 | lexClearToken(); | 664 | lexClearToken(); |
665 | curgetptr = (int)lexBuf.getPtr;// remember! | 665 | curgetptr = (int)lexBuf.getPtr;// remember! |
666 | while (len < (MAX_LEX_LOOKAHEAD_0)) { | 666 | while (len < (MAX_LEX_LOOKAHEAD_0)) { |
667 | c = lexGetc(); | 667 | c = lexGetc(); |
668 | len++; | 668 | len++; |
669 | if (c == EOF || strchr("\t\n ;:=", c)) { | 669 | if (c == EOF || strchr("\t\n ;:=", c)) { |
670 | lexAppendc(0); | 670 | lexAppendc(0); |
671 | /* restore lookahead buf. */ | 671 | /* restore lookahead buf. */ |
672 | lexBuf.len += len; | 672 | lexBuf.len += len; |
673 | lexBuf.getPtr = curgetptr; | 673 | lexBuf.getPtr = curgetptr; |
674 | return lexStr(); | 674 | return lexStr(); |
675 | } | 675 | } |
676 | else | 676 | else |
677 | lexAppendc(c); | 677 | lexAppendc(c); |
678 | } | 678 | } |
679 | lexBuf.len += len;/* char that has been moved to lookahead buffer */ | 679 | lexBuf.len += len;/* char that has been moved to lookahead buffer */ |
680 | lexBuf.getPtr = curgetptr; | 680 | lexBuf.getPtr = curgetptr; |
681 | return 0; | 681 | return 0; |
682 | } | 682 | } |
683 | 683 | ||
684 | #ifdef _SUPPORT_LINE_FOLDING | 684 | #ifdef _SUPPORT_LINE_FOLDING |
685 | static void handleMoreRFC822LineBreak(int c) { | 685 | static void handleMoreRFC822LineBreak(int c) { |
686 | /* suport RFC 822 line break in cases like | 686 | /* suport RFC 822 line break in cases like |
687 | *ADR: foo; | 687 | *ADR: foo; |
688 | * morefoo; | 688 | * morefoo; |
689 | * more foo; | 689 | * more foo; |
690 | */ | 690 | */ |
691 | if (c == ';') { | 691 | if (c == ';') { |
692 | int a; | 692 | int a; |
693 | lexSkipLookahead(); | 693 | lexSkipLookahead(); |
694 | /* skip white spaces */ | 694 | /* skip white spaces */ |
695 | a = lexLookahead(); | 695 | a = lexLookahead(); |
696 | while (a == ' ' || a == '\t') { | 696 | while (a == ' ' || a == '\t') { |
697 | lexSkipLookahead(); | 697 | lexSkipLookahead(); |
698 | a = lexLookahead(); | 698 | a = lexLookahead(); |
699 | } | 699 | } |
700 | if (a == '\n') { | 700 | if (a == '\n') { |
701 | lexSkipLookahead(); | 701 | lexSkipLookahead(); |
702 | a = lexLookahead(); | 702 | a = lexLookahead(); |
703 | if (a == ' ' || a == '\t') { | 703 | if (a == ' ' || a == '\t') { |
704 | /* continuation, throw away all the \n and spaces read so | 704 | /* continuation, throw away all the \n and spaces read so |
705 | * far | 705 | * far |
706 | */ | 706 | */ |
707 | lexSkipWhite(); | 707 | lexSkipWhite(); |
708 | lexPushLookaheadc(';'); | 708 | lexPushLookaheadc(';'); |
709 | } | 709 | } |
710 | else { | 710 | else { |
711 | lexPushLookaheadc('\n'); | 711 | lexPushLookaheadc('\n'); |
712 | lexPushLookaheadc(';'); | 712 | lexPushLookaheadc(';'); |
713 | } | 713 | } |
714 | } | 714 | } |
715 | else { | 715 | else { |
716 | lexPushLookaheadc(';'); | 716 | lexPushLookaheadc(';'); |
717 | } | 717 | } |
718 | } | 718 | } |
719 | } | 719 | } |
720 | 720 | ||
721 | static char* lexGet1Value() { | 721 | static char* lexGet1Value() { |
722 | int c; | 722 | int c; |
723 | lexSkipWhite(); | 723 | lexSkipWhite(); |
724 | c = lexLookahead(); | 724 | c = lexLookahead(); |
725 | lexClearToken(); | 725 | lexClearToken(); |
726 | while (c != EOF && c != ';') { | 726 | while (c != EOF && c != ';') { |
727 | if (c == '\\' ) { | 727 | if (c == '\\' ) { |
728 | int a; | 728 | int a; |
729 | lexSkipLookahead(); | 729 | lexSkipLookahead(); |
730 | a = lexLookahead(); | 730 | a = lexLookahead(); |
731 | if ( a != ';' ) { | 731 | if ( a != ';' ) { |
732 | lexAppendc('\\'); | 732 | lexAppendc('\\'); |
733 | } else { | 733 | } else { |
734 | lexAppendc( ';' ); | 734 | lexAppendc( ';' ); |
735 | lexSkipLookahead(); | 735 | lexSkipLookahead(); |
736 | } | 736 | } |
737 | } else if (c == '\n') { | 737 | } else if (c == '\n') { |
738 | int a; | 738 | int a; |
739 | lexSkipLookahead(); | 739 | lexSkipLookahead(); |
740 | a = lexLookahead(); | 740 | a = lexLookahead(); |
741 | if (a == ' ' || a == '\t') { | 741 | if (a == ' ' || a == '\t') { |
742 | lexAppendc(' '); | 742 | lexAppendc(' '); |
743 | lexSkipLookahead(); | 743 | lexSkipLookahead(); |
744 | } | 744 | } |
745 | else { | 745 | else { |
746 | lexPushLookaheadc('\n'); | 746 | lexPushLookaheadc('\n'); |
747 | break; | 747 | break; |
748 | } | 748 | } |
749 | } | 749 | } |
750 | else { | 750 | else { |
751 | lexAppendc(c); | 751 | lexAppendc(c); |
752 | lexSkipLookahead(); | 752 | lexSkipLookahead(); |
753 | } | 753 | } |
754 | c = lexLookahead(); | 754 | c = lexLookahead(); |
755 | } | 755 | } |
756 | lexAppendc(0); | 756 | lexAppendc(0); |
757 | handleMoreRFC822LineBreak(c); | 757 | handleMoreRFC822LineBreak(c); |
758 | return c==EOF?0:lexStr(); | 758 | return c==EOF?0:lexStr(); |
759 | } | 759 | } |
760 | #endif | 760 | #endif |
761 | 761 | ||
762 | static int match_begin_name(int end) { | 762 | static int match_begin_name(int end) { |
763 | char *n = lexLookaheadWord(); | 763 | char *n = lexLookaheadWord(); |
764 | int token = ID; | 764 | int token = ID; |
765 | if (n) { | 765 | if (n) { |
766 | if (!qstricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD; | 766 | if (!qstricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD; |
767 | else if (!qstricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL; | 767 | else if (!qstricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL; |
768 | else if (!qstricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT; | 768 | else if (!qstricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT; |
769 | else if (!qstricmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO; | 769 | else if (!qstricmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO; |
770 | deleteStr(n); | 770 | deleteStr(n); |
771 | return token; | 771 | return token; |
772 | } | 772 | } |
773 | return 0; | 773 | return 0; |
774 | } | 774 | } |
775 | 775 | ||
776 | 776 | ||
777 | #ifdef INCLUDEMFC | 777 | #ifdef INCLUDEMFC |
778 | void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile) | 778 | void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile) |
779 | #else | 779 | #else |
780 | void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile) | 780 | void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile) |
781 | #endif | 781 | #endif |
782 | { | 782 | { |
783 | // initialize lex mode stack | 783 | // initialize lex mode stack |
784 | lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL; | 784 | lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL; |
785 | 785 | ||
786 | // iniatialize lex buffer. | 786 | // iniatialize lex buffer. |
787 | lexBuf.inputString = (char*) inputstring; | 787 | lexBuf.inputString = (char*) inputstring; |
788 | lexBuf.inputLen = inputlen; | 788 | lexBuf.inputLen = inputlen; |
789 | lexBuf.curPos = 0; | 789 | lexBuf.curPos = 0; |
790 | lexBuf.inputFile = inputfile; | 790 | lexBuf.inputFile = inputfile; |
791 | 791 | ||
792 | lexBuf.len = 0; | 792 | lexBuf.len = 0; |
793 | lexBuf.getPtr = 0; | 793 | lexBuf.getPtr = 0; |
794 | 794 | ||
795 | lexBuf.maxToken = MAXTOKEN; | 795 | lexBuf.maxToken = MAXTOKEN; |
796 | lexBuf.strs = (char*)malloc(MAXTOKEN); | 796 | lexBuf.strs = (char*)malloc(MAXTOKEN); |
797 | lexBuf.strsLen = 0; | 797 | lexBuf.strsLen = 0; |
798 | 798 | ||
799 | } | 799 | } |
800 | 800 | ||
801 | static void finiLex() { | 801 | static void finiLex() { |
802 | free(lexBuf.strs); | 802 | free(lexBuf.strs); |
803 | } | 803 | } |
804 | 804 | ||
805 | 805 | ||
806 | /*-----------------------------------*/ | 806 | /*-----------------------------------*/ |
807 | /* This parses and converts the base64 format for binary encoding into | 807 | /* This parses and converts the base64 format for binary encoding into |
808 | * a decoded buffer (allocated with new). See RFC 1521. | 808 | * a decoded buffer (allocated with new). See RFC 1521. |
809 | */ | 809 | */ |
810 | static char * lexGetDataFromBase64() | 810 | static char * lexGetDataFromBase64() |
811 | { | 811 | { |
812 | unsigned long bytesLen = 0, bytesMax = 0; | 812 | unsigned long bytesLen = 0, bytesMax = 0; |
813 | int quadIx = 0, pad = 0; | 813 | int quadIx = 0, pad = 0; |
814 | unsigned long trip = 0; | 814 | unsigned long trip = 0; |
815 | unsigned char b; | 815 | unsigned char b; |
816 | int c; | 816 | int c; |
817 | unsigned char *bytes = NULL; | 817 | unsigned char *bytes = NULL; |
818 | unsigned char *oldBytes = NULL; | 818 | unsigned char *oldBytes = NULL; |
819 | 819 | ||
820 | DBG_(("db: lexGetDataFromBase64\n")); | 820 | DBG_(("db: lexGetDataFromBase64\n")); |
821 | while (1) { | 821 | while (1) { |
822 | c = lexGetc(); | 822 | c = lexGetc(); |
823 | if (c == '\n') { | 823 | if (c == '\n') { |
824 | ++mime_lineNum; | 824 | ++mime_lineNum; |
825 | if (lexLookahead() == '\n') { | 825 | if (lexLookahead() == '\n') { |
826 | /* a '\n' character by itself means end of data */ | 826 | /* a '\n' character by itself means end of data */ |
827 | break; | 827 | break; |
828 | } | 828 | } |
829 | else continue; /* ignore '\n' */ | 829 | else continue; /* ignore '\n' */ |
830 | } | 830 | } |
831 | else { | 831 | else { |
832 | if ((c >= 'A') && (c <= 'Z')) | 832 | if ((c >= 'A') && (c <= 'Z')) |
833 | b = (unsigned char)(c - 'A'); | 833 | b = (unsigned char)(c - 'A'); |
834 | else if ((c >= 'a') && (c <= 'z')) | 834 | else if ((c >= 'a') && (c <= 'z')) |
835 | b = (unsigned char)(c - 'a') + 26; | 835 | b = (unsigned char)(c - 'a') + 26; |
836 | else if ((c >= '0') && (c <= '9')) | 836 | else if ((c >= '0') && (c <= '9')) |
837 | b = (unsigned char)(c - '0') + 52; | 837 | b = (unsigned char)(c - '0') + 52; |
838 | else if (c == '+') | 838 | else if (c == '+') |
839 | b = 62; | 839 | b = 62; |
840 | else if (c == '/') | 840 | else if (c == '/') |
841 | b = 63; | 841 | b = 63; |
842 | else if (c == '=') { | 842 | else if (c == '=') { |
843 | b = 0; | 843 | b = 0; |
844 | pad++; | 844 | pad++; |
845 | } else if ((c == ' ') || (c == '\t')) { | 845 | } else if ((c == ' ') || (c == '\t')) { |
846 | continue; | 846 | continue; |
847 | } else { /* error condition */ | 847 | } else { /* error condition */ |
848 | if (bytes) free(bytes); | 848 | if (bytes) free(bytes); |
849 | else if (oldBytes) free(oldBytes); | 849 | else if (oldBytes) free(oldBytes); |
850 | // error recovery: skip until 2 adjacent newlines. | 850 | // error recovery: skip until 2 adjacent newlines. |
851 | DBG_(("db: invalid character 0x%x '%c'\n", c,c)); | 851 | DBG_(("db: invalid character 0x%x '%c'\n", c,c)); |
852 | if (c != EOF) { | 852 | if (c != EOF) { |
853 | c = lexGetc(); | 853 | c = lexGetc(); |
854 | while (c != EOF) { | 854 | while (c != EOF) { |
855 | if (c == '\n' && lexLookahead() == '\n') { | 855 | if (c == '\n' && lexLookahead() == '\n') { |
856 | ++mime_lineNum; | 856 | ++mime_lineNum; |
857 | break; | 857 | break; |
858 | } | 858 | } |
859 | c = lexGetc(); | 859 | c = lexGetc(); |
860 | } | 860 | } |
861 | } | 861 | } |
862 | return NULL; | 862 | return NULL; |
863 | } | 863 | } |
864 | trip = (trip << 6) | b; | 864 | trip = (trip << 6) | b; |
865 | if (++quadIx == 4) { | 865 | if (++quadIx == 4) { |
866 | unsigned char outBytes[3]; | 866 | unsigned char outBytes[3]; |
867 | int numOut; | 867 | int numOut; |
868 | int i; | 868 | int i; |
869 | for (i = 0; i < 3; i++) { | 869 | for (i = 0; i < 3; i++) { |
870 | outBytes[2-i] = (unsigned char)(trip & 0xFF); | 870 | outBytes[2-i] = (unsigned char)(trip & 0xFF); |
871 | trip >>= 8; | 871 | trip >>= 8; |
872 | } | 872 | } |
873 | numOut = 3 - pad; | 873 | numOut = 3 - pad; |
874 | if (bytesLen + numOut > bytesMax) { | 874 | if (bytesLen + numOut > bytesMax) { |
875 | if (!bytes) { | 875 | if (!bytes) { |
876 | bytesMax = 1024; | 876 | bytesMax = 1024; |
877 | bytes = (unsigned char*)malloc((size_t)bytesMax); | 877 | bytes = (unsigned char*)malloc((size_t)bytesMax); |
878 | } | 878 | } |
879 | else { | 879 | else { |
880 | bytesMax <<= 2; | 880 | bytesMax <<= 2; |
881 | oldBytes = bytes; | 881 | oldBytes = bytes; |
882 | bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax); | 882 | bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax); |
883 | } | 883 | } |
884 | if (bytes == 0) { | 884 | if (bytes == 0) { |
885 | mime_error("out of memory while processing BASE64 data\n"); | 885 | mime_error("out of memory while processing BASE64 data\n"); |
886 | } | 886 | } |
887 | } | 887 | } |
888 | if (bytes) { | 888 | if (bytes) { |
889 | memcpy(bytes + bytesLen, outBytes, numOut); | 889 | memcpy(bytes + bytesLen, outBytes, numOut); |
890 | bytesLen += numOut; | 890 | bytesLen += numOut; |
891 | } | 891 | } |
892 | trip = 0; | 892 | trip = 0; |
893 | quadIx = 0; | 893 | quadIx = 0; |
894 | } | 894 | } |
895 | } | 895 | } |
896 | } /* while */ | 896 | } /* while */ |
897 | DBG_(("db: bytesLen = %d\n", bytesLen)); | 897 | DBG_(("db: bytesLen = %d\n", bytesLen)); |
898 | /* kludge: all this won't be necessary if we have tree form | 898 | /* kludge: all this won't be necessary if we have tree form |
899 | representation */ | 899 | representation */ |
900 | if (bytes) { | 900 | if (bytes) { |
901 | setValueWithSize(curProp,bytes,(unsigned int)bytesLen); | 901 | setValueWithSize(curProp,bytes,(unsigned int)bytesLen); |
902 | free(bytes); | 902 | free(bytes); |
903 | } | 903 | } |
904 | else if (oldBytes) { | 904 | else if (oldBytes) { |
905 | setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen); | 905 | setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen); |
906 | free(oldBytes); | 906 | free(oldBytes); |
907 | } | 907 | } |
908 | return 0; | 908 | return 0; |
909 | } | 909 | } |
910 | 910 | ||
911 | static int match_begin_end_name(int end) { | 911 | static int match_begin_end_name(int end) { |
912 | int token; | 912 | int token; |
913 | lexSkipWhite(); | 913 | lexSkipWhite(); |
914 | if (lexLookahead() != ':') return ID; | 914 | if (lexLookahead() != ':') return ID; |
915 | lexSkipLookahead(); | 915 | lexSkipLookahead(); |
916 | lexSkipWhite(); | 916 | lexSkipWhite(); |
917 | token = match_begin_name(end); | 917 | token = match_begin_name(end); |
918 | if (token == ID) { | 918 | if (token == ID) { |
919 | lexPushLookaheadc(':'); | 919 | lexPushLookaheadc(':'); |
920 | DBG_(("db: ID '%s'\n", yylval.str)); | 920 | DBG_(("db: ID '%s'\n", yylval.str)); |
921 | return ID; | 921 | return ID; |
922 | } | 922 | } |
923 | else if (token != 0) { | 923 | else if (token != 0) { |
924 | lexSkipLookaheadWord(); | 924 | lexSkipLookaheadWord(); |
925 | deleteStr(yylval.str); | 925 | deleteStr(yylval.str); |
926 | DBG_(("db: begin/end %d\n", token)); | 926 | DBG_(("db: begin/end %d\n", token)); |
927 | return token; | 927 | return token; |
928 | } | 928 | } |
929 | return 0; | 929 | return 0; |
930 | } | 930 | } |
931 | 931 | ||
932 | static char* lexGetQuotedPrintable() | 932 | static char* lexGetQuotedPrintable() |
933 | { | 933 | { |
934 | char cur; | 934 | int c; |
935 | 935 | lexSkipWhite(); | |
936 | lexClearToken(); | 936 | c = lexLookahead(); |
937 | do { | 937 | lexClearToken(); |
938 | cur = lexGetc(); | 938 | |
939 | switch (cur) { | 939 | while (c != EOF && c != ';') { |
940 | case '=': { | 940 | if (c == '\n') { |
941 | int c = 0; | 941 | // break, leave '\n' on remaining chars. |
942 | int next[2]; | 942 | break; |
943 | int i; | 943 | } else if (c == '=') { |
944 | for (i = 0; i < 2; i++) { | 944 | int cur = 0; |
945 | next[i] = lexGetc(); | 945 | int next; |
946 | if (next[i] >= '0' && next[i] <= '9') | 946 | |
947 | c = c * 16 + next[i] - '0'; | 947 | lexSkipLookahead(); // skip '=' |
948 | else if (next[i] >= 'A' && next[i] <= 'F') | 948 | next = lexLookahead(); |
949 | c = c * 16 + next[i] - 'A' + 10; | 949 | |
950 | else | 950 | if (next == '\n') { |
951 | break; | 951 | // skip and only skip the \n |
952 | } | 952 | lexSkipLookahead(); |
953 | if (i == 0) { | 953 | c = lexLookahead(); |
954 | /* single '=' follow by LINESEP is continuation sign? */ | 954 | ++mime_lineNum; // aid in error reporting |
955 | if (next[0] == '\n') { | 955 | continue; |
956 | ++mime_lineNum; | 956 | } else if (next >= '0' && next <= '9') { |
957 | } | 957 | cur = next - '0'; |
958 | else { | 958 | } else if (next >= 'A' && next <= 'F') { |
959 | lexPushLookaheadc('='); | 959 | cur = next - 'A' + 10; |
960 | goto EndString; | 960 | } else { |
961 | } | 961 | // we have been sent buggy stuff. doesn't matter |
962 | } | 962 | // what we do so long as we keep going. |
963 | else if (i == 1) { | 963 | // should probably spit an error here |
964 | lexPushLookaheadc(next[1]); | 964 | c = lexLookahead(); |
965 | lexPushLookaheadc(next[0]); | 965 | continue; |
966 | lexAppendc('='); | 966 | } |
967 | } else { | 967 | |
968 | lexAppendc(c); | 968 | lexSkipLookahead(); // skip A-Z0-9 |
969 | } | 969 | next = lexLookahead(); |
970 | break; | 970 | |
971 | } /* '=' */ | 971 | cur = cur * 16; |
972 | case '\n': { | 972 | // this time really just expecting 0-9A-F |
973 | lexPushLookaheadc('\n'); | 973 | if (next >= '0' && next <= '9') { |
974 | goto EndString; | 974 | cur += next - '0'; |
975 | } | 975 | } else if (next >= 'A' && next <= 'F') { |
976 | case (char)EOF: | 976 | cur += next - 'A' + 10; |
977 | break; | 977 | } else { |
978 | default: | 978 | // we have been sent buggy stuff. doesn't matter |
979 | lexAppendc(cur); | 979 | // what we do so long as we keep going. |
980 | break; | 980 | // should probably spit an error here |
981 | } /* switch */ | 981 | c = lexLookahead(); |
982 | } while (cur != (char)EOF); | 982 | continue; |
983 | 983 | } | |
984 | EndString: | 984 | |
985 | lexAppendc(0); | 985 | // got a valid escaped =. append it. |
986 | return lexStr(); | 986 | lexSkipLookahead(); // skip second 0-9A-F |
987 | } /* LexQuotedPrintable */ | 987 | lexAppendc(cur); |
988 | 988 | } else { | |
989 | static int yylex() { | 989 | lexSkipLookahead(); // skip whatever we just read. |
990 | 990 | lexAppendc(c); // and append it. | |
991 | int lexmode = LEXMODE(); | 991 | } |
992 | if (lexmode == L_VALUES) { | 992 | c = lexLookahead(); |
993 | int c = lexGetc(); | 993 | } |
994 | if (c == ';') { | 994 | lexAppendc(0); |
995 | DBG_(("db: SEMICOLON\n")); | 995 | return c==EOF?0:lexStr(); |
996 | lexPushLookaheadc(c); | 996 | } |
997 | handleMoreRFC822LineBreak(c); | 997 | |
998 | lexSkipLookahead(); | 998 | static int yylex() { |
999 | return SEMICOLON; | 999 | |
1000 | } | 1000 | int lexmode = LEXMODE(); |
1001 | else if (strchr("\n",c)) { | 1001 | if (lexmode == L_VALUES) { |
1002 | ++mime_lineNum; | 1002 | int c = lexGetc(); |
1003 | /* consume all line separator(s) adjacent to each other */ | 1003 | if (c == ';') { |
1004 | c = lexLookahead(); | 1004 | DBG_(("db: SEMICOLON\n")); |
1005 | while (strchr("\n",c)) { | 1005 | lexPushLookaheadc(c); |
1006 | lexSkipLookahead(); | 1006 | handleMoreRFC822LineBreak(c); |
1007 | c = lexLookahead(); | 1007 | lexSkipLookahead(); |
1008 | ++mime_lineNum; | 1008 | return SEMICOLON; |
1009 | } | 1009 | } |
1010 | DBG_(("db: LINESEP\n")); | 1010 | else if (strchr("\n",c)) { |
1011 | return LINESEP; | 1011 | ++mime_lineNum; |
1012 | } | 1012 | /* consume all line separator(s) adjacent to each other */ |
1013 | else { | 1013 | c = lexLookahead(); |
1014 | char *p = 0; | 1014 | while (strchr("\n",c)) { |
1015 | lexPushLookaheadc(c); | 1015 | lexSkipLookahead(); |
1016 | if (lexWithinMode(L_BASE64)) { | 1016 | c = lexLookahead(); |
1017 | /* get each char and convert to bin on the fly... */ | 1017 | ++mime_lineNum; |
1018 | p = lexGetDataFromBase64(); | 1018 | } |
1019 | yylval.str = p; | 1019 | DBG_(("db: LINESEP\n")); |
1020 | return STRING; | 1020 | return LINESEP; |
1021 | } | 1021 | } |
1022 | else if (lexWithinMode(L_QUOTED_PRINTABLE)) { | 1022 | else { |
1023 | p = lexGetQuotedPrintable(); | 1023 | char *p = 0; |
1024 | } | 1024 | lexPushLookaheadc(c); |
1025 | else { | 1025 | if (lexWithinMode(L_BASE64)) { |
1026 | #ifdef _SUPPORT_LINE_FOLDING | 1026 | /* get each char and convert to bin on the fly... */ |
1027 | p = lexGet1Value(); | 1027 | p = lexGetDataFromBase64(); |
1028 | #else | 1028 | yylval.str = p; |
1029 | p = lexGetStrUntil(";\n"); | 1029 | return STRING; |
1030 | #endif | 1030 | } |
1031 | } | 1031 | else if (lexWithinMode(L_QUOTED_PRINTABLE)) { |
1032 | if (p) { | 1032 | p = lexGetQuotedPrintable(); |
1033 | DBG_(("db: STRING: '%s'\n", p)); | 1033 | } |
1034 | yylval.str = p; | 1034 | else { |
1035 | return STRING; | 1035 | #ifdef _SUPPORT_LINE_FOLDING |
1036 | } | 1036 | p = lexGet1Value(); |
1037 | else return 0; | 1037 | #else |
1038 | } | 1038 | p = lexGetStrUntil(";\n"); |
1039 | } | 1039 | #endif |
1040 | else { | 1040 | } |
1041 | /* normal mode */ | 1041 | if (p) { |
1042 | while (1) { | 1042 | DBG_(("db: STRING: '%s'\n", p)); |
1043 | int c = lexGetc(); | 1043 | yylval.str = p; |
1044 | switch(c) { | 1044 | return STRING; |
1045 | case ':': { | 1045 | } |
1046 | /* consume all line separator(s) adjacent to each other */ | 1046 | else return 0; |
1047 | /* ignoring linesep immediately after colon. */ | 1047 | } |
1048 | c = lexLookahead(); | 1048 | } |
1049 | while (strchr("\n",c)) { | 1049 | else { |
1050 | lexSkipLookahead(); | 1050 | /* normal mode */ |
1051 | c = lexLookahead(); | 1051 | while (1) { |
1052 | ++mime_lineNum; | 1052 | int c = lexGetc(); |
1053 | } | 1053 | switch(c) { |
1054 | DBG_(("db: COLON\n")); | 1054 | case ':': { |
1055 | return COLON; | 1055 | /* consume all line separator(s) adjacent to each other */ |
1056 | } | 1056 | /* ignoring linesep immediately after colon. */ |
1057 | case ';': | 1057 | c = lexLookahead(); |
1058 | DBG_(("db: SEMICOLON\n")); | 1058 | while (strchr("\n",c)) { |
1059 | return SEMICOLON; | 1059 | lexSkipLookahead(); |
1060 | case '=': | 1060 | c = lexLookahead(); |
1061 | DBG_(("db: EQ\n")); | 1061 | ++mime_lineNum; |
1062 | return EQ; | 1062 | } |
1063 | /* ignore whitespace in this mode */ | 1063 | DBG_(("db: COLON\n")); |
1064 | case '\t': | 1064 | return COLON; |
1065 | case ' ': continue; | 1065 | } |
1066 | case '\n': { | 1066 | case ';': |
1067 | ++mime_lineNum; | 1067 | DBG_(("db: SEMICOLON\n")); |
1068 | continue; | 1068 | return SEMICOLON; |
1069 | } | 1069 | case '=': |
1070 | case EOF: return 0; | 1070 | DBG_(("db: EQ\n")); |
1071 | break; | 1071 | return EQ; |
1072 | default: { | 1072 | /* ignore whitespace in this mode */ |
1073 | lexPushLookaheadc(c); | 1073 | case '\t': |
1074 | if (isalnum(c)) { | 1074 | case ' ': continue; |
1075 | char *t = lexGetWord(); | 1075 | case '\n': { |
1076 | yylval.str = t; | 1076 | ++mime_lineNum; |
1077 | if (!qstricmp(t, "begin")) { | 1077 | continue; |
1078 | return match_begin_end_name(0); | 1078 | } |
1079 | } | 1079 | case EOF: return 0; |
1080 | else if (!qstricmp(t,"end")) { | 1080 | break; |
1081 | return match_begin_end_name(1); | 1081 | default: { |
1082 | } | 1082 | lexPushLookaheadc(c); |
1083 | else { | 1083 | if (isalnum(c)) { |
1084 | DBG_(("db: ID '%s'\n", t)); | 1084 | char *t = lexGetWord(); |
1085 | return ID; | 1085 | yylval.str = t; |
1086 | } | 1086 | if (!qstricmp(t, "begin")) { |
1087 | } | 1087 | return match_begin_end_name(0); |
1088 | else { | 1088 | } |
1089 | /* unknow token */ | 1089 | else if (!qstricmp(t,"end")) { |
1090 | return 0; | 1090 | return match_begin_end_name(1); |
1091 | } | 1091 | } |
1092 | break; | 1092 | else { |
1093 | } | 1093 | DBG_(("db: ID '%s'\n", t)); |
1094 | } | 1094 | return ID; |
1095 | } | 1095 | } |
1096 | } | 1096 | } |
1097 | return 0; | 1097 | else { |
1098 | } | 1098 | /* unknow token */ |
1099 | 1099 | return 0; | |
1100 | 1100 | } | |
1101 | /***************************************************************************/ | 1101 | break; |
1102 | /*** Public Functions ****/ | 1102 | } |
1103 | /***************************************************************************/ | 1103 | } |
1104 | 1104 | } | |
1105 | static VObject* Parse_MIMEHelper() | 1105 | } |
1106 | { | 1106 | return 0; |
1107 | ObjStackTop = -1; | 1107 | } |
1108 | mime_numErrors = 0; | 1108 | |
1109 | mime_lineNum = 1; | 1109 | |
1110 | vObjList = 0; | 1110 | /***************************************************************************/ |
1111 | curObj = 0; | 1111 | /*** Public Functions ****/ |
1112 | 1112 | /***************************************************************************/ | |
1113 | if (yyparse() != 0) | 1113 | |
1114 | return 0; | 1114 | static VObject* Parse_MIMEHelper() |
1115 | 1115 | { | |
1116 | finiLex(); | 1116 | ObjStackTop = -1; |
1117 | return vObjList; | 1117 | mime_numErrors = 0; |
1118 | } | 1118 | mime_lineNum = 1; |
1119 | 1119 | vObjList = 0; | |
1120 | /*--------------------------------------------*/ | 1120 | curObj = 0; |
1121 | DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len) | 1121 | |
1122 | { | 1122 | if (yyparse() != 0) |
1123 | initLex(input, len, 0); | 1123 | return 0; |
1124 | return Parse_MIMEHelper(); | 1124 | |
1125 | } | 1125 | finiLex(); |
1126 | 1126 | return vObjList; | |
1127 | 1127 | } | |
1128 | #if INCLUDEMFC | 1128 | |
1129 | 1129 | /*--------------------------------------------*/ | |
1130 | DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file) | 1130 | DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len) |
1131 | { | 1131 | { |
1132 | unsigned long startPos; | 1132 | initLex(input, len, 0); |
1133 | VObject *result; | 1133 | return Parse_MIMEHelper(); |
1134 | 1134 | } | |
1135 | initLex(0,-1,file); | 1135 | |
1136 | startPos = file->GetPosition(); | 1136 | |
1137 | if (!(result = Parse_MIMEHelper())) | 1137 | #if INCLUDEMFC |
1138 | file->Seek(startPos, CFile::begin); | 1138 | |
1139 | return result; | 1139 | DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file) |
1140 | } | 1140 | { |
1141 | 1141 | unsigned long startPos; | |
1142 | #else | 1142 | VObject *result; |
1143 | 1143 | ||
1144 | VObject* Parse_MIME_FromFile(FILE *file) | 1144 | initLex(0,-1,file); |
1145 | { | 1145 | startPos = file->GetPosition(); |
1146 | VObject *result; | 1146 | if (!(result = Parse_MIMEHelper())) |
1147 | long startPos; | 1147 | file->Seek(startPos, CFile::begin); |
1148 | 1148 | return result; | |
1149 | initLex(0,(unsigned long)-1,file); | 1149 | } |
1150 | startPos = ftell(file); | 1150 | |
1151 | if (!(result = Parse_MIMEHelper())) { | 1151 | #else |
1152 | fseek(file,startPos,SEEK_SET); | 1152 | |
1153 | } | 1153 | VObject* Parse_MIME_FromFile(FILE *file) |
1154 | return result; | 1154 | { |
1155 | } | 1155 | VObject *result; |
1156 | 1156 | long startPos; | |
1157 | DLLEXPORT(VObject*) Parse_MIME_FromFileName(char *fname) | 1157 | |
1158 | { | 1158 | initLex(0,(unsigned long)-1,file); |
1159 | FILE *fp = fopen(fname,"r"); | 1159 | startPos = ftell(file); |
1160 | if (fp) { | 1160 | if (!(result = Parse_MIMEHelper())) { |
1161 | VObject* o = Parse_MIME_FromFile(fp); | 1161 | fseek(file,startPos,SEEK_SET); |
1162 | fclose(fp); | 1162 | } |
1163 | return o; | 1163 | return result; |
1164 | } | 1164 | } |
1165 | else { | 1165 | |
1166 | char msg[80]; | 1166 | DLLEXPORT(VObject*) Parse_MIME_FromFileName(char *fname) |
1167 | sprintf(msg, "can't open file '%s' for reading\n", fname); | 1167 | { |
1168 | mime_error_(msg); | 1168 | FILE *fp = fopen(fname,"r"); |
1169 | return 0; | 1169 | if (fp) { |
1170 | } | 1170 | VObject* o = Parse_MIME_FromFile(fp); |
1171 | } | 1171 | fclose(fp); |
1172 | 1172 | return o; | |
1173 | #endif | 1173 | } |
1174 | 1174 | else { | |
1175 | /*-------------------------------------*/ | 1175 | char msg[80]; |
1176 | 1176 | sprintf(msg, "can't open file '%s' for reading\n", fname); | |
1177 | static MimeErrorHandler mimeErrorHandler; | 1177 | mime_error_(msg); |
1178 | 1178 | return 0; | |
1179 | DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler me) | 1179 | } |
1180 | { | 1180 | } |
1181 | mimeErrorHandler = me; | 1181 | |
1182 | } | 1182 | #endif |
1183 | 1183 | ||
1184 | void mime_error(char *s) | 1184 | /*-------------------------------------*/ |
1185 | { | 1185 | |
1186 | char msg[256]; | 1186 | static MimeErrorHandler mimeErrorHandler; |
1187 | if (mimeErrorHandler) { | 1187 | |
1188 | sprintf(msg,"%s at line %d", s, mime_lineNum); | 1188 | DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler me) |
1189 | mimeErrorHandler(msg); | 1189 | { |
1190 | } | 1190 | mimeErrorHandler = me; |
1191 | } | 1191 | } |
1192 | 1192 | ||
1193 | void mime_error_(char *s) | 1193 | void mime_error(char *s) |
1194 | { | 1194 | { |
1195 | if (mimeErrorHandler) { | 1195 | char msg[256]; |
1196 | mimeErrorHandler(s); | 1196 | if (mimeErrorHandler) { |
1197 | } | 1197 | sprintf(msg,"%s at line %d", s, mime_lineNum); |
1198 | } | 1198 | mimeErrorHandler(msg); |
1199 | 1199 | } | |
1200 | } | ||
1201 | |||
1202 | void mime_error_(char *s) | ||
1203 | { | ||
1204 | if (mimeErrorHandler) { | ||
1205 | mimeErrorHandler(s); | ||
1206 | } | ||
1207 | } | ||
1208 | |||
diff --git a/library/backend/vcc_yacc.cpp b/library/backend/vcc_yacc.cpp index cb24631..19a108f 100644 --- a/library/backend/vcc_yacc.cpp +++ b/library/backend/vcc_yacc.cpp | |||
@@ -1,706 +1,732 @@ | |||
1 | #ifndef lint | 1 | #ifndef lint |
2 | static char yysccsid[] = "@(#)yaccpar1.9 (Berkeley) 02/21/93"; | 2 | /*static char yysccsid[] = "from: @(#)yaccpar1.9 (Berkeley) 02/21/93";*/ |
3 | static char yyrcsid[] = "$Id$"; | ||
3 | #endif | 4 | #endif |
4 | #define YYBYACC 1 | 5 | #define YYBYACC 1 |
5 | #define YYMAJOR 1 | 6 | #define YYMAJOR 1 |
6 | #define YYMINOR 9 | 7 | #define YYMINOR 9 |
7 | #define yyclearin (yychar=(-1)) | 8 | #define yyclearin (yychar=(-1)) |
8 | #define yyerrok (yyerrflag=0) | 9 | #define yyerrok (yyerrflag=0) |
9 | #define YYRECOVERING (yyerrflag!=0) | 10 | #define YYRECOVERING (yyerrflag!=0) |
10 | #define YYPREFIX "yy" | 11 | #define yyparse vccparse |
11 | #line 1 "vcc.y" | 12 | #define yylex vcclex |
13 | #define yyerror vccerror | ||
14 | #define yychar vccchar | ||
15 | #define yyval vccval | ||
16 | #define yylval vcclval | ||
17 | #define yydebug vccdebug | ||
18 | #define yynerrs vccnerrs | ||
19 | #define yyerrflag vccerrflag | ||
20 | #define yyss vccss | ||
21 | #define yyssp vccssp | ||
22 | #define yyvs vccvs | ||
23 | #define yyvsp vccvsp | ||
24 | #define yylhs vcclhs | ||
25 | #define yylen vcclen | ||
26 | #define yydefred vccdefred | ||
27 | #define yydgoto vccdgoto | ||
28 | #define yysindex vccsindex | ||
29 | #define yyrindex vccrindex | ||
30 | #define yygindex vccgindex | ||
31 | #define yytable vcctable | ||
32 | #define yycheck vcccheck | ||
33 | #define yyname vccname | ||
34 | #define yyrule vccrule | ||
35 | #define YYPREFIX "vcc" | ||
36 | #line 1 "backend/vcc.y" | ||
12 | 37 | ||
13 | 38 | ||
14 | /*************************************************************************** | 39 | /*************************************************************************** |
15 | (C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International | 40 | (C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International |
16 | Business Machines Corporation and Siemens Rolm Communications Inc. | 41 | Business Machines Corporation and Siemens Rolm Communications Inc. |
17 | 42 | ||
18 | For purposes of this license notice, the term Licensors shall mean, | 43 | For purposes of this license notice, the term Licensors shall mean, |
19 | collectively, Apple Computer, Inc., AT&T Corp., International | 44 | collectively, Apple Computer, Inc., AT&T Corp., International |
20 | Business Machines Corporation and Siemens Rolm Communications Inc. | 45 | Business Machines Corporation and Siemens Rolm Communications Inc. |
21 | The term Licensor shall mean any of the Licensors. | 46 | The term Licensor shall mean any of the Licensors. |
22 | 47 | ||
23 | Subject to acceptance of the following conditions, permission is hereby | 48 | Subject to acceptance of the following conditions, permission is hereby |
24 | granted by Licensors without the need for written agreement and without | 49 | granted by Licensors without the need for written agreement and without |
25 | license or royalty fees, to use, copy, modify and distribute this | 50 | license or royalty fees, to use, copy, modify and distribute this |
26 | software for any purpose. | 51 | software for any purpose. |
27 | 52 | ||
28 | The above copyright notice and the following four paragraphs must be | 53 | The above copyright notice and the following four paragraphs must be |
29 | reproduced in all copies of this software and any software including | 54 | reproduced in all copies of this software and any software including |
30 | this software. | 55 | this software. |
31 | 56 | ||
32 | THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE | 57 | THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE |
33 | ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR | 58 | ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR |
34 | MODIFICATIONS. | 59 | MODIFICATIONS. |
35 | 60 | ||
36 | IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, | 61 | IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, |
37 | INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT | 62 | INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT |
38 | OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | 63 | OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
39 | DAMAGE. | 64 | DAMAGE. |
40 | 65 | ||
41 | EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, | 66 | EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, |
42 | INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE | 67 | INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE |
43 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 68 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
44 | PURPOSE. | 69 | PURPOSE. |
45 | 70 | ||
46 | The software is provided with RESTRICTED RIGHTS. Use, duplication, or | 71 | The software is provided with RESTRICTED RIGHTS. Use, duplication, or |
47 | disclosure by the government are subject to restrictions set forth in | 72 | disclosure by the government are subject to restrictions set forth in |
48 | DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. | 73 | DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. |
49 | 74 | ||
50 | ***************************************************************************/ | 75 | ***************************************************************************/ |
51 | 76 | ||
52 | /* | 77 | /* |
53 | * src: vcc.c | 78 | * src: vcc.c |
54 | * doc: Parser for vCard and vCalendar. Note that this code is | 79 | * doc: Parser for vCard and vCalendar. Note that this code is |
55 | * generated by a yacc parser generator. Generally it should not | 80 | * generated by a yacc parser generator. Generally it should not |
56 | * be edited by hand. The real source is vcc.y. The #line directives | 81 | * be edited by hand. The real source is vcc.y. The #line directives |
57 | * can be commented out here to make it easier to trace through | 82 | * can be commented out here to make it easier to trace through |
58 | * in a debugger. However, if a bug is found it should | 83 | * in a debugger. However, if a bug is found it should |
59 | * be fixed in vcc.y and this file regenerated. | 84 | * be fixed in vcc.y and this file regenerated. |
60 | */ | 85 | */ |
61 | 86 | ||
62 | 87 | ||
63 | /* debugging utilities */ | 88 | /* debugging utilities */ |
64 | #if __DEBUG | 89 | #if __DEBUG |
65 | #define DBG_(x) printf x | 90 | #define DBG_(x) printf x |
66 | #else | 91 | #else |
67 | #define DBG_(x) | 92 | #define DBG_(x) |
68 | #endif | 93 | #endif |
69 | 94 | ||
70 | /**** External Functions ****/ | 95 | /**** External Functions ****/ |
71 | 96 | ||
72 | /* assign local name to parser variables and functions so that | 97 | /* assign local name to parser variables and functions so that |
73 | we can use more than one yacc based parser. | 98 | we can use more than one yacc based parser. |
74 | */ | 99 | */ |
75 | 100 | ||
101 | #if 0 | ||
76 | #define yyparse mime_parse | 102 | #define yyparse mime_parse |
77 | #define yylex mime_lex | 103 | #define yylex mime_lex |
78 | #define yyerror mime_error | 104 | #define yyerror mime_error |
79 | #define yychar mime_char | 105 | #define yychar mime_char |
80 | /* #define p_yyval p_mime_val */ | 106 | /* #define p_yyval p_mime_val */ |
81 | #undef yyval | 107 | #undef yyval |
82 | #define yyval mime_yyval | 108 | #define yyval mime_yyval |
83 | /* #define p_yylval p_mime_lval */ | 109 | /* #define p_yylval p_mime_lval */ |
84 | #undef yylval | 110 | #undef yylval |
85 | #define yylval mime_yylval | 111 | #define yylval mime_yylval |
86 | #define yydebug mime_debug | 112 | #define yydebug mime_debug |
87 | #define yynerrs mime_nerrs | 113 | #define yynerrs mime_nerrs |
88 | #define yyerrflag mime_errflag | 114 | #define yyerrflag mime_errflag |
89 | #define yyss mime_ss | 115 | #define yyss mime_ss |
90 | #define yyssp mime_ssp | 116 | #define yyssp mime_ssp |
91 | #define yyvs mime_vs | 117 | #define yyvs mime_vs |
92 | #define yyvsp mime_vsp | 118 | #define yyvsp mime_vsp |
93 | #define yylhs mime_lhs | 119 | #define yylhs mime_lhs |
94 | #define yylen mime_len | 120 | #define yylen mime_len |
95 | #define yydefred mime_defred | 121 | #define yydefred mime_defred |
96 | #define yydgoto mime_dgoto | 122 | #define yydgoto mime_dgoto |
97 | #define yysindex mime_sindex | 123 | #define yysindex mime_sindex |
98 | #define yyrindex mime_rindex | 124 | #define yyrindex mime_rindex |
99 | #define yygindex mime_gindex | 125 | #define yygindex mime_gindex |
100 | #define yytable mime_table | 126 | #define yytable mime_table |
101 | #define yycheck mime_check | 127 | #define yycheck mime_check |
102 | #define yyname mime_name | 128 | #define yyname mime_name |
103 | #define yyrule mime_rule | 129 | #define yyrule mime_rule |
104 | #ifdef YYPREFIX | 130 | #ifdef YYPREFIX |
105 | #undef YYPREFIX | 131 | #undef YYPREFIX |
106 | #endif | 132 | #endif |
107 | #define YYPREFIX "mime_" | 133 | #define YYPREFIX "mime_" |
134 | #endif | ||
108 | 135 | ||
109 | 136 | ||
110 | #ifndef _NO_LINE_FOLDING | 137 | #ifndef _NO_LINE_FOLDING |
111 | #define _SUPPORT_LINE_FOLDING 1 | 138 | #define _SUPPORT_LINE_FOLDING 1 |
112 | #endif | 139 | #endif |
113 | 140 | ||
114 | /* undef below if compile with MFC */ | 141 | /* undef below if compile with MFC */ |
115 | /* #define INCLUDEMFC 1 */ | 142 | /* #define INCLUDEMFC 1 */ |
116 | 143 | ||
117 | #if defined(WIN32) || defined(_WIN32) | 144 | #if defined(WIN32) || defined(_WIN32) |
118 | #ifdef INCLUDEMFC | 145 | #ifdef INCLUDEMFC |
119 | #include <afx.h> | 146 | #include <afx.h> |
120 | #endif | 147 | #endif |
121 | #endif | 148 | #endif |
122 | 149 | ||
123 | #include <string.h> | 150 | #include <string.h> |
124 | #ifndef __MWERKS__ | 151 | #ifndef __MWERKS__ |
125 | #include <stdlib.h> | 152 | #include <stdlib.h> |
126 | #endif | 153 | #endif |
127 | #include <stdio.h> | 154 | #include <stdio.h> |
128 | #include <stdlib.h> | 155 | #include <stdlib.h> |
129 | #include <ctype.h> | 156 | #include <ctype.h> |
130 | 157 | ||
131 | #ifdef PALMTOPCENTER | 158 | /*#ifdef PALMTOPCENTER */ |
132 | #include <qpe/vobject_p.h> | 159 | /*#include <qpe/vobject_p.h> */ |
133 | #include <qpe/qfiledirect_p.h> | 160 | /*#else */ |
134 | #else | ||
135 | #include "vobject_p.h" | 161 | #include "vobject_p.h" |
136 | #include "qfiledirect_p.h" | 162 | /*#endif */ |
137 | #endif | ||
138 | 163 | ||
139 | /**** Types, Constants ****/ | 164 | /**** Types, Constants ****/ |
140 | 165 | ||
141 | #define YYDEBUG 0/* 1 to compile in some debugging code */ | 166 | #define YYDEBUG 0/* 1 to compile in some debugging code */ |
142 | #define MAXTOKEN 256/* maximum token (line) length */ | 167 | #define MAXTOKEN 256/* maximum token (line) length */ |
143 | #define YYSTACKSIZE 100/* ~unref ? | 168 | #define YYSTACKSIZE 100/* ~unref ? */ |
144 | */ | ||
145 | #define MAXLEVEL 10/* max # of nested objects parseable */ | 169 | #define MAXLEVEL 10/* max # of nested objects parseable */ |
146 | /* (includes outermost) */ | 170 | /* (includes outermost) */ |
147 | 171 | ||
148 | 172 | ||
149 | /**** Global Variables ****/ | 173 | /**** Global Variables ****/ |
150 | int mime_lineNum, mime_numErrors; /* yyerror() can use these */ | 174 | int mime_lineNum, mime_numErrors; /* yyerror() can use these */ |
151 | static VObject* vObjList; | 175 | static VObject* vObjList; |
152 | static VObject *curProp; | 176 | static VObject *curProp; |
153 | static VObject *curObj; | 177 | static VObject *curObj; |
154 | static VObject* ObjStack[MAXLEVEL]; | 178 | static VObject* ObjStack[MAXLEVEL]; |
155 | static int ObjStackTop; | 179 | static int ObjStackTop; |
156 | 180 | ||
157 | 181 | ||
158 | /* A helpful utility for the rest of the app. */ | 182 | /* A helpful utility for the rest of the app. */ |
159 | #if __CPLUSPLUS__ | 183 | #if __CPLUSPLUS__ |
160 | extern "C" { | 184 | extern "C" { |
161 | #endif | 185 | #endif |
162 | 186 | ||
163 | extern void yyerror(char *s); | 187 | extern void yyerror(char *s); |
164 | 188 | ||
165 | #if __CPLUSPLUS__ | 189 | #if __CPLUSPLUS__ |
166 | }; | 190 | }; |
167 | #endif | 191 | #endif |
168 | 192 | ||
169 | int yyparse(); | 193 | int yyparse(); |
170 | 194 | ||
171 | enum LexMode { | 195 | enum LexMode { |
172 | L_NORMAL, | 196 | L_NORMAL, |
173 | L_VCARD, | 197 | L_VCARD, |
174 | L_VCAL, | 198 | L_VCAL, |
175 | L_VEVENT, | 199 | L_VEVENT, |
176 | L_VTODO, | 200 | L_VTODO, |
177 | L_VALUES, | 201 | L_VALUES, |
178 | L_BASE64, | 202 | L_BASE64, |
179 | L_QUOTED_PRINTABLE | 203 | L_QUOTED_PRINTABLE |
180 | }; | 204 | }; |
181 | 205 | ||
182 | /**** Private Forward Declarations ****/ | 206 | /**** Private Forward Declarations ****/ |
183 | static int pushVObject(const char *prop); | 207 | static int pushVObject(const char *prop); |
184 | static VObject* popVObject(); | 208 | static VObject* popVObject(); |
185 | static void lexPopMode(int top); | 209 | static void lexPopMode(int top); |
186 | static int lexWithinMode(enum LexMode mode); | 210 | static int lexWithinMode(enum LexMode mode); |
187 | static void lexPushMode(enum LexMode mode); | 211 | static void lexPushMode(enum LexMode mode); |
188 | static void enterProps(const char *s); | 212 | static void enterProps(const char *s); |
189 | static void enterAttr(const char *s1, const char *s2); | 213 | static void enterAttr(const char *s1, const char *s2); |
190 | static void enterValues(const char *value); | 214 | static void enterValues(const char *value); |
215 | #define mime_error yyerror | ||
216 | void mime_error(char *s); | ||
191 | void mime_error_(char *s); | 217 | void mime_error_(char *s); |
192 | 218 | ||
193 | #line 185 "vcc.y" | 219 | #line 189 "backend/vcc.y" |
194 | typedef union { | 220 | typedef union { |
195 | char *str; | 221 | char *str; |
196 | VObject *vobj; | 222 | VObject *vobj; |
197 | } YYSTYPE; | 223 | } YYSTYPE; |
198 | #line 196 "y.tab.c" | 224 | #line 225 "y.tab.c" |
199 | #define EQ 257 | 225 | #define EQ 257 |
200 | #define COLON 258 | 226 | #define COLON 258 |
201 | #define DOT 259 | 227 | #define DOT 259 |
202 | #define SEMICOLON 260 | 228 | #define SEMICOLON 260 |
203 | #define SPACE 261 | 229 | #define SPACE 261 |
204 | #define HTAB 262 | 230 | #define HTAB 262 |
205 | #define LINESEP 263 | 231 | #define LINESEP 263 |
206 | #define NEWLINE 264 | 232 | #define NEWLINE 264 |
207 | #define BEGIN_VCARD 265 | 233 | #define BEGIN_VCARD 265 |
208 | #define END_VCARD 266 | 234 | #define END_VCARD 266 |
209 | #define BEGIN_VCAL 267 | 235 | #define BEGIN_VCAL 267 |
210 | #define END_VCAL 268 | 236 | #define END_VCAL 268 |
211 | #define BEGIN_VEVENT 269 | 237 | #define BEGIN_VEVENT 269 |
212 | #define END_VEVENT 270 | 238 | #define END_VEVENT 270 |
213 | #define BEGIN_VTODO 271 | 239 | #define BEGIN_VTODO 271 |
214 | #define END_VTODO 272 | 240 | #define END_VTODO 272 |
215 | #define ID 273 | 241 | #define ID 273 |
216 | #define STRING 274 | 242 | #define STRING 274 |
217 | #define YYERRCODE 256 | 243 | #define YYERRCODE 256 |
218 | short yylhs[] = { -1, | 244 | short vcclhs[] = { -1, |
219 | 0, 6, 6, 5, 5, 8, 3, 9, 3, 7, | 245 | 0, 6, 6, 5, 5, 8, 3, 9, 3, 7, |
220 | 7, 13, 10, 10, 15, 11, 11, 14, 14, 16, | 246 | 7, 13, 10, 10, 15, 11, 11, 14, 14, 16, |
221 | 17, 17, 1, 18, 12, 12, 2, 2, 20, 4, | 247 | 17, 17, 1, 18, 12, 12, 2, 2, 20, 4, |
222 | 21, 4, 19, 19, 22, 22, 22, 25, 23, 26, | 248 | 21, 4, 19, 19, 22, 22, 22, 25, 23, 26, |
223 | 23, 27, 24, 28, 24, | 249 | 23, 27, 24, 28, 24, |
224 | }; | 250 | }; |
225 | short yylen[] = { 2, | 251 | short vcclen[] = { 2, |
226 | 1, 2, 1, 1, 1, 0, 4, 0, 3, 2, | 252 | 1, 2, 1, 1, 1, 0, 4, 0, 3, 2, |
227 | 1, 0, 5, 1, 0, 3, 1, 2, 1, 2, | 253 | 1, 0, 5, 1, 0, 3, 1, 2, 1, 2, |
228 | 1, 3, 1, 0, 4, 1, 1, 0, 0, 4, | 254 | 1, 3, 1, 0, 4, 1, 1, 0, 0, 4, |
229 | 0, 3, 2, 1, 1, 1, 1, 0, 4, 0, | 255 | 0, 3, 2, 1, 1, 1, 1, 0, 4, 0, |
230 | 3, 0, 4, 0, 3, | 256 | 3, 0, 4, 0, 3, |
231 | }; | 257 | }; |
232 | short yydefred[] = { 0, | 258 | short vccdefred[] = { 0, |
233 | 0, 0, 0, 4, 5, 3, 0, 0, 0, 0, | 259 | 0, 0, 0, 4, 5, 3, 0, 0, 0, 0, |
234 | 0, 2, 14, 23, 0, 0, 11, 0, 9, 0, | 260 | 0, 2, 14, 23, 0, 0, 11, 0, 9, 0, |
235 | 0, 0, 0, 34, 35, 36, 32, 0, 7, 10, | 261 | 0, 0, 0, 34, 35, 36, 32, 0, 7, 10, |
236 | 12, 0, 0, 0, 0, 30, 33, 0, 0, 19, | 262 | 12, 0, 0, 0, 0, 30, 33, 0, 0, 19, |
237 | 0, 0, 41, 0, 45, 0, 20, 18, 27, 0, | 263 | 0, 0, 41, 0, 45, 0, 20, 18, 27, 0, |
238 | 0, 39, 43, 0, 24, 13, 22, 0, 25, | 264 | 0, 39, 43, 0, 24, 13, 22, 0, 25, |
239 | }; | 265 | }; |
240 | short yydgoto[] = { 3, | 266 | short vccdgoto[] = { 3, |
241 | 15, 50, 4, 5, 6, 7, 22, 8, 9, 17, | 267 | 15, 50, 4, 5, 6, 7, 22, 8, 9, 17, |
242 | 18, 51, 41, 39, 28, 40, 47, 58, 23, 10, | 268 | 18, 51, 41, 39, 28, 40, 47, 58, 23, 10, |
243 | 11, 24, 25, 26, 32, 33, 34, 35, | 269 | 11, 24, 25, 26, 32, 33, 34, 35, |
244 | }; | 270 | }; |
245 | short yysindex[] = { -262, | 271 | short vccsindex[] = { -262, |
246 | 0, 0, 0, 0, 0, 0, -262, -252, -219, -249, | 272 | 0, 0, 0, 0, 0, 0, -262, -252, -219, -249, |
247 | -256, 0, 0, 0, 0, -227, 0, -242, 0, 0, | 273 | -256, 0, 0, 0, 0, -227, 0, -242, 0, 0, |
248 | 0, -252, -254, 0, 0, 0, 0, -208, 0, 0, | 274 | 0, -252, -254, 0, 0, 0, 0, -208, 0, 0, |
249 | 0, -252, -228, -252, -213, 0, 0, -212, -208, 0, | 275 | 0, -252, -228, -252, -213, 0, 0, -212, -208, 0, |
250 | -214, -233, 0, -224, 0, -195, 0, 0, 0, -197, | 276 | -214, -233, 0, -224, 0, -195, 0, 0, 0, -197, |
251 | -199, 0, 0, -212, 0, 0, 0, -214, 0, | 277 | -199, 0, 0, -212, 0, 0, 0, -214, 0, |
252 | }; | 278 | }; |
253 | short yyrindex[] = { 0, | 279 | short vccrindex[] = { 0, |
254 | -222, -238, 0, 0, 0, 0, 65, 0, 0, 0, | 280 | -222, -238, 0, 0, 0, 0, 65, 0, 0, 0, |
255 | 0, 0, 0, 0, -215, 0, 0, 0, 0, -220, | 281 | 0, 0, 0, 0, -215, 0, 0, 0, 0, -220, |
256 | -218, -260, 0, 0, 0, 0, 0, 0, 0, 0, | 282 | -218, -260, 0, 0, 0, 0, 0, 0, 0, 0, |
257 | 0, 0, 0, 0, 0, 0, 0, 0, -192, 0, | 283 | 0, 0, 0, 0, 0, 0, 0, 0, -192, 0, |
258 | -250, 0, 0, 0, 0, -202, 0, 0, 0, -196, | 284 | -250, 0, 0, 0, 0, -202, 0, 0, 0, -196, |
259 | 0, 0, 0, 0, 0, 0, 0, -250, 0, | 285 | 0, 0, 0, 0, 0, 0, 0, -250, 0, |
260 | }; | 286 | }; |
261 | short yygindex[] = { 0, | 287 | short vccgindex[] = { 0, |
262 | 3, 0, 0, 0, 61, 0, -7, 0, 0, -16, | 288 | 3, 0, 0, 0, 61, 0, -7, 0, 0, -16, |
263 | 0, 11, 0, 0, 0, 31, 0, 0, 0, 0, | 289 | 0, 11, 0, 0, 0, 31, 0, 0, 0, 0, |
264 | 0, 48, 0, 0, 0, 0, 0, 0, | 290 | 0, 48, 0, 0, 0, 0, 0, 0, |
265 | }; | 291 | }; |
266 | #define YYTABLESIZE 71 | 292 | #define YYTABLESIZE 71 |
267 | short yytable[] = { 30, | 293 | short vcctable[] = { 30, |
268 | 16, 13, 1, 13, 2, 30, 13, 37, 37, 28, | 294 | 16, 13, 1, 13, 2, 30, 13, 37, 37, 28, |
269 | 37, 27, 28, 36, 20, 31, 21, 29, 14, 20, | 295 | 37, 27, 28, 36, 20, 31, 21, 29, 14, 20, |
270 | 14, 21, 13, 14, 42, 30, 44, 30, 13, 31, | 296 | 14, 21, 13, 14, 42, 30, 44, 30, 13, 31, |
271 | 29, 13, 29, 6, 29, 38, 52, 42, 29, 14, | 297 | 29, 13, 29, 6, 29, 38, 52, 42, 29, 14, |
272 | 46, 43, 17, 8, 15, 14, 19, 53, 14, 40, | 298 | 46, 43, 17, 8, 15, 14, 19, 53, 14, 40, |
273 | 6, 38, 38, 44, 42, 21, 57, 21, 45, 49, | 299 | 6, 38, 38, 44, 42, 21, 57, 21, 45, 49, |
274 | 14, 54, 55, 56, 1, 16, 26, 12, 59, 48, | 300 | 14, 54, 55, 56, 1, 16, 26, 12, 59, 48, |
275 | 37, | 301 | 37, |
276 | }; | 302 | }; |
277 | short yycheck[] = { 16, | 303 | short vcccheck[] = { 16, |
278 | 8, 256, 265, 256, 267, 22, 256, 268, 269, 260, | 304 | 8, 256, 265, 256, 267, 22, 256, 268, 269, 260, |
279 | 271, 268, 263, 268, 269, 258, 271, 256, 273, 269, | 305 | 271, 268, 263, 268, 269, 258, 271, 256, 273, 269, |
280 | 273, 271, 256, 273, 32, 42, 34, 44, 256, 268, | 306 | 273, 271, 256, 273, 32, 42, 34, 44, 256, 268, |
281 | 269, 256, 271, 256, 273, 256, 270, 256, 266, 273, | 307 | 269, 256, 271, 256, 273, 256, 270, 256, 266, 273, |
282 | 38, 270, 258, 266, 260, 273, 266, 272, 273, 270, | 308 | 38, 270, 258, 266, 260, 273, 266, 272, 273, 270, |
283 | 273, 260, 273, 272, 273, 258, 54, 260, 272, 274, | 309 | 273, 260, 273, 272, 273, 258, 54, 260, 272, 274, |
284 | 273, 257, 260, 263, 0, 258, 263, 7, 58, 39, | 310 | 273, 257, 260, 263, 0, 258, 263, 7, 58, 39, |
285 | 23, | 311 | 23, |
286 | }; | 312 | }; |
287 | #define YYFINAL 3 | 313 | #define YYFINAL 3 |
288 | #ifndef YYDEBUG | 314 | #ifndef YYDEBUG |
289 | #define YYDEBUG 0 | 315 | #define YYDEBUG 0 |
290 | #endif | 316 | #endif |
291 | #define YYMAXTOKEN 274 | 317 | #define YYMAXTOKEN 274 |
292 | #if YYDEBUG | 318 | #if YYDEBUG |
293 | char *yyname[] = { | 319 | char *vccname[] = { |
294 | "end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | 320 | "end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
295 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | 321 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
296 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | 322 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
297 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | 323 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
298 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | 324 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
299 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | 325 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
300 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"EQ","COLON","DOT","SEMICOLON", | 326 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"EQ","COLON","DOT","SEMICOLON", |
301 | "SPACE","HTAB","LINESEP","NEWLINE","BEGIN_VCARD","END_VCARD","BEGIN_VCAL", | 327 | "SPACE","HTAB","LINESEP","NEWLINE","BEGIN_VCARD","END_VCARD","BEGIN_VCAL", |
302 | "END_VCAL","BEGIN_VEVENT","END_VEVENT","BEGIN_VTODO","END_VTODO","ID","STRING", | 328 | "END_VCAL","BEGIN_VEVENT","END_VEVENT","BEGIN_VTODO","END_VTODO","ID","STRING", |
303 | }; | 329 | }; |
304 | char *yyrule[] = { | 330 | char *vccrule[] = { |
305 | "$accept : mime", | 331 | "$accept : mime", |
306 | "mime : vobjects", | 332 | "mime : vobjects", |
307 | "vobjects : vobjects vobject", | 333 | "vobjects : vobjects vobject", |
308 | "vobjects : vobject", | 334 | "vobjects : vobject", |
309 | "vobject : vcard", | 335 | "vobject : vcard", |
310 | "vobject : vcal", | 336 | "vobject : vcal", |
311 | "$$1 :", | 337 | "$$1 :", |
312 | "vcard : BEGIN_VCARD $$1 items END_VCARD", | 338 | "vcard : BEGIN_VCARD $$1 items END_VCARD", |
313 | "$$2 :", | 339 | "$$2 :", |
314 | "vcard : BEGIN_VCARD $$2 END_VCARD", | 340 | "vcard : BEGIN_VCARD $$2 END_VCARD", |
315 | "items : items item", | 341 | "items : items item", |
316 | "items : item", | 342 | "items : item", |
317 | "$$3 :", | 343 | "$$3 :", |
318 | "item : prop COLON $$3 values LINESEP", | 344 | "item : prop COLON $$3 values LINESEP", |
319 | "item : error", | 345 | "item : error", |
320 | "$$4 :", | 346 | "$$4 :", |
321 | "prop : name $$4 attr_params", | 347 | "prop : name $$4 attr_params", |
322 | "prop : name", | 348 | "prop : name", |
323 | "attr_params : attr_params attr_param", | 349 | "attr_params : attr_params attr_param", |
324 | "attr_params : attr_param", | 350 | "attr_params : attr_param", |
325 | "attr_param : SEMICOLON attr", | 351 | "attr_param : SEMICOLON attr", |
326 | "attr : name", | 352 | "attr : name", |
327 | "attr : name EQ name", | 353 | "attr : name EQ name", |
328 | "name : ID", | 354 | "name : ID", |
329 | "$$5 :", | 355 | "$$5 :", |
330 | "values : value SEMICOLON $$5 values", | 356 | "values : value SEMICOLON $$5 values", |
331 | "values : value", | 357 | "values : value", |
332 | "value : STRING", | 358 | "value : STRING", |
333 | "value :", | 359 | "value :", |
334 | "$$6 :", | 360 | "$$6 :", |
335 | "vcal : BEGIN_VCAL $$6 calitems END_VCAL", | 361 | "vcal : BEGIN_VCAL $$6 calitems END_VCAL", |
336 | "$$7 :", | 362 | "$$7 :", |
337 | "vcal : BEGIN_VCAL $$7 END_VCAL", | 363 | "vcal : BEGIN_VCAL $$7 END_VCAL", |
338 | "calitems : calitems calitem", | 364 | "calitems : calitems calitem", |
339 | "calitems : calitem", | 365 | "calitems : calitem", |
340 | "calitem : eventitem", | 366 | "calitem : eventitem", |
341 | "calitem : todoitem", | 367 | "calitem : todoitem", |
342 | "calitem : items", | 368 | "calitem : items", |
343 | "$$8 :", | 369 | "$$8 :", |
344 | "eventitem : BEGIN_VEVENT $$8 items END_VEVENT", | 370 | "eventitem : BEGIN_VEVENT $$8 items END_VEVENT", |
345 | "$$9 :", | 371 | "$$9 :", |
346 | "eventitem : BEGIN_VEVENT $$9 END_VEVENT", | 372 | "eventitem : BEGIN_VEVENT $$9 END_VEVENT", |
347 | "$$10 :", | 373 | "$$10 :", |
348 | "todoitem : BEGIN_VTODO $$10 items END_VTODO", | 374 | "todoitem : BEGIN_VTODO $$10 items END_VTODO", |
349 | "$$11 :", | 375 | "$$11 :", |
350 | "todoitem : BEGIN_VTODO $$11 END_VTODO", | 376 | "todoitem : BEGIN_VTODO $$11 END_VTODO", |
351 | }; | 377 | }; |
352 | #endif | 378 | #endif |
353 | #ifdef YYSTACKSIZE | 379 | #ifdef YYSTACKSIZE |
354 | #undef YYMAXDEPTH | 380 | #undef YYMAXDEPTH |
355 | #define YYMAXDEPTH YYSTACKSIZE | 381 | #define YYMAXDEPTH YYSTACKSIZE |
356 | #else | 382 | #else |
357 | #ifdef YYMAXDEPTH | 383 | #ifdef YYMAXDEPTH |
358 | #define YYSTACKSIZE YYMAXDEPTH | 384 | #define YYSTACKSIZE YYMAXDEPTH |
359 | #else | 385 | #else |
360 | #define YYSTACKSIZE 500 | 386 | #define YYSTACKSIZE 500 |
361 | #define YYMAXDEPTH 500 | 387 | #define YYMAXDEPTH 500 |
362 | #endif | 388 | #endif |
363 | #endif | 389 | #endif |
364 | int yydebug; | 390 | int yydebug; |
365 | int yynerrs; | 391 | int yynerrs; |
366 | int yyerrflag; | 392 | int yyerrflag; |
367 | int yychar; | 393 | int yychar; |
368 | short *yyssp; | 394 | short *yyssp; |
369 | YYSTYPE *yyvsp; | 395 | YYSTYPE *yyvsp; |
370 | YYSTYPE yyval; | 396 | YYSTYPE yyval; |
371 | YYSTYPE yylval; | 397 | YYSTYPE yylval; |
372 | short yyss[YYSTACKSIZE]; | 398 | short yyss[YYSTACKSIZE]; |
373 | YYSTYPE yyvs[YYSTACKSIZE]; | 399 | YYSTYPE yyvs[YYSTACKSIZE]; |
374 | #define yystacksize YYSTACKSIZE | 400 | #define yystacksize YYSTACKSIZE |
375 | #line 378 "vcc.y" | 401 | #line 382 "backend/vcc.y" |
376 | 402 | ||
377 | /*------------------------------------*/ | 403 | /*------------------------------------*/ |
378 | static int pushVObject(const char *prop) | 404 | static int pushVObject(const char *prop) |
379 | { | 405 | { |
380 | VObject *newObj; | 406 | VObject *newObj; |
381 | if (ObjStackTop == MAXLEVEL) | 407 | if (ObjStackTop == MAXLEVEL) |
382 | return FALSE; | 408 | return FALSE; |
383 | 409 | ||
384 | ObjStack[++ObjStackTop] = curObj; | 410 | ObjStack[++ObjStackTop] = curObj; |
385 | 411 | ||
386 | if (curObj) { | 412 | if (curObj) { |
387 | newObj = addProp(curObj,prop); | 413 | newObj = addProp(curObj,prop); |
388 | curObj = newObj; | 414 | curObj = newObj; |
389 | } | 415 | } |
390 | else | 416 | else |
391 | curObj = newVObject(prop); | 417 | curObj = newVObject(prop); |
392 | 418 | ||
393 | return TRUE; | 419 | return TRUE; |
394 | } | 420 | } |
395 | 421 | ||
396 | 422 | ||
397 | /*---------------------------------------*/ | 423 | /*---------------------------------------*/ |
398 | /* This pops the recently built vCard off the stack and returns it. */ | 424 | /* This pops the recently built vCard off the stack and returns it. */ |
399 | static VObject* popVObject() | 425 | static VObject* popVObject() |
400 | { | 426 | { |
401 | VObject *oldObj; | 427 | VObject *oldObj; |
402 | if (ObjStackTop < 0) { | 428 | if (ObjStackTop < 0) { |
403 | yyerror("pop on empty Object Stack\n"); | 429 | yyerror("pop on empty Object Stack\n"); |
404 | return 0; | 430 | return 0; |
405 | } | 431 | } |
406 | oldObj = curObj; | 432 | oldObj = curObj; |
407 | curObj = ObjStack[ObjStackTop--]; | 433 | curObj = ObjStack[ObjStackTop--]; |
408 | 434 | ||
409 | return oldObj; | 435 | return oldObj; |
410 | } | 436 | } |
411 | 437 | ||
412 | 438 | ||
413 | static void enterValues(const char *value) | 439 | static void enterValues(const char *value) |
414 | { | 440 | { |
415 | if (fieldedProp && *fieldedProp) { | 441 | if (fieldedProp && *fieldedProp) { |
416 | if (value) { | 442 | if (value) { |
417 | addPropValue(curProp,*fieldedProp,value); | 443 | addPropValue(curProp,*fieldedProp,value); |
418 | } | 444 | } |
419 | /* else this field is empty, advance to next field */ | 445 | /* else this field is empty, advance to next field */ |
420 | fieldedProp++; | 446 | fieldedProp++; |
421 | } | 447 | } |
422 | else { | 448 | else { |
423 | if (value) { | 449 | if (value) { |
424 | setVObjectStringZValue_(curProp,strdup( value )); | 450 | setVObjectStringZValue_(curProp,strdup( value )); |
425 | } | 451 | } |
426 | } | 452 | } |
427 | deleteStr(value); | 453 | deleteStr(value); |
428 | } | 454 | } |
429 | 455 | ||
430 | static void enterProps(const char *s) | 456 | static void enterProps(const char *s) |
431 | { | 457 | { |
432 | curProp = addGroup(curObj,s); | 458 | curProp = addGroup(curObj,s); |
433 | deleteStr(s); | 459 | deleteStr(s); |
434 | } | 460 | } |
435 | 461 | ||
436 | static void enterAttr(const char *s1, const char *s2) | 462 | static void enterAttr(const char *s1, const char *s2) |
437 | { | 463 | { |
438 | const char *p1, *p2; | 464 | const char *p1, *p2; |
439 | p1 = lookupProp_(s1); | 465 | p1 = lookupProp_(s1); |
440 | if (s2) { | 466 | if (s2) { |
441 | VObject *a; | 467 | VObject *a; |
442 | p2 = lookupProp_(s2); | 468 | p2 = lookupProp_(s2); |
443 | a = addProp(curProp,p1); | 469 | a = addProp(curProp,p1); |
444 | setVObjectStringZValue(a,p2); | 470 | setVObjectStringZValue(a,p2); |
445 | } | 471 | } |
446 | else | 472 | else |
447 | addProp(curProp,p1); | 473 | addProp(curProp,p1); |
448 | if (qstricmp(p1,VCBase64Prop) == 0 || (s2 && qstricmp(p2,VCBase64Prop)==0)) | 474 | if (qstricmp(p1,VCBase64Prop) == 0 || (s2 && qstricmp(p2,VCBase64Prop)==0)) |
449 | lexPushMode(L_BASE64); | 475 | lexPushMode(L_BASE64); |
450 | else if (qstricmp(p1,VCQuotedPrintableProp) == 0 | 476 | else if (qstricmp(p1,VCQuotedPrintableProp) == 0 |
451 | || (s2 && qstricmp(p2,VCQuotedPrintableProp)==0)) | 477 | || (s2 && qstricmp(p2,VCQuotedPrintableProp)==0)) |
452 | lexPushMode(L_QUOTED_PRINTABLE); | 478 | lexPushMode(L_QUOTED_PRINTABLE); |
453 | deleteStr(s1); deleteStr(s2); | 479 | deleteStr(s1); deleteStr(s2); |
454 | } | 480 | } |
455 | 481 | ||
456 | 482 | ||
457 | #define MAX_LEX_LOOKAHEAD_0 32 | 483 | #define MAX_LEX_LOOKAHEAD_0 32 |
458 | #define MAX_LEX_LOOKAHEAD 64 | 484 | #define MAX_LEX_LOOKAHEAD 64 |
459 | #define MAX_LEX_MODE_STACK_SIZE 10 | 485 | #define MAX_LEX_MODE_STACK_SIZE 10 |
460 | #define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop]) | 486 | #define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop]) |
461 | 487 | ||
462 | struct LexBuf { | 488 | struct LexBuf { |
463 | /* input */ | 489 | /* input */ |
464 | #ifdef INCLUDEMFC | 490 | #ifdef INCLUDEMFC |
465 | CFile *inputFile; | 491 | CFile *inputFile; |
466 | #else | 492 | #else |
467 | FILE *inputFile; | 493 | FILE *inputFile; |
468 | #endif | 494 | #endif |
469 | char *inputString; | 495 | char *inputString; |
470 | unsigned long curPos; | 496 | unsigned long curPos; |
471 | unsigned long inputLen; | 497 | unsigned long inputLen; |
472 | /* lookahead buffer */ | 498 | /* lookahead buffer */ |
473 | /* -- lookahead buffer is short instead of char so that EOF | 499 | /* -- lookahead buffer is short instead of char so that EOF |
474 | / can be represented correctly. | 500 | / can be represented correctly. |
475 | */ | 501 | */ |
476 | unsigned long len; | 502 | unsigned long len; |
477 | short buf[MAX_LEX_LOOKAHEAD]; | 503 | short buf[MAX_LEX_LOOKAHEAD]; |
478 | unsigned long getPtr; | 504 | unsigned long getPtr; |
479 | /* context stack */ | 505 | /* context stack */ |
480 | unsigned long lexModeStackTop; | 506 | unsigned long lexModeStackTop; |
481 | enum LexMode lexModeStack[MAX_LEX_MODE_STACK_SIZE]; | 507 | enum LexMode lexModeStack[MAX_LEX_MODE_STACK_SIZE]; |
482 | /* token buffer */ | 508 | /* token buffer */ |
483 | unsigned long maxToken; | 509 | unsigned long maxToken; |
484 | char *strs; | 510 | char *strs; |
485 | unsigned long strsLen; | 511 | unsigned long strsLen; |
486 | } lexBuf; | 512 | } lexBuf; |
487 | 513 | ||
488 | static void lexPushMode(enum LexMode mode) | 514 | static void lexPushMode(enum LexMode mode) |
489 | { | 515 | { |
490 | if (lexBuf.lexModeStackTop == (MAX_LEX_MODE_STACK_SIZE-1)) | 516 | if (lexBuf.lexModeStackTop == (MAX_LEX_MODE_STACK_SIZE-1)) |
491 | yyerror("lexical context stack overflow"); | 517 | yyerror("lexical context stack overflow"); |
492 | else { | 518 | else { |
493 | lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode; | 519 | lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode; |
494 | } | 520 | } |
495 | } | 521 | } |
496 | 522 | ||
497 | static void lexPopMode(int top) | 523 | static void lexPopMode(int top) |
498 | { | 524 | { |
499 | /* special case of pop for ease of error recovery -- this | 525 | /* special case of pop for ease of error recovery -- this |
500 | version will never underflow */ | 526 | version will never underflow */ |
501 | if (top) | 527 | if (top) |
502 | lexBuf.lexModeStackTop = 0; | 528 | lexBuf.lexModeStackTop = 0; |
503 | else | 529 | else |
504 | if (lexBuf.lexModeStackTop > 0) lexBuf.lexModeStackTop--; | 530 | if (lexBuf.lexModeStackTop > 0) lexBuf.lexModeStackTop--; |
505 | } | 531 | } |
506 | 532 | ||
507 | static int lexWithinMode(enum LexMode mode) { | 533 | static int lexWithinMode(enum LexMode mode) { |
508 | unsigned long i; | 534 | unsigned long i; |
509 | for (i=0;i<lexBuf.lexModeStackTop;i++) | 535 | for (i=0;i<lexBuf.lexModeStackTop;i++) |
510 | if (mode == lexBuf.lexModeStack[i]) return 1; | 536 | if (mode == lexBuf.lexModeStack[i]) return 1; |
511 | return 0; | 537 | return 0; |
512 | } | 538 | } |
513 | 539 | ||
514 | static char lexGetc_() | 540 | static int lexGetc_() |
515 | { | 541 | { |
516 | /* get next char from input, no buffering. */ | 542 | /* get next char from input, no buffering. */ |
517 | if (lexBuf.curPos == lexBuf.inputLen) | 543 | if (lexBuf.curPos == lexBuf.inputLen) |
518 | return EOF; | 544 | return EOF; |
519 | else if (lexBuf.inputString) | 545 | else if (lexBuf.inputString) |
520 | return *(lexBuf.inputString + lexBuf.curPos++); | 546 | return *(lexBuf.inputString + lexBuf.curPos++); |
521 | else { | 547 | else { |
522 | #ifdef INCLUDEMFC | 548 | #ifdef INCLUDEMFC |
523 | char result; | 549 | char result; |
524 | return lexBuf.inputFile->Read(&result, 1) == 1 ? result : EOF; | 550 | return lexBuf.inputFile->Read(&result, 1) == 1 ? result : EOF; |
525 | #else | 551 | #else |
526 | return fgetc(lexBuf.inputFile); | 552 | return fgetc(lexBuf.inputFile); |
527 | #endif | 553 | #endif |
528 | } | 554 | } |
529 | } | 555 | } |
530 | 556 | ||
531 | static int lexGeta() | 557 | static int lexGeta() |
532 | { | 558 | { |
533 | ++lexBuf.len; | 559 | ++lexBuf.len; |
534 | return (lexBuf.buf[lexBuf.getPtr] = lexGetc_()); | 560 | return (lexBuf.buf[lexBuf.getPtr] = lexGetc_()); |
535 | } | 561 | } |
536 | 562 | ||
537 | static int lexGeta_(int i) | 563 | static int lexGeta_(int i) |
538 | { | 564 | { |
539 | ++lexBuf.len; | 565 | ++lexBuf.len; |
540 | return (lexBuf.buf[(lexBuf.getPtr+i)%MAX_LEX_LOOKAHEAD] = lexGetc_()); | 566 | return (lexBuf.buf[(lexBuf.getPtr+i)%MAX_LEX_LOOKAHEAD] = lexGetc_()); |
541 | } | 567 | } |
542 | 568 | ||
543 | static void lexSkipLookahead() { | 569 | static void lexSkipLookahead() { |
544 | if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) { | 570 | if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) { |
545 | /* don't skip EOF. */ | 571 | /* don't skip EOF. */ |
546 | lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD; | 572 | lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD; |
547 | lexBuf.len--; | 573 | lexBuf.len--; |
548 | } | 574 | } |
549 | } | 575 | } |
550 | 576 | ||
551 | static int lexLookahead() { | 577 | static int lexLookahead() { |
552 | int c = (lexBuf.len)? | 578 | int c = (lexBuf.len)? |
553 | lexBuf.buf[lexBuf.getPtr]: | 579 | lexBuf.buf[lexBuf.getPtr]: |
554 | lexGeta(); | 580 | lexGeta(); |
555 | /* do the \r\n -> \n or \r -> \n translation here */ | 581 | /* do the \r\n -> \n or \r -> \n translation here */ |
556 | if (c == '\r') { | 582 | if (c == '\r') { |
557 | int a = (lexBuf.len>1)? | 583 | int a = (lexBuf.len>1)? |
558 | lexBuf.buf[(lexBuf.getPtr+1)%MAX_LEX_LOOKAHEAD]: | 584 | lexBuf.buf[(lexBuf.getPtr+1)%MAX_LEX_LOOKAHEAD]: |
559 | lexGeta_(1); | 585 | lexGeta_(1); |
560 | if (a == '\n') { | 586 | if (a == '\n') { |
561 | lexSkipLookahead(); | 587 | lexSkipLookahead(); |
562 | } | 588 | } |
563 | lexBuf.buf[lexBuf.getPtr] = c = '\n'; | 589 | lexBuf.buf[lexBuf.getPtr] = c = '\n'; |
564 | } | 590 | } |
565 | else if (c == '\n') { | 591 | else if (c == '\n') { |
566 | int a = (lexBuf.len>1)? | 592 | int a = (lexBuf.len>1)? |
567 | lexBuf.buf[lexBuf.getPtr+1]: | 593 | lexBuf.buf[lexBuf.getPtr+1]: |
568 | lexGeta_(1); | 594 | lexGeta_(1); |
569 | if (a == '\r') { | 595 | if (a == '\r') { |
570 | lexSkipLookahead(); | 596 | lexSkipLookahead(); |
571 | } | 597 | } |
572 | lexBuf.buf[lexBuf.getPtr] = '\n'; | 598 | lexBuf.buf[lexBuf.getPtr] = '\n'; |
573 | } | 599 | } |
574 | return c; | 600 | return c; |
575 | } | 601 | } |
576 | 602 | ||
577 | static int lexGetc() { | 603 | static int lexGetc() { |
578 | int c = lexLookahead(); | 604 | int c = lexLookahead(); |
579 | if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) { | 605 | if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) { |
580 | /* EOF will remain in lookahead buffer */ | 606 | /* EOF will remain in lookahead buffer */ |
581 | lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD; | 607 | lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD; |
582 | lexBuf.len--; | 608 | lexBuf.len--; |
583 | } | 609 | } |
584 | return c; | 610 | return c; |
585 | } | 611 | } |
586 | 612 | ||
587 | static void lexSkipLookaheadWord() { | 613 | static void lexSkipLookaheadWord() { |
588 | if (lexBuf.strsLen <= lexBuf.len) { | 614 | if (lexBuf.strsLen <= lexBuf.len) { |
589 | lexBuf.len -= lexBuf.strsLen; | 615 | lexBuf.len -= lexBuf.strsLen; |
590 | lexBuf.getPtr = (lexBuf.getPtr + lexBuf.strsLen) % MAX_LEX_LOOKAHEAD; | 616 | lexBuf.getPtr = (lexBuf.getPtr + lexBuf.strsLen) % MAX_LEX_LOOKAHEAD; |
591 | } | 617 | } |
592 | } | 618 | } |
593 | 619 | ||
594 | static void lexClearToken() | 620 | static void lexClearToken() |
595 | { | 621 | { |
596 | lexBuf.strsLen = 0; | 622 | lexBuf.strsLen = 0; |
597 | } | 623 | } |
598 | 624 | ||
599 | static void lexAppendc(int c) | 625 | static void lexAppendc(int c) |
600 | { | 626 | { |
601 | lexBuf.strs[lexBuf.strsLen] = c; | 627 | lexBuf.strs[lexBuf.strsLen] = c; |
602 | /* append up to zero termination */ | 628 | /* append up to zero termination */ |
603 | if (c == 0) return; | 629 | if (c == 0) return; |
604 | lexBuf.strsLen++; | 630 | lexBuf.strsLen++; |
605 | if (lexBuf.strsLen > lexBuf.maxToken) { | 631 | if (lexBuf.strsLen > lexBuf.maxToken) { |
606 | /* double the token string size */ | 632 | /* double the token string size */ |
607 | lexBuf.maxToken <<= 1; | 633 | lexBuf.maxToken <<= 1; |
608 | lexBuf.strs = (char*) realloc(lexBuf.strs,(size_t)lexBuf.maxToken); | 634 | lexBuf.strs = (char*) realloc(lexBuf.strs,(size_t)lexBuf.maxToken); |
609 | } | 635 | } |
610 | } | 636 | } |
611 | 637 | ||
612 | static char* lexStr() { | 638 | static char* lexStr() { |
613 | return dupStr(lexBuf.strs,(size_t)lexBuf.strsLen+1); | 639 | return dupStr(lexBuf.strs,(size_t)lexBuf.strsLen+1); |
614 | } | 640 | } |
615 | 641 | ||
616 | static void lexSkipWhite() { | 642 | static void lexSkipWhite() { |
617 | int c = lexLookahead(); | 643 | int c = lexLookahead(); |
618 | while (c == ' ' || c == '\t') { | 644 | while (c == ' ' || c == '\t') { |
619 | lexSkipLookahead(); | 645 | lexSkipLookahead(); |
620 | c = lexLookahead(); | 646 | c = lexLookahead(); |
621 | } | 647 | } |
622 | } | 648 | } |
623 | 649 | ||
624 | static char* lexGetWord() { | 650 | static char* lexGetWord() { |
625 | int c; | 651 | int c; |
626 | lexSkipWhite(); | 652 | lexSkipWhite(); |
627 | lexClearToken(); | 653 | lexClearToken(); |
628 | c = lexLookahead(); | 654 | c = lexLookahead(); |
629 | while (c != EOF && !strchr("\t\n ;:=",c)) { | 655 | while (c != EOF && !strchr("\t\n ;:=",c)) { |
630 | lexAppendc(c); | 656 | lexAppendc(c); |
631 | lexSkipLookahead(); | 657 | lexSkipLookahead(); |
632 | c = lexLookahead(); | 658 | c = lexLookahead(); |
633 | } | 659 | } |
634 | lexAppendc(0); | 660 | lexAppendc(0); |
635 | return lexStr(); | 661 | return lexStr(); |
636 | } | 662 | } |
637 | 663 | ||
638 | static void lexPushLookaheadc(int c) { | 664 | static void lexPushLookaheadc(int c) { |
639 | int putptr; | 665 | int putptr; |
640 | /* can't putback EOF, because it never leaves lookahead buffer */ | 666 | /* can't putback EOF, because it never leaves lookahead buffer */ |
641 | if (c == EOF) return; | 667 | if (c == EOF) return; |
642 | putptr = (int)lexBuf.getPtr - 1; | 668 | putptr = (int)lexBuf.getPtr - 1; |
643 | if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD; | 669 | if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD; |
644 | lexBuf.getPtr = putptr; | 670 | lexBuf.getPtr = putptr; |
645 | lexBuf.buf[putptr] = c; | 671 | lexBuf.buf[putptr] = c; |
646 | lexBuf.len += 1; | 672 | lexBuf.len += 1; |
647 | } | 673 | } |
648 | 674 | ||
649 | static char* lexLookaheadWord() { | 675 | static char* lexLookaheadWord() { |
650 | /* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0 | 676 | /* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0 |
651 | / and thing bigger than that will stop the lookahead and return 0; | 677 | / and thing bigger than that will stop the lookahead and return 0; |
652 | / leading white spaces are not recoverable. | 678 | / leading white spaces are not recoverable. |
653 | */ | 679 | */ |
654 | int c; | 680 | int c; |
655 | int len = 0; | 681 | int len = 0; |
656 | int curgetptr = 0; | 682 | int curgetptr = 0; |
657 | lexSkipWhite(); | 683 | lexSkipWhite(); |
658 | lexClearToken(); | 684 | lexClearToken(); |
659 | curgetptr = (int)lexBuf.getPtr;// remember! | 685 | curgetptr = (int)lexBuf.getPtr;// remember! |
660 | while (len < (MAX_LEX_LOOKAHEAD_0)) { | 686 | while (len < (MAX_LEX_LOOKAHEAD_0)) { |
661 | c = lexGetc(); | 687 | c = lexGetc(); |
662 | len++; | 688 | len++; |
663 | if (c == EOF || strchr("\t\n ;:=", c)) { | 689 | if (c == EOF || strchr("\t\n ;:=", c)) { |
664 | lexAppendc(0); | 690 | lexAppendc(0); |
665 | /* restore lookahead buf. */ | 691 | /* restore lookahead buf. */ |
666 | lexBuf.len += len; | 692 | lexBuf.len += len; |
667 | lexBuf.getPtr = curgetptr; | 693 | lexBuf.getPtr = curgetptr; |
668 | return lexStr(); | 694 | return lexStr(); |
669 | } | 695 | } |
670 | else | 696 | else |
671 | lexAppendc(c); | 697 | lexAppendc(c); |
672 | } | 698 | } |
673 | lexBuf.len += len;/* char that has been moved to lookahead buffer */ | 699 | lexBuf.len += len;/* char that has been moved to lookahead buffer */ |
674 | lexBuf.getPtr = curgetptr; | 700 | lexBuf.getPtr = curgetptr; |
675 | return 0; | 701 | return 0; |
676 | } | 702 | } |
677 | 703 | ||
678 | #ifdef _SUPPORT_LINE_FOLDING | 704 | #ifdef _SUPPORT_LINE_FOLDING |
679 | static void handleMoreRFC822LineBreak(int c) { | 705 | static void handleMoreRFC822LineBreak(int c) { |
680 | /* suport RFC 822 line break in cases like | 706 | /* suport RFC 822 line break in cases like |
681 | *ADR: foo; | 707 | *ADR: foo; |
682 | * morefoo; | 708 | * morefoo; |
683 | * more foo; | 709 | * more foo; |
684 | */ | 710 | */ |
685 | if (c == ';') { | 711 | if (c == ';') { |
686 | int a; | 712 | int a; |
687 | lexSkipLookahead(); | 713 | lexSkipLookahead(); |
688 | /* skip white spaces */ | 714 | /* skip white spaces */ |
689 | a = lexLookahead(); | 715 | a = lexLookahead(); |
690 | while (a == ' ' || a == '\t') { | 716 | while (a == ' ' || a == '\t') { |
691 | lexSkipLookahead(); | 717 | lexSkipLookahead(); |
692 | a = lexLookahead(); | 718 | a = lexLookahead(); |
693 | } | 719 | } |
694 | if (a == '\n') { | 720 | if (a == '\n') { |
695 | lexSkipLookahead(); | 721 | lexSkipLookahead(); |
696 | a = lexLookahead(); | 722 | a = lexLookahead(); |
697 | if (a == ' ' || a == '\t') { | 723 | if (a == ' ' || a == '\t') { |
698 | /* continuation, throw away all the \n and spaces read so | 724 | /* continuation, throw away all the \n and spaces read so |
699 | * far | 725 | * far |
700 | */ | 726 | */ |
701 | lexSkipWhite(); | 727 | lexSkipWhite(); |
702 | lexPushLookaheadc(';'); | 728 | lexPushLookaheadc(';'); |
703 | } | 729 | } |
704 | else { | 730 | else { |
705 | lexPushLookaheadc('\n'); | 731 | lexPushLookaheadc('\n'); |
706 | lexPushLookaheadc(';'); | 732 | lexPushLookaheadc(';'); |
@@ -736,810 +762,815 @@ static char* lexGet1Value() { | |||
736 | lexAppendc(' '); | 762 | lexAppendc(' '); |
737 | lexSkipLookahead(); | 763 | lexSkipLookahead(); |
738 | } | 764 | } |
739 | else { | 765 | else { |
740 | lexPushLookaheadc('\n'); | 766 | lexPushLookaheadc('\n'); |
741 | break; | 767 | break; |
742 | } | 768 | } |
743 | } | 769 | } |
744 | else { | 770 | else { |
745 | lexAppendc(c); | 771 | lexAppendc(c); |
746 | lexSkipLookahead(); | 772 | lexSkipLookahead(); |
747 | } | 773 | } |
748 | c = lexLookahead(); | 774 | c = lexLookahead(); |
749 | } | 775 | } |
750 | lexAppendc(0); | 776 | lexAppendc(0); |
751 | handleMoreRFC822LineBreak(c); | 777 | handleMoreRFC822LineBreak(c); |
752 | return c==EOF?0:lexStr(); | 778 | return c==EOF?0:lexStr(); |
753 | } | 779 | } |
754 | #endif | 780 | #endif |
755 | 781 | ||
756 | static int match_begin_name(int end) { | 782 | static int match_begin_name(int end) { |
757 | char *n = lexLookaheadWord(); | 783 | char *n = lexLookaheadWord(); |
758 | int token = ID; | 784 | int token = ID; |
759 | if (n) { | 785 | if (n) { |
760 | if (!qstricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD; | 786 | if (!qstricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD; |
761 | else if (!qstricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL; | 787 | else if (!qstricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL; |
762 | else if (!qstricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT; | 788 | else if (!qstricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT; |
763 | else if (!qstricmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO; | 789 | else if (!qstricmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO; |
764 | deleteStr(n); | 790 | deleteStr(n); |
765 | return token; | 791 | return token; |
766 | } | 792 | } |
767 | return 0; | 793 | return 0; |
768 | } | 794 | } |
769 | 795 | ||
770 | 796 | ||
771 | #ifdef INCLUDEMFC | 797 | #ifdef INCLUDEMFC |
772 | void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile) | 798 | void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile) |
773 | #else | 799 | #else |
774 | void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile) | 800 | void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile) |
775 | #endif | 801 | #endif |
776 | { | 802 | { |
777 | // initialize lex mode stack | 803 | // initialize lex mode stack |
778 | lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL; | 804 | lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL; |
779 | 805 | ||
780 | // iniatialize lex buffer. | 806 | // iniatialize lex buffer. |
781 | lexBuf.inputString = (char*) inputstring; | 807 | lexBuf.inputString = (char*) inputstring; |
782 | lexBuf.inputLen = inputlen; | 808 | lexBuf.inputLen = inputlen; |
783 | lexBuf.curPos = 0; | 809 | lexBuf.curPos = 0; |
784 | lexBuf.inputFile = inputfile; | 810 | lexBuf.inputFile = inputfile; |
785 | 811 | ||
786 | lexBuf.len = 0; | 812 | lexBuf.len = 0; |
787 | lexBuf.getPtr = 0; | 813 | lexBuf.getPtr = 0; |
788 | 814 | ||
789 | lexBuf.maxToken = MAXTOKEN; | 815 | lexBuf.maxToken = MAXTOKEN; |
790 | lexBuf.strs = (char*)malloc(MAXTOKEN); | 816 | lexBuf.strs = (char*)malloc(MAXTOKEN); |
791 | lexBuf.strsLen = 0; | 817 | lexBuf.strsLen = 0; |
792 | 818 | ||
793 | } | 819 | } |
794 | 820 | ||
795 | static void finiLex() { | 821 | static void finiLex() { |
796 | free(lexBuf.strs); | 822 | free(lexBuf.strs); |
797 | } | 823 | } |
798 | 824 | ||
799 | 825 | ||
800 | /*-----------------------------------*/ | 826 | /*-----------------------------------*/ |
801 | /* This parses and converts the base64 format for binary encoding into | 827 | /* This parses and converts the base64 format for binary encoding into |
802 | * a decoded buffer (allocated with new). See RFC 1521. | 828 | * a decoded buffer (allocated with new). See RFC 1521. |
803 | */ | 829 | */ |
804 | static char * lexGetDataFromBase64() | 830 | static char * lexGetDataFromBase64() |
805 | { | 831 | { |
806 | unsigned long bytesLen = 0, bytesMax = 0; | 832 | unsigned long bytesLen = 0, bytesMax = 0; |
807 | int quadIx = 0, pad = 0; | 833 | int quadIx = 0, pad = 0; |
808 | unsigned long trip = 0; | 834 | unsigned long trip = 0; |
809 | unsigned char b; | 835 | unsigned char b; |
810 | int c; | 836 | int c; |
811 | unsigned char *bytes = NULL; | 837 | unsigned char *bytes = NULL; |
812 | unsigned char *oldBytes = NULL; | 838 | unsigned char *oldBytes = NULL; |
813 | 839 | ||
814 | DBG_(("db: lexGetDataFromBase64\n")); | 840 | DBG_(("db: lexGetDataFromBase64\n")); |
815 | while (1) { | 841 | while (1) { |
816 | c = lexGetc(); | 842 | c = lexGetc(); |
817 | if (c == '\n') { | 843 | if (c == '\n') { |
818 | ++mime_lineNum; | 844 | ++mime_lineNum; |
819 | if (lexLookahead() == '\n') { | 845 | if (lexLookahead() == '\n') { |
820 | /* a '\n' character by itself means end of data */ | 846 | /* a '\n' character by itself means end of data */ |
821 | break; | 847 | break; |
822 | } | 848 | } |
823 | else continue; /* ignore '\n' */ | 849 | else continue; /* ignore '\n' */ |
824 | } | 850 | } |
825 | else { | 851 | else { |
826 | if ((c >= 'A') && (c <= 'Z')) | 852 | if ((c >= 'A') && (c <= 'Z')) |
827 | b = (unsigned char)(c - 'A'); | 853 | b = (unsigned char)(c - 'A'); |
828 | else if ((c >= 'a') && (c <= 'z')) | 854 | else if ((c >= 'a') && (c <= 'z')) |
829 | b = (unsigned char)(c - 'a') + 26; | 855 | b = (unsigned char)(c - 'a') + 26; |
830 | else if ((c >= '0') && (c <= '9')) | 856 | else if ((c >= '0') && (c <= '9')) |
831 | b = (unsigned char)(c - '0') + 52; | 857 | b = (unsigned char)(c - '0') + 52; |
832 | else if (c == '+') | 858 | else if (c == '+') |
833 | b = 62; | 859 | b = 62; |
834 | else if (c == '/') | 860 | else if (c == '/') |
835 | b = 63; | 861 | b = 63; |
836 | else if (c == '=') { | 862 | else if (c == '=') { |
837 | b = 0; | 863 | b = 0; |
838 | pad++; | 864 | pad++; |
839 | } else if ((c == ' ') || (c == '\t')) { | 865 | } else if ((c == ' ') || (c == '\t')) { |
840 | continue; | 866 | continue; |
841 | } else { /* error condition */ | 867 | } else { /* error condition */ |
842 | if (bytes) free(bytes); | 868 | if (bytes) free(bytes); |
843 | else if (oldBytes) free(oldBytes); | 869 | else if (oldBytes) free(oldBytes); |
844 | // error recovery: skip until 2 adjacent newlines. | 870 | // error recovery: skip until 2 adjacent newlines. |
845 | DBG_(("db: invalid character 0x%x '%c'\n", c,c)); | 871 | DBG_(("db: invalid character 0x%x '%c'\n", c,c)); |
846 | if (c != EOF) { | 872 | if (c != EOF) { |
847 | c = lexGetc(); | 873 | c = lexGetc(); |
848 | while (c != EOF) { | 874 | while (c != EOF) { |
849 | if (c == '\n' && lexLookahead() == '\n') { | 875 | if (c == '\n' && lexLookahead() == '\n') { |
850 | ++mime_lineNum; | 876 | ++mime_lineNum; |
851 | break; | 877 | break; |
852 | } | 878 | } |
853 | c = lexGetc(); | 879 | c = lexGetc(); |
854 | } | 880 | } |
855 | } | 881 | } |
856 | return NULL; | 882 | return NULL; |
857 | } | 883 | } |
858 | trip = (trip << 6) | b; | 884 | trip = (trip << 6) | b; |
859 | if (++quadIx == 4) { | 885 | if (++quadIx == 4) { |
860 | unsigned char outBytes[3]; | 886 | unsigned char outBytes[3]; |
861 | int numOut; | 887 | int numOut; |
862 | int i; | 888 | int i; |
863 | for (i = 0; i < 3; i++) { | 889 | for (i = 0; i < 3; i++) { |
864 | outBytes[2-i] = (unsigned char)(trip & 0xFF); | 890 | outBytes[2-i] = (unsigned char)(trip & 0xFF); |
865 | trip >>= 8; | 891 | trip >>= 8; |
866 | } | 892 | } |
867 | numOut = 3 - pad; | 893 | numOut = 3 - pad; |
868 | if (bytesLen + numOut > bytesMax) { | 894 | if (bytesLen + numOut > bytesMax) { |
869 | if (!bytes) { | 895 | if (!bytes) { |
870 | bytesMax = 1024; | 896 | bytesMax = 1024; |
871 | bytes = (unsigned char*)malloc((size_t)bytesMax); | 897 | bytes = (unsigned char*)malloc((size_t)bytesMax); |
872 | } | 898 | } |
873 | else { | 899 | else { |
874 | bytesMax <<= 2; | 900 | bytesMax <<= 2; |
875 | oldBytes = bytes; | 901 | oldBytes = bytes; |
876 | bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax); | 902 | bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax); |
877 | } | 903 | } |
878 | if (bytes == 0) { | 904 | if (bytes == 0) { |
879 | mime_error("out of memory while processing BASE64 data\n"); | 905 | mime_error("out of memory while processing BASE64 data\n"); |
880 | } | 906 | } |
881 | } | 907 | } |
882 | if (bytes) { | 908 | if (bytes) { |
883 | memcpy(bytes + bytesLen, outBytes, numOut); | 909 | memcpy(bytes + bytesLen, outBytes, numOut); |
884 | bytesLen += numOut; | 910 | bytesLen += numOut; |
885 | } | 911 | } |
886 | trip = 0; | 912 | trip = 0; |
887 | quadIx = 0; | 913 | quadIx = 0; |
888 | } | 914 | } |
889 | } | 915 | } |
890 | } /* while */ | 916 | } /* while */ |
891 | DBG_(("db: bytesLen = %d\n", bytesLen)); | 917 | DBG_(("db: bytesLen = %d\n", bytesLen)); |
892 | /* kludge: all this won't be necessary if we have tree form | 918 | /* kludge: all this won't be necessary if we have tree form |
893 | representation */ | 919 | representation */ |
894 | if (bytes) { | 920 | if (bytes) { |
895 | setValueWithSize(curProp,bytes,(unsigned int)bytesLen); | 921 | setValueWithSize(curProp,bytes,(unsigned int)bytesLen); |
896 | free(bytes); | 922 | free(bytes); |
897 | } | 923 | } |
898 | else if (oldBytes) { | 924 | else if (oldBytes) { |
899 | setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen); | 925 | setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen); |
900 | free(oldBytes); | 926 | free(oldBytes); |
901 | } | 927 | } |
902 | return 0; | 928 | return 0; |
903 | } | 929 | } |
904 | 930 | ||
905 | static int match_begin_end_name(int end) { | 931 | static int match_begin_end_name(int end) { |
906 | int token; | 932 | int token; |
907 | lexSkipWhite(); | 933 | lexSkipWhite(); |
908 | if (lexLookahead() != ':') return ID; | 934 | if (lexLookahead() != ':') return ID; |
909 | lexSkipLookahead(); | 935 | lexSkipLookahead(); |
910 | lexSkipWhite(); | 936 | lexSkipWhite(); |
911 | token = match_begin_name(end); | 937 | token = match_begin_name(end); |
912 | if (token == ID) { | 938 | if (token == ID) { |
913 | lexPushLookaheadc(':'); | 939 | lexPushLookaheadc(':'); |
914 | DBG_(("db: ID '%s'\n", yylval.str)); | 940 | DBG_(("db: ID '%s'\n", yylval.str)); |
915 | return ID; | 941 | return ID; |
916 | } | 942 | } |
917 | else if (token != 0) { | 943 | else if (token != 0) { |
918 | lexSkipLookaheadWord(); | 944 | lexSkipLookaheadWord(); |
919 | deleteStr(yylval.str); | 945 | deleteStr(yylval.str); |
920 | DBG_(("db: begin/end %d\n", token)); | 946 | DBG_(("db: begin/end %d\n", token)); |
921 | return token; | 947 | return token; |
922 | } | 948 | } |
923 | return 0; | 949 | return 0; |
924 | } | 950 | } |
925 | 951 | ||
926 | static char* lexGetQuotedPrintable() | 952 | static char* lexGetQuotedPrintable() |
927 | { | 953 | { |
928 | char cur; | 954 | int cur; |
929 | 955 | ||
930 | lexClearToken(); | 956 | lexClearToken(); |
931 | do { | 957 | do { |
932 | cur = lexGetc(); | 958 | cur = lexGetc(); |
933 | switch (cur) { | 959 | switch (cur) { |
934 | case '=': { | 960 | case '=': { |
935 | int c = 0; | 961 | int c = 0; |
936 | int next[2]; | 962 | int next[2]; |
937 | int i; | 963 | int i; |
938 | for (i = 0; i < 2; i++) { | 964 | for (i = 0; i < 2; i++) { |
939 | next[i] = lexGetc(); | 965 | next[i] = lexGetc(); |
940 | if (next[i] >= '0' && next[i] <= '9') | 966 | if (next[i] >= '0' && next[i] <= '9') |
941 | c = c * 16 + next[i] - '0'; | 967 | c = c * 16 + next[i] - '0'; |
942 | else if (next[i] >= 'A' && next[i] <= 'F') | 968 | else if (next[i] >= 'A' && next[i] <= 'F') |
943 | c = c * 16 + next[i] - 'A' + 10; | 969 | c = c * 16 + next[i] - 'A' + 10; |
944 | else | 970 | else |
945 | break; | 971 | break; |
946 | } | 972 | } |
947 | if (i == 0) { | 973 | if (i == 0) { |
948 | /* single '=' follow by LINESEP is continuation sign? */ | 974 | /* single '=' follow by LINESEP is continuation sign? */ |
949 | if (next[0] == '\n') { | 975 | if (next[0] == '\n') { |
950 | ++mime_lineNum; | 976 | ++mime_lineNum; |
951 | } | 977 | } |
952 | else { | 978 | else { |
953 | lexPushLookaheadc('='); | 979 | lexPushLookaheadc('='); |
954 | goto EndString; | 980 | goto EndString; |
955 | } | 981 | } |
956 | } | 982 | } |
957 | else if (i == 1) { | 983 | else if (i == 1) { |
958 | lexPushLookaheadc(next[1]); | 984 | lexPushLookaheadc(next[1]); |
959 | lexPushLookaheadc(next[0]); | 985 | lexPushLookaheadc(next[0]); |
960 | lexAppendc('='); | 986 | lexAppendc('='); |
961 | } else { | 987 | } else { |
962 | lexAppendc(c); | 988 | lexAppendc(c); |
963 | } | 989 | } |
964 | break; | 990 | break; |
965 | } /* '=' */ | 991 | } /* '=' */ |
966 | case '\n': { | 992 | case '\n': { |
967 | lexPushLookaheadc('\n'); | 993 | lexPushLookaheadc('\n'); |
968 | goto EndString; | 994 | goto EndString; |
969 | } | 995 | } |
970 | case (char)EOF: | 996 | case (int)EOF: |
971 | break; | 997 | break; |
972 | default: | 998 | default: |
973 | lexAppendc(cur); | 999 | lexAppendc(cur); |
974 | break; | 1000 | break; |
975 | } /* switch */ | 1001 | } /* switch */ |
976 | } while (cur != (char)EOF); | 1002 | } while (cur != (int)EOF); |
977 | 1003 | ||
978 | EndString: | 1004 | EndString: |
979 | lexAppendc(0); | 1005 | lexAppendc(0); |
980 | return lexStr(); | 1006 | return lexStr(); |
981 | } /* LexQuotedPrintable */ | 1007 | } /* LexQuotedPrintable */ |
982 | 1008 | ||
983 | static int yylex() { | 1009 | static int yylex() { |
984 | 1010 | ||
985 | int lexmode = LEXMODE(); | 1011 | int lexmode = LEXMODE(); |
986 | if (lexmode == L_VALUES) { | 1012 | if (lexmode == L_VALUES) { |
987 | int c = lexGetc(); | 1013 | int c = lexGetc(); |
988 | if (c == ';') { | 1014 | if (c == ';') { |
989 | DBG_(("db: SEMICOLON\n")); | 1015 | DBG_(("db: SEMICOLON\n")); |
990 | lexPushLookaheadc(c); | 1016 | lexPushLookaheadc(c); |
991 | handleMoreRFC822LineBreak(c); | 1017 | handleMoreRFC822LineBreak(c); |
992 | lexSkipLookahead(); | 1018 | lexSkipLookahead(); |
993 | return SEMICOLON; | 1019 | return SEMICOLON; |
994 | } | 1020 | } |
995 | else if (strchr("\n",c)) { | 1021 | else if (strchr("\n",c)) { |
996 | ++mime_lineNum; | 1022 | ++mime_lineNum; |
997 | /* consume all line separator(s) adjacent to each other */ | 1023 | /* consume all line separator(s) adjacent to each other */ |
998 | c = lexLookahead(); | 1024 | c = lexLookahead(); |
999 | while (strchr("\n",c)) { | 1025 | while (strchr("\n",c)) { |
1000 | lexSkipLookahead(); | 1026 | lexSkipLookahead(); |
1001 | c = lexLookahead(); | 1027 | c = lexLookahead(); |
1002 | ++mime_lineNum; | 1028 | ++mime_lineNum; |
1003 | } | 1029 | } |
1004 | DBG_(("db: LINESEP\n")); | 1030 | DBG_(("db: LINESEP\n")); |
1005 | return LINESEP; | 1031 | return LINESEP; |
1006 | } | 1032 | } |
1007 | else { | 1033 | else { |
1008 | char *p = 0; | 1034 | char *p = 0; |
1009 | lexPushLookaheadc(c); | 1035 | lexPushLookaheadc(c); |
1010 | if (lexWithinMode(L_BASE64)) { | 1036 | if (lexWithinMode(L_BASE64)) { |
1011 | /* get each char and convert to bin on the fly... */ | 1037 | /* get each char and convert to bin on the fly... */ |
1012 | p = lexGetDataFromBase64(); | 1038 | p = lexGetDataFromBase64(); |
1013 | yylval.str = p; | 1039 | yylval.str = p; |
1014 | return STRING; | 1040 | return STRING; |
1015 | } | 1041 | } |
1016 | else if (lexWithinMode(L_QUOTED_PRINTABLE)) { | 1042 | else if (lexWithinMode(L_QUOTED_PRINTABLE)) { |
1017 | p = lexGetQuotedPrintable(); | 1043 | p = lexGetQuotedPrintable(); |
1018 | } | 1044 | } |
1019 | else { | 1045 | else { |
1020 | #ifdef _SUPPORT_LINE_FOLDING | 1046 | #ifdef _SUPPORT_LINE_FOLDING |
1021 | p = lexGet1Value(); | 1047 | p = lexGet1Value(); |
1022 | #else | 1048 | #else |
1023 | p = lexGetStrUntil(";\n"); | 1049 | p = lexGetStrUntil(";\n"); |
1024 | #endif | 1050 | #endif |
1025 | } | 1051 | } |
1026 | if (p) { | 1052 | if (p) { |
1027 | DBG_(("db: STRING: '%s'\n", p)); | 1053 | DBG_(("db: STRING: '%s'\n", p)); |
1028 | yylval.str = p; | 1054 | yylval.str = p; |
1029 | return STRING; | 1055 | return STRING; |
1030 | } | 1056 | } |
1031 | else return 0; | 1057 | else return 0; |
1032 | } | 1058 | } |
1033 | } | 1059 | } |
1034 | else { | 1060 | else { |
1035 | /* normal mode */ | 1061 | /* normal mode */ |
1036 | while (1) { | 1062 | while (1) { |
1037 | int c = lexGetc(); | 1063 | int c = lexGetc(); |
1038 | switch(c) { | 1064 | switch(c) { |
1039 | case ':': { | 1065 | case ':': { |
1040 | /* consume all line separator(s) adjacent to each other */ | 1066 | /* consume all line separator(s) adjacent to each other */ |
1041 | /* ignoring linesep immediately after colon. */ | 1067 | /* ignoring linesep immediately after colon. */ |
1042 | c = lexLookahead(); | 1068 | c = lexLookahead(); |
1043 | while (strchr("\n",c)) { | 1069 | while (strchr("\n",c)) { |
1044 | lexSkipLookahead(); | 1070 | lexSkipLookahead(); |
1045 | c = lexLookahead(); | 1071 | c = lexLookahead(); |
1046 | ++mime_lineNum; | 1072 | ++mime_lineNum; |
1047 | } | 1073 | } |
1048 | DBG_(("db: COLON\n")); | 1074 | DBG_(("db: COLON\n")); |
1049 | return COLON; | 1075 | return COLON; |
1050 | } | 1076 | } |
1051 | case ';': | 1077 | case ';': |
1052 | DBG_(("db: SEMICOLON\n")); | 1078 | DBG_(("db: SEMICOLON\n")); |
1053 | return SEMICOLON; | 1079 | return SEMICOLON; |
1054 | case '=': | 1080 | case '=': |
1055 | DBG_(("db: EQ\n")); | 1081 | DBG_(("db: EQ\n")); |
1056 | return EQ; | 1082 | return EQ; |
1057 | /* ignore whitespace in this mode */ | 1083 | /* ignore whitespace in this mode */ |
1058 | case '\t': | 1084 | case '\t': |
1059 | case ' ': continue; | 1085 | case ' ': continue; |
1060 | case '\n': { | 1086 | case '\n': { |
1061 | ++mime_lineNum; | 1087 | ++mime_lineNum; |
1062 | continue; | 1088 | continue; |
1063 | } | 1089 | } |
1064 | case EOF: return 0; | 1090 | case EOF: return 0; |
1065 | break; | 1091 | break; |
1066 | default: { | 1092 | default: { |
1067 | lexPushLookaheadc(c); | 1093 | lexPushLookaheadc(c); |
1068 | if (isalnum(c)) { | 1094 | if (isalnum(c)) { |
1069 | char *t = lexGetWord(); | 1095 | char *t = lexGetWord(); |
1070 | yylval.str = t; | 1096 | yylval.str = t; |
1071 | if (!qstricmp(t, "begin")) { | 1097 | if (!qstricmp(t, "begin")) { |
1072 | return match_begin_end_name(0); | 1098 | return match_begin_end_name(0); |
1073 | } | 1099 | } |
1074 | else if (!qstricmp(t,"end")) { | 1100 | else if (!qstricmp(t,"end")) { |
1075 | return match_begin_end_name(1); | 1101 | return match_begin_end_name(1); |
1076 | } | 1102 | } |
1077 | else { | 1103 | else { |
1078 | DBG_(("db: ID '%s'\n", t)); | 1104 | DBG_(("db: ID '%s'\n", t)); |
1079 | return ID; | 1105 | return ID; |
1080 | } | 1106 | } |
1081 | } | 1107 | } |
1082 | else { | 1108 | else { |
1083 | /* unknow token */ | 1109 | /* unknow token */ |
1084 | return 0; | 1110 | return 0; |
1085 | } | 1111 | } |
1086 | break; | 1112 | break; |
1087 | } | 1113 | } |
1088 | } | 1114 | } |
1089 | } | 1115 | } |
1090 | } | 1116 | } |
1091 | return 0; | 1117 | return 0; |
1092 | } | 1118 | } |
1093 | 1119 | ||
1094 | 1120 | ||
1095 | /***************************************************************************/ | 1121 | /***************************************************************************/ |
1096 | /*** Public Functions ****/ | 1122 | /*** Public Functions ****/ |
1097 | /***************************************************************************/ | 1123 | /***************************************************************************/ |
1098 | 1124 | ||
1099 | static VObject* Parse_MIMEHelper() | 1125 | static VObject* Parse_MIMEHelper() |
1100 | { | 1126 | { |
1101 | ObjStackTop = -1; | 1127 | ObjStackTop = -1; |
1102 | mime_numErrors = 0; | 1128 | mime_numErrors = 0; |
1103 | mime_lineNum = 1; | 1129 | mime_lineNum = 1; |
1104 | vObjList = 0; | 1130 | vObjList = 0; |
1105 | curObj = 0; | 1131 | curObj = 0; |
1106 | 1132 | ||
1107 | if (yyparse() != 0) | 1133 | if (yyparse() != 0) |
1108 | return 0; | 1134 | return 0; |
1109 | 1135 | ||
1110 | finiLex(); | 1136 | finiLex(); |
1111 | return vObjList; | 1137 | return vObjList; |
1112 | } | 1138 | } |
1113 | 1139 | ||
1114 | /*--------------------------------------------*/ | 1140 | /*--------------------------------------------*/ |
1115 | DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len) | 1141 | DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len) |
1116 | { | 1142 | { |
1117 | initLex(input, len, 0); | 1143 | initLex(input, len, 0); |
1118 | return Parse_MIMEHelper(); | 1144 | return Parse_MIMEHelper(); |
1119 | } | 1145 | } |
1120 | 1146 | ||
1121 | 1147 | ||
1122 | #if INCLUDEMFC | 1148 | #if INCLUDEMFC |
1123 | 1149 | ||
1124 | DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file) | 1150 | DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file) |
1125 | { | 1151 | { |
1126 | unsigned long startPos; | 1152 | unsigned long startPos; |
1127 | VObject *result; | 1153 | VObject *result; |
1128 | 1154 | ||
1129 | initLex(0,-1,file); | 1155 | initLex(0,-1,file); |
1130 | startPos = file->GetPosition(); | 1156 | startPos = file->GetPosition(); |
1131 | if (!(result = Parse_MIMEHelper())) | 1157 | if (!(result = Parse_MIMEHelper())) |
1132 | file->Seek(startPos, CFile::begin); | 1158 | file->Seek(startPos, CFile::begin); |
1133 | return result; | 1159 | return result; |
1134 | } | 1160 | } |
1135 | 1161 | ||
1136 | #else | 1162 | #else |
1137 | 1163 | ||
1138 | VObject* Parse_MIME_FromFile(FILE *file) | 1164 | VObject* Parse_MIME_FromFile(FILE *file) |
1139 | { | 1165 | { |
1140 | VObject *result; | 1166 | VObject *result; |
1141 | long startPos; | 1167 | long startPos; |
1142 | 1168 | ||
1143 | initLex(0,(unsigned long)-1,file); | 1169 | initLex(0,(unsigned long)-1,file); |
1144 | startPos = ftell(file); | 1170 | startPos = ftell(file); |
1145 | if (!(result = Parse_MIMEHelper())) { | 1171 | if (!(result = Parse_MIMEHelper())) { |
1146 | fseek(file,startPos,SEEK_SET); | 1172 | fseek(file,startPos,SEEK_SET); |
1147 | } | 1173 | } |
1148 | return result; | 1174 | return result; |
1149 | } | 1175 | } |
1150 | 1176 | ||
1151 | DLLEXPORT(VObject*) Parse_MIME_FromFileName(char *fname) | 1177 | DLLEXPORT(VObject*) Parse_MIME_FromFileName(char *fname) |
1152 | { | 1178 | { |
1153 | QFileDirect f( fname ); | 1179 | FILE *fp = fopen(fname,"r"); |
1154 | if ( !f.open( IO_ReadOnly ) ) { | 1180 | if (fp) { |
1155 | qWarning("Unable to open mime for reading %s", fname); | 1181 | VObject* o = Parse_MIME_FromFile(fp); |
1156 | return 0; | 1182 | fclose(fp); |
1183 | return o; | ||
1184 | } | ||
1185 | else { | ||
1186 | char msg[80]; | ||
1187 | sprintf(msg, "can't open file '%s' for reading\n", fname); | ||
1188 | mime_error_(msg); | ||
1189 | return 0; | ||
1157 | } | 1190 | } |
1158 | |||
1159 | return Parse_MIME_FromFile( f.directHandle() ); | ||
1160 | } | 1191 | } |
1161 | 1192 | ||
1162 | #endif | 1193 | #endif |
1163 | 1194 | ||
1164 | /*-------------------------------------*/ | 1195 | /*-------------------------------------*/ |
1165 | 1196 | ||
1166 | static MimeErrorHandler mimeErrorHandler; | 1197 | static MimeErrorHandler mimeErrorHandler; |
1167 | 1198 | ||
1168 | DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler me) | 1199 | DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler me) |
1169 | { | 1200 | { |
1170 | mimeErrorHandler = me; | 1201 | mimeErrorHandler = me; |
1171 | } | 1202 | } |
1172 | 1203 | ||
1173 | void mime_error(char *s) | 1204 | void mime_error(char *s) |
1174 | { | 1205 | { |
1175 | char msg[256]; | 1206 | char msg[256]; |
1176 | if (mimeErrorHandler) { | 1207 | if (mimeErrorHandler) { |
1177 | sprintf(msg,"%s at line %d", s, mime_lineNum); | 1208 | sprintf(msg,"%s at line %d", s, mime_lineNum); |
1178 | mimeErrorHandler(msg); | 1209 | mimeErrorHandler(msg); |
1179 | } | 1210 | } |
1180 | } | 1211 | } |
1181 | 1212 | ||
1182 | void mime_error_(char *s) | 1213 | void mime_error_(char *s) |
1183 | { | 1214 | { |
1184 | if (mimeErrorHandler) { | 1215 | if (mimeErrorHandler) { |
1185 | mimeErrorHandler(s); | 1216 | mimeErrorHandler(s); |
1186 | } | 1217 | } |
1187 | } | 1218 | } |
1188 | 1219 | ||
1189 | #line 1192 "y.tab.c" | 1220 | #line 1221 "y.tab.c" |
1190 | #define YYABORT goto yyabort | 1221 | #define YYABORT goto yyabort |
1191 | #define YYREJECT goto yyabort | 1222 | #define YYREJECT goto yyabort |
1192 | #define YYACCEPT goto yyaccept | 1223 | #define YYACCEPT goto yyaccept |
1193 | #define YYERROR goto yyerrlab | 1224 | #define YYERROR goto yyerrlab |
1194 | int | 1225 | int |
1226 | #if defined(__STDC__) | ||
1227 | yyparse(void) | ||
1228 | #else | ||
1195 | yyparse() | 1229 | yyparse() |
1230 | #endif | ||
1196 | { | 1231 | { |
1197 | register int yym, yyn, yystate; | 1232 | register int yym, yyn, yystate; |
1198 | #if YYDEBUG | 1233 | #if YYDEBUG |
1199 | register char *yys; | 1234 | register char *yys; |
1200 | extern char *getenv(); | 1235 | extern char *getenv(); |
1201 | 1236 | ||
1202 | if (yys = getenv("YYDEBUG")) | 1237 | if (yys = getenv("YYDEBUG")) |
1203 | { | 1238 | { |
1204 | yyn = *yys; | 1239 | yyn = *yys; |
1205 | if (yyn >= '0' && yyn <= '9') | 1240 | if (yyn >= '0' && yyn <= '9') |
1206 | yydebug = yyn - '0'; | 1241 | yydebug = yyn - '0'; |
1207 | } | 1242 | } |
1208 | #endif | 1243 | #endif |
1209 | 1244 | ||
1210 | yynerrs = 0; | 1245 | yynerrs = 0; |
1211 | yyerrflag = 0; | 1246 | yyerrflag = 0; |
1212 | yychar = (-1); | 1247 | yychar = (-1); |
1213 | 1248 | ||
1214 | yyssp = yyss; | 1249 | yyssp = yyss; |
1215 | yyvsp = yyvs; | 1250 | yyvsp = yyvs; |
1216 | *yyssp = yystate = 0; | 1251 | *yyssp = yystate = 0; |
1217 | 1252 | ||
1218 | yyloop: | 1253 | yyloop: |
1219 | if (yyn = yydefred[yystate]) goto yyreduce; | 1254 | if ((yyn = yydefred[yystate]) != 0) goto yyreduce; |
1220 | if (yychar < 0) | 1255 | if (yychar < 0) |
1221 | { | 1256 | { |
1222 | if ((yychar = yylex()) < 0) yychar = 0; | 1257 | if ((yychar = yylex()) < 0) yychar = 0; |
1223 | #if YYDEBUG | 1258 | #if YYDEBUG |
1224 | if (yydebug) | 1259 | if (yydebug) |
1225 | { | 1260 | { |
1226 | yys = 0; | 1261 | yys = 0; |
1227 | if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; | 1262 | if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; |
1228 | if (!yys) yys = "illegal-symbol"; | 1263 | if (!yys) yys = "illegal-symbol"; |
1229 | printf("%sdebug: state %d, reading %d (%s)\n", | 1264 | printf("%sdebug: state %d, reading %d (%s)\n", |
1230 | YYPREFIX, yystate, yychar, yys); | 1265 | YYPREFIX, yystate, yychar, yys); |
1231 | } | 1266 | } |
1232 | #endif | 1267 | #endif |
1233 | } | 1268 | } |
1234 | if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && | 1269 | if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && |
1235 | yyn <= YYTABLESIZE && yycheck[yyn] == yychar) | 1270 | yyn <= YYTABLESIZE && yycheck[yyn] == yychar) |
1236 | { | 1271 | { |
1237 | #if YYDEBUG | 1272 | #if YYDEBUG |
1238 | if (yydebug) | 1273 | if (yydebug) |
1239 | printf("%sdebug: state %d, shifting to state %d\n", | 1274 | printf("%sdebug: state %d, shifting to state %d\n", |
1240 | YYPREFIX, yystate, yytable[yyn]); | 1275 | YYPREFIX, yystate, yytable[yyn]); |
1241 | #endif | 1276 | #endif |
1242 | if (yyssp >= yyss + yystacksize - 1) | 1277 | if (yyssp >= yyss + yystacksize - 1) |
1243 | { | 1278 | { |
1244 | goto yyoverflow; | 1279 | goto yyoverflow; |
1245 | } | 1280 | } |
1246 | *++yyssp = yystate = yytable[yyn]; | 1281 | *++yyssp = yystate = yytable[yyn]; |
1247 | *++yyvsp = yylval; | 1282 | *++yyvsp = yylval; |
1248 | yychar = (-1); | 1283 | yychar = (-1); |
1249 | if (yyerrflag > 0) --yyerrflag; | 1284 | if (yyerrflag > 0) --yyerrflag; |
1250 | goto yyloop; | 1285 | goto yyloop; |
1251 | } | 1286 | } |
1252 | if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && | 1287 | if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && |
1253 | yyn <= YYTABLESIZE && yycheck[yyn] == yychar) | 1288 | yyn <= YYTABLESIZE && yycheck[yyn] == yychar) |
1254 | { | 1289 | { |
1255 | yyn = yytable[yyn]; | 1290 | yyn = yytable[yyn]; |
1256 | goto yyreduce; | 1291 | goto yyreduce; |
1257 | } | 1292 | } |
1258 | if (yyerrflag) goto yyinrecovery; | 1293 | if (yyerrflag) goto yyinrecovery; |
1259 | #ifdef lint | ||
1260 | goto yynewerror; | ||
1261 | #endif | ||
1262 | yynewerror: | ||
1263 | yyerror("syntax error"); | 1294 | yyerror("syntax error"); |
1264 | #ifdef lint | 1295 | #ifdef lint |
1265 | goto yyerrlab; | 1296 | goto yyerrlab; |
1266 | #endif | 1297 | #endif |
1267 | yyerrlab: | 1298 | yyerrlab: |
1268 | ++yynerrs; | 1299 | ++yynerrs; |
1269 | yyinrecovery: | 1300 | yyinrecovery: |
1270 | if (yyerrflag < 3) | 1301 | if (yyerrflag < 3) |
1271 | { | 1302 | { |
1272 | yyerrflag = 3; | 1303 | yyerrflag = 3; |
1273 | for (;;) | 1304 | for (;;) |
1274 | { | 1305 | { |
1275 | if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 && | 1306 | if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 && |
1276 | yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) | 1307 | yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) |
1277 | { | 1308 | { |
1278 | #if YYDEBUG | 1309 | #if YYDEBUG |
1279 | if (yydebug) | 1310 | if (yydebug) |
1280 | printf("%sdebug: state %d, error recovery shifting\ | 1311 | printf("%sdebug: state %d, error recovery shifting\ |
1281 | to state %d\n", YYPREFIX, *yyssp, yytable[yyn]); | 1312 | to state %d\n", YYPREFIX, *yyssp, yytable[yyn]); |
1282 | #endif | 1313 | #endif |
1283 | if (yyssp >= yyss + yystacksize - 1) | 1314 | if (yyssp >= yyss + yystacksize - 1) |
1284 | { | 1315 | { |
1285 | goto yyoverflow; | 1316 | goto yyoverflow; |
1286 | } | 1317 | } |
1287 | *++yyssp = yystate = yytable[yyn]; | 1318 | *++yyssp = yystate = yytable[yyn]; |
1288 | *++yyvsp = yylval; | 1319 | *++yyvsp = yylval; |
1289 | goto yyloop; | 1320 | goto yyloop; |
1290 | } | 1321 | } |
1291 | else | 1322 | else |
1292 | { | 1323 | { |
1293 | #if YYDEBUG | 1324 | #if YYDEBUG |
1294 | if (yydebug) | 1325 | if (yydebug) |
1295 | printf("%sdebug: error recovery discarding state %d\n", | 1326 | printf("%sdebug: error recovery discarding state %d\n", |
1296 | YYPREFIX, *yyssp); | 1327 | YYPREFIX, *yyssp); |
1297 | #endif | 1328 | #endif |
1298 | if (yyssp <= yyss) goto yyabort; | 1329 | if (yyssp <= yyss) goto yyabort; |
1299 | --yyssp; | 1330 | --yyssp; |
1300 | --yyvsp; | 1331 | --yyvsp; |
1301 | } | 1332 | } |
1302 | } | 1333 | } |
1303 | } | 1334 | } |
1304 | else | 1335 | else |
1305 | { | 1336 | { |
1306 | if (yychar == 0) goto yyabort; | 1337 | if (yychar == 0) goto yyabort; |
1307 | #if YYDEBUG | 1338 | #if YYDEBUG |
1308 | if (yydebug) | 1339 | if (yydebug) |
1309 | { | 1340 | { |
1310 | yys = 0; | 1341 | yys = 0; |
1311 | if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; | 1342 | if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; |
1312 | if (!yys) yys = "illegal-symbol"; | 1343 | if (!yys) yys = "illegal-symbol"; |
1313 | printf("%sdebug: state %d, error recovery discards token %d (%s)\n", | 1344 | printf("%sdebug: state %d, error recovery discards token %d (%s)\n", |
1314 | YYPREFIX, yystate, yychar, yys); | 1345 | YYPREFIX, yystate, yychar, yys); |
1315 | } | 1346 | } |
1316 | #endif | 1347 | #endif |
1317 | yychar = (-1); | 1348 | yychar = (-1); |
1318 | goto yyloop; | 1349 | goto yyloop; |
1319 | } | 1350 | } |
1320 | yyreduce: | 1351 | yyreduce: |
1321 | #if YYDEBUG | 1352 | #if YYDEBUG |
1322 | if (yydebug) | 1353 | if (yydebug) |
1323 | printf("%sdebug: state %d, reducing by rule %d (%s)\n", | 1354 | printf("%sdebug: state %d, reducing by rule %d (%s)\n", |
1324 | YYPREFIX, yystate, yyn, yyrule[yyn]); | 1355 | YYPREFIX, yystate, yyn, yyrule[yyn]); |
1325 | #endif | 1356 | #endif |
1326 | yym = yylen[yyn]; | 1357 | yym = yylen[yyn]; |
1327 | yyval = yyvsp[1-yym]; | 1358 | yyval = yyvsp[1-yym]; |
1328 | switch (yyn) | 1359 | switch (yyn) |
1329 | { | 1360 | { |
1330 | case 2: | 1361 | case 2: |
1331 | #line 217 "vcc.y" | 1362 | #line 221 "backend/vcc.y" |
1332 | { addList(&vObjList, yyvsp[0].vobj); curObj = 0; } | 1363 | { addList(&vObjList, yyvsp[0].vobj); curObj = 0; } |
1333 | break; | 1364 | break; |
1334 | case 3: | 1365 | case 3: |
1335 | #line 219 "vcc.y" | 1366 | #line 223 "backend/vcc.y" |
1336 | { addList(&vObjList, yyvsp[0].vobj); curObj = 0; } | 1367 | { addList(&vObjList, yyvsp[0].vobj); curObj = 0; } |
1337 | break; | 1368 | break; |
1338 | case 6: | 1369 | case 6: |
1339 | #line 228 "vcc.y" | 1370 | #line 232 "backend/vcc.y" |
1340 | { | 1371 | { |
1341 | lexPushMode(L_VCARD); | 1372 | lexPushMode(L_VCARD); |
1342 | if (!pushVObject(VCCardProp)) YYERROR; | 1373 | if (!pushVObject(VCCardProp)) YYERROR; |
1343 | } | 1374 | } |
1344 | break; | 1375 | break; |
1345 | case 7: | 1376 | case 7: |
1346 | #line 233 "vcc.y" | 1377 | #line 237 "backend/vcc.y" |
1347 | { | 1378 | { |
1348 | lexPopMode(0); | 1379 | lexPopMode(0); |
1349 | yyval.vobj = popVObject(); | 1380 | yyval.vobj = popVObject(); |
1350 | } | 1381 | } |
1351 | break; | 1382 | break; |
1352 | case 8: | 1383 | case 8: |
1353 | #line 238 "vcc.y" | 1384 | #line 242 "backend/vcc.y" |
1354 | { | 1385 | { |
1355 | lexPushMode(L_VCARD); | 1386 | lexPushMode(L_VCARD); |
1356 | if (!pushVObject(VCCardProp)) YYERROR; | 1387 | if (!pushVObject(VCCardProp)) YYERROR; |
1357 | } | 1388 | } |
1358 | break; | 1389 | break; |
1359 | case 9: | 1390 | case 9: |
1360 | #line 243 "vcc.y" | 1391 | #line 247 "backend/vcc.y" |
1361 | { | 1392 | { |
1362 | lexPopMode(0); | 1393 | lexPopMode(0); |
1363 | yyval.vobj = popVObject(); | 1394 | yyval.vobj = popVObject(); |
1364 | } | 1395 | } |
1365 | break; | 1396 | break; |
1366 | case 12: | 1397 | case 12: |
1367 | #line 254 "vcc.y" | 1398 | #line 258 "backend/vcc.y" |
1368 | { | 1399 | { |
1369 | lexPushMode(L_VALUES); | 1400 | lexPushMode(L_VALUES); |
1370 | } | 1401 | } |
1371 | break; | 1402 | break; |
1372 | case 13: | 1403 | case 13: |
1373 | #line 258 "vcc.y" | 1404 | #line 262 "backend/vcc.y" |
1374 | { | 1405 | { |
1375 | if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE)) | 1406 | if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE)) |
1376 | lexPopMode(0); | 1407 | lexPopMode(0); |
1377 | lexPopMode(0); | 1408 | lexPopMode(0); |
1378 | } | 1409 | } |
1379 | break; | 1410 | break; |
1380 | case 15: | 1411 | case 15: |
1381 | #line 267 "vcc.y" | 1412 | #line 271 "backend/vcc.y" |
1382 | { | 1413 | { |
1383 | enterProps(yyvsp[0].str); | 1414 | enterProps(yyvsp[0].str); |
1384 | } | 1415 | } |
1385 | break; | 1416 | break; |
1386 | case 17: | 1417 | case 17: |
1387 | #line 272 "vcc.y" | 1418 | #line 276 "backend/vcc.y" |
1388 | { | 1419 | { |
1389 | enterProps(yyvsp[0].str); | 1420 | enterProps(yyvsp[0].str); |
1390 | } | 1421 | } |
1391 | break; | 1422 | break; |
1392 | case 21: | 1423 | case 21: |
1393 | #line 285 "vcc.y" | 1424 | #line 289 "backend/vcc.y" |
1394 | { | 1425 | { |
1395 | enterAttr(yyvsp[0].str,0); | 1426 | enterAttr(yyvsp[0].str,0); |
1396 | } | 1427 | } |
1397 | break; | 1428 | break; |
1398 | case 22: | 1429 | case 22: |
1399 | #line 289 "vcc.y" | 1430 | #line 293 "backend/vcc.y" |
1400 | { | 1431 | { |
1401 | enterAttr(yyvsp[-2].str,yyvsp[0].str); | 1432 | enterAttr(yyvsp[-2].str,yyvsp[0].str); |
1402 | 1433 | ||
1403 | } | 1434 | } |
1404 | break; | 1435 | break; |
1405 | case 24: | 1436 | case 24: |
1406 | #line 298 "vcc.y" | 1437 | #line 302 "backend/vcc.y" |
1407 | { enterValues(yyvsp[-1].str); } | 1438 | { enterValues(yyvsp[-1].str); } |
1408 | break; | 1439 | break; |
1409 | case 26: | 1440 | case 26: |
1410 | #line 300 "vcc.y" | 1441 | #line 304 "backend/vcc.y" |
1411 | { enterValues(yyvsp[0].str); } | 1442 | { enterValues(yyvsp[0].str); } |
1412 | break; | 1443 | break; |
1413 | case 28: | 1444 | case 28: |
1414 | #line 305 "vcc.y" | 1445 | #line 309 "backend/vcc.y" |
1415 | { yyval.str = 0; } | 1446 | { yyval.str = 0; } |
1416 | break; | 1447 | break; |
1417 | case 29: | 1448 | case 29: |
1418 | #line 310 "vcc.y" | 1449 | #line 314 "backend/vcc.y" |
1419 | { if (!pushVObject(VCCalProp)) YYERROR; } | 1450 | { if (!pushVObject(VCCalProp)) YYERROR; } |
1420 | break; | 1451 | break; |
1421 | case 30: | 1452 | case 30: |
1422 | #line 313 "vcc.y" | 1453 | #line 317 "backend/vcc.y" |
1423 | { yyval.vobj = popVObject(); } | 1454 | { yyval.vobj = popVObject(); } |
1424 | break; | 1455 | break; |
1425 | case 31: | 1456 | case 31: |
1426 | #line 315 "vcc.y" | 1457 | #line 319 "backend/vcc.y" |
1427 | { if (!pushVObject(VCCalProp)) YYERROR; } | 1458 | { if (!pushVObject(VCCalProp)) YYERROR; } |
1428 | break; | 1459 | break; |
1429 | case 32: | 1460 | case 32: |
1430 | #line 317 "vcc.y" | 1461 | #line 321 "backend/vcc.y" |
1431 | { yyval.vobj = popVObject(); } | 1462 | { yyval.vobj = popVObject(); } |
1432 | break; | 1463 | break; |
1433 | case 38: | 1464 | case 38: |
1434 | #line 332 "vcc.y" | 1465 | #line 336 "backend/vcc.y" |
1435 | { | 1466 | { |
1436 | lexPushMode(L_VEVENT); | 1467 | lexPushMode(L_VEVENT); |
1437 | if (!pushVObject(VCEventProp)) YYERROR; | 1468 | if (!pushVObject(VCEventProp)) YYERROR; |
1438 | } | 1469 | } |
1439 | break; | 1470 | break; |
1440 | case 39: | 1471 | case 39: |
1441 | #line 338 "vcc.y" | 1472 | #line 342 "backend/vcc.y" |
1442 | { | 1473 | { |
1443 | lexPopMode(0); | 1474 | lexPopMode(0); |
1444 | popVObject(); | 1475 | popVObject(); |
1445 | } | 1476 | } |
1446 | break; | 1477 | break; |
1447 | case 40: | 1478 | case 40: |
1448 | #line 343 "vcc.y" | 1479 | #line 347 "backend/vcc.y" |
1449 | { | 1480 | { |
1450 | lexPushMode(L_VEVENT); | 1481 | lexPushMode(L_VEVENT); |
1451 | if (!pushVObject(VCEventProp)) YYERROR; | 1482 | if (!pushVObject(VCEventProp)) YYERROR; |
1452 | } | 1483 | } |
1453 | break; | 1484 | break; |
1454 | case 41: | 1485 | case 41: |
1455 | #line 348 "vcc.y" | 1486 | #line 352 "backend/vcc.y" |
1456 | { | 1487 | { |
1457 | lexPopMode(0); | 1488 | lexPopMode(0); |
1458 | popVObject(); | 1489 | popVObject(); |
1459 | } | 1490 | } |
1460 | break; | 1491 | break; |
1461 | case 42: | 1492 | case 42: |
1462 | #line 356 "vcc.y" | 1493 | #line 360 "backend/vcc.y" |
1463 | { | 1494 | { |
1464 | lexPushMode(L_VTODO); | 1495 | lexPushMode(L_VTODO); |
1465 | if (!pushVObject(VCTodoProp)) YYERROR; | 1496 | if (!pushVObject(VCTodoProp)) YYERROR; |
1466 | } | 1497 | } |
1467 | break; | 1498 | break; |
1468 | case 43: | 1499 | case 43: |
1469 | #line 362 "vcc.y" | 1500 | #line 366 "backend/vcc.y" |
1470 | { | 1501 | { |
1471 | lexPopMode(0); | 1502 | lexPopMode(0); |
1472 | popVObject(); | 1503 | popVObject(); |
1473 | } | 1504 | } |
1474 | break; | 1505 | break; |
1475 | case 44: | 1506 | case 44: |
1476 | #line 367 "vcc.y" | 1507 | #line 371 "backend/vcc.y" |
1477 | { | 1508 | { |
1478 | lexPushMode(L_VTODO); | 1509 | lexPushMode(L_VTODO); |
1479 | if (!pushVObject(VCTodoProp)) YYERROR; | 1510 | if (!pushVObject(VCTodoProp)) YYERROR; |
1480 | } | 1511 | } |
1481 | break; | 1512 | break; |
1482 | case 45: | 1513 | case 45: |
1483 | #line 372 "vcc.y" | 1514 | #line 376 "backend/vcc.y" |
1484 | { | 1515 | { |
1485 | lexPopMode(0); | 1516 | lexPopMode(0); |
1486 | popVObject(); | 1517 | popVObject(); |
1487 | } | 1518 | } |
1488 | break; | 1519 | break; |
1489 | #line 1492 "y.tab.c" | 1520 | #line 1521 "y.tab.c" |
1490 | } | 1521 | } |
1491 | yyssp -= yym; | 1522 | yyssp -= yym; |
1492 | yystate = *yyssp; | 1523 | yystate = *yyssp; |
1493 | yyvsp -= yym; | 1524 | yyvsp -= yym; |
1494 | yym = yylhs[yyn]; | 1525 | yym = yylhs[yyn]; |
1495 | if (yystate == 0 && yym == 0) | 1526 | if (yystate == 0 && yym == 0) |
1496 | { | 1527 | { |
1497 | #if YYDEBUG | 1528 | #if YYDEBUG |
1498 | if (yydebug) | 1529 | if (yydebug) |
1499 | printf("%sdebug: after reduction, shifting from state 0 to\ | 1530 | printf("%sdebug: after reduction, shifting from state 0 to\ |
1500 | state %d\n", YYPREFIX, YYFINAL); | 1531 | state %d\n", YYPREFIX, YYFINAL); |
1501 | #endif | 1532 | #endif |
1502 | yystate = YYFINAL; | 1533 | yystate = YYFINAL; |
1503 | *++yyssp = YYFINAL; | 1534 | *++yyssp = YYFINAL; |
1504 | *++yyvsp = yyval; | 1535 | *++yyvsp = yyval; |
1505 | if (yychar < 0) | 1536 | if (yychar < 0) |
1506 | { | 1537 | { |
1507 | if ((yychar = yylex()) < 0) yychar = 0; | 1538 | if ((yychar = yylex()) < 0) yychar = 0; |
1508 | #if YYDEBUG | 1539 | #if YYDEBUG |
1509 | if (yydebug) | 1540 | if (yydebug) |
1510 | { | 1541 | { |
1511 | yys = 0; | 1542 | yys = 0; |
1512 | if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; | 1543 | if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; |
1513 | if (!yys) yys = "illegal-symbol"; | 1544 | if (!yys) yys = "illegal-symbol"; |
1514 | printf("%sdebug: state %d, reading %d (%s)\n", | 1545 | printf("%sdebug: state %d, reading %d (%s)\n", |
1515 | YYPREFIX, YYFINAL, yychar, yys); | 1546 | YYPREFIX, YYFINAL, yychar, yys); |
1516 | } | 1547 | } |
1517 | #endif | 1548 | #endif |
1518 | } | 1549 | } |
1519 | if (yychar == 0) goto yyaccept; | 1550 | if (yychar == 0) goto yyaccept; |
1520 | goto yyloop; | 1551 | goto yyloop; |
1521 | } | 1552 | } |
1522 | if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && | 1553 | if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && |
1523 | yyn <= YYTABLESIZE && yycheck[yyn] == yystate) | 1554 | yyn <= YYTABLESIZE && yycheck[yyn] == yystate) |
1524 | yystate = yytable[yyn]; | 1555 | yystate = yytable[yyn]; |
1525 | else | 1556 | else |
1526 | yystate = yydgoto[yym]; | 1557 | yystate = yydgoto[yym]; |
1527 | #if YYDEBUG | 1558 | #if YYDEBUG |
1528 | if (yydebug) | 1559 | if (yydebug) |
1529 | printf("%sdebug: after reduction, shifting from state %d \ | 1560 | printf("%sdebug: after reduction, shifting from state %d \ |
1530 | to state %d\n", YYPREFIX, *yyssp, yystate); | 1561 | to state %d\n", YYPREFIX, *yyssp, yystate); |
1531 | #endif | 1562 | #endif |
1532 | if (yyssp >= yyss + yystacksize - 1) | 1563 | if (yyssp >= yyss + yystacksize - 1) |
1533 | { | 1564 | { |
1534 | goto yyoverflow; | 1565 | goto yyoverflow; |
1535 | } | 1566 | } |
1536 | *++yyssp = yystate; | 1567 | *++yyssp = yystate; |
1537 | *++yyvsp = yyval; | 1568 | *++yyvsp = yyval; |
1538 | goto yyloop; | 1569 | goto yyloop; |
1539 | yyoverflow: | 1570 | yyoverflow: |
1540 | yyerror("yacc stack overflow"); | 1571 | yyerror("yacc stack overflow"); |
1541 | yyabort: | 1572 | yyabort: |
1542 | return (1); | 1573 | return (1); |
1543 | yyaccept: | 1574 | yyaccept: |
1544 | return (0); | 1575 | return (0); |
1545 | } | 1576 | } |
diff --git a/library/backend/vobject.cpp b/library/backend/vobject.cpp index 9c2ba3b..e6f6b78 100644 --- a/library/backend/vobject.cpp +++ b/library/backend/vobject.cpp | |||
@@ -1,1219 +1,1315 @@ | |||
1 | /*************************************************************************** | 1 | /*************************************************************************** |
2 | (C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International | 2 | (C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International |
3 | Business Machines Corporation and Siemens Rolm Communications Inc. | 3 | Business Machines Corporation and Siemens Rolm Communications Inc. |
4 | 4 | ||
5 | For purposes of this license notice, the term Licensors shall mean, | 5 | For purposes of this license notice, the term Licensors shall mean, |
6 | collectively, Apple Computer, Inc., AT&T Corp., International | 6 | collectively, Apple Computer, Inc., AT&T Corp., International |
7 | Business Machines Corporation and Siemens Rolm Communications Inc. | 7 | Business Machines Corporation and Siemens Rolm Communications Inc. |
8 | The term Licensor shall mean any of the Licensors. | 8 | The term Licensor shall mean any of the Licensors. |
9 | 9 | ||
10 | Subject to acceptance of the following conditions, permission is hereby | 10 | Subject to acceptance of the following conditions, permission is hereby |
11 | granted by Licensors without the need for written agreement and without | 11 | granted by Licensors without the need for written agreement and without |
12 | license or royalty fees, to use, copy, modify and distribute this | 12 | license or royalty fees, to use, copy, modify and distribute this |
13 | software for any purpose. | 13 | software for any purpose. |
14 | 14 | ||
15 | The above copyright notice and the following four paragraphs must be | 15 | The above copyright notice and the following four paragraphs must be |
16 | reproduced in all copies of this software and any software including | 16 | reproduced in all copies of this software and any software including |
17 | this software. | 17 | this software. |
18 | 18 | ||
19 | THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE | 19 | THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE |
20 | ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR | 20 | ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR |
21 | MODIFICATIONS. | 21 | MODIFICATIONS. |
22 | 22 | ||
23 | IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, | 23 | IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, |
24 | INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT | 24 | INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT |
25 | OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | 25 | OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
26 | DAMAGE. | 26 | DAMAGE. |
27 | 27 | ||
28 | EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, | 28 | EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, |
29 | INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE | 29 | INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE |
30 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 30 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
31 | PURPOSE. | 31 | PURPOSE. |
32 | 32 | ||
33 | The software is provided with RESTRICTED RIGHTS. Use, duplication, or | 33 | The software is provided with RESTRICTED RIGHTS. Use, duplication, or |
34 | disclosure by the government are subject to restrictions set forth in | 34 | disclosure by the government are subject to restrictions set forth in |
35 | DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. | 35 | DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. |
36 | 36 | ||
37 | ***************************************************************************/ | 37 | ***************************************************************************/ |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * src: vobject.c | 40 | * src: vobject.c |
41 | * doc: vobject and APIs to construct vobject, APIs pretty print | 41 | * doc: vobject and APIs to construct vobject, APIs pretty print |
42 | * vobject, and convert a vobject into its textual representation. | 42 | * vobject, and convert a vobject into its textual representation. |
43 | */ | 43 | */ |
44 | 44 | ||
45 | #ifndef MWERKS | 45 | #ifndef MWERKS |
46 | #include <malloc.h> | 46 | #include <malloc.h> |
47 | #endif | 47 | #endif |
48 | 48 | ||
49 | #include "vobject_p.h" | 49 | #include "vobject_p.h" |
50 | #include "qfiledirect_p.h" | 50 | #include "qfiledirect_p.h" |
51 | #include <string.h> | 51 | #include <string.h> |
52 | #include <stdio.h> | 52 | #include <stdio.h> |
53 | #include <fcntl.h> | 53 | #include <fcntl.h> |
54 | //#include <io.h> | 54 | //#include <io.h> |
55 | 55 | ||
56 | 56 | ||
57 | #define NAME_OF(o) o->id | 57 | #define NAME_OF(o) o->id |
58 | #define VALUE_TYPE(o) o->valType | 58 | #define VALUE_TYPE(o) o->valType |
59 | #define STRINGZ_VALUE_OF(o) o->val.strs | 59 | #define STRINGZ_VALUE_OF(o) o->val.strs |
60 | #define INTEGER_VALUE_OF(o) o->val.i | 60 | #define INTEGER_VALUE_OF(o) o->val.i |
61 | #define LONG_VALUE_OF(o) o->val.l | 61 | #define LONG_VALUE_OF(o) o->val.l |
62 | #define ANY_VALUE_OF(o) o->val.any | 62 | #define ANY_VALUE_OF(o) o->val.any |
63 | #define VOBJECT_VALUE_OF(o) o->val.vobj | 63 | #define VOBJECT_VALUE_OF(o) o->val.vobj |
64 | 64 | ||
65 | typedef union ValueItem { | 65 | typedef union ValueItem { |
66 | const char *strs; | 66 | const char *strs; |
67 | unsigned int i; | 67 | unsigned int i; |
68 | unsigned long l; | 68 | unsigned long l; |
69 | void *any; | 69 | void *any; |
70 | VObject *vobj; | 70 | VObject *vobj; |
71 | } ValueItem; | 71 | } ValueItem; |
72 | 72 | ||
73 | struct VObject { | 73 | struct VObject { |
74 | VObject *next; | 74 | VObject *next; |
75 | const char *id; | 75 | const char *id; |
76 | VObject *prop; | 76 | VObject *prop; |
77 | unsigned short valType; | 77 | unsigned short valType; |
78 | ValueItem val; | 78 | ValueItem val; |
79 | }; | 79 | }; |
80 | 80 | ||
81 | typedef struct StrItem StrItem; | 81 | typedef struct StrItem StrItem; |
82 | 82 | ||
83 | struct StrItem { | 83 | struct StrItem { |
84 | StrItem *next; | 84 | StrItem *next; |
85 | const char *s; | 85 | const char *s; |
86 | unsigned int refCnt; | 86 | unsigned int refCnt; |
87 | }; | 87 | }; |
88 | 88 | ||
89 | const char** fieldedProp; | 89 | const char** fieldedProp; |
90 | 90 | ||
91 | 91 | ||
92 | 92 | ||
93 | /*---------------------------------------------------------------------- | 93 | /*---------------------------------------------------------------------- |
94 | The following functions involve with memory allocation: | 94 | The following functions involve with memory allocation: |
95 | newVObject | 95 | newVObject |
96 | deleteVObject | 96 | deleteVObject |
97 | dupStr | 97 | dupStr |
98 | deleteStr | 98 | deleteStr |
99 | newStrItem | 99 | newStrItem |
100 | deleteStrItem | 100 | deleteStrItem |
101 | ----------------------------------------------------------------------*/ | 101 | ----------------------------------------------------------------------*/ |
102 | 102 | ||
103 | DLLEXPORT(VObject*) newVObject_(const char *id) | 103 | DLLEXPORT(VObject*) newVObject_(const char *id) |
104 | { | 104 | { |
105 | VObject *p = (VObject*)malloc(sizeof(VObject)); | 105 | VObject *p = (VObject*)malloc(sizeof(VObject)); |
106 | p->next = 0; | 106 | p->next = 0; |
107 | p->id = id; | 107 | p->id = id; |
108 | p->prop = 0; | 108 | p->prop = 0; |
109 | VALUE_TYPE(p) = 0; | 109 | VALUE_TYPE(p) = 0; |
110 | ANY_VALUE_OF(p) = 0; | 110 | ANY_VALUE_OF(p) = 0; |
111 | return p; | 111 | return p; |
112 | } | 112 | } |
113 | 113 | ||
114 | DLLEXPORT(VObject*) newVObject(const char *id) | 114 | DLLEXPORT(VObject*) newVObject(const char *id) |
115 | { | 115 | { |
116 | return newVObject_(lookupStr(id)); | 116 | return newVObject_(lookupStr(id)); |
117 | } | 117 | } |
118 | 118 | ||
119 | DLLEXPORT(void) deleteVObject(VObject *p) | 119 | DLLEXPORT(void) deleteVObject(VObject *p) |
120 | { | 120 | { |
121 | unUseStr(p->id); | 121 | unUseStr(p->id); |
122 | free(p); | 122 | free(p); |
123 | } | 123 | } |
124 | 124 | ||
125 | DLLEXPORT(char*) dupStr(const char *s, unsigned int size) | 125 | DLLEXPORT(char*) dupStr(const char *s, unsigned int size) |
126 | { | 126 | { |
127 | char *t; | 127 | char *t; |
128 | if (size == 0) { | 128 | if (size == 0) { |
129 | size = strlen(s); | 129 | size = strlen(s); |
130 | } | 130 | } |
131 | t = (char*)malloc(size+1); | 131 | t = (char*)malloc(size+1); |
132 | if (t) { | 132 | if (t) { |
133 | memcpy(t,s,size); | 133 | memcpy(t,s,size); |
134 | t[size] = 0; | 134 | t[size] = 0; |
135 | return t; | 135 | return t; |
136 | } | 136 | } |
137 | else { | 137 | else { |
138 | return (char*)0; | 138 | return (char*)0; |
139 | } | 139 | } |
140 | } | 140 | } |
141 | 141 | ||
142 | DLLEXPORT(void) deleteStr(const char *p) | 142 | DLLEXPORT(void) deleteStr(const char *p) |
143 | { | 143 | { |
144 | if (p) free((void*)p); | 144 | if (p) free((void*)p); |
145 | } | 145 | } |
146 | 146 | ||
147 | 147 | ||
148 | static StrItem* newStrItem(const char *s, StrItem *next) | 148 | static StrItem* newStrItem(const char *s, StrItem *next) |
149 | { | 149 | { |
150 | StrItem *p = (StrItem*)malloc(sizeof(StrItem)); | 150 | StrItem *p = (StrItem*)malloc(sizeof(StrItem)); |
151 | p->next = next; | 151 | p->next = next; |
152 | p->s = s; | 152 | p->s = s; |
153 | p->refCnt = 1; | 153 | p->refCnt = 1; |
154 | return p; | 154 | return p; |
155 | } | 155 | } |
156 | 156 | ||
157 | static void deleteStrItem(StrItem *p) | 157 | static void deleteStrItem(StrItem *p) |
158 | { | 158 | { |
159 | free((void*)p); | 159 | free((void*)p); |
160 | } | 160 | } |
161 | 161 | ||
162 | 162 | ||
163 | /*---------------------------------------------------------------------- | 163 | /*---------------------------------------------------------------------- |
164 | The following function provide accesses to VObject's value. | 164 | The following function provide accesses to VObject's value. |
165 | ----------------------------------------------------------------------*/ | 165 | ----------------------------------------------------------------------*/ |
166 | 166 | ||
167 | DLLEXPORT(const char*) vObjectName(VObject *o) | 167 | DLLEXPORT(const char*) vObjectName(VObject *o) |
168 | { | 168 | { |
169 | return NAME_OF(o); | 169 | return NAME_OF(o); |
170 | } | 170 | } |
171 | 171 | ||
172 | DLLEXPORT(void) setVObjectName(VObject *o, const char* id) | 172 | DLLEXPORT(void) setVObjectName(VObject *o, const char* id) |
173 | { | 173 | { |
174 | NAME_OF(o) = id; | 174 | NAME_OF(o) = id; |
175 | } | 175 | } |
176 | 176 | ||
177 | DLLEXPORT(const char*) vObjectStringZValue(VObject *o) | 177 | DLLEXPORT(const char*) vObjectStringZValue(VObject *o) |
178 | { | 178 | { |
179 | return STRINGZ_VALUE_OF(o); | 179 | return STRINGZ_VALUE_OF(o); |
180 | } | 180 | } |
181 | 181 | ||
182 | DLLEXPORT(void) setVObjectStringZValue(VObject *o, const char *s) | 182 | DLLEXPORT(void) setVObjectStringZValue(VObject *o, const char *s) |
183 | { | 183 | { |
184 | STRINGZ_VALUE_OF(o) = dupStr(s,0); | 184 | STRINGZ_VALUE_OF(o) = dupStr(s,0); |
185 | VALUE_TYPE(o) = VCVT_STRINGZ; | 185 | VALUE_TYPE(o) = VCVT_STRINGZ; |
186 | } | 186 | } |
187 | 187 | ||
188 | DLLEXPORT(void) setVObjectStringZValue_(VObject *o, const char *s) | 188 | DLLEXPORT(void) setVObjectStringZValue_(VObject *o, const char *s) |
189 | { | 189 | { |
190 | STRINGZ_VALUE_OF(o) = s; | 190 | STRINGZ_VALUE_OF(o) = s; |
191 | VALUE_TYPE(o) = VCVT_STRINGZ; | 191 | VALUE_TYPE(o) = VCVT_STRINGZ; |
192 | } | 192 | } |
193 | 193 | ||
194 | DLLEXPORT(unsigned int) vObjectIntegerValue(VObject *o) | 194 | DLLEXPORT(unsigned int) vObjectIntegerValue(VObject *o) |
195 | { | 195 | { |
196 | return INTEGER_VALUE_OF(o); | 196 | return INTEGER_VALUE_OF(o); |
197 | } | 197 | } |
198 | 198 | ||
199 | DLLEXPORT(void) setVObjectIntegerValue(VObject *o, unsigned int i) | 199 | DLLEXPORT(void) setVObjectIntegerValue(VObject *o, unsigned int i) |
200 | { | 200 | { |
201 | INTEGER_VALUE_OF(o) = i; | 201 | INTEGER_VALUE_OF(o) = i; |
202 | VALUE_TYPE(o) = VCVT_UINT; | 202 | VALUE_TYPE(o) = VCVT_UINT; |
203 | } | 203 | } |
204 | 204 | ||
205 | DLLEXPORT(unsigned long) vObjectLongValue(VObject *o) | 205 | DLLEXPORT(unsigned long) vObjectLongValue(VObject *o) |
206 | { | 206 | { |
207 | return LONG_VALUE_OF(o); | 207 | return LONG_VALUE_OF(o); |
208 | } | 208 | } |
209 | 209 | ||
210 | DLLEXPORT(void) setVObjectLongValue(VObject *o, unsigned long l) | 210 | DLLEXPORT(void) setVObjectLongValue(VObject *o, unsigned long l) |
211 | { | 211 | { |
212 | LONG_VALUE_OF(o) = l; | 212 | LONG_VALUE_OF(o) = l; |
213 | VALUE_TYPE(o) = VCVT_ULONG; | 213 | VALUE_TYPE(o) = VCVT_ULONG; |
214 | } | 214 | } |
215 | 215 | ||
216 | DLLEXPORT(void*) vObjectAnyValue(VObject *o) | 216 | DLLEXPORT(void*) vObjectAnyValue(VObject *o) |
217 | { | 217 | { |
218 | return ANY_VALUE_OF(o); | 218 | return ANY_VALUE_OF(o); |
219 | } | 219 | } |
220 | 220 | ||
221 | DLLEXPORT(void) setVObjectAnyValue(VObject *o, void *t) | 221 | DLLEXPORT(void) setVObjectAnyValue(VObject *o, void *t) |
222 | { | 222 | { |
223 | ANY_VALUE_OF(o) = t; | 223 | ANY_VALUE_OF(o) = t; |
224 | VALUE_TYPE(o) = VCVT_RAW; | 224 | VALUE_TYPE(o) = VCVT_RAW; |
225 | } | 225 | } |
226 | 226 | ||
227 | DLLEXPORT(VObject*) vObjectVObjectValue(VObject *o) | 227 | DLLEXPORT(VObject*) vObjectVObjectValue(VObject *o) |
228 | { | 228 | { |
229 | return VOBJECT_VALUE_OF(o); | 229 | return VOBJECT_VALUE_OF(o); |
230 | } | 230 | } |
231 | 231 | ||
232 | DLLEXPORT(void) setVObjectVObjectValue(VObject *o, VObject *p) | 232 | DLLEXPORT(void) setVObjectVObjectValue(VObject *o, VObject *p) |
233 | { | 233 | { |
234 | VOBJECT_VALUE_OF(o) = p; | 234 | VOBJECT_VALUE_OF(o) = p; |
235 | VALUE_TYPE(o) = VCVT_VOBJECT; | 235 | VALUE_TYPE(o) = VCVT_VOBJECT; |
236 | } | 236 | } |
237 | 237 | ||
238 | DLLEXPORT(int) vObjectValueType(VObject *o) | 238 | DLLEXPORT(int) vObjectValueType(VObject *o) |
239 | { | 239 | { |
240 | return VALUE_TYPE(o); | 240 | return VALUE_TYPE(o); |
241 | } | 241 | } |
242 | 242 | ||
243 | 243 | ||
244 | /*---------------------------------------------------------------------- | 244 | /*---------------------------------------------------------------------- |
245 | The following functions can be used to build VObject. | 245 | The following functions can be used to build VObject. |
246 | ----------------------------------------------------------------------*/ | 246 | ----------------------------------------------------------------------*/ |
247 | 247 | ||
248 | DLLEXPORT(VObject*) addVObjectProp(VObject *o, VObject *p) | 248 | DLLEXPORT(VObject*) addVObjectProp(VObject *o, VObject *p) |
249 | { | 249 | { |
250 | /* circular link list pointed to tail */ | 250 | /* circular link list pointed to tail */ |
251 | /* | 251 | /* |
252 | o {next,id,prop,val} | 252 | o {next,id,prop,val} |
253 | V | 253 | V |
254 | pn {next,id,prop,val} | 254 | pn {next,id,prop,val} |
255 | V | 255 | V |
256 | ... | 256 | ... |
257 | p1 {next,id,prop,val} | 257 | p1 {next,id,prop,val} |
258 | V | 258 | V |
259 | pn | 259 | pn |
260 | --> | 260 | --> |
261 | o {next,id,prop,val} | 261 | o {next,id,prop,val} |
262 | V | 262 | V |
263 | pn {next,id,prop,val} | 263 | pn {next,id,prop,val} |
264 | V | 264 | V |
265 | p {next,id,prop,val} | 265 | p {next,id,prop,val} |
266 | ... | 266 | ... |
267 | p1 {next,id,prop,val} | 267 | p1 {next,id,prop,val} |
268 | V | 268 | V |
269 | pn | 269 | pn |
270 | */ | 270 | */ |
271 | 271 | ||
272 | VObject *tail = o->prop; | 272 | VObject *tail = o->prop; |
273 | if (tail) { | 273 | if (tail) { |
274 | p->next = tail->next; | 274 | p->next = tail->next; |
275 | o->prop = tail->next = p; | 275 | o->prop = tail->next = p; |
276 | } | 276 | } |
277 | else { | 277 | else { |
278 | o->prop = p->next = p; | 278 | o->prop = p->next = p; |
279 | } | 279 | } |
280 | return p; | 280 | return p; |
281 | } | 281 | } |
282 | 282 | ||
283 | DLLEXPORT(VObject*) addProp(VObject *o, const char *id) | 283 | DLLEXPORT(VObject*) addProp(VObject *o, const char *id) |
284 | { | 284 | { |
285 | return addVObjectProp(o,newVObject(id)); | 285 | return addVObjectProp(o,newVObject(id)); |
286 | } | 286 | } |
287 | 287 | ||
288 | DLLEXPORT(VObject*) addProp_(VObject *o, const char *id) | 288 | DLLEXPORT(VObject*) addProp_(VObject *o, const char *id) |
289 | { | 289 | { |
290 | return addVObjectProp(o,newVObject_(id)); | 290 | return addVObjectProp(o,newVObject_(id)); |
291 | } | 291 | } |
292 | 292 | ||
293 | DLLEXPORT(void) addList(VObject **o, VObject *p) | 293 | DLLEXPORT(void) addList(VObject **o, VObject *p) |
294 | { | 294 | { |
295 | p->next = 0; | 295 | p->next = 0; |
296 | if (*o == 0) { | 296 | if (*o == 0) { |
297 | *o = p; | 297 | *o = p; |
298 | } | 298 | } |
299 | else { | 299 | else { |
300 | VObject *t = *o; | 300 | VObject *t = *o; |
301 | while (t->next) { | 301 | while (t->next) { |
302 | t = t->next; | 302 | t = t->next; |
303 | } | 303 | } |
304 | t->next = p; | 304 | t->next = p; |
305 | } | 305 | } |
306 | } | 306 | } |
307 | 307 | ||
308 | DLLEXPORT(VObject*) nextVObjectInList(VObject *o) | 308 | DLLEXPORT(VObject*) nextVObjectInList(VObject *o) |
309 | { | 309 | { |
310 | return o->next; | 310 | return o->next; |
311 | } | 311 | } |
312 | 312 | ||
313 | DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size) | 313 | DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size) |
314 | { | 314 | { |
315 | VObject *sizeProp; | 315 | VObject *sizeProp; |
316 | setVObjectAnyValue(prop, val); | 316 | setVObjectAnyValue(prop, val); |
317 | sizeProp = addProp(prop,VCDataSizeProp); | 317 | sizeProp = addProp(prop,VCDataSizeProp); |
318 | setVObjectLongValue(sizeProp, size); | 318 | setVObjectLongValue(sizeProp, size); |
319 | return prop; | 319 | return prop; |
320 | } | 320 | } |
321 | 321 | ||
322 | DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size) | 322 | DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size) |
323 | { | 323 | { |
324 | void *p = dupStr((const char *)val,size); | 324 | void *p = dupStr((const char *)val,size); |
325 | return setValueWithSize_(prop,p,p?size:0); | 325 | return setValueWithSize_(prop,p,p?size:0); |
326 | } | 326 | } |
327 | 327 | ||
328 | DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o) | 328 | DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o) |
329 | { | 329 | { |
330 | i->start = o->prop; | 330 | i->start = o->prop; |
331 | i->next = 0; | 331 | i->next = 0; |
332 | } | 332 | } |
333 | 333 | ||
334 | DLLEXPORT(void) initVObjectIterator(VObjectIterator *i, VObject *o) | 334 | DLLEXPORT(void) initVObjectIterator(VObjectIterator *i, VObject *o) |
335 | { | 335 | { |
336 | i->start = o->next; | 336 | i->start = o->next; |
337 | i->next = 0; | 337 | i->next = 0; |
338 | } | 338 | } |
339 | 339 | ||
340 | DLLEXPORT(int) moreIteration(VObjectIterator *i) | 340 | DLLEXPORT(int) moreIteration(VObjectIterator *i) |
341 | { | 341 | { |
342 | return (i->start && (i->next==0 || i->next!=i->start)); | 342 | return (i->start && (i->next==0 || i->next!=i->start)); |
343 | } | 343 | } |
344 | 344 | ||
345 | DLLEXPORT(VObject*) nextVObject(VObjectIterator *i) | 345 | DLLEXPORT(VObject*) nextVObject(VObjectIterator *i) |
346 | { | 346 | { |
347 | if (i->start && i->next != i->start) { | 347 | if (i->start && i->next != i->start) { |
348 | if (i->next == 0) { | 348 | if (i->next == 0) { |
349 | i->next = i->start->next; | 349 | i->next = i->start->next; |
350 | return i->next; | 350 | return i->next; |
351 | } | 351 | } |
352 | else { | 352 | else { |
353 | i->next = i->next->next; | 353 | i->next = i->next->next; |
354 | return i->next; | 354 | return i->next; |
355 | } | 355 | } |
356 | } | 356 | } |
357 | else return (VObject*)0; | 357 | else return (VObject*)0; |
358 | } | 358 | } |
359 | 359 | ||
360 | DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id) | 360 | DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id) |
361 | { | 361 | { |
362 | VObjectIterator i; | 362 | VObjectIterator i; |
363 | initPropIterator(&i,o); | 363 | initPropIterator(&i,o); |
364 | while (moreIteration(&i)) { | 364 | while (moreIteration(&i)) { |
365 | VObject *each = nextVObject(&i); | 365 | VObject *each = nextVObject(&i); |
366 | if (!qstricmp(id,each->id)) | 366 | if (!qstricmp(id,each->id)) |
367 | return each; | 367 | return each; |
368 | } | 368 | } |
369 | return (VObject*)0; | 369 | return (VObject*)0; |
370 | } | 370 | } |
371 | 371 | ||
372 | DLLEXPORT(VObject*) addGroup(VObject *o, const char *g) | 372 | DLLEXPORT(VObject*) addGroup(VObject *o, const char *g) |
373 | { | 373 | { |
374 | /* | 374 | /* |
375 | a.b.c | 375 | a.b.c |
376 | --> | 376 | --> |
377 | prop(c) | 377 | prop(c) |
378 | prop(VCGrouping=b) | 378 | prop(VCGrouping=b) |
379 | prop(VCGrouping=a) | 379 | prop(VCGrouping=a) |
380 | */ | 380 | */ |
381 | char *dot = strrchr(g,'.'); | 381 | char *dot = strrchr(g,'.'); |
382 | if (dot) { | 382 | if (dot) { |
383 | VObject *p, *t; | 383 | VObject *p, *t; |
384 | char *gs, *n = dot+1; | 384 | char *gs, *n = dot+1; |
385 | gs = dupStr(g,0);/* so we can write to it. */ | 385 | gs = dupStr(g,0);/* so we can write to it. */ |
386 | /* used to be | 386 | /* used to be |
387 | * t = p = addProp_(o,lookupProp_(n)); | 387 | * t = p = addProp_(o,lookupProp_(n)); |
388 | */ | 388 | */ |
389 | t = p = addProp_(o,lookupProp(n)); | 389 | t = p = addProp_(o,lookupProp(n)); |
390 | dot = strrchr(gs,'.'); | 390 | dot = strrchr(gs,'.'); |
391 | *dot = 0; | 391 | *dot = 0; |
392 | do { | 392 | do { |
393 | dot = strrchr(gs,'.'); | 393 | dot = strrchr(gs,'.'); |
394 | if (dot) { | 394 | if (dot) { |
395 | n = dot+1; | 395 | n = dot+1; |
396 | *dot=0; | 396 | *dot=0; |
397 | } | 397 | } |
398 | else | 398 | else |
399 | n = gs; | 399 | n = gs; |
400 | /* property(VCGroupingProp=n); | 400 | /* property(VCGroupingProp=n); |
401 | *and the value may have VCGrouping property | 401 | *and the value may have VCGrouping property |
402 | */ | 402 | */ |
403 | t = addProp(t,VCGroupingProp); | 403 | t = addProp(t,VCGroupingProp); |
404 | setVObjectStringZValue(t,lookupProp_(n)); | 404 | setVObjectStringZValue(t,lookupProp_(n)); |
405 | } while (n != gs); | 405 | } while (n != gs); |
406 | deleteStr(gs); | 406 | deleteStr(gs); |
407 | return p; | 407 | return p; |
408 | } | 408 | } |
409 | else | 409 | else |
410 | return addProp_(o,lookupProp(g)); | 410 | return addProp_(o,lookupProp(g)); |
411 | } | 411 | } |
412 | 412 | ||
413 | DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v) | 413 | DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v) |
414 | { | 414 | { |
415 | VObject *prop; | 415 | VObject *prop; |
416 | prop = addProp(o,p); | 416 | prop = addProp(o,p); |
417 | setVObjectStringZValue_(prop, strdup( v ) ); | 417 | setVObjectStringZValue_(prop, strdup( v ) ); |
418 | return prop; | 418 | return prop; |
419 | } | 419 | } |
420 | 420 | ||
421 | DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v, | 421 | DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v, |
422 | unsigned int size) | 422 | unsigned int size) |
423 | { | 423 | { |
424 | VObject *prop; | 424 | VObject *prop; |
425 | prop = addProp(o,p); | 425 | prop = addProp(o,p); |
426 | setValueWithSize_(prop, (void*)v, size); | 426 | setValueWithSize_(prop, (void*)v, size); |
427 | return prop; | 427 | return prop; |
428 | } | 428 | } |
429 | 429 | ||
430 | DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v, | 430 | DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v, |
431 | unsigned int size) | 431 | unsigned int size) |
432 | { | 432 | { |
433 | return addPropSizedValue_(o,p,dupStr(v,size),size); | 433 | return addPropSizedValue_(o,p,dupStr(v,size),size); |
434 | } | 434 | } |
435 | 435 | ||
436 | 436 | ||
437 | DLLEXPORT(void) cleanVObject(VObject *o) | 437 | DLLEXPORT(void) cleanVObject(VObject *o) |
438 | { | 438 | { |
439 | if (o == 0) return; | 439 | if (o == 0) return; |
440 | if (o->prop) { | 440 | if (o->prop) { |
441 | /* destroy time: cannot use the iterator here. | 441 | /* destroy time: cannot use the iterator here. |
442 | Have to break the cycle in the circular link | 442 | Have to break the cycle in the circular link |
443 | list and turns it into regular NULL-terminated | 443 | list and turns it into regular NULL-terminated |
444 | list -- since at some point of destruction, | 444 | list -- since at some point of destruction, |
445 | the reference entry for the iterator to work | 445 | the reference entry for the iterator to work |
446 | will not longer be valid. | 446 | will not longer be valid. |
447 | */ | 447 | */ |
448 | VObject *p; | 448 | VObject *p; |
449 | p = o->prop->next; | 449 | p = o->prop->next; |
450 | o->prop->next = 0; | 450 | o->prop->next = 0; |
451 | do { | 451 | do { |
452 | VObject *t = p->next; | 452 | VObject *t = p->next; |
453 | cleanVObject(p); | 453 | cleanVObject(p); |
454 | p = t; | 454 | p = t; |
455 | } while (p); | 455 | } while (p); |
456 | } | 456 | } |
457 | switch (VALUE_TYPE(o)) { | 457 | switch (VALUE_TYPE(o)) { |
458 | case VCVT_STRINGZ: | 458 | case VCVT_STRINGZ: |
459 | case VCVT_RAW: | 459 | case VCVT_RAW: |
460 | // assume they are all allocated by malloc. | 460 | // assume they are all allocated by malloc. |
461 | free((char*)STRINGZ_VALUE_OF(o)); | 461 | free((char*)STRINGZ_VALUE_OF(o)); |
462 | break; | 462 | break; |
463 | case VCVT_VOBJECT: | 463 | case VCVT_VOBJECT: |
464 | cleanVObject(VOBJECT_VALUE_OF(o)); | 464 | cleanVObject(VOBJECT_VALUE_OF(o)); |
465 | break; | 465 | break; |
466 | } | 466 | } |
467 | deleteVObject(o); | 467 | deleteVObject(o); |
468 | } | 468 | } |
469 | 469 | ||
470 | DLLEXPORT(void) cleanVObjects(VObject *list) | 470 | DLLEXPORT(void) cleanVObjects(VObject *list) |
471 | { | 471 | { |
472 | while (list) { | 472 | while (list) { |
473 | VObject *t = list; | 473 | VObject *t = list; |
474 | list = nextVObjectInList(list); | 474 | list = nextVObjectInList(list); |
475 | cleanVObject(t); | 475 | cleanVObject(t); |
476 | } | 476 | } |
477 | } | 477 | } |
478 | 478 | ||
479 | /*---------------------------------------------------------------------- | 479 | /*---------------------------------------------------------------------- |
480 | The following is a String Table Facilities. | 480 | The following is a String Table Facilities. |
481 | ----------------------------------------------------------------------*/ | 481 | ----------------------------------------------------------------------*/ |
482 | 482 | ||
483 | #define STRTBLSIZE 255 | 483 | #define STRTBLSIZE 255 |
484 | 484 | ||
485 | static StrItem *strTbl[STRTBLSIZE]; | 485 | static StrItem *strTbl[STRTBLSIZE]; |
486 | 486 | ||
487 | static unsigned int hashStr(const char *s) | 487 | static unsigned int hashStr(const char *s) |
488 | { | 488 | { |
489 | unsigned int h = 0; | 489 | unsigned int h = 0; |
490 | int i; | 490 | int i; |
491 | for (i=0;s[i];i++) { | 491 | for (i=0;s[i];i++) { |
492 | h += s[i]*i; | 492 | h += s[i]*i; |
493 | } | 493 | } |
494 | return h % STRTBLSIZE; | 494 | return h % STRTBLSIZE; |
495 | } | 495 | } |
496 | 496 | ||
497 | DLLEXPORT(const char*) lookupStr(const char *s) | 497 | DLLEXPORT(const char*) lookupStr(const char *s) |
498 | { | 498 | { |
499 | StrItem *t; | 499 | StrItem *t; |
500 | unsigned int h = hashStr(s); | 500 | unsigned int h = hashStr(s); |
501 | if ((t = strTbl[h]) != 0) { | 501 | if ((t = strTbl[h]) != 0) { |
502 | do { | 502 | do { |
503 | if (qstricmp(t->s,s) == 0) { | 503 | if (qstricmp(t->s,s) == 0) { |
504 | t->refCnt++; | 504 | t->refCnt++; |
505 | return t->s; | 505 | return t->s; |
506 | } | 506 | } |
507 | t = t->next; | 507 | t = t->next; |
508 | } while (t); | 508 | } while (t); |
509 | } | 509 | } |
510 | s = dupStr(s,0); | 510 | s = dupStr(s,0); |
511 | strTbl[h] = newStrItem(s,strTbl[h]); | 511 | strTbl[h] = newStrItem(s,strTbl[h]); |
512 | return s; | 512 | return s; |
513 | } | 513 | } |
514 | 514 | ||
515 | DLLEXPORT(void) unUseStr(const char *s) | 515 | DLLEXPORT(void) unUseStr(const char *s) |
516 | { | 516 | { |
517 | StrItem *t, *p; | 517 | StrItem *t, *p; |
518 | unsigned int h = hashStr(s); | 518 | unsigned int h = hashStr(s); |
519 | if ((t = strTbl[h]) != 0) { | 519 | if ((t = strTbl[h]) != 0) { |
520 | p = t; | 520 | p = t; |
521 | do { | 521 | do { |
522 | if (qstricmp(t->s,s) == 0) { | 522 | if (qstricmp(t->s,s) == 0) { |
523 | t->refCnt--; | 523 | t->refCnt--; |
524 | if (t->refCnt == 0) { | 524 | if (t->refCnt == 0) { |
525 | if (p == strTbl[h]) { | 525 | if (p == strTbl[h]) { |
526 | strTbl[h] = t->next; | 526 | strTbl[h] = t->next; |
527 | } | 527 | } |
528 | else { | 528 | else { |
529 | p->next = t->next; | 529 | p->next = t->next; |
530 | } | 530 | } |
531 | deleteStr(t->s); | 531 | deleteStr(t->s); |
532 | deleteStrItem(t); | 532 | deleteStrItem(t); |
533 | return; | 533 | return; |
534 | } | 534 | } |
535 | } | 535 | } |
536 | p = t; | 536 | p = t; |
537 | t = t->next; | 537 | t = t->next; |
538 | } while (t); | 538 | } while (t); |
539 | } | 539 | } |
540 | } | 540 | } |
541 | 541 | ||
542 | DLLEXPORT(void) cleanStrTbl() | 542 | DLLEXPORT(void) cleanStrTbl() |
543 | { | 543 | { |
544 | int i; | 544 | int i; |
545 | for (i=0; i<STRTBLSIZE;i++) { | 545 | for (i=0; i<STRTBLSIZE;i++) { |
546 | StrItem *t = strTbl[i]; | 546 | StrItem *t = strTbl[i]; |
547 | while (t) { | 547 | while (t) { |
548 | StrItem *p; | 548 | StrItem *p; |
549 | deleteStr(t->s); | 549 | deleteStr(t->s); |
550 | p = t; | 550 | p = t; |
551 | t = t->next; | 551 | t = t->next; |
552 | deleteStrItem(p); | 552 | deleteStrItem(p); |
553 | } while (t); | 553 | } while (t); |
554 | strTbl[i] = 0; | 554 | strTbl[i] = 0; |
555 | } | 555 | } |
556 | } | 556 | } |
557 | 557 | ||
558 | 558 | ||
559 | struct PreDefProp { | 559 | struct PreDefProp { |
560 | const char *name; | 560 | const char *name; |
561 | const char *alias; | 561 | const char *alias; |
562 | const char** fields; | 562 | const char** fields; |
563 | unsigned int flags; | 563 | unsigned int flags; |
564 | }; | 564 | }; |
565 | 565 | ||
566 | /* flags in PreDefProp */ | 566 | /* flags in PreDefProp */ |
567 | #define PD_BEGIN0x1 | 567 | #define PD_BEGIN0x1 |
568 | #define PD_INTERNAL0x2 | 568 | #define PD_INTERNAL0x2 |
569 | 569 | ||
570 | static const char *adrFields[] = { | 570 | static const char *adrFields[] = { |
571 | VCPostalBoxProp, | 571 | VCPostalBoxProp, |
572 | VCExtAddressProp, | 572 | VCExtAddressProp, |
573 | VCStreetAddressProp, | 573 | VCStreetAddressProp, |
574 | VCCityProp, | 574 | VCCityProp, |
575 | VCRegionProp, | 575 | VCRegionProp, |
576 | VCPostalCodeProp, | 576 | VCPostalCodeProp, |
577 | VCCountryNameProp, | 577 | VCCountryNameProp, |
578 | 0 | 578 | 0 |
579 | }; | 579 | }; |
580 | 580 | ||
581 | static const char *nameFields[] = { | 581 | static const char *nameFields[] = { |
582 | VCFamilyNameProp, | 582 | VCFamilyNameProp, |
583 | VCGivenNameProp, | 583 | VCGivenNameProp, |
584 | VCAdditionalNamesProp, | 584 | VCAdditionalNamesProp, |
585 | VCNamePrefixesProp, | 585 | VCNamePrefixesProp, |
586 | VCNameSuffixesProp, | 586 | VCNameSuffixesProp, |
587 | NULL | 587 | NULL |
588 | }; | 588 | }; |
589 | 589 | ||
590 | static const char *orgFields[] = { | 590 | static const char *orgFields[] = { |
591 | VCOrgNameProp, | 591 | VCOrgNameProp, |
592 | VCOrgUnitProp, | 592 | VCOrgUnitProp, |
593 | VCOrgUnit2Prop, | 593 | VCOrgUnit2Prop, |
594 | VCOrgUnit3Prop, | 594 | VCOrgUnit3Prop, |
595 | VCOrgUnit4Prop, | 595 | VCOrgUnit4Prop, |
596 | NULL | 596 | NULL |
597 | }; | 597 | }; |
598 | 598 | ||
599 | static const char *AAlarmFields[] = { | 599 | static const char *AAlarmFields[] = { |
600 | VCRunTimeProp, | 600 | VCRunTimeProp, |
601 | VCSnoozeTimeProp, | 601 | VCSnoozeTimeProp, |
602 | VCRepeatCountProp, | 602 | VCRepeatCountProp, |
603 | VCAudioContentProp, | 603 | VCAudioContentProp, |
604 | 0 | 604 | 0 |
605 | }; | 605 | }; |
606 | 606 | ||
607 | /* ExDate -- has unamed fields */ | 607 | /* ExDate -- has unamed fields */ |
608 | /* RDate -- has unamed fields */ | 608 | /* RDate -- has unamed fields */ |
609 | 609 | ||
610 | static const char *DAlarmFields[] = { | 610 | static const char *DAlarmFields[] = { |
611 | VCRunTimeProp, | 611 | VCRunTimeProp, |
612 | VCSnoozeTimeProp, | 612 | VCSnoozeTimeProp, |
613 | VCRepeatCountProp, | 613 | VCRepeatCountProp, |
614 | VCDisplayStringProp, | 614 | VCDisplayStringProp, |
615 | 0 | 615 | 0 |
616 | }; | 616 | }; |
617 | 617 | ||
618 | static const char *MAlarmFields[] = { | 618 | static const char *MAlarmFields[] = { |
619 | VCRunTimeProp, | 619 | VCRunTimeProp, |
620 | VCSnoozeTimeProp, | 620 | VCSnoozeTimeProp, |
621 | VCRepeatCountProp, | 621 | VCRepeatCountProp, |
622 | VCEmailAddressProp, | 622 | VCEmailAddressProp, |
623 | VCNoteProp, | 623 | VCNoteProp, |
624 | 0 | 624 | 0 |
625 | }; | 625 | }; |
626 | 626 | ||
627 | static const char *PAlarmFields[] = { | 627 | static const char *PAlarmFields[] = { |
628 | VCRunTimeProp, | 628 | VCRunTimeProp, |
629 | VCSnoozeTimeProp, | 629 | VCSnoozeTimeProp, |
630 | VCRepeatCountProp, | 630 | VCRepeatCountProp, |
631 | VCProcedureNameProp, | 631 | VCProcedureNameProp, |
632 | 0 | 632 | 0 |
633 | }; | 633 | }; |
634 | 634 | ||
635 | static struct PreDefProp propNames[] = { | 635 | static struct PreDefProp propNames[] = { |
636 | { VC7bitProp, 0, 0, 0 }, | 636 | { VC7bitProp, 0, 0, 0 }, |
637 | { VC8bitProp, 0, 0, 0 }, | 637 | { VC8bitProp, 0, 0, 0 }, |
638 | { VCAAlarmProp, 0, AAlarmFields, 0 }, | 638 | { VCAAlarmProp, 0, AAlarmFields, 0 }, |
639 | { VCAdditionalNamesProp, 0, 0, 0 }, | 639 | { VCAdditionalNamesProp, 0, 0, 0 }, |
640 | { VCAdrProp, 0, adrFields, 0 }, | 640 | { VCAdrProp, 0, adrFields, 0 }, |
641 | { VCAgentProp, 0, 0, 0 }, | 641 | { VCAgentProp, 0, 0, 0 }, |
642 | { VCAIFFProp, 0, 0, 0 }, | 642 | { VCAIFFProp, 0, 0, 0 }, |
643 | { VCAOLProp, 0, 0, 0 }, | 643 | { VCAOLProp, 0, 0, 0 }, |
644 | { VCAppleLinkProp, 0, 0, 0 }, | 644 | { VCAppleLinkProp, 0, 0, 0 }, |
645 | { VCAttachProp, 0, 0, 0 }, | 645 | { VCAttachProp, 0, 0, 0 }, |
646 | { VCAttendeeProp, 0, 0, 0 }, | 646 | { VCAttendeeProp, 0, 0, 0 }, |
647 | { VCATTMailProp, 0, 0, 0 }, | 647 | { VCATTMailProp, 0, 0, 0 }, |
648 | { VCAudioContentProp, 0, 0, 0 }, | 648 | { VCAudioContentProp, 0, 0, 0 }, |
649 | { VCAVIProp, 0, 0, 0 }, | 649 | { VCAVIProp, 0, 0, 0 }, |
650 | { VCBase64Prop, 0, 0, 0 }, | 650 | { VCBase64Prop, 0, 0, 0 }, |
651 | { VCBBSProp, 0, 0, 0 }, | 651 | { VCBBSProp, 0, 0, 0 }, |
652 | { VCBirthDateProp, 0, 0, 0 }, | 652 | { VCBirthDateProp, 0, 0, 0 }, |
653 | { VCBMPProp, 0, 0, 0 }, | 653 | { VCBMPProp, 0, 0, 0 }, |
654 | { VCBodyProp, 0, 0, 0 }, | 654 | { VCBodyProp, 0, 0, 0 }, |
655 | { VCBusinessRoleProp, 0, 0, 0 }, | 655 | { VCBusinessRoleProp, 0, 0, 0 }, |
656 | { VCCalProp, 0, 0, PD_BEGIN }, | 656 | { VCCalProp, 0, 0, PD_BEGIN }, |
657 | { VCCaptionProp, 0, 0, 0 }, | 657 | { VCCaptionProp, 0, 0, 0 }, |
658 | { VCCardProp, 0, 0, PD_BEGIN }, | 658 | { VCCardProp, 0, 0, PD_BEGIN }, |
659 | { VCCarProp, 0, 0, 0 }, | 659 | { VCCarProp, 0, 0, 0 }, |
660 | { VCCategoriesProp, 0, 0, 0 }, | 660 | { VCCategoriesProp, 0, 0, 0 }, |
661 | { VCCellularProp, 0, 0, 0 }, | 661 | { VCCellularProp, 0, 0, 0 }, |
662 | { VCCGMProp, 0, 0, 0 }, | 662 | { VCCGMProp, 0, 0, 0 }, |
663 | { VCCharSetProp, 0, 0, 0 }, | 663 | { VCCharSetProp, 0, 0, 0 }, |
664 | { VCCIDProp, VCContentIDProp, 0, 0 }, | 664 | { VCCIDProp, VCContentIDProp, 0, 0 }, |
665 | { VCCISProp, 0, 0, 0 }, | 665 | { VCCISProp, 0, 0, 0 }, |
666 | { VCCityProp, 0, 0, 0 }, | 666 | { VCCityProp, 0, 0, 0 }, |
667 | { VCClassProp, 0, 0, 0 }, | 667 | { VCClassProp, 0, 0, 0 }, |
668 | { VCCommentProp, 0, 0, 0 }, | 668 | { VCCommentProp, 0, 0, 0 }, |
669 | { VCCompletedProp, 0, 0, 0 }, | 669 | { VCCompletedProp, 0, 0, 0 }, |
670 | { VCContentIDProp, 0, 0, 0 }, | 670 | { VCContentIDProp, 0, 0, 0 }, |
671 | { VCCountryNameProp, 0, 0, 0 }, | 671 | { VCCountryNameProp, 0, 0, 0 }, |
672 | { VCDAlarmProp, 0, DAlarmFields, 0 }, | 672 | { VCDAlarmProp, 0, DAlarmFields, 0 }, |
673 | { VCDataSizeProp, 0, 0, PD_INTERNAL }, | 673 | { VCDataSizeProp, 0, 0, PD_INTERNAL }, |
674 | { VCDayLightProp, 0, 0, 0 }, | 674 | { VCDayLightProp, 0, 0, 0 }, |
675 | { VCDCreatedProp, 0, 0, 0 }, | 675 | { VCDCreatedProp, 0, 0, 0 }, |
676 | { VCDeliveryLabelProp, 0, 0, 0 }, | 676 | { VCDeliveryLabelProp, 0, 0, 0 }, |
677 | { VCDescriptionProp, 0, 0, 0 }, | 677 | { VCDescriptionProp, 0, 0, 0 }, |
678 | { VCDIBProp, 0, 0, 0 }, | 678 | { VCDIBProp, 0, 0, 0 }, |
679 | { VCDisplayStringProp, 0, 0, 0 }, | 679 | { VCDisplayStringProp, 0, 0, 0 }, |
680 | { VCDomesticProp, 0, 0, 0 }, | 680 | { VCDomesticProp, 0, 0, 0 }, |
681 | { VCDTendProp, 0, 0, 0 }, | 681 | { VCDTendProp, 0, 0, 0 }, |
682 | { VCDTstartProp, 0, 0, 0 }, | 682 | { VCDTstartProp, 0, 0, 0 }, |
683 | { VCDueProp, 0, 0, 0 }, | 683 | { VCDueProp, 0, 0, 0 }, |
684 | { VCEmailAddressProp, 0, 0, 0 }, | 684 | { VCEmailAddressProp, 0, 0, 0 }, |
685 | { VCEncodingProp, 0, 0, 0 }, | 685 | { VCEncodingProp, 0, 0, 0 }, |
686 | { VCEndProp, 0, 0, 0 }, | 686 | { VCEndProp, 0, 0, 0 }, |
687 | { VCEventProp, 0, 0, PD_BEGIN }, | 687 | { VCEventProp, 0, 0, PD_BEGIN }, |
688 | { VCEWorldProp, 0, 0, 0 }, | 688 | { VCEWorldProp, 0, 0, 0 }, |
689 | { VCExNumProp, 0, 0, 0 }, | 689 | { VCExNumProp, 0, 0, 0 }, |
690 | { VCExpDateProp, 0, 0, 0 }, | 690 | { VCExpDateProp, 0, 0, 0 }, |
691 | { VCExpectProp, 0, 0, 0 }, | 691 | { VCExpectProp, 0, 0, 0 }, |
692 | { VCExtAddressProp, 0, 0, 0 }, | 692 | { VCExtAddressProp, 0, 0, 0 }, |
693 | { VCFamilyNameProp, 0, 0, 0 }, | 693 | { VCFamilyNameProp, 0, 0, 0 }, |
694 | { VCFaxProp, 0, 0, 0 }, | 694 | { VCFaxProp, 0, 0, 0 }, |
695 | { VCFullNameProp, 0, 0, 0 }, | 695 | { VCFullNameProp, 0, 0, 0 }, |
696 | { VCGeoLocationProp, 0, 0, 0 }, | 696 | { VCGeoLocationProp, 0, 0, 0 }, |
697 | { VCGeoProp, 0, 0, 0 }, | 697 | { VCGeoProp, 0, 0, 0 }, |
698 | { VCGIFProp, 0, 0, 0 }, | 698 | { VCGIFProp, 0, 0, 0 }, |
699 | { VCGivenNameProp, 0, 0, 0 }, | 699 | { VCGivenNameProp, 0, 0, 0 }, |
700 | { VCGroupingProp, 0, 0, 0 }, | 700 | { VCGroupingProp, 0, 0, 0 }, |
701 | { VCHomeProp, 0, 0, 0 }, | 701 | { VCHomeProp, 0, 0, 0 }, |
702 | { VCIBMMailProp, 0, 0, 0 }, | 702 | { VCIBMMailProp, 0, 0, 0 }, |
703 | { VCInlineProp, 0, 0, 0 }, | 703 | { VCInlineProp, 0, 0, 0 }, |
704 | { VCInternationalProp, 0, 0, 0 }, | 704 | { VCInternationalProp, 0, 0, 0 }, |
705 | { VCInternetProp, 0, 0, 0 }, | 705 | { VCInternetProp, 0, 0, 0 }, |
706 | { VCISDNProp, 0, 0, 0 }, | 706 | { VCISDNProp, 0, 0, 0 }, |
707 | { VCJPEGProp, 0, 0, 0 }, | 707 | { VCJPEGProp, 0, 0, 0 }, |
708 | { VCLanguageProp, 0, 0, 0 }, | 708 | { VCLanguageProp, 0, 0, 0 }, |
709 | { VCLastModifiedProp, 0, 0, 0 }, | 709 | { VCLastModifiedProp, 0, 0, 0 }, |
710 | { VCLastRevisedProp, 0, 0, 0 }, | 710 | { VCLastRevisedProp, 0, 0, 0 }, |
711 | { VCLocationProp, 0, 0, 0 }, | 711 | { VCLocationProp, 0, 0, 0 }, |
712 | { VCLogoProp, 0, 0, 0 }, | 712 | { VCLogoProp, 0, 0, 0 }, |
713 | { VCMailerProp, 0, 0, 0 }, | 713 | { VCMailerProp, 0, 0, 0 }, |
714 | { VCMAlarmProp, 0, MAlarmFields, 0 }, | 714 | { VCMAlarmProp, 0, MAlarmFields, 0 }, |
715 | { VCMCIMailProp, 0, 0, 0 }, | 715 | { VCMCIMailProp, 0, 0, 0 }, |
716 | { VCMessageProp, 0, 0, 0 }, | 716 | { VCMessageProp, 0, 0, 0 }, |
717 | { VCMETProp, 0, 0, 0 }, | 717 | { VCMETProp, 0, 0, 0 }, |
718 | { VCModemProp, 0, 0, 0 }, | 718 | { VCModemProp, 0, 0, 0 }, |
719 | { VCMPEG2Prop, 0, 0, 0 }, | 719 | { VCMPEG2Prop, 0, 0, 0 }, |
720 | { VCMPEGProp, 0, 0, 0 }, | 720 | { VCMPEGProp, 0, 0, 0 }, |
721 | { VCMSNProp, 0, 0, 0 }, | 721 | { VCMSNProp, 0, 0, 0 }, |
722 | { VCNamePrefixesProp, 0, 0, 0 }, | 722 | { VCNamePrefixesProp, 0, 0, 0 }, |
723 | { VCNameProp, 0, nameFields, 0 }, | 723 | { VCNameProp, 0, nameFields, 0 }, |
724 | { VCNameSuffixesProp, 0, 0, 0 }, | 724 | { VCNameSuffixesProp, 0, 0, 0 }, |
725 | { VCNoteProp, 0, 0, 0 }, | 725 | { VCNoteProp, 0, 0, 0 }, |
726 | { VCOrgNameProp, 0, 0, 0 }, | 726 | { VCOrgNameProp, 0, 0, 0 }, |
727 | { VCOrgProp, 0, orgFields, 0 }, | 727 | { VCOrgProp, 0, orgFields, 0 }, |
728 | { VCOrgUnit2Prop, 0, 0, 0 }, | 728 | { VCOrgUnit2Prop, 0, 0, 0 }, |
729 | { VCOrgUnit3Prop, 0, 0, 0 }, | 729 | { VCOrgUnit3Prop, 0, 0, 0 }, |
730 | { VCOrgUnit4Prop, 0, 0, 0 }, | 730 | { VCOrgUnit4Prop, 0, 0, 0 }, |
731 | { VCOrgUnitProp, 0, 0, 0 }, | 731 | { VCOrgUnitProp, 0, 0, 0 }, |
732 | { VCPagerProp, 0, 0, 0 }, | 732 | { VCPagerProp, 0, 0, 0 }, |
733 | { VCPAlarmProp, 0, PAlarmFields, 0 }, | 733 | { VCPAlarmProp, 0, PAlarmFields, 0 }, |
734 | { VCParcelProp, 0, 0, 0 }, | 734 | { VCParcelProp, 0, 0, 0 }, |
735 | { VCPartProp, 0, 0, 0 }, | 735 | { VCPartProp, 0, 0, 0 }, |
736 | { VCPCMProp, 0, 0, 0 }, | 736 | { VCPCMProp, 0, 0, 0 }, |
737 | { VCPDFProp, 0, 0, 0 }, | 737 | { VCPDFProp, 0, 0, 0 }, |
738 | { VCPGPProp, 0, 0, 0 }, | 738 | { VCPGPProp, 0, 0, 0 }, |
739 | { VCPhotoProp, 0, 0, 0 }, | 739 | { VCPhotoProp, 0, 0, 0 }, |
740 | { VCPICTProp, 0, 0, 0 }, | 740 | { VCPICTProp, 0, 0, 0 }, |
741 | { VCPMBProp, 0, 0, 0 }, | 741 | { VCPMBProp, 0, 0, 0 }, |
742 | { VCPostalBoxProp, 0, 0, 0 }, | 742 | { VCPostalBoxProp, 0, 0, 0 }, |
743 | { VCPostalCodeProp, 0, 0, 0 }, | 743 | { VCPostalCodeProp, 0, 0, 0 }, |
744 | { VCPostalProp, 0, 0, 0 }, | 744 | { VCPostalProp, 0, 0, 0 }, |
745 | { VCPowerShareProp, 0, 0, 0 }, | 745 | { VCPowerShareProp, 0, 0, 0 }, |
746 | { VCPreferredProp, 0, 0, 0 }, | 746 | { VCPreferredProp, 0, 0, 0 }, |
747 | { VCPriorityProp, 0, 0, 0 }, | 747 | { VCPriorityProp, 0, 0, 0 }, |
748 | { VCProcedureNameProp, 0, 0, 0 }, | 748 | { VCProcedureNameProp, 0, 0, 0 }, |
749 | { VCProdIdProp, 0, 0, 0 }, | 749 | { VCProdIdProp, 0, 0, 0 }, |
750 | { VCProdigyProp, 0, 0, 0 }, | 750 | { VCProdigyProp, 0, 0, 0 }, |
751 | { VCPronunciationProp, 0, 0, 0 }, | 751 | { VCPronunciationProp, 0, 0, 0 }, |
752 | { VCPSProp, 0, 0, 0 }, | 752 | { VCPSProp, 0, 0, 0 }, |
753 | { VCPublicKeyProp, 0, 0, 0 }, | 753 | { VCPublicKeyProp, 0, 0, 0 }, |
754 | { VCQPProp, VCQuotedPrintableProp, 0, 0 }, | 754 | { VCQPProp, VCQuotedPrintableProp, 0, 0 }, |
755 | { VCQuickTimeProp, 0, 0, 0 }, | 755 | { VCQuickTimeProp, 0, 0, 0 }, |
756 | { VCQuotedPrintableProp, 0, 0, 0 }, | 756 | { VCQuotedPrintableProp, 0, 0, 0 }, |
757 | { VCRDateProp, 0, 0, 0 }, | 757 | { VCRDateProp, 0, 0, 0 }, |
758 | { VCRegionProp, 0, 0, 0 }, | 758 | { VCRegionProp, 0, 0, 0 }, |
759 | { VCRelatedToProp, 0, 0, 0 }, | 759 | { VCRelatedToProp, 0, 0, 0 }, |
760 | { VCRepeatCountProp, 0, 0, 0 }, | 760 | { VCRepeatCountProp, 0, 0, 0 }, |
761 | { VCResourcesProp, 0, 0, 0 }, | 761 | { VCResourcesProp, 0, 0, 0 }, |
762 | { VCRNumProp, 0, 0, 0 }, | 762 | { VCRNumProp, 0, 0, 0 }, |
763 | { VCRoleProp, 0, 0, 0 }, | 763 | { VCRoleProp, 0, 0, 0 }, |
764 | { VCRRuleProp, 0, 0, 0 }, | 764 | { VCRRuleProp, 0, 0, 0 }, |
765 | { VCRSVPProp, 0, 0, 0 }, | 765 | { VCRSVPProp, 0, 0, 0 }, |
766 | { VCRunTimeProp, 0, 0, 0 }, | 766 | { VCRunTimeProp, 0, 0, 0 }, |
767 | { VCSequenceProp, 0, 0, 0 }, | 767 | { VCSequenceProp, 0, 0, 0 }, |
768 | { VCSnoozeTimeProp, 0, 0, 0 }, | 768 | { VCSnoozeTimeProp, 0, 0, 0 }, |
769 | { VCStartProp, 0, 0, 0 }, | 769 | { VCStartProp, 0, 0, 0 }, |
770 | { VCStatusProp, 0, 0, 0 }, | 770 | { VCStatusProp, 0, 0, 0 }, |
771 | { VCStreetAddressProp, 0, 0, 0 }, | 771 | { VCStreetAddressProp, 0, 0, 0 }, |
772 | { VCSubTypeProp, 0, 0, 0 }, | 772 | { VCSubTypeProp, 0, 0, 0 }, |
773 | { VCSummaryProp, 0, 0, 0 }, | 773 | { VCSummaryProp, 0, 0, 0 }, |
774 | { VCTelephoneProp, 0, 0, 0 }, | 774 | { VCTelephoneProp, 0, 0, 0 }, |
775 | { VCTIFFProp, 0, 0, 0 }, | 775 | { VCTIFFProp, 0, 0, 0 }, |
776 | { VCTimeZoneProp, 0, 0, 0 }, | 776 | { VCTimeZoneProp, 0, 0, 0 }, |
777 | { VCTitleProp, 0, 0, 0 }, | 777 | { VCTitleProp, 0, 0, 0 }, |
778 | { VCTLXProp, 0, 0, 0 }, | 778 | { VCTLXProp, 0, 0, 0 }, |
779 | { VCTodoProp, 0, 0, PD_BEGIN }, | 779 | { VCTodoProp, 0, 0, PD_BEGIN }, |
780 | { VCTranspProp, 0, 0, 0 }, | 780 | { VCTranspProp, 0, 0, 0 }, |
781 | { VCUniqueStringProp, 0, 0, 0 }, | 781 | { VCUniqueStringProp, 0, 0, 0 }, |
782 | { VCURLProp, 0, 0, 0 }, | 782 | { VCURLProp, 0, 0, 0 }, |
783 | { VCURLValueProp, 0, 0, 0 }, | 783 | { VCURLValueProp, 0, 0, 0 }, |
784 | { VCValueProp, 0, 0, 0 }, | 784 | { VCValueProp, 0, 0, 0 }, |
785 | { VCVersionProp, 0, 0, 0 }, | 785 | { VCVersionProp, 0, 0, 0 }, |
786 | { VCVideoProp, 0, 0, 0 }, | 786 | { VCVideoProp, 0, 0, 0 }, |
787 | { VCVoiceProp, 0, 0, 0 }, | 787 | { VCVoiceProp, 0, 0, 0 }, |
788 | { VCWAVEProp, 0, 0, 0 }, | 788 | { VCWAVEProp, 0, 0, 0 }, |
789 | { VCWMFProp, 0, 0, 0 }, | 789 | { VCWMFProp, 0, 0, 0 }, |
790 | { VCWorkProp, 0, 0, 0 }, | 790 | { VCWorkProp, 0, 0, 0 }, |
791 | { VCX400Prop, 0, 0, 0 }, | 791 | { VCX400Prop, 0, 0, 0 }, |
792 | { VCX509Prop, 0, 0, 0 }, | 792 | { VCX509Prop, 0, 0, 0 }, |
793 | { VCXRuleProp, 0, 0, 0 }, | 793 | { VCXRuleProp, 0, 0, 0 }, |
794 | { 0,0,0,0 } | 794 | { 0,0,0,0 } |
795 | }; | 795 | }; |
796 | 796 | ||
797 | 797 | ||
798 | static struct PreDefProp* lookupPropInfo(const char* str) | 798 | static struct PreDefProp* lookupPropInfo(const char* str) |
799 | { | 799 | { |
800 | /* brute force for now, could use a hash table here. */ | 800 | /* brute force for now, could use a hash table here. */ |
801 | int i; | 801 | int i; |
802 | 802 | ||
803 | for (i = 0; propNames[i].name; i++) | 803 | for (i = 0; propNames[i].name; i++) |
804 | if (qstricmp(str, propNames[i].name) == 0) { | 804 | if (qstricmp(str, propNames[i].name) == 0) { |
805 | return &propNames[i]; | 805 | return &propNames[i]; |
806 | } | 806 | } |
807 | 807 | ||
808 | return 0; | 808 | return 0; |
809 | } | 809 | } |
810 | 810 | ||
811 | 811 | ||
812 | DLLEXPORT(const char*) lookupProp_(const char* str) | 812 | DLLEXPORT(const char*) lookupProp_(const char* str) |
813 | { | 813 | { |
814 | int i; | 814 | int i; |
815 | 815 | ||
816 | for (i = 0; propNames[i].name; i++) | 816 | for (i = 0; propNames[i].name; i++) |
817 | if (qstricmp(str, propNames[i].name) == 0) { | 817 | if (qstricmp(str, propNames[i].name) == 0) { |
818 | const char* s; | 818 | const char* s; |
819 | s = propNames[i].alias?propNames[i].alias:propNames[i].name; | 819 | s = propNames[i].alias?propNames[i].alias:propNames[i].name; |
820 | return lookupStr(s); | 820 | return lookupStr(s); |
821 | } | 821 | } |
822 | return lookupStr(str); | 822 | return lookupStr(str); |
823 | } | 823 | } |
824 | 824 | ||
825 | 825 | ||
826 | DLLEXPORT(const char*) lookupProp(const char* str) | 826 | DLLEXPORT(const char*) lookupProp(const char* str) |
827 | { | 827 | { |
828 | int i; | 828 | int i; |
829 | 829 | ||
830 | for (i = 0; propNames[i].name; i++) | 830 | for (i = 0; propNames[i].name; i++) |
831 | if (qstricmp(str, propNames[i].name) == 0) { | 831 | if (qstricmp(str, propNames[i].name) == 0) { |
832 | const char *s; | 832 | const char *s; |
833 | fieldedProp = propNames[i].fields; | 833 | fieldedProp = propNames[i].fields; |
834 | s = propNames[i].alias?propNames[i].alias:propNames[i].name; | 834 | s = propNames[i].alias?propNames[i].alias:propNames[i].name; |
835 | return lookupStr(s); | 835 | return lookupStr(s); |
836 | } | 836 | } |
837 | fieldedProp = 0; | 837 | fieldedProp = 0; |
838 | return lookupStr(str); | 838 | return lookupStr(str); |
839 | } | 839 | } |
840 | 840 | ||
841 | 841 | ||
842 | /*---------------------------------------------------------------------- | 842 | /*---------------------------------------------------------------------- |
843 | APIs to Output text form. | 843 | APIs to Output text form. |
844 | ----------------------------------------------------------------------*/ | 844 | ----------------------------------------------------------------------*/ |
845 | #define OFILE_REALLOC_SIZE 256 | 845 | #define OFILE_REALLOC_SIZE 256 |
846 | typedef struct OFile { | 846 | typedef struct OFile { |
847 | FILE *fp; | 847 | FILE *fp; |
848 | char *s; | 848 | char *s; |
849 | int len; | 849 | int len; |
850 | int limit; | 850 | int limit; |
851 | int alloc:1; | 851 | int alloc:1; |
852 | int fail:1; | 852 | int fail:1; |
853 | } OFile; | 853 | } OFile; |
854 | 854 | ||
855 | #if 0 | 855 | #if 0 |
856 | static void appendsOFile(OFile *fp, const char *s) | 856 | static void appendsOFile(OFile *fp, const char *s) |
857 | { | 857 | { |
858 | int slen; | 858 | int slen; |
859 | if (fp->fail) return; | 859 | if (fp->fail) return; |
860 | slen = strlen(s); | 860 | slen = strlen(s); |
861 | if (fp->fp) { | 861 | if (fp->fp) { |
862 | fwrite(s,1,slen,fp->fp); | 862 | fwrite(s,1,slen,fp->fp); |
863 | } | 863 | } |
864 | else { | 864 | else { |
865 | stuff: | 865 | stuff: |
866 | if (fp->len + slen < fp->limit) { | 866 | if (fp->len + slen < fp->limit) { |
867 | memcpy(fp->s+fp->len,s,slen); | 867 | memcpy(fp->s+fp->len,s,slen); |
868 | fp->len += slen; | 868 | fp->len += slen; |
869 | return; | 869 | return; |
870 | } | 870 | } |
871 | else if (fp->alloc) { | 871 | else if (fp->alloc) { |
872 | fp->limit = fp->limit + OFILE_REALLOC_SIZE; | 872 | fp->limit = fp->limit + OFILE_REALLOC_SIZE; |
873 | if (OFILE_REALLOC_SIZE <= slen) fp->limit += slen; | 873 | if (OFILE_REALLOC_SIZE <= slen) fp->limit += slen; |
874 | fp->s = (char *) realloc(fp->s,fp->limit); | 874 | fp->s = (char *) realloc(fp->s,fp->limit); |
875 | if (fp->s) goto stuff; | 875 | if (fp->s) goto stuff; |
876 | } | 876 | } |
877 | if (fp->alloc) | 877 | if (fp->alloc) |
878 | free(fp->s); | 878 | free(fp->s); |
879 | fp->s = 0; | 879 | fp->s = 0; |
880 | fp->fail = 1; | 880 | fp->fail = 1; |
881 | } | 881 | } |
882 | } | 882 | } |
883 | 883 | ||
884 | static void appendcOFile(OFile *fp, char c) | 884 | static void appendcOFile(OFile *fp, char c) |
885 | { | 885 | { |
886 | if (fp->fail) return; | 886 | if (fp->fail) return; |
887 | if (fp->fp) { | 887 | if (fp->fp) { |
888 | fputc(c,fp->fp); | 888 | fputc(c,fp->fp); |
889 | } | 889 | } |
890 | else { | 890 | else { |
891 | stuff: | 891 | stuff: |
892 | if (fp->len+1 < fp->limit) { | 892 | if (fp->len+1 < fp->limit) { |
893 | fp->s[fp->len] = c; | 893 | fp->s[fp->len] = c; |
894 | fp->len++; | 894 | fp->len++; |
895 | return; | 895 | return; |
896 | } | 896 | } |
897 | else if (fp->alloc) { | 897 | else if (fp->alloc) { |
898 | fp->limit = fp->limit + OFILE_REALLOC_SIZE; | 898 | fp->limit = fp->limit + OFILE_REALLOC_SIZE; |
899 | fp->s = (char *) realloc(fp->s,fp->limit); | 899 | fp->s = (char *) realloc(fp->s,fp->limit); |
900 | if (fp->s) goto stuff; | 900 | if (fp->s) goto stuff; |
901 | } | 901 | } |
902 | if (fp->alloc) | 902 | if (fp->alloc) |
903 | free(fp->s); | 903 | free(fp->s); |
904 | fp->s = 0; | 904 | fp->s = 0; |
905 | fp->fail = 1; | 905 | fp->fail = 1; |
906 | } | 906 | } |
907 | } | 907 | } |
908 | #else | 908 | #else |
909 | static void appendcOFile_(OFile *fp, char c) | 909 | static void appendcOFile_(OFile *fp, char c) |
910 | { | 910 | { |
911 | if (fp->fail) return; | 911 | if (fp->fail) return; |
912 | if (fp->fp) { | 912 | if (fp->fp) { |
913 | fputc(c,fp->fp); | 913 | fputc(c,fp->fp); |
914 | } | 914 | } |
915 | else { | 915 | else { |
916 | stuff: | 916 | stuff: |
917 | if (fp->len+1 < fp->limit) { | 917 | if (fp->len+1 < fp->limit) { |
918 | fp->s[fp->len] = c; | 918 | fp->s[fp->len] = c; |
919 | fp->len++; | 919 | fp->len++; |
920 | return; | 920 | return; |
921 | } | 921 | } |
922 | else if (fp->alloc) { | 922 | else if (fp->alloc) { |
923 | fp->limit = fp->limit + OFILE_REALLOC_SIZE; | 923 | fp->limit = fp->limit + OFILE_REALLOC_SIZE; |
924 | fp->s = (char *)realloc(fp->s,fp->limit); | 924 | fp->s = (char *)realloc(fp->s,fp->limit); |
925 | if (fp->s) goto stuff; | 925 | if (fp->s) goto stuff; |
926 | } | 926 | } |
927 | if (fp->alloc) | 927 | if (fp->alloc) |
928 | free(fp->s); | 928 | free(fp->s); |
929 | fp->s = 0; | 929 | fp->s = 0; |
930 | fp->fail = 1; | 930 | fp->fail = 1; |
931 | } | 931 | } |
932 | } | 932 | } |
933 | 933 | ||
934 | static void appendcOFile(OFile *fp, char c) | 934 | static void appendcOFile(OFile *fp, char c) |
935 | { | 935 | { |
936 | if (c == '\n') { | 936 | if (c == '\n') { |
937 | /* write out as <CR><LF> */ | 937 | /* write out as <CR><LF> */ |
938 | appendcOFile_(fp,0xd); | 938 | appendcOFile_(fp,0xd); |
939 | appendcOFile_(fp,0xa); | 939 | appendcOFile_(fp,0xa); |
940 | } | 940 | } |
941 | else | 941 | else |
942 | appendcOFile_(fp,c); | 942 | appendcOFile_(fp,c); |
943 | } | 943 | } |
944 | 944 | ||
945 | static void appendsOFile(OFile *fp, const char *s) | 945 | static void appendsOFile(OFile *fp, const char *s) |
946 | { | 946 | { |
947 | int i, slen; | 947 | int i, slen; |
948 | slen = strlen(s); | 948 | slen = strlen(s); |
949 | for (i=0; i<slen; i++) { | 949 | for (i=0; i<slen; i++) { |
950 | appendcOFile(fp,s[i]); | 950 | appendcOFile(fp,s[i]); |
951 | } | 951 | } |
952 | } | 952 | } |
953 | 953 | ||
954 | #endif | 954 | #endif |
955 | 955 | ||
956 | static void initOFile(OFile *fp, FILE *ofp) | 956 | static void initOFile(OFile *fp, FILE *ofp) |
957 | { | 957 | { |
958 | fp->fp = ofp; | 958 | fp->fp = ofp; |
959 | fp->s = 0; | 959 | fp->s = 0; |
960 | fp->len = 0; | 960 | fp->len = 0; |
961 | fp->limit = 0; | 961 | fp->limit = 0; |
962 | fp->alloc = 0; | 962 | fp->alloc = 0; |
963 | fp->fail = 0; | 963 | fp->fail = 0; |
964 | } | 964 | } |
965 | 965 | ||
966 | static int writeBase64(OFile *fp, unsigned char *s, long len) | 966 | static int writeBase64(OFile *fp, unsigned char *s, long len) |
967 | { | 967 | { |
968 | long cur = 0; | 968 | long cur = 0; |
969 | int i, numQuads = 0; | 969 | int i, numQuads = 0; |
970 | unsigned long trip; | 970 | unsigned long trip; |
971 | unsigned char b; | 971 | unsigned char b; |
972 | char quad[5]; | 972 | char quad[5]; |
973 | #define MAXQUADS 16 | 973 | #define MAXQUADS 16 |
974 | 974 | ||
975 | quad[4] = 0; | 975 | quad[4] = 0; |
976 | 976 | ||
977 | while (cur < len) { | 977 | while (cur < len) { |
978 | // collect the triplet of bytes into 'trip' | 978 | // collect the triplet of bytes into 'trip' |
979 | trip = 0; | 979 | trip = 0; |
980 | for (i = 0; i < 3; i++) { | 980 | for (i = 0; i < 3; i++) { |
981 | b = (cur < len) ? *(s + cur) : 0; | 981 | b = (cur < len) ? *(s + cur) : 0; |
982 | cur++; | 982 | cur++; |
983 | trip = trip << 8 | b; | 983 | trip = trip << 8 | b; |
984 | } | 984 | } |
985 | // fill in 'quad' with the appropriate four characters | 985 | // fill in 'quad' with the appropriate four characters |
986 | for (i = 3; i >= 0; i--) { | 986 | for (i = 3; i >= 0; i--) { |
987 | b = (unsigned char)(trip & 0x3F); | 987 | b = (unsigned char)(trip & 0x3F); |
988 | trip = trip >> 6; | 988 | trip = trip >> 6; |
989 | if ((3 - i) < (cur - len)) | 989 | if ((3 - i) < (cur - len)) |
990 | quad[i] = '='; // pad char | 990 | quad[i] = '='; // pad char |
991 | else if (b < 26) quad[i] = (char)b + 'A'; | 991 | else if (b < 26) quad[i] = (char)b + 'A'; |
992 | else if (b < 52) quad[i] = (char)(b - 26) + 'a'; | 992 | else if (b < 52) quad[i] = (char)(b - 26) + 'a'; |
993 | else if (b < 62) quad[i] = (char)(b - 52) + '0'; | 993 | else if (b < 62) quad[i] = (char)(b - 52) + '0'; |
994 | else if (b == 62) quad[i] = '+'; | 994 | else if (b == 62) quad[i] = '+'; |
995 | else quad[i] = '/'; | 995 | else quad[i] = '/'; |
996 | } | 996 | } |
997 | // now output 'quad' with appropriate whitespace and line ending | 997 | // now output 'quad' with appropriate whitespace and line ending |
998 | appendsOFile(fp, (numQuads == 0 ? " " : "")); | 998 | appendsOFile(fp, (numQuads == 0 ? " " : "")); |
999 | appendsOFile(fp, quad); | 999 | appendsOFile(fp, quad); |
1000 | appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : ""))); | 1000 | appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : ""))); |
1001 | numQuads = (numQuads + 1) % MAXQUADS; | 1001 | numQuads = (numQuads + 1) % MAXQUADS; |
1002 | } | 1002 | } |
1003 | appendcOFile(fp,'\n'); | 1003 | appendcOFile(fp,'\n'); |
1004 | 1004 | ||
1005 | return 1; | 1005 | return 1; |
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | static void writeQPString(OFile *fp, const char *s) | 1008 | static const char *replaceChar(unsigned char c) |
1009 | { | 1009 | { |
1010 | const char *p = s; | 1010 | if (c == '\n') { |
1011 | while (*p) { | 1011 | return "=0A=\n"; |
1012 | if (*p == '\n') { | 1012 | } else if ( |
1013 | if (p[1]) appendsOFile(fp,"=0A="); | 1013 | (c >= 'A' && c <= 'Z') |
1014 | } | 1014 | || |
1015 | appendcOFile(fp,*p); | 1015 | (c >= 'a' && c <= 'z') |
1016 | p++; | 1016 | || |
1017 | } | 1017 | (c >= '0' && c <= '9') |
1018 | } | 1018 | || |
1019 | 1019 | (c >= '\'' && c <= ')') | |
1020 | 1020 | || | |
1021 | 1021 | (c >= '+' && c <= '-') | |
1022 | static void writeVObject_(OFile *fp, VObject *o); | 1022 | || |
1023 | 1023 | (c == '/') | |
1024 | static void writeValue(OFile *fp, VObject *o, unsigned long size) | 1024 | || |
1025 | { | 1025 | (c == '?') |
1026 | if (o == 0) return; | 1026 | || |
1027 | switch (VALUE_TYPE(o)) { | 1027 | (c == ' ')) |
1028 | case VCVT_STRINGZ: { | 1028 | { |
1029 | writeQPString(fp, STRINGZ_VALUE_OF(o)); | 1029 | return 0; |
1030 | break; | 1030 | } |
1031 | } | 1031 | |
1032 | case VCVT_UINT: { | 1032 | static char trans[4]; |
1033 | char buf[16]; | 1033 | trans[0] = '='; |
1034 | sprintf(buf,"%u", INTEGER_VALUE_OF(o)); | 1034 | trans[3] = '\0'; |
1035 | appendsOFile(fp,buf); | 1035 | int rem = c % 16; |
1036 | break; | 1036 | int div = c / 16; |
1037 | } | 1037 | |
1038 | case VCVT_ULONG: { | 1038 | if (div < 10) |
1039 | char buf[16]; | 1039 | trans[1] = '0' + div; |
1040 | sprintf(buf,"%lu", LONG_VALUE_OF(o)); | 1040 | else |
1041 | appendsOFile(fp,buf); | 1041 | trans[1] = 'A' + (div - 10); |
1042 | break; | 1042 | |
1043 | } | 1043 | if (rem < 10) |
1044 | case VCVT_RAW: { | 1044 | trans[2] = '0' + rem; |
1045 | appendcOFile(fp,'\n'); | 1045 | else |
1046 | writeBase64(fp,(unsigned char*)(ANY_VALUE_OF(o)),size); | 1046 | trans[2] = 'A' + (rem - 10); |
1047 | break; | 1047 | |
1048 | } | 1048 | return trans; |
1049 | case VCVT_VOBJECT: | 1049 | } |
1050 | appendcOFile(fp,'\n'); | 1050 | |
1051 | writeVObject_(fp,VOBJECT_VALUE_OF(o)); | 1051 | static void writeQPString(OFile *fp, const char *s) |
1052 | break; | 1052 | { |
1053 | } | 1053 | /* |
1054 | } | 1054 | only A-Z, 0-9 and |
1055 | 1055 | "'" (ASCII code 39) | |
1056 | static void writeAttrValue(OFile *fp, VObject *o) | 1056 | "(" (ASCII code 40) |
1057 | { | 1057 | ")" (ASCII code 41) |
1058 | if (NAME_OF(o)) { | 1058 | "+" (ASCII code 43) |
1059 | struct PreDefProp *pi; | 1059 | "," (ASCII code 44) |
1060 | pi = lookupPropInfo(NAME_OF(o)); | 1060 | "-" (ASCII code 45) |
1061 | if (pi && ((pi->flags & PD_INTERNAL) != 0)) return; | 1061 | "/" (ASCII code 47) |
1062 | appendcOFile(fp,';'); | 1062 | "?" (ASCII code 63) |
1063 | appendsOFile(fp,NAME_OF(o)); | 1063 | |
1064 | } | 1064 | should remain un-encoded. |
1065 | else | 1065 | '=' needs to be encoded as it is the escape character. |
1066 | appendcOFile(fp,';'); | 1066 | ';' needs to be as it is a field separator. |
1067 | if (VALUE_TYPE(o)) { | 1067 | |
1068 | appendcOFile(fp,'='); | 1068 | */ |
1069 | writeValue(fp,o,0); | 1069 | const char *p = s; |
1070 | } | 1070 | while (*p) { |
1071 | } | 1071 | const char *rep = replaceChar(*p); |
1072 | 1072 | if (rep) | |
1073 | static void writeGroup(OFile *fp, VObject *o) | 1073 | appendsOFile(fp, rep); |
1074 | { | 1074 | else |
1075 | char buf1[256]; | 1075 | appendcOFile(fp, *p); |
1076 | char buf2[256]; | 1076 | p++; |
1077 | strcpy(buf1,NAME_OF(o)); | 1077 | } |
1078 | while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) { | 1078 | } |
1079 | strcpy(buf2,STRINGZ_VALUE_OF(o)); | 1079 | |
1080 | strcat(buf2,"."); | 1080 | static bool includesUnprintable(VObject *o) |
1081 | strcat(buf2,buf1); | 1081 | { |
1082 | strcpy(buf1,buf2); | 1082 | if (o) { |
1083 | } | 1083 | if (VALUE_TYPE(o) == VCVT_STRINGZ) { |
1084 | appendsOFile(fp,buf1); | 1084 | const char *p = STRINGZ_VALUE_OF(o); |
1085 | } | 1085 | if (p) { |
1086 | 1086 | while (*p) { | |
1087 | static int inList(const char **list, const char *s) | 1087 | if (replaceChar(*p)) |
1088 | { | 1088 | return TRUE; |
1089 | if (list == 0) return 0; | 1089 | p++; |
1090 | while (*list) { | 1090 | } |
1091 | if (qstricmp(*list,s) == 0) return 1; | 1091 | } |
1092 | list++; | 1092 | } |
1093 | } | 1093 | } |
1094 | return 0; | 1094 | return FALSE; |
1095 | } | 1095 | } |
1096 | 1096 | ||
1097 | static void writeProp(OFile *fp, VObject *o) | 1097 | static void writeVObject_(OFile *fp, VObject *o); |
1098 | { | 1098 | |
1099 | if (NAME_OF(o)) { | 1099 | static void writeValue(OFile *fp, VObject *o, unsigned long size) |
1100 | struct PreDefProp *pi; | 1100 | { |
1101 | VObjectIterator t; | 1101 | if (o == 0) return; |
1102 | const char **fields_ = 0; | 1102 | switch (VALUE_TYPE(o)) { |
1103 | pi = lookupPropInfo(NAME_OF(o)); | 1103 | case VCVT_STRINGZ: { |
1104 | if (pi && ((pi->flags & PD_BEGIN) != 0)) { | 1104 | writeQPString(fp, STRINGZ_VALUE_OF(o)); |
1105 | writeVObject_(fp,o); | 1105 | break; |
1106 | return; | 1106 | } |
1107 | } | 1107 | case VCVT_UINT: { |
1108 | if (isAPropertyOf(o,VCGroupingProp)) | 1108 | char buf[16]; |
1109 | writeGroup(fp,o); | 1109 | sprintf(buf,"%u", INTEGER_VALUE_OF(o)); |
1110 | else | 1110 | appendsOFile(fp,buf); |
1111 | appendsOFile(fp,NAME_OF(o)); | 1111 | break; |
1112 | if (pi) fields_ = pi->fields; | 1112 | } |
1113 | initPropIterator(&t,o); | 1113 | case VCVT_ULONG: { |
1114 | while (moreIteration(&t)) { | 1114 | char buf[16]; |
1115 | const char *s; | 1115 | sprintf(buf,"%lu", LONG_VALUE_OF(o)); |
1116 | VObject *eachProp = nextVObject(&t); | 1116 | appendsOFile(fp,buf); |
1117 | s = NAME_OF(eachProp); | 1117 | break; |
1118 | if (qstricmp(VCGroupingProp,s) && !inList(fields_,s)) | 1118 | } |
1119 | writeAttrValue(fp,eachProp); | 1119 | case VCVT_RAW: { |
1120 | } | 1120 | appendcOFile(fp,'\n'); |
1121 | if (fields_) { | 1121 | writeBase64(fp,(unsigned char*)(ANY_VALUE_OF(o)),size); |
1122 | int i = 0, n = 0; | 1122 | break; |
1123 | const char** fields = fields_; | 1123 | } |
1124 | /* output prop as fields */ | 1124 | case VCVT_VOBJECT: |
1125 | appendcOFile(fp,':'); | 1125 | appendcOFile(fp,'\n'); |
1126 | while (*fields) { | 1126 | writeVObject_(fp,VOBJECT_VALUE_OF(o)); |
1127 | VObject *t = isAPropertyOf(o,*fields); | 1127 | break; |
1128 | i++; | 1128 | } |
1129 | if (t) n = i; | 1129 | } |
1130 | fields++; | 1130 | |
1131 | } | 1131 | static void writeAttrValue(OFile *fp, VObject *o) |
1132 | fields = fields_; | 1132 | { |
1133 | for (i=0;i<n;i++) { | 1133 | if (NAME_OF(o)) { |
1134 | writeValue(fp,isAPropertyOf(o,*fields),0); | 1134 | struct PreDefProp *pi; |
1135 | fields++; | 1135 | pi = lookupPropInfo(NAME_OF(o)); |
1136 | if (i<(n-1)) appendcOFile(fp,';'); | 1136 | if (pi && ((pi->flags & PD_INTERNAL) != 0)) return; |
1137 | } | 1137 | if ( includesUnprintable(o) ) { |
1138 | } | 1138 | appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp); |
1139 | } | 1139 | appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8"); |
1140 | 1140 | } | |
1141 | if (VALUE_TYPE(o)) { | 1141 | appendcOFile(fp,';'); |
1142 | unsigned long size = 0; | 1142 | appendsOFile(fp,NAME_OF(o)); |
1143 | VObject *p = isAPropertyOf(o,VCDataSizeProp); | 1143 | } |
1144 | if (p) size = LONG_VALUE_OF(p); | 1144 | else |
1145 | appendcOFile(fp,':'); | 1145 | appendcOFile(fp,';'); |
1146 | writeValue(fp,o,size); | 1146 | if (VALUE_TYPE(o)) { |
1147 | } | 1147 | appendcOFile(fp,'='); |
1148 | 1148 | writeValue(fp,o,0); | |
1149 | appendcOFile(fp,'\n'); | 1149 | } |
1150 | } | 1150 | } |
1151 | 1151 | ||
1152 | static void writeVObject_(OFile *fp, VObject *o) | 1152 | static void writeGroup(OFile *fp, VObject *o) |
1153 | { | 1153 | { |
1154 | if (NAME_OF(o)) { | 1154 | char buf1[256]; |
1155 | struct PreDefProp *pi; | 1155 | char buf2[256]; |
1156 | pi = lookupPropInfo(NAME_OF(o)); | 1156 | strcpy(buf1,NAME_OF(o)); |
1157 | 1157 | while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) { | |
1158 | if (pi && ((pi->flags & PD_BEGIN) != 0)) { | 1158 | strcpy(buf2,STRINGZ_VALUE_OF(o)); |
1159 | VObjectIterator t; | 1159 | strcat(buf2,"."); |
1160 | const char *begin = NAME_OF(o); | 1160 | strcat(buf2,buf1); |
1161 | appendsOFile(fp,"BEGIN:"); | 1161 | strcpy(buf1,buf2); |
1162 | appendsOFile(fp,begin); | 1162 | } |
1163 | appendcOFile(fp,'\n'); | 1163 | appendsOFile(fp,buf1); |
1164 | initPropIterator(&t,o); | 1164 | } |
1165 | while (moreIteration(&t)) { | 1165 | |
1166 | VObject *eachProp = nextVObject(&t); | 1166 | static int inList(const char **list, const char *s) |
1167 | writeProp(fp, eachProp); | 1167 | { |
1168 | } | 1168 | if (list == 0) return 0; |
1169 | appendsOFile(fp,"END:"); | 1169 | while (*list) { |
1170 | appendsOFile(fp,begin); | 1170 | if (qstricmp(*list,s) == 0) return 1; |
1171 | appendsOFile(fp,"\n\n"); | 1171 | list++; |
1172 | } | 1172 | } |
1173 | } | 1173 | return 0; |
1174 | } | 1174 | } |
1175 | 1175 | ||
1176 | void writeVObject(FILE *fp, VObject *o) | 1176 | static void writeProp(OFile *fp, VObject *o) |
1177 | { | 1177 | { |
1178 | OFile ofp; | 1178 | if (NAME_OF(o)) { |
1179 | // ##### | 1179 | struct PreDefProp *pi; |
1180 | //_setmode(_fileno(fp), _O_BINARY); | 1180 | VObjectIterator t; |
1181 | initOFile(&ofp,fp); | 1181 | const char **fields_ = 0; |
1182 | writeVObject_(&ofp,o); | 1182 | pi = lookupPropInfo(NAME_OF(o)); |
1183 | } | 1183 | if (pi && ((pi->flags & PD_BEGIN) != 0)) { |
1184 | 1184 | writeVObject_(fp,o); | |
1185 | DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o) | 1185 | return; |
1186 | { | 1186 | } |
1187 | QFileDirect f( fname); | 1187 | if (isAPropertyOf(o,VCGroupingProp)) |
1188 | if ( !f.open( IO_WriteOnly ) ) { | 1188 | writeGroup(fp,o); |
1189 | qWarning("Unable to open vobject write %s", fname); | 1189 | else |
1190 | return; | 1190 | appendsOFile(fp,NAME_OF(o)); |
1191 | } | 1191 | if (pi) fields_ = pi->fields; |
1192 | 1192 | initPropIterator(&t,o); | |
1193 | writeVObject( f.directHandle(),o ); | 1193 | while (moreIteration(&t)) { |
1194 | } | 1194 | const char *s; |
1195 | 1195 | VObject *eachProp = nextVObject(&t); | |
1196 | DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list) | 1196 | s = NAME_OF(eachProp); |
1197 | { | 1197 | if (qstricmp(VCGroupingProp,s) && !inList(fields_,s)) |
1198 | QFileDirect f( fname); | 1198 | writeAttrValue(fp,eachProp); |
1199 | if ( !f.open( IO_WriteOnly ) ) { | 1199 | } |
1200 | qWarning("Unable to open vobject write %s", fname); | 1200 | if (fields_) { |
1201 | return; | 1201 | int i = 0, n = 0; |
1202 | } | 1202 | const char** fields = fields_; |
1203 | 1203 | /* output prop as fields */ | |
1204 | while (list) { | 1204 | bool printable = TRUE; |
1205 | writeVObject(f.directHandle(),list); | 1205 | while (*fields && printable) { |
1206 | list = nextVObjectInList(list); | 1206 | VObject *t = isAPropertyOf(o,*fields); |
1207 | } | 1207 | if (includesUnprintable(t)) |
1208 | } | 1208 | printable = FALSE; |
1209 | 1209 | fields++; | |
1210 | DLLEXPORT(const char *) vObjectTypeInfo(VObject *o) | 1210 | } |
1211 | { | 1211 | fields = fields_; |
1212 | const char *type = vObjectName( o ); | 1212 | if (!printable) { |
1213 | if ( strcmp( type, "TYPE" ) == 0 ) | 1213 | appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp); |
1214 | type = vObjectStringZValue( o ); | 1214 | appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8"); |
1215 | return type; | 1215 | } |
1216 | } | 1216 | appendcOFile(fp,':'); |
1217 | 1217 | while (*fields) { | |
1218 | 1218 | VObject *t = isAPropertyOf(o,*fields); | |
1219 | // end of source file vobject.c | 1219 | i++; |
1220 | if (t) n = i; | ||
1221 | fields++; | ||
1222 | } | ||
1223 | fields = fields_; | ||
1224 | for (i=0;i<n;i++) { | ||
1225 | writeValue(fp,isAPropertyOf(o,*fields),0); | ||
1226 | fields++; | ||
1227 | if (i<(n-1)) appendcOFile(fp,';'); | ||
1228 | } | ||
1229 | } | ||
1230 | } | ||
1231 | |||
1232 | |||
1233 | if (VALUE_TYPE(o)) { | ||
1234 | if ( includesUnprintable(o) ) { | ||
1235 | appendsOFile(fp, ";" VCEncodingProp "=" VCQuotedPrintableProp); | ||
1236 | appendsOFile(fp, ";" VCCharSetProp "=" "UTF-8"); | ||
1237 | } | ||
1238 | unsigned long size = 0; | ||
1239 | VObject *p = isAPropertyOf(o,VCDataSizeProp); | ||
1240 | if (p) size = LONG_VALUE_OF(p); | ||
1241 | appendcOFile(fp,':'); | ||
1242 | writeValue(fp,o,size); | ||
1243 | } | ||
1244 | |||
1245 | appendcOFile(fp,'\n'); | ||
1246 | } | ||
1247 | |||
1248 | static void writeVObject_(OFile *fp, VObject *o) | ||
1249 | { | ||
1250 | if (NAME_OF(o)) { | ||
1251 | struct PreDefProp *pi; | ||
1252 | pi = lookupPropInfo(NAME_OF(o)); | ||
1253 | |||
1254 | if (pi && ((pi->flags & PD_BEGIN) != 0)) { | ||
1255 | VObjectIterator t; | ||
1256 | const char *begin = NAME_OF(o); | ||
1257 | appendsOFile(fp,"BEGIN:"); | ||
1258 | appendsOFile(fp,begin); | ||
1259 | appendcOFile(fp,'\n'); | ||
1260 | initPropIterator(&t,o); | ||
1261 | while (moreIteration(&t)) { | ||
1262 | VObject *eachProp = nextVObject(&t); | ||
1263 | writeProp(fp, eachProp); | ||
1264 | } | ||
1265 | appendsOFile(fp,"END:"); | ||
1266 | appendsOFile(fp,begin); | ||
1267 | appendsOFile(fp,"\n\n"); | ||
1268 | } | ||
1269 | } | ||
1270 | } | ||
1271 | |||
1272 | void writeVObject(FILE *fp, VObject *o) | ||
1273 | { | ||
1274 | OFile ofp; | ||
1275 | // ##### | ||
1276 | //_setmode(_fileno(fp), _O_BINARY); | ||
1277 | initOFile(&ofp,fp); | ||
1278 | writeVObject_(&ofp,o); | ||
1279 | } | ||
1280 | |||
1281 | DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o) | ||
1282 | { | ||
1283 | QFileDirect f( fname); | ||
1284 | if ( !f.open( IO_WriteOnly ) ) { | ||
1285 | qWarning("Unable to open vobject write %s", fname); | ||
1286 | return; | ||
1287 | } | ||
1288 | |||
1289 | writeVObject( f.directHandle(),o ); | ||
1290 | } | ||
1291 | |||
1292 | DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list) | ||
1293 | { | ||
1294 | QFileDirect f( fname); | ||
1295 | if ( !f.open( IO_WriteOnly ) ) { | ||
1296 | qWarning("Unable to open vobject write %s", fname); | ||
1297 | return; | ||
1298 | } | ||
1299 | |||
1300 | while (list) { | ||
1301 | writeVObject(f.directHandle(),list); | ||
1302 | list = nextVObjectInList(list); | ||
1303 | } | ||
1304 | } | ||
1305 | |||
1306 | DLLEXPORT(const char *) vObjectTypeInfo(VObject *o) | ||
1307 | { | ||
1308 | const char *type = vObjectName( o ); | ||
1309 | if ( strcmp( type, "TYPE" ) == 0 ) | ||
1310 | type = vObjectStringZValue( o ); | ||
1311 | return type; | ||
1312 | } | ||
1313 | |||
1314 | |||
1315 | // end of source file vobject.c | ||
diff --git a/library/backend/vobject_p.h b/library/backend/vobject_p.h index a0d921e..0d0a2a8 100644 --- a/library/backend/vobject_p.h +++ b/library/backend/vobject_p.h | |||
@@ -1,404 +1,406 @@ | |||
1 | /*************************************************************************** | 1 | /*************************************************************************** |
2 | (C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International | 2 | (C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International |
3 | Business Machines Corporation and Siemens Rolm Communications Inc. | 3 | Business Machines Corporation and Siemens Rolm Communications Inc. |
4 | 4 | ||
5 | For purposes of this license notice, the term Licensors shall mean, | 5 | For purposes of this license notice, the term Licensors shall mean, |
6 | collectively, Apple Computer, Inc., AT&T Corp., International | 6 | collectively, Apple Computer, Inc., AT&T Corp., International |
7 | Business Machines Corporation and Siemens Rolm Communications Inc. | 7 | Business Machines Corporation and Siemens Rolm Communications Inc. |
8 | The term Licensor shall mean any of the Licensors. | 8 | The term Licensor shall mean any of the Licensors. |
9 | 9 | ||
10 | Subject to acceptance of the following conditions, permission is hereby | 10 | Subject to acceptance of the following conditions, permission is hereby |
11 | granted by Licensors without the need for written agreement and without | 11 | granted by Licensors without the need for written agreement and without |
12 | license or royalty fees, to use, copy, modify and distribute this | 12 | license or royalty fees, to use, copy, modify and distribute this |
13 | software for any purpose. | 13 | software for any purpose. |
14 | 14 | ||
15 | The above copyright notice and the following four paragraphs must be | 15 | The above copyright notice and the following four paragraphs must be |
16 | reproduced in all copies of this software and any software including | 16 | reproduced in all copies of this software and any software including |
17 | this software. | 17 | this software. |
18 | 18 | ||
19 | THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE | 19 | THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE |
20 | ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR | 20 | ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR |
21 | MODIFICATIONS. | 21 | MODIFICATIONS. |
22 | 22 | ||
23 | IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, | 23 | IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, |
24 | INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT | 24 | INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT |
25 | OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | 25 | OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
26 | DAMAGE. | 26 | DAMAGE. |
27 | 27 | ||
28 | EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, | 28 | EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, |
29 | INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE | 29 | INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE |
30 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 30 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
31 | PURPOSE. | 31 | PURPOSE. |
32 | 32 | ||
33 | The software is provided with RESTRICTED RIGHTS. Use, duplication, or | 33 | The software is provided with RESTRICTED RIGHTS. Use, duplication, or |
34 | disclosure by the government are subject to restrictions set forth in | 34 | disclosure by the government are subject to restrictions set forth in |
35 | DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. | 35 | DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. |
36 | 36 | ||
37 | ***************************************************************************/ | 37 | ***************************************************************************/ |
38 | 38 | ||
39 | /* | 39 | /* |
40 | 40 | ||
41 | The vCard/vCalendar C interface is implemented in the set | 41 | The vCard/vCalendar C interface is implemented in the set |
42 | of files as follows: | 42 | of files as follows: |
43 | 43 | ||
44 | vcc.y, yacc source, and vcc.c, the yacc output you will use | 44 | vcc.y, yacc source, and vcc.c, the yacc output you will use |
45 | implements the core parser | 45 | implements the core parser |
46 | 46 | ||
47 | vobject.c implements an API that insulates the caller from | 47 | vobject.c implements an API that insulates the caller from |
48 | the parser and changes in the vCard/vCalendar BNF | 48 | the parser and changes in the vCard/vCalendar BNF |
49 | 49 | ||
50 | port.h defines compilation environment dependent stuff | 50 | port.h defines compilation environment dependent stuff |
51 | 51 | ||
52 | vcc.h and vobject.h are header files for their .c counterparts | 52 | vcc.h and vobject.h are header files for their .c counterparts |
53 | 53 | ||
54 | vcaltmp.h and vcaltmp.c implement vCalendar "macro" functions | 54 | vcaltmp.h and vcaltmp.c implement vCalendar "macro" functions |
55 | which you may find useful. | 55 | which you may find useful. |
56 | 56 | ||
57 | test.c is a standalone test driver that exercises some of | 57 | test.c is a standalone test driver that exercises some of |
58 | the features of the APIs provided. Invoke test.exe on a | 58 | the features of the APIs provided. Invoke test.exe on a |
59 | VCARD/VCALENDAR input text file and you will see the pretty | 59 | VCARD/VCALENDAR input text file and you will see the pretty |
60 | print output of the internal representation (this pretty print | 60 | print output of the internal representation (this pretty print |
61 | output should give you a good idea of how the internal | 61 | output should give you a good idea of how the internal |
62 | representation looks like -- there is one such output in the | 62 | representation looks like -- there is one such output in the |
63 | following too). Also, a file with the .out suffix is generated | 63 | following too). Also, a file with the .out suffix is generated |
64 | to show that the internal representation can be written back | 64 | to show that the internal representation can be written back |
65 | in the original text format. | 65 | in the original text format. |
66 | 66 | ||
67 | For more information on this API see the readme.txt file | 67 | For more information on this API see the readme.txt file |
68 | which accompanied this distribution. | 68 | which accompanied this distribution. |
69 | 69 | ||
70 | Also visit: | 70 | Also visit: |
71 | 71 | ||
72 | http://www.versit.com | 72 | http://www.versit.com |
73 | http://www.ralden.com | 73 | http://www.ralden.com |
74 | 74 | ||
75 | */ | 75 | */ |
76 | 76 | ||
77 | 77 | // No tr() anywhere in this file | |
78 | #ifndef __VOBJECT_H__ | 78 | |
79 | #define __VOBJECT_H__ 1 | 79 | |
80 | 80 | #ifndef __VOBJECT_H__ | |
81 | #include <qstring.h> | 81 | #define __VOBJECT_H__ 1 |
82 | 82 | ||
83 | #define vCardClipboardFormat "+//ISBN 1-887687-00-9::versit::PDI//vCard" | 83 | #include <qstring.h> |
84 | #define vCalendarClipboardFormat"+//ISBN 1-887687-00-9::versit::PDI//vCalendar" | 84 | |
85 | 85 | #define vCardClipboardFormat "+//ISBN 1-887687-00-9::versit::PDI//vCard" | |
86 | /* The above strings vCardClipboardFormat and vCalendarClipboardFormat | 86 | #define vCalendarClipboardFormat"+//ISBN 1-887687-00-9::versit::PDI//vCalendar" |
87 | are globally unique IDs which can be used to generate clipboard format | 87 | |
88 | ID's as per the requirements of a specific platform. For example, in | 88 | /* The above strings vCardClipboardFormat and vCalendarClipboardFormat |
89 | Windows they are used as the parameter in a call to RegisterClipboardFormat. | 89 | are globally unique IDs which can be used to generate clipboard format |
90 | For example: | 90 | ID's as per the requirements of a specific platform. For example, in |
91 | 91 | Windows they are used as the parameter in a call to RegisterClipboardFormat. | |
92 | CLIPFORMAT foo = RegisterClipboardFormat(vCardClipboardFormat); | 92 | For example: |
93 | 93 | ||
94 | */ | 94 | CLIPFORMAT foo = RegisterClipboardFormat(vCardClipboardFormat); |
95 | 95 | ||
96 | #define vCardMimeType "text/x-vCard" | 96 | */ |
97 | #define vCalendarMimeType"text/x-vCalendar" | 97 | |
98 | 98 | #define vCardMimeType "text/x-vCard" | |
99 | #undef DLLEXPORT | 99 | #define vCalendarMimeType"text/x-vCalendar" |
100 | #include <qglobal.h> | 100 | |
101 | #if defined(Q_WS_WIN) | 101 | #undef DLLEXPORT |
102 | #define DLLEXPORT(t) __declspec(dllexport) t | 102 | #include <qglobal.h> |
103 | #else | 103 | #if defined(Q_WS_WIN) |
104 | #define DLLEXPORT(t) t | 104 | #define DLLEXPORT(t) __declspec(dllexport) t |
105 | #endif | 105 | #else |
106 | 106 | #define DLLEXPORT(t) t | |
107 | #ifndef FALSE | 107 | #endif |
108 | #define FALSE0 | 108 | |
109 | #endif | 109 | #ifndef FALSE |
110 | #ifndef TRUE | 110 | #define FALSE0 |
111 | #define TRUE1 | 111 | #endif |
112 | #endif | 112 | #ifndef TRUE |
113 | 113 | #define TRUE1 | |
114 | #include <stdlib.h> | 114 | #endif |
115 | #include <stdio.h> | 115 | |
116 | 116 | #include <stdlib.h> | |
117 | 117 | #include <stdio.h> | |
118 | #define VC7bitProp "7BIT" | 118 | |
119 | #define VC8bitProp "8BIT" | 119 | |
120 | #define VCAAlarmProp "AALARM" | 120 | #define VC7bitProp "7BIT" |
121 | #define VCAdditionalNamesProp"ADDN" | 121 | #define VC8bitProp "8BIT" |
122 | #define VCAdrProp "ADR" | 122 | #define VCAAlarmProp "AALARM" |
123 | #define VCAgentProp "AGENT" | 123 | #define VCAdditionalNamesProp"ADDN" |
124 | #define VCAIFFProp "AIFF" | 124 | #define VCAdrProp "ADR" |
125 | #define VCAOLProp "AOL" | 125 | #define VCAgentProp "AGENT" |
126 | #define VCAppleLinkProp "APPLELINK" | 126 | #define VCAIFFProp "AIFF" |
127 | #define VCAttachProp "ATTACH" | 127 | #define VCAOLProp "AOL" |
128 | #define VCAttendeeProp "ATTENDEE" | 128 | #define VCAppleLinkProp "APPLELINK" |
129 | #define VCATTMailProp "ATTMAIL" | 129 | #define VCAttachProp "ATTACH" |
130 | #define VCAudioContentProp "AUDIOCONTENT" | 130 | #define VCAttendeeProp "ATTENDEE" |
131 | #define VCAVIProp "AVI" | 131 | #define VCATTMailProp "ATTMAIL" |
132 | #define VCBase64Prop "BASE64" | 132 | #define VCAudioContentProp "AUDIOCONTENT" |
133 | #define VCBBSProp "BBS" | 133 | #define VCAVIProp "AVI" |
134 | #define VCBirthDateProp "BDAY" | 134 | #define VCBase64Prop "BASE64" |
135 | #define VCBMPProp "BMP" | 135 | #define VCBBSProp "BBS" |
136 | #define VCBodyProp "BODY" | 136 | #define VCBirthDateProp "BDAY" |
137 | #define VCBusinessRoleProp "ROLE" | 137 | #define VCBMPProp "BMP" |
138 | #define VCCalProp "VCALENDAR" | 138 | #define VCBodyProp "BODY" |
139 | #define VCCaptionProp "CAP" | 139 | #define VCBusinessRoleProp "ROLE" |
140 | #define VCCardProp "VCARD" | 140 | #define VCCalProp "VCALENDAR" |
141 | #define VCCarProp "CAR" | 141 | #define VCCaptionProp "CAP" |
142 | #define VCCategoriesProp "CATEGORIES" | 142 | #define VCCardProp "VCARD" |
143 | #define VCCellularProp "CELL" | 143 | #define VCCarProp "CAR" |
144 | #define VCCGMProp "CGM" | 144 | #define VCCategoriesProp "CATEGORIES" |
145 | #define VCCharSetProp "CS" | 145 | #define VCCellularProp "CELL" |
146 | #define VCCIDProp "CID" | 146 | #define VCCGMProp "CGM" |
147 | #define VCCISProp "CIS" | 147 | #define VCCharSetProp "CHARSET" |
148 | #define VCCityProp "L" | 148 | #define VCCIDProp "CID" |
149 | #define VCClassProp "CLASS" | 149 | #define VCCISProp "CIS" |
150 | #define VCCommentProp "NOTE" | 150 | #define VCCityProp "L" |
151 | #define VCCompletedProp "COMPLETED" | 151 | #define VCClassProp "CLASS" |
152 | #define VCContentIDProp "CONTENT-ID" | 152 | #define VCCommentProp "NOTE" |
153 | #define VCCountryNameProp "C" | 153 | #define VCCompletedProp "COMPLETED" |
154 | #define VCDAlarmProp "DALARM" | 154 | #define VCContentIDProp "CONTENT-ID" |
155 | #define VCDataSizeProp "DATASIZE" | 155 | #define VCCountryNameProp "C" |
156 | #define VCDayLightProp "DAYLIGHT" | 156 | #define VCDAlarmProp "DALARM" |
157 | #define VCDCreatedProp "DCREATED" | 157 | #define VCDataSizeProp "DATASIZE" |
158 | #define VCDeliveryLabelProp "LABEL" | 158 | #define VCDayLightProp "DAYLIGHT" |
159 | #define VCDescriptionProp "DESCRIPTION" | 159 | #define VCDCreatedProp "DCREATED" |
160 | #define VCDIBProp "DIB" | 160 | #define VCDeliveryLabelProp "LABEL" |
161 | #define VCDisplayStringProp "DISPLAYSTRING" | 161 | #define VCDescriptionProp "DESCRIPTION" |
162 | #define VCDomesticProp "DOM" | 162 | #define VCDIBProp "DIB" |
163 | #define VCDTendProp "DTEND" | 163 | #define VCDisplayStringProp "DISPLAYSTRING" |
164 | #define VCDTstartProp "DTSTART" | 164 | #define VCDomesticProp "DOM" |
165 | #define VCDueProp "DUE" | 165 | #define VCDTendProp "DTEND" |
166 | #define VCEmailAddressProp "EMAIL" | 166 | #define VCDTstartProp "DTSTART" |
167 | #define VCEncodingProp "ENCODING" | 167 | #define VCDueProp "DUE" |
168 | #define VCEndProp "END" | 168 | #define VCEmailAddressProp "EMAIL" |
169 | #define VCEventProp "VEVENT" | 169 | #define VCEncodingProp "ENCODING" |
170 | #define VCEWorldProp "EWORLD" | 170 | #define VCEndProp "END" |
171 | #define VCExNumProp "EXNUM" | 171 | #define VCEventProp "VEVENT" |
172 | #define VCExpDateProp "EXDATE" | 172 | #define VCEWorldProp "EWORLD" |
173 | #define VCExpectProp "EXPECT" | 173 | #define VCExNumProp "EXNUM" |
174 | #define VCExtAddressProp "EXT ADD" | 174 | #define VCExpDateProp "EXDATE" |
175 | #define VCFamilyNameProp "F" | 175 | #define VCExpectProp "EXPECT" |
176 | #define VCFaxProp "FAX" | 176 | #define VCExtAddressProp "EXT ADD" |
177 | #define VCFullNameProp "FN" | 177 | #define VCFamilyNameProp "F" |
178 | #define VCGeoProp "GEO" | 178 | #define VCFaxProp "FAX" |
179 | #define VCGeoLocationProp "GEO" | 179 | #define VCFullNameProp "FN" |
180 | #define VCGIFProp "GIF" | 180 | #define VCGeoProp "GEO" |
181 | #define VCGivenNameProp "G" | 181 | #define VCGeoLocationProp "GEO" |
182 | #define VCGroupingProp "Grouping" | 182 | #define VCGIFProp "GIF" |
183 | #define VCHomeProp "HOME" | 183 | #define VCGivenNameProp "G" |
184 | #define VCIBMMailProp "IBMMail" | 184 | #define VCGroupingProp "Grouping" |
185 | #define VCInlineProp "INLINE" | 185 | #define VCHomeProp "HOME" |
186 | #define VCInternationalProp "INTL" | 186 | #define VCIBMMailProp "IBMMail" |
187 | #define VCInternetProp "INTERNET" | 187 | #define VCInlineProp "INLINE" |
188 | #define VCISDNProp "ISDN" | 188 | #define VCInternationalProp "INTL" |
189 | #define VCJPEGProp "JPEG" | 189 | #define VCInternetProp "INTERNET" |
190 | #define VCLanguageProp "LANG" | 190 | #define VCISDNProp "ISDN" |
191 | #define VCLastModifiedProp "LAST-MODIFIED" | 191 | #define VCJPEGProp "JPEG" |
192 | #define VCLastRevisedProp "REV" | 192 | #define VCLanguageProp "LANG" |
193 | #define VCLocationProp "LOCATION" | 193 | #define VCLastModifiedProp "LAST-MODIFIED" |
194 | #define VCLogoProp "LOGO" | 194 | #define VCLastRevisedProp "REV" |
195 | #define VCMailerProp "MAILER" | 195 | #define VCLocationProp "LOCATION" |
196 | #define VCMAlarmProp "MALARM" | 196 | #define VCLogoProp "LOGO" |
197 | #define VCMCIMailProp "MCIMAIL" | 197 | #define VCMailerProp "MAILER" |
198 | #define VCMessageProp "MSG" | 198 | #define VCMAlarmProp "MALARM" |
199 | #define VCMETProp "MET" | 199 | #define VCMCIMailProp "MCIMAIL" |
200 | #define VCModemProp "MODEM" | 200 | #define VCMessageProp "MSG" |
201 | #define VCMPEG2Prop "MPEG2" | 201 | #define VCMETProp "MET" |
202 | #define VCMPEGProp "MPEG" | 202 | #define VCModemProp "MODEM" |
203 | #define VCMSNProp "MSN" | 203 | #define VCMPEG2Prop "MPEG2" |
204 | #define VCNamePrefixesProp "NPRE" | 204 | #define VCMPEGProp "MPEG" |
205 | #define VCNameProp "N" | 205 | #define VCMSNProp "MSN" |
206 | #define VCNameSuffixesProp "NSUF" | 206 | #define VCNamePrefixesProp "NPRE" |
207 | #define VCNoteProp "NOTE" | 207 | #define VCNameProp "N" |
208 | #define VCOrgNameProp "ORGNAME" | 208 | #define VCNameSuffixesProp "NSUF" |
209 | #define VCOrgProp "ORG" | 209 | #define VCNoteProp "NOTE" |
210 | #define VCOrgUnit2Prop "OUN2" | 210 | #define VCOrgNameProp "ORGNAME" |
211 | #define VCOrgUnit3Prop "OUN3" | 211 | #define VCOrgProp "ORG" |
212 | #define VCOrgUnit4Prop "OUN4" | 212 | #define VCOrgUnit2Prop "OUN2" |
213 | #define VCOrgUnitProp "OUN" | 213 | #define VCOrgUnit3Prop "OUN3" |
214 | #define VCPagerProp "PAGER" | 214 | #define VCOrgUnit4Prop "OUN4" |
215 | #define VCPAlarmProp "PALARM" | 215 | #define VCOrgUnitProp "OUN" |
216 | #define VCParcelProp "PARCEL" | 216 | #define VCPagerProp "PAGER" |
217 | #define VCPartProp "PART" | 217 | #define VCPAlarmProp "PALARM" |
218 | #define VCPCMProp "PCM" | 218 | #define VCParcelProp "PARCEL" |
219 | #define VCPDFProp "PDF" | 219 | #define VCPartProp "PART" |
220 | #define VCPGPProp "PGP" | 220 | #define VCPCMProp "PCM" |
221 | #define VCPhotoProp "PHOTO" | 221 | #define VCPDFProp "PDF" |
222 | #define VCPICTProp "PICT" | 222 | #define VCPGPProp "PGP" |
223 | #define VCPMBProp "PMB" | 223 | #define VCPhotoProp "PHOTO" |
224 | #define VCPostalBoxProp "BOX" | 224 | #define VCPICTProp "PICT" |
225 | #define VCPostalCodeProp "PC" | 225 | #define VCPMBProp "PMB" |
226 | #define VCPostalProp "POSTAL" | 226 | #define VCPostalBoxProp "BOX" |
227 | #define VCPowerShareProp "POWERSHARE" | 227 | #define VCPostalCodeProp "PC" |
228 | #define VCPreferredProp "PREF" | 228 | #define VCPostalProp "POSTAL" |
229 | #define VCPriorityProp "PRIORITY" | 229 | #define VCPowerShareProp "POWERSHARE" |
230 | #define VCProcedureNameProp "PROCEDURENAME" | 230 | #define VCPreferredProp "PREF" |
231 | #define VCProdIdProp "PRODID" | 231 | #define VCPriorityProp "PRIORITY" |
232 | #define VCProdigyProp "PRODIGY" | 232 | #define VCProcedureNameProp "PROCEDURENAME" |
233 | #define VCPronunciationProp "SOUND" | 233 | #define VCProdIdProp "PRODID" |
234 | #define VCPSProp "PS" | 234 | #define VCProdigyProp "PRODIGY" |
235 | #define VCPublicKeyProp "KEY" | 235 | #define VCPronunciationProp "SOUND" |
236 | #define VCQPProp "QP" | 236 | #define VCPSProp "PS" |
237 | #define VCQuickTimeProp "QTIME" | 237 | #define VCPublicKeyProp "KEY" |
238 | #define VCQuotedPrintableProp"QUOTED-PRINTABLE" | 238 | #define VCQPProp "QP" |
239 | #define VCRDateProp "RDATE" | 239 | #define VCQuickTimeProp "QTIME" |
240 | #define VCRegionProp "R" | 240 | #define VCQuotedPrintableProp"QUOTED-PRINTABLE" |
241 | #define VCRelatedToProp "RELATED-TO" | 241 | #define VCRDateProp "RDATE" |
242 | #define VCRepeatCountProp "REPEATCOUNT" | 242 | #define VCRegionProp "R" |
243 | #define VCResourcesProp "RESOURCES" | 243 | #define VCRelatedToProp "RELATED-TO" |
244 | #define VCRNumProp "RNUM" | 244 | #define VCRepeatCountProp "REPEATCOUNT" |
245 | #define VCRoleProp "ROLE" | 245 | #define VCResourcesProp "RESOURCES" |
246 | #define VCRRuleProp "RRULE" | 246 | #define VCRNumProp "RNUM" |
247 | #define VCRSVPProp "RSVP" | 247 | #define VCRoleProp "ROLE" |
248 | #define VCRunTimeProp "RUNTIME" | 248 | #define VCRRuleProp "RRULE" |
249 | #define VCSequenceProp "SEQUENCE" | 249 | #define VCRSVPProp "RSVP" |
250 | #define VCSnoozeTimeProp "SNOOZETIME" | 250 | #define VCRunTimeProp "RUNTIME" |
251 | #define VCStartProp "START" | 251 | #define VCSequenceProp "SEQUENCE" |
252 | #define VCStatusProp "STATUS" | 252 | #define VCSnoozeTimeProp "SNOOZETIME" |
253 | #define VCStreetAddressProp "STREET" | 253 | #define VCStartProp "START" |
254 | #define VCSubTypeProp "SUBTYPE" | 254 | #define VCStatusProp "STATUS" |
255 | #define VCSummaryProp "SUMMARY" | 255 | #define VCStreetAddressProp "STREET" |
256 | #define VCTelephoneProp "TEL" | 256 | #define VCSubTypeProp "SUBTYPE" |
257 | #define VCTIFFProp "TIFF" | 257 | #define VCSummaryProp "SUMMARY" |
258 | #define VCTimeZoneProp "TZ" | 258 | #define VCTelephoneProp "TEL" |
259 | #define VCTitleProp "TITLE" | 259 | #define VCTIFFProp "TIFF" |
260 | #define VCTLXProp "TLX" | 260 | #define VCTimeZoneProp "TZ" |
261 | #define VCTodoProp "VTODO" | 261 | #define VCTitleProp "TITLE" |
262 | #define VCTranspProp "TRANSP" | 262 | #define VCTLXProp "TLX" |
263 | #define VCUniqueStringProp "UID" | 263 | #define VCTodoProp "VTODO" |
264 | #define VCURLProp "URL" | 264 | #define VCTranspProp "TRANSP" |
265 | #define VCURLValueProp "URLVAL" | 265 | #define VCUniqueStringProp "UID" |
266 | #define VCValueProp "VALUE" | 266 | #define VCURLProp "URL" |
267 | #define VCVersionProp "VERSION" | 267 | #define VCURLValueProp "URLVAL" |
268 | #define VCVideoProp "VIDEO" | 268 | #define VCValueProp "VALUE" |
269 | #define VCVoiceProp "VOICE" | 269 | #define VCVersionProp "VERSION" |
270 | #define VCWAVEProp "WAVE" | 270 | #define VCVideoProp "VIDEO" |
271 | #define VCWMFProp "WMF" | 271 | #define VCVoiceProp "VOICE" |
272 | #define VCWorkProp "WORK" | 272 | #define VCWAVEProp "WAVE" |
273 | #define VCX400Prop "X400" | 273 | #define VCWMFProp "WMF" |
274 | #define VCX509Prop "X509" | 274 | #define VCWorkProp "WORK" |
275 | #define VCXRuleProp "XRULE" | 275 | #define VCX400Prop "X400" |
276 | 276 | #define VCX509Prop "X509" | |
277 | 277 | #define VCXRuleProp "XRULE" | |
278 | typedef struct VObject VObject; | 278 | |
279 | 279 | ||
280 | typedef struct VObjectIterator { | 280 | typedef struct VObject VObject; |
281 | VObject* start; | 281 | |
282 | VObject* next; | 282 | typedef struct VObjectIterator { |
283 | } VObjectIterator; | 283 | VObject* start; |
284 | 284 | VObject* next; | |
285 | extern DLLEXPORT(VObject*) newVObject(const char *id); | 285 | } VObjectIterator; |
286 | extern DLLEXPORT(void) deleteVObject(VObject *p); | 286 | |
287 | extern DLLEXPORT(char*) dupStr(const char *s, unsigned int size); | 287 | extern DLLEXPORT(VObject*) newVObject(const char *id); |
288 | extern DLLEXPORT(void) deleteStr(const char *p); | 288 | extern DLLEXPORT(void) deleteVObject(VObject *p); |
289 | extern DLLEXPORT(void) unUseStr(const char *s); | 289 | extern DLLEXPORT(char*) dupStr(const char *s, unsigned int size); |
290 | 290 | extern DLLEXPORT(void) deleteStr(const char *p); | |
291 | extern DLLEXPORT(void) setVObjectName(VObject *o, const char* id); | 291 | extern DLLEXPORT(void) unUseStr(const char *s); |
292 | extern DLLEXPORT(void) setVObjectStringZValue(VObject *o, const char *s); | 292 | |
293 | extern DLLEXPORT(void) setVObjectStringZValue_(VObject *o, const char *s); | 293 | extern DLLEXPORT(void) setVObjectName(VObject *o, const char* id); |
294 | extern DLLEXPORT(void) setVObjectIntegerValue(VObject *o, unsigned int i); | 294 | extern DLLEXPORT(void) setVObjectStringZValue(VObject *o, const char *s); |
295 | extern DLLEXPORT(void) setVObjectLongValue(VObject *o, unsigned long l); | 295 | extern DLLEXPORT(void) setVObjectStringZValue_(VObject *o, const char *s); |
296 | extern DLLEXPORT(void) setVObjectAnyValue(VObject *o, void *t); | 296 | extern DLLEXPORT(void) setVObjectIntegerValue(VObject *o, unsigned int i); |
297 | extern DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size); | 297 | extern DLLEXPORT(void) setVObjectLongValue(VObject *o, unsigned long l); |
298 | extern DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size); | 298 | extern DLLEXPORT(void) setVObjectAnyValue(VObject *o, void *t); |
299 | 299 | extern DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size); | |
300 | extern DLLEXPORT(const char*) vObjectName(VObject *o); | 300 | extern DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size); |
301 | extern DLLEXPORT(const char*) vObjectStringZValue(VObject *o); | 301 | |
302 | extern DLLEXPORT(unsigned int) vObjectIntegerValue(VObject *o); | 302 | extern DLLEXPORT(const char*) vObjectName(VObject *o); |
303 | extern DLLEXPORT(unsigned long) vObjectLongValue(VObject *o); | 303 | extern DLLEXPORT(const char*) vObjectStringZValue(VObject *o); |
304 | extern DLLEXPORT(void*) vObjectAnyValue(VObject *o); | 304 | extern DLLEXPORT(unsigned int) vObjectIntegerValue(VObject *o); |
305 | extern DLLEXPORT(VObject*) vObjectVObjectValue(VObject *o); | 305 | extern DLLEXPORT(unsigned long) vObjectLongValue(VObject *o); |
306 | extern DLLEXPORT(void) setVObjectVObjectValue(VObject *o, VObject *p); | 306 | extern DLLEXPORT(void*) vObjectAnyValue(VObject *o); |
307 | 307 | extern DLLEXPORT(VObject*) vObjectVObjectValue(VObject *o); | |
308 | extern DLLEXPORT(VObject*) addVObjectProp(VObject *o, VObject *p); | 308 | extern DLLEXPORT(void) setVObjectVObjectValue(VObject *o, VObject *p); |
309 | extern DLLEXPORT(VObject*) addProp(VObject *o, const char *id); | 309 | |
310 | extern DLLEXPORT(VObject*) addProp_(VObject *o, const char *id); | 310 | extern DLLEXPORT(VObject*) addVObjectProp(VObject *o, VObject *p); |
311 | extern DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v); | 311 | extern DLLEXPORT(VObject*) addProp(VObject *o, const char *id); |
312 | extern DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v, unsigned int size); | 312 | extern DLLEXPORT(VObject*) addProp_(VObject *o, const char *id); |
313 | extern DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v, unsigned int size); | 313 | extern DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v); |
314 | extern DLLEXPORT(VObject*) addGroup(VObject *o, const char *g); | 314 | extern DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v, unsigned int size); |
315 | extern DLLEXPORT(void) addList(VObject **o, VObject *p); | 315 | extern DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v, unsigned int size); |
316 | 316 | extern DLLEXPORT(VObject*) addGroup(VObject *o, const char *g); | |
317 | extern DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id); | 317 | extern DLLEXPORT(void) addList(VObject **o, VObject *p); |
318 | 318 | ||
319 | extern DLLEXPORT(VObject*) nextVObjectInList(VObject *o); | 319 | extern DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id); |
320 | extern DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o); | 320 | |
321 | extern DLLEXPORT(int) moreIteration(VObjectIterator *i); | 321 | extern DLLEXPORT(VObject*) nextVObjectInList(VObject *o); |
322 | extern DLLEXPORT(VObject*) nextVObject(VObjectIterator *i); | 322 | extern DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o); |
323 | 323 | extern DLLEXPORT(int) moreIteration(VObjectIterator *i); | |
324 | extern DLLEXPORT(const char*) lookupStr(const char *s); | 324 | extern DLLEXPORT(VObject*) nextVObject(VObjectIterator *i); |
325 | extern DLLEXPORT(void) cleanStrTbl(); | 325 | |
326 | 326 | extern DLLEXPORT(const char*) lookupStr(const char *s); | |
327 | extern DLLEXPORT(void) cleanVObject(VObject *o); | 327 | extern DLLEXPORT(void) cleanStrTbl(); |
328 | extern DLLEXPORT(void) cleanVObjects(VObject *list); | 328 | |
329 | 329 | extern DLLEXPORT(void) cleanVObject(VObject *o); | |
330 | extern DLLEXPORT(const char*) lookupProp(const char* str); | 330 | extern DLLEXPORT(void) cleanVObjects(VObject *list); |
331 | extern DLLEXPORT(const char*) lookupProp_(const char* str); | 331 | |
332 | 332 | extern DLLEXPORT(const char*) lookupProp(const char* str); | |
333 | extern DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o); | 333 | extern DLLEXPORT(const char*) lookupProp_(const char* str); |
334 | extern DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list); | 334 | |
335 | 335 | extern DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o); | |
336 | extern DLLEXPORT(int) vObjectValueType(VObject *o); | 336 | extern DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list); |
337 | 337 | ||
338 | /* return type of vObjectValueType: */ | 338 | extern DLLEXPORT(int) vObjectValueType(VObject *o); |
339 | #define VCVT_NOVALUE0 | 339 | |
340 | /* if the VObject has no value associated with it. */ | 340 | /* return type of vObjectValueType: */ |
341 | #define VCVT_STRINGZ1 | 341 | #define VCVT_NOVALUE0 |
342 | /* if the VObject has value set by setVObjectStringZValue. */ | 342 | /* if the VObject has no value associated with it. */ |
343 | #define VCVT_UINT 2 | 343 | #define VCVT_STRINGZ1 |
344 | /* if the VObject has value set by setVObjectIntegerValue. */ | 344 | /* if the VObject has value set by setVObjectStringZValue. */ |
345 | #define VCVT_ULONG 3 | 345 | #define VCVT_UINT 2 |
346 | /* if the VObject has value set by setVObjectLongValue. */ | 346 | /* if the VObject has value set by setVObjectIntegerValue. */ |
347 | #define VCVT_RAW 4 | 347 | #define VCVT_ULONG 3 |
348 | /* if the VObject has value set by setVObjectAnyValue. */ | 348 | /* if the VObject has value set by setVObjectLongValue. */ |
349 | #define VCVT_VOBJECT5 | 349 | #define VCVT_RAW 4 |
350 | /* if the VObject has value set by setVObjectVObjectValue. */ | 350 | /* if the VObject has value set by setVObjectAnyValue. */ |
351 | 351 | #define VCVT_VOBJECT5 | |
352 | extern const char** fieldedProp; | 352 | /* if the VObject has value set by setVObjectVObjectValue. */ |
353 | 353 | ||
354 | /*************************************************** | 354 | extern const char** fieldedProp; |
355 | * The methods below are implemented in vcc.c (generated from vcc.y ) | 355 | |
356 | ***************************************************/ | 356 | /*************************************************** |
357 | 357 | * The methods below are implemented in vcc.c (generated from vcc.y ) | |
358 | /* NOTE regarding printVObject and writeVObject | 358 | ***************************************************/ |
359 | 359 | ||
360 | The functions below are not exported from the DLL because they | 360 | /* NOTE regarding printVObject and writeVObject |
361 | take a FILE* as a parameter, which cannot be passed across a DLL | 361 | |
362 | interface (at least that is my experience). Instead you can use | 362 | The functions below are not exported from the DLL because they |
363 | their companion functions which take file names or pointers | 363 | take a FILE* as a parameter, which cannot be passed across a DLL |
364 | to memory. However, if you are linking this code into | 364 | interface (at least that is my experience). Instead you can use |
365 | your build directly then you may find them a more convenient API | 365 | their companion functions which take file names or pointers |
366 | and you can go ahead and use them. If you try to use them with | 366 | to memory. However, if you are linking this code into |
367 | the DLL LIB you will get a link error. | 367 | your build directly then you may find them a more convenient API |
368 | */ | 368 | and you can go ahead and use them. If you try to use them with |
369 | extern void writeVObject(FILE *fp, VObject *o); | 369 | the DLL LIB you will get a link error. |
370 | 370 | */ | |
371 | 371 | extern void writeVObject(FILE *fp, VObject *o); | |
372 | 372 | ||
373 | typedef void (*MimeErrorHandler)(char *); | 373 | |
374 | 374 | ||
375 | extern DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler); | 375 | typedef void (*MimeErrorHandler)(char *); |
376 | 376 | ||
377 | extern DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len); | 377 | extern DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler); |
378 | extern DLLEXPORT(VObject*) Parse_MIME_FromFileName(char* fname); | 378 | |
379 | 379 | extern DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len); | |
380 | 380 | extern DLLEXPORT(VObject*) Parse_MIME_FromFileName(char* fname); | |
381 | /* NOTE regarding Parse_MIME_FromFile | 381 | |
382 | The function above, Parse_MIME_FromFile, comes in two flavors, | 382 | |
383 | neither of which is exported from the DLL. Each version takes | 383 | /* NOTE regarding Parse_MIME_FromFile |
384 | a CFile or FILE* as a parameter, neither of which can be | 384 | The function above, Parse_MIME_FromFile, comes in two flavors, |
385 | passed across a DLL interface (at least that is my experience). | 385 | neither of which is exported from the DLL. Each version takes |
386 | If you are linking this code into your build directly then | 386 | a CFile or FILE* as a parameter, neither of which can be |
387 | you may find them a more convenient API that the other flavors | 387 | passed across a DLL interface (at least that is my experience). |
388 | that take a file name. If you use them with the DLL LIB you | 388 | If you are linking this code into your build directly then |
389 | will get a link error. | 389 | you may find them a more convenient API that the other flavors |
390 | */ | 390 | that take a file name. If you use them with the DLL LIB you |
391 | 391 | will get a link error. | |
392 | 392 | */ | |
393 | #if INCLUDEMFC | 393 | |
394 | extern VObject* Parse_MIME_FromFile(CFile *file); | 394 | |
395 | #else | 395 | #if INCLUDEMFC |
396 | extern VObject* Parse_MIME_FromFile(FILE *file); | 396 | extern VObject* Parse_MIME_FromFile(CFile *file); |
397 | #endif | 397 | #else |
398 | 398 | extern VObject* Parse_MIME_FromFile(FILE *file); | |
399 | extern DLLEXPORT(const char *) vObjectTypeInfo(VObject *o); | 399 | #endif |
400 | 400 | ||
401 | 401 | extern DLLEXPORT(const char *) vObjectTypeInfo(VObject *o); | |
402 | #endif /* __VOBJECT_H__ */ | 402 | |
403 | 403 | ||
404 | 404 | #endif /* __VOBJECT_H__ */ | |
405 | |||
406 | |||