summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--library/applnk.cpp16
-rw-r--r--library/backend/categories.cpp9
-rw-r--r--library/backend/categories.h2
-rw-r--r--library/backend/event.cpp4
-rw-r--r--library/backend/palmtoprecord.h12
-rw-r--r--library/datebookdb.cpp12
-rw-r--r--library/finddialog.cpp7
-rw-r--r--library/global.cpp28
-rw-r--r--library/qpeapplication.cpp3
-rw-r--r--library/storage.cpp6
10 files changed, 65 insertions, 34 deletions
diff --git a/library/applnk.cpp b/library/applnk.cpp
index 35822dd..00030e8 100644
--- a/library/applnk.cpp
+++ b/library/applnk.cpp
@@ -79,513 +79,529 @@ public:
79 QPixmap pix; 79 QPixmap pix;
80 mPixmaps.insert(0, pix ); 80 mPixmaps.insert(0, pix );
81 mPixmaps.insert(1, pix); 81 mPixmaps.insert(1, pix);
82 } 82 }
83 83
84 QStringList mCatList; // always correct 84 QStringList mCatList; // always correct
85 QArray<int> mCat; // cached value; correct if not empty 85 QArray<int> mCat; // cached value; correct if not empty
86 QMap<int, QPixmap> mPixmaps; 86 QMap<int, QPixmap> mPixmaps;
87 87
88 void updateCatListFromArray() 88 void updateCatListFromArray()
89 { 89 {
90 Categories cat( 0 ); 90 Categories cat( 0 );
91 cat.load( categoryFileName() ); 91 cat.load( categoryFileName() );
92 // we need to update the names for the mCat... to mCatList 92 // we need to update the names for the mCat... to mCatList
93 mCatList.clear(); 93 mCatList.clear();
94 for (uint i = 0; i < mCat.count(); i++ ) 94 for (uint i = 0; i < mCat.count(); i++ )
95 mCatList << cat.label("Document View", mCat[i] ); 95 mCatList << cat.label("Document View", mCat[i] );
96 96
97 } 97 }
98 98
99 void setCatArrayDirty() 99 void setCatArrayDirty()
100 { 100 {
101 mCat.resize(0); 101 mCat.resize(0);
102 } 102 }
103 103
104 void ensureCatArray() 104 void ensureCatArray()
105 { 105 {
106 if ( mCat.count() > 0 || mCatList.count()==0 ) 106 if ( mCat.count() > 0 || mCatList.count()==0 )
107 return; 107 return;
108 108
109 Categories cat( 0 ); 109 Categories cat( 0 );
110 cat.load( categoryFileName() ); 110 cat.load( categoryFileName() );
111 mCat.resize( mCatList.count() ); 111 mCat.resize( mCatList.count() );
112 int i; 112 int i;
113 QStringList::ConstIterator it; 113 QStringList::ConstIterator it;
114 for ( i = 0, it = mCatList.begin(); it != mCatList.end(); 114 for ( i = 0, it = mCatList.begin(); it != mCatList.end();
115 ++it, i++ ) { 115 ++it, i++ ) {
116 116
117 bool number; 117 bool number;
118 int id = (*it).toInt( &number ); 118 int id = (*it).toInt( &number );
119 if ( !number ) { 119 if ( !number ) {
120 id = cat.id( "Document View", *it ); 120 id = cat.id( "Document View", *it );
121 if ( id == 0 ) 121 if ( id == 0 )
122 id = cat.addCategory( "Document View", *it ); 122 id = cat.addCategory( "Document View", *it );
123 } 123 }
124 mCat[i] = id; 124 mCat[i] = id;
125 } 125 }
126 } 126 }
127}; 127};
128 128
129/*! 129/*!
130 \class AppLnk applnk.h 130 \class AppLnk applnk.h
131 \brief The AppLnk class represents an application available on the system. 131 \brief The AppLnk class represents an application available on the system.
132 132
133 Every Qtopia application \e app has a corresponding \e app.desktop 133 Every Qtopia application \e app has a corresponding \e app.desktop
134 file. When one of these files is read its data is stored as an 134 file. When one of these files is read its data is stored as an
135 AppLnk object. 135 AppLnk object.
136 136
137 The AppLnk class introduces some Qtopia-specific concepts, and 137 The AppLnk class introduces some Qtopia-specific concepts, and
138 provides a variety of functions, as described in the following 138 provides a variety of functions, as described in the following
139 sections. 139 sections.
140 \tableofcontents 140 \tableofcontents
141 141
142 \target Types 142 \target Types
143 \section1 Types 143 \section1 Types
144 144
145 Every AppLnk object has a \e type. For applications, games and 145 Every AppLnk object has a \e type. For applications, games and
146 settings the type is \c Application; for documents the 146 settings the type is \c Application; for documents the
147 type is the document's MIME type. 147 type is the document's MIME type.
148 148
149 \target files-and-links 149 \target files-and-links
150 \section1 Files and Links 150 \section1 Files and Links
151 151
152 When you create an AppLnk (or more likely, a \link doclnk.html 152 When you create an AppLnk (or more likely, a \link doclnk.html
153 DocLnk\endlink), you don't deal directly with filenames in the 153 DocLnk\endlink), you don't deal directly with filenames in the
154 filesystem. Instead you do this: 154 filesystem. Instead you do this:
155 \code 155 \code
156 DocLnk d; 156 DocLnk d;
157 d.setType("text/plain"); 157 d.setType("text/plain");
158 d.setName("My Nicely Named Document / Whatever"); // Yes, "/" is legal. 158 d.setName("My Nicely Named Document / Whatever"); // Yes, "/" is legal.
159 \endcode 159 \endcode
160 At this point, the file() and linkFile() are unknown. Normally 160 At this point, the file() and linkFile() are unknown. Normally
161 this is uninteresting, and the names become automatically known, 161 this is uninteresting, and the names become automatically known,
162 and more importantly, becomes reserved, when you ask what they are: 162 and more importantly, becomes reserved, when you ask what they are:
163 163
164 \code 164 \code
165 QString fn = d.file(); 165 QString fn = d.file();
166 \endcode 166 \endcode
167 This invents a filename, and creates the file on disk (an empty 167 This invents a filename, and creates the file on disk (an empty
168 reservation file) to prevent the name being used by another 168 reservation file) to prevent the name being used by another
169 application. 169 application.
170 170
171 In some circumstances, you don't want to create the file if it 171 In some circumstances, you don't want to create the file if it
172 doesn't already exist (e.g. in the Document tab, some of the \link 172 doesn't already exist (e.g. in the Document tab, some of the \link
173 doclnk.html DocLnk\endlink objects represented by icons are 173 doclnk.html DocLnk\endlink objects represented by icons are
174 DocLnk's created just for that view - they don't have 174 DocLnk's created just for that view - they don't have
175 corresponding \c .desktop files. To avoid littering empty 175 corresponding \c .desktop files. To avoid littering empty
176 reservation files around, we check in a few places to see whether 176 reservation files around, we check in a few places to see whether
177 the file really needs to exist). 177 the file really needs to exist).
178 178
179 \section1 Functionality 179 \section1 Functionality
180 180
181 AppLnk objects are created by calling the constructor with the 181 AppLnk objects are created by calling the constructor with the
182 name of a \e .desktop file. The object can be checked for validity 182 name of a \e .desktop file. The object can be checked for validity
183 using isValid(). 183 using isValid().
184 184
185 The following functions are used to set or retrieve information 185 The following functions are used to set or retrieve information
186 about the application: 186 about the application:
187 \table 187 \table
188 \header \i Get Function \i Set Function \i Short Description 188 \header \i Get Function \i Set Function \i Short Description
189 \row \i \l name() \i \l setName() \i application's name 189 \row \i \l name() \i \l setName() \i application's name
190 \row \i \l pixmap() \i \e none \i application's icon 190 \row \i \l pixmap() \i \e none \i application's icon
191 \row \i \l bigPixmap() \i \e none \i application's large icon 191 \row \i \l bigPixmap() \i \e none \i application's large icon
192 \row \i \e none \i setIcon() \i sets the icon's filename 192 \row \i \e none \i setIcon() \i sets the icon's filename
193 \row \i \l type() \i \l setType() \i see \link #Types Types\endlink above 193 \row \i \l type() \i \l setType() \i see \link #Types Types\endlink above
194 \row \i \l rotation() \i \e none \i 0, 90, 180 or 270 degrees 194 \row \i \l rotation() \i \e none \i 0, 90, 180 or 270 degrees
195 \row \i \l comment() \i \l setComment() \i text for the Details dialog 195 \row \i \l comment() \i \l setComment() \i text for the Details dialog
196 \row \i \l exec() \i \l setExec() \i executable's filename 196 \row \i \l exec() \i \l setExec() \i executable's filename
197 \row \i \l file() \i \e none \i document's filename 197 \row \i \l file() \i \e none \i document's filename
198 \row \i \l linkFile() \i \l setLinkFile()\i \e .desktop filename 198 \row \i \l linkFile() \i \l setLinkFile()\i \e .desktop filename
199 \row \i \l mimeTypes() \i \e none \i the mime types the application can view or edit 199 \row \i \l mimeTypes() \i \e none \i the mime types the application can view or edit
200 \row \i \l categories() \i \l setCategories()\i \e{see the function descriptions} 200 \row \i \l categories() \i \l setCategories()\i \e{see the function descriptions}
201 \row \i \l fileKnown() \i \e none \i see \link 201 \row \i \l fileKnown() \i \e none \i see \link
202#files-and-links Files and Links\endlink above 202#files-and-links Files and Links\endlink above
203 \row \i \l linkFileKnown() \i \e none \i see \link 203 \row \i \l linkFileKnown() \i \e none \i see \link
204#files-and-links Files and Links\endlink above 204#files-and-links Files and Links\endlink above
205 \row \i \l property() \i \l setProperty()\i any AppLnk property 205 \row \i \l property() \i \l setProperty()\i any AppLnk property
206 can be retrieved or set (if writeable) using these 206 can be retrieved or set (if writeable) using these
207 \endtable 207 \endtable
208 208
209 To save an AppLnk to disk use writeLink(). To execute the 209 To save an AppLnk to disk use writeLink(). To execute the
210 application that the AppLnk object refers to, use execute(). 210 application that the AppLnk object refers to, use execute().
211 211
212 AppLnk's can be deleted from disk using removeLinkFile(). To 212 AppLnk's can be deleted from disk using removeLinkFile(). To
213 remove both the link and the application's executable use 213 remove both the link and the application's executable use
214 removeFiles(). 214 removeFiles().
215 215
216 Icon sizes can be globally changed (but only for AppLnk objects 216 Icon sizes can be globally changed (but only for AppLnk objects
217 created after the calls) with setSmallIconSize() and 217 created after the calls) with setSmallIconSize() and
218 setBigIconSize(). 218 setBigIconSize().
219 219
220 \ingroup qtopiaemb 220 \ingroup qtopiaemb
221*/ 221*/
222 222
223/*! 223/*!
224 Sets the size used for small icons to \a small pixels. 224 Sets the size used for small icons to \a small pixels.
225 Only affects AppLnk objects created after the call. 225 Only affects AppLnk objects created after the call.
226 226
227 \sa smallIconSize() setIcon() 227 \sa smallIconSize() setIcon()
228*/ 228*/
229void AppLnk::setSmallIconSize(int small) 229void AppLnk::setSmallIconSize(int small)
230{ 230{
231 smallSize = small; 231 smallSize = small;
232} 232}
233 233
234/*! 234/*!
235 Returns the size used for small icons. 235 Returns the size used for small icons.
236 236
237 \sa setSmallIconSize() setIcon() 237 \sa setSmallIconSize() setIcon()
238*/ 238*/
239int AppLnk::smallIconSize() 239int AppLnk::smallIconSize()
240{ 240{
241 return smallSize; 241 return smallSize;
242} 242}
243 243
244 244
245/*! 245/*!
246 Sets the size used for large icons to \a big pixels. 246 Sets the size used for large icons to \a big pixels.
247 Only affects AppLnk objects created after the call. 247 Only affects AppLnk objects created after the call.
248 248
249 \sa bigIconSize() setIcon() 249 \sa bigIconSize() setIcon()
250*/ 250*/
251void AppLnk::setBigIconSize(int big) 251void AppLnk::setBigIconSize(int big)
252{ 252{
253 bigSize = big; 253 bigSize = big;
254} 254}
255 255
256/*! 256/*!
257 Returns the size used for large icons. 257 Returns the size used for large icons.
258 258
259 \sa setBigIconSize() setIcon() 259 \sa setBigIconSize() setIcon()
260*/ 260*/
261int AppLnk::bigIconSize() 261int AppLnk::bigIconSize()
262{ 262{
263 return bigSize; 263 return bigSize;
264} 264}
265 265
266 266
267/*! 267/*!
268 \fn QString AppLnk::name() const 268 \fn QString AppLnk::name() const
269 269
270 Returns the Name property. This is the user-visible name for the 270 Returns the Name property. This is the user-visible name for the
271 document or application, not the filename. 271 document or application, not the filename.
272 272
273 See \link #files-and-links Files and Links\endlink. 273 See \link #files-and-links Files and Links\endlink.
274 274
275 \sa setName() 275 \sa setName()
276*/ 276*/
277/*! 277/*!
278 \fn QString AppLnk::exec() const 278 \fn QString AppLnk::exec() const
279 279
280 Returns the Exec property. This is the name of the executable 280 Returns the Exec property. This is the name of the executable
281 program associated with the AppLnk. 281 program associated with the AppLnk.
282 282
283 \sa setExec() 283 \sa setExec()
284*/ 284*/
285/*! 285/*!
286 \fn QString AppLnk::rotation() const 286 \fn QString AppLnk::rotation() const
287 287
288 Returns the Rotation property. The value is 0, 90, 180 or 270 288 Returns the Rotation property. The value is 0, 90, 180 or 270
289 degrees. 289 degrees.
290*/ 290*/
291/*! 291/*!
292 \fn QString AppLnk::comment() const 292 \fn QString AppLnk::comment() const
293 293
294 Returns the Comment property. 294 Returns the Comment property.
295 295
296 \sa setComment() 296 \sa setComment()
297*/ 297*/
298/*! 298/*!
299 \fn QStringList AppLnk::mimeTypes() const 299 \fn QStringList AppLnk::mimeTypes() const
300 300
301 Returns the MimeTypes property. This is the list of MIME types 301 Returns the MimeTypes property. This is the list of MIME types
302 that the application can view or edit. 302 that the application can view or edit.
303*/ 303*/
304/*! 304/*!
305 \fn const QArray<int>& AppLnk::categories() const 305 \fn const QArray<int>& AppLnk::categories() const
306 306
307 Returns the Categories property. 307 Returns the Categories property.
308 308
309 See the CategoryWidget for more details. 309 See the CategoryWidget for more details.
310 310
311 \sa setCategories() 311 \sa setCategories()
312*/ 312*/
313 313
314const QArray<int>& AppLnk::categories() const 314const QArray<int>& AppLnk::categories() const
315{ 315{
316 d->ensureCatArray(); 316 d->ensureCatArray();
317 return d->mCat; 317 return d->mCat;
318} 318}
319 319
320/*! 320/*!
321 \fn int AppLnk::id() const 321 \fn int AppLnk::id() const
322 322
323 Returns the id of the AppLnk. If the AppLnk is not in an AppLnkSet, 323 Returns the id of the AppLnk. If the AppLnk is not in an AppLnkSet,
324 this value is 0, otherwise it is a value that is unique for the 324 this value is 0, otherwise it is a value that is unique for the
325 duration of the current process. 325 duration of the current process.
326 326
327 \sa AppLnkSet::find() 327 \sa AppLnkSet::find()
328*/ 328*/
329 329
330/*! 330/*!
331 \fn bool AppLnk::isValid() const 331 \fn bool AppLnk::isValid() const
332 332
333 Returns TRUE if this AppLnk is valid; otherwise returns FALSE. 333 Returns TRUE if this AppLnk is valid; otherwise returns FALSE.
334*/ 334*/
335/*!
336 \fn bool AppLnk::fileKnown() const
337
338 If the with the AppLnk associated file is not equal to QString::null
339*/
340/*!
341 \fn bool AppLnk::linkFileKnown()const
342
343 The filename of the AppLnk
335 344
345*/
346/*!
347 \fn void AppLnk::setRotation( const QString& )
348
349 The default rotation of the associated application. This
350 function is included inline for binary compatible issues
351*/
336/*! 352/*!
337 Creates an invalid AppLnk. 353 Creates an invalid AppLnk.
338 354
339 \sa isValid() 355 \sa isValid()
340*/ 356*/
341AppLnk::AppLnk() 357AppLnk::AppLnk()
342{ 358{
343 mId = 0; 359 mId = 0;
344 d = new AppLnkPrivate(); 360 d = new AppLnkPrivate();
345} 361}
346 362
347/*! 363/*!
348 Loads \a file (e.g. \e app.desktop) as an AppLnk. 364 Loads \a file (e.g. \e app.desktop) as an AppLnk.
349 365
350 \sa writeLink() 366 \sa writeLink()
351*/ 367*/
352AppLnk::AppLnk( const QString &file ) 368AppLnk::AppLnk( const QString &file )
353{ 369{
354 QStringList sl; 370 QStringList sl;
355 d = new AppLnkPrivate(); 371 d = new AppLnkPrivate();
356 if ( !file.isNull() ) { 372 if ( !file.isNull() ) {
357 Config config( file, Config::File ); 373 Config config( file, Config::File );
358 374
359 if ( config.isValid() ) { 375 if ( config.isValid() ) {
360 config.setGroup( "Desktop Entry" ); 376 config.setGroup( "Desktop Entry" );
361 377
362 mName = config.readEntry( "Name", file ); 378 mName = config.readEntry( "Name", file );
363 mExec = config.readEntry( "Exec" ); 379 mExec = config.readEntry( "Exec" );
364 mType = config.readEntry( "Type", QString::null ); 380 mType = config.readEntry( "Type", QString::null );
365 mIconFile = config.readEntry( "Icon", QString::null ); 381 mIconFile = config.readEntry( "Icon", QString::null );
366 mRotation = config.readEntry( "Rotation", "" ); 382 mRotation = config.readEntry( "Rotation", "" );
367 mComment = config.readEntry( "Comment", QString::null ); 383 mComment = config.readEntry( "Comment", QString::null );
368 // MIME types are case-insensitive. 384 // MIME types are case-insensitive.
369 mMimeTypes = config.readListEntry( "MimeType", ';' ); 385 mMimeTypes = config.readListEntry( "MimeType", ';' );
370 for (QStringList::Iterator it=mMimeTypes.begin(); it!=mMimeTypes.end(); ++it) 386 for (QStringList::Iterator it=mMimeTypes.begin(); it!=mMimeTypes.end(); ++it)
371 *it = (*it).lower(); 387 *it = (*it).lower();
372 mMimeTypeIcons = config.readListEntry( "MimeTypeIcons", ';' ); 388 mMimeTypeIcons = config.readListEntry( "MimeTypeIcons", ';' );
373 mLinkFile = file; 389 mLinkFile = file;
374 mFile = config.readEntry("File", QString::null); 390 mFile = config.readEntry("File", QString::null);
375 if ( !mExec. isEmpty ( )) { 391 if ( !mExec. isEmpty ( )) {
376 mFile = QString::null; 392 mFile = QString::null;
377 } 393 }
378 else if ( mFile[0] != '/' ) { 394 else if ( mFile[0] != '/' ) {
379 int slash = file.findRev('/'); 395 int slash = file.findRev('/');
380 if ( slash >= 0 ) { 396 if ( slash >= 0 ) {
381 mFile = file.left(slash) + '/' + mFile; 397 mFile = file.left(slash) + '/' + mFile;
382 } 398 }
383 } 399 }
384 d->mCatList = config.readListEntry("Categories", ';'); 400 d->mCatList = config.readListEntry("Categories", ';');
385 if ( d->mCatList[0].toInt() < -1 ) { 401 if ( d->mCatList[0].toInt() < -1 ) {
386 // numeric cats in file! convert to text 402 // numeric cats in file! convert to text
387 Categories cat( 0 ); 403 Categories cat( 0 );
388 cat.load( categoryFileName() ); 404 cat.load( categoryFileName() );
389 d->mCat.resize( d->mCatList.count() ); 405 d->mCat.resize( d->mCatList.count() );
390 int i; 406 int i;
391 QStringList::ConstIterator it; 407 QStringList::ConstIterator it;
392 for ( i = 0, it = d->mCatList.begin(); it != d->mCatList.end(); 408 for ( i = 0, it = d->mCatList.begin(); it != d->mCatList.end();
393 ++it, i++ ) { 409 ++it, i++ ) {
394 bool number; 410 bool number;
395 int id = (*it).toInt( &number ); 411 int id = (*it).toInt( &number );
396 if ( !number ) { 412 if ( !number ) {
397 // convert from text 413 // convert from text
398 id = cat.id( "Document View", *it ); 414 id = cat.id( "Document View", *it );
399 if ( id == 0 ) 415 if ( id == 0 )
400 id = cat.addCategory( "Document View", *it ); 416 id = cat.addCategory( "Document View", *it );
401 } 417 }
402 d->mCat[i] = id; 418 d->mCat[i] = id;
403 } 419 }
404 d->updateCatListFromArray(); 420 d->updateCatListFromArray();
405 } 421 }
406 } 422 }
407 } 423 }
408 mId = 0; 424 mId = 0;
409} 425}
410 426
411AppLnk& AppLnk::operator=(const AppLnk &copy) 427AppLnk& AppLnk::operator=(const AppLnk &copy)
412{ 428{
413 if ( this == &copy ) return *this; 429 if ( this == &copy ) return *this;
414 if ( mId ) 430 if ( mId )
415 qWarning("Deleting AppLnk that is in an AppLnkSet"); 431 qWarning("Deleting AppLnk that is in an AppLnkSet");
416 if ( d ) 432 if ( d )
417 delete d; 433 delete d;
418 434
419 435
420 mName = copy.mName; 436 mName = copy.mName;
421 437
422 /* remove for Qtopia 3.0 -zecke */ 438 /* remove for Qtopia 3.0 -zecke */
423 mPixmap = copy.mPixmap; 439 mPixmap = copy.mPixmap;
424 mBigPixmap = copy.mBigPixmap; 440 mBigPixmap = copy.mBigPixmap;
425 441
426 mExec = copy.mExec; 442 mExec = copy.mExec;
427 mType = copy.mType; 443 mType = copy.mType;
428 mRotation = copy.mRotation; 444 mRotation = copy.mRotation;
429 mComment = copy.mComment; 445 mComment = copy.mComment;
430 mFile = copy.mFile; 446 mFile = copy.mFile;
431 mLinkFile = copy.mLinkFile; 447 mLinkFile = copy.mLinkFile;
432 mIconFile = copy.mIconFile; 448 mIconFile = copy.mIconFile;
433 mMimeTypes = copy.mMimeTypes; 449 mMimeTypes = copy.mMimeTypes;
434 mMimeTypeIcons = copy.mMimeTypeIcons; 450 mMimeTypeIcons = copy.mMimeTypeIcons;
435 mId = 0; 451 mId = 0;
436 d = new AppLnkPrivate(); 452 d = new AppLnkPrivate();
437 d->mCat = copy.d->mCat; 453 d->mCat = copy.d->mCat;
438 d->mCatList = copy.d->mCatList; 454 d->mCatList = copy.d->mCatList;
439 d->mPixmaps = copy.d->mPixmaps; 455 d->mPixmaps = copy.d->mPixmaps;
440 456
441 return *this; 457 return *this;
442} 458}
443/*! 459/*!
444 protected internally to share code 460 protected internally to share code
445 should I document that at all? 461 should I document that at all?
446 I don't know the TT style for that 462 I don't know the TT style for that
447*/ 463*/
448const QPixmap& AppLnk::pixmap( int pos, int size ) const { 464const QPixmap& AppLnk::pixmap( int pos, int size ) const {
449 if ( d->mPixmaps[pos].isNull() ) { 465 if ( d->mPixmaps[pos].isNull() ) {
450 AppLnk* that = (AppLnk*)this; 466 AppLnk* that = (AppLnk*)this;
451 if ( mIconFile.isEmpty() ) { 467 if ( mIconFile.isEmpty() ) {
452 MimeType mt(type()); 468 MimeType mt(type());
453 that->d->mPixmaps[pos] = mt.pixmap(); 469 that->d->mPixmaps[pos] = mt.pixmap();
454 if ( that->d->mPixmaps[pos].isNull() ) 470 if ( that->d->mPixmaps[pos].isNull() )
455 that->d->mPixmaps[pos].convertFromImage( 471 that->d->mPixmaps[pos].convertFromImage(
456 Resource::loadImage("UnknownDocument") 472 Resource::loadImage("UnknownDocument")
457 .smoothScale( size, size ) ); 473 .smoothScale( size, size ) );
458 return that->d->mPixmaps[pos]; 474 return that->d->mPixmaps[pos];
459 } 475 }
460 QImage unscaledIcon = Resource::loadImage( that->mIconFile ); 476 QImage unscaledIcon = Resource::loadImage( that->mIconFile );
461 if ( unscaledIcon.isNull() ) { 477 if ( unscaledIcon.isNull() ) {
462 qDebug( "Cannot find icon: %s", that->mIconFile.latin1() ); 478 qDebug( "Cannot find icon: %s", that->mIconFile.latin1() );
463 that->d->mPixmaps[pos].convertFromImage( 479 that->d->mPixmaps[pos].convertFromImage(
464 Resource::loadImage("UnknownDocument") 480 Resource::loadImage("UnknownDocument")
465 .smoothScale( size, size ) ); 481 .smoothScale( size, size ) );
466 } else { 482 } else {
467 that->d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) ); 483 that->d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
468 that->d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) ); 484 that->d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
469 } 485 }
470 return that->d->mPixmaps[pos]; 486 return that->d->mPixmaps[pos];
471 } 487 }
472 return d->mPixmaps[pos]; 488 return d->mPixmaps[pos];
473} 489}
474 490
475/*! 491/*!
476 Returns a small pixmap associated with the application. 492 Returns a small pixmap associated with the application.
477 493
478 \sa bigPixmap() setIcon() 494 \sa bigPixmap() setIcon()
479*/ 495*/
480const QPixmap& AppLnk::pixmap() const 496const QPixmap& AppLnk::pixmap() const
481{ 497{
482 if ( d->mPixmaps[0].isNull() ) { 498 if ( d->mPixmaps[0].isNull() ) {
483 return pixmap(AppLnkPrivate::Normal, smallSize ); 499 return pixmap(AppLnkPrivate::Normal, smallSize );
484 } 500 }
485 return d->mPixmaps[0]; 501 return d->mPixmaps[0];
486} 502}
487 503
488/*! 504/*!
489 Returns a large pixmap associated with the application. 505 Returns a large pixmap associated with the application.
490 506
491 \sa pixmap() setIcon() 507 \sa pixmap() setIcon()
492*/ 508*/
493const QPixmap& AppLnk::bigPixmap() const 509const QPixmap& AppLnk::bigPixmap() const
494{ 510{
495 if ( d->mPixmaps[1].isNull() ) { 511 if ( d->mPixmaps[1].isNull() ) {
496 return pixmap( AppLnkPrivate::Big, bigSize ); 512 return pixmap( AppLnkPrivate::Big, bigSize );
497 } 513 }
498 return d->mPixmaps[1]; 514 return d->mPixmaps[1];
499} 515}
500 516
501/*! 517/*!
502 Returns the type of the AppLnk. For applications, games and 518 Returns the type of the AppLnk. For applications, games and
503 settings the type is \c Application; for documents the type is the 519 settings the type is \c Application; for documents the type is the
504 document's MIME type. 520 document's MIME type.
505*/ 521*/
506QString AppLnk::type() const 522QString AppLnk::type() const
507{ 523{
508 if ( mType.isNull() ) { 524 if ( mType.isNull() ) {
509 AppLnk* that = (AppLnk*)this; 525 AppLnk* that = (AppLnk*)this;
510 QString f = file(); 526 QString f = file();
511 if ( !f.isNull() ) { 527 if ( !f.isNull() ) {
512 MimeType mt(f); 528 MimeType mt(f);
513 that->mType = mt.id(); 529 that->mType = mt.id();
514 return that->mType; 530 return that->mType;
515 } 531 }
516 } 532 }
517 return mType; 533 return mType;
518} 534}
519 535
520/*! 536/*!
521 Returns the file associated with the AppLnk. 537 Returns the file associated with the AppLnk.
522 538
523 \sa exec() name() 539 \sa exec() name()
524*/ 540*/
525QString AppLnk::file() const 541QString AppLnk::file() const
526{ 542{
527 if ( mExec.isEmpty ( ) && mFile.isNull() ) { 543 if ( mExec.isEmpty ( ) && mFile.isNull() ) {
528 AppLnk* that = (AppLnk*)this; 544 AppLnk* that = (AppLnk*)this;
529 QString ext = MimeType(mType).extension(); 545 QString ext = MimeType(mType).extension();
530 if ( !ext.isEmpty() ) 546 if ( !ext.isEmpty() )
531 ext = "." + ext; 547 ext = "." + ext;
532 if ( !mLinkFile.isEmpty() ) { 548 if ( !mLinkFile.isEmpty() ) {
533 that->mFile = 549 that->mFile =
534 mLinkFile.right(8)==".desktop" // 8 = strlen(".desktop") 550 mLinkFile.right(8)==".desktop" // 8 = strlen(".desktop")
535 ? mLinkFile.left(mLinkFile.length()-8) : mLinkFile; 551 ? mLinkFile.left(mLinkFile.length()-8) : mLinkFile;
536 qDebug("mFile now == %s", mFile.latin1()); 552 qDebug("mFile now == %s", mFile.latin1());
537 } else if ( mType.contains('/') ) { 553 } else if ( mType.contains('/') ) {
538 that->mFile = 554 that->mFile =
539 QString(getenv("HOME"))+"/Documents/"+mType+"/"+safeFileName(that->mName); 555 QString(getenv("HOME"))+"/Documents/"+mType+"/"+safeFileName(that->mName);
540 /* 556 /*
541 * A file with the same name or a .desktop file already exists 557 * A file with the same name or a .desktop file already exists
542 */ 558 */
543 if ( QFile::exists(that->mFile+ext) || QFile::exists(that->mFile+".desktop") ) { 559 if ( QFile::exists(that->mFile+ext) || QFile::exists(that->mFile+".desktop") ) {
544 int n=1; 560 int n=1;
545 QString nn; 561 QString nn;
546 while (QFile::exists((nn=(that->mFile+"_"+QString::number(n)))+ext) 562 while (QFile::exists((nn=(that->mFile+"_"+QString::number(n)))+ext)
547 || QFile::exists(nn+".desktop")) 563 || QFile::exists(nn+".desktop"))
548 n++; 564 n++;
549 that->mFile = nn; 565 that->mFile = nn;
550 } 566 }
551 that->mLinkFile = that->mFile+".desktop"; 567 that->mLinkFile = that->mFile+".desktop";
552 that->mFile += ext; 568 that->mFile += ext;
553 } 569 }
554 prepareDirectories(that->mFile); 570 prepareDirectories(that->mFile);
555 if ( !that->mFile.isEmpty() ) { 571 if ( !that->mFile.isEmpty() ) {
556 QFile f(that->mFile); 572 QFile f(that->mFile);
557 if ( !f.open(IO_WriteOnly) ) 573 if ( !f.open(IO_WriteOnly) )
558 that->mFile = QString::null; 574 that->mFile = QString::null;
559 return that->mFile; 575 return that->mFile;
560 } 576 }
561 } 577 }
562 return mFile; 578 return mFile;
563} 579}
564 580
565/*! 581/*!
566 Returns the desktop file corresponding to this AppLnk. 582 Returns the desktop file corresponding to this AppLnk.
567 583
568 \sa file() exec() name() 584 \sa file() exec() name()
569*/ 585*/
570QString AppLnk::linkFile() const 586QString AppLnk::linkFile() const
571{ 587{
572 if ( mLinkFile.isNull() ) { 588 if ( mLinkFile.isNull() ) {
573 AppLnk* that = (AppLnk*)this; 589 AppLnk* that = (AppLnk*)this;
574 if ( type().contains('/') ) { 590 if ( type().contains('/') ) {
575 StorageInfo storage; 591 StorageInfo storage;
576 const FileSystem *fs = storage.fileSystemOf( that->mFile ); 592 const FileSystem *fs = storage.fileSystemOf( that->mFile );
577 /* tmpfs + and ramfs are available too but not removable 593 /* tmpfs + and ramfs are available too but not removable
578 * either we fix storage or add this 594 * either we fix storage or add this
579 */ 595 */
580 if ( fs && ( fs->isRemovable() || fs->disk() == "/dev/mtdblock6" || fs->disk() == "tmpfs") ) { 596 if ( fs && ( fs->isRemovable() || fs->disk() == "/dev/mtdblock6" || fs->disk() == "tmpfs") ) {
581 that->mLinkFile = fs->path(); 597 that->mLinkFile = fs->path();
582 } else 598 } else
583 that->mLinkFile = getenv( "HOME" ); 599 that->mLinkFile = getenv( "HOME" );
584 that->mLinkFile += "/Documents/"+type()+"/"+safeFileName(that->mName); 600 that->mLinkFile += "/Documents/"+type()+"/"+safeFileName(that->mName);
585 601
586 /* the desktop file exists make sure we don't point to the same file */ 602 /* the desktop file exists make sure we don't point to the same file */
587 if ( QFile::exists(that->mLinkFile+".desktop") ) { 603 if ( QFile::exists(that->mLinkFile+".desktop") ) {
588 AppLnk lnk( that->mLinkFile + ".desktop" ); 604 AppLnk lnk( that->mLinkFile + ".desktop" );
589 605
590 /* the linked is different */ 606 /* the linked is different */
591 if(that->file() != lnk.file() ) { 607 if(that->file() != lnk.file() ) {
diff --git a/library/backend/categories.cpp b/library/backend/categories.cpp
index 2e84089..cce9f38 100644
--- a/library/backend/categories.cpp
+++ b/library/backend/categories.cpp
@@ -234,703 +234,698 @@ QStringList CategoryGroup::labels(const QArray<int> &catids ) const
234 also be accessed via CategoryGroup objects. See appGroupMap() and 234 also be accessed via CategoryGroup objects. See appGroupMap() and
235 globalGroup() for the appropriate accessor methods. 235 globalGroup() for the appropriate accessor methods.
236 236
237 Categories are stored in an xml file in the Settings directory 237 Categories are stored in an xml file in the Settings directory
238 (Categories.xml). A global function called categoryFileName() will 238 (Categories.xml). A global function called categoryFileName() will
239 return to appropriate QString file location to be passed to load() 239 return to appropriate QString file location to be passed to load()
240 and save() for the master categories database. 240 and save() for the master categories database.
241 241
242 \ingroup qtopiaemb 242 \ingroup qtopiaemb
243 \ingroup qtopiadesktop 243 \ingroup qtopiadesktop
244 \warning Categories API will likely change between Qtopia 1.5 and Qtopia 3 244 \warning Categories API will likely change between Qtopia 1.5 and Qtopia 3
245 \sa CategoryGroup, CategoryMenu 245 \sa CategoryGroup, CategoryMenu
246*/ 246*/
247 247
248 248
249/*! 249/*!
250 Add the category name as long as it doesn't already exist locally or 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 251 globally. The \a uid is assigned to the category if successfully
252 added. Return \a uid if added, 0 if conflicts (error). 252 added. Return \a uid if added, 0 if conflicts (error).
253 253
254 \internal 254 \internal
255*/ 255*/
256int Categories::addCategory( const QString &appname, 256int Categories::addCategory( const QString &appname,
257 const QString &catname, 257 const QString &catname,
258 int uid ) 258 int uid )
259{ 259{
260 if ( mGlobalCats.contains(catname) ) 260 if ( mGlobalCats.contains(catname) )
261 return 0; 261 return 0;
262 262
263 QMap< QString, CategoryGroup >::Iterator 263 QMap< QString, CategoryGroup >::Iterator
264 appIt = mAppCats.find( appname ); 264 appIt = mAppCats.find( appname );
265 265
266 if ( appIt == mAppCats.end() ) { 266 if ( appIt == mAppCats.end() ) {
267 CategoryGroup newgroup; 267 CategoryGroup newgroup;
268 newgroup.add( uid, catname ); 268 newgroup.add( uid, catname );
269 mAppCats.insert( appname, newgroup ); 269 mAppCats.insert( appname, newgroup );
270 emit categoryAdded( *this, appname, uid ); 270 emit categoryAdded( *this, appname, uid );
271 return uid; 271 return uid;
272 } 272 }
273 273
274 CategoryGroup &cats = *appIt; 274 CategoryGroup &cats = *appIt;
275 cats.add( uid, catname ); 275 cats.add( uid, catname );
276 emit categoryAdded( *this, appname, uid ); 276 emit categoryAdded( *this, appname, uid );
277 return uid; 277 return uid;
278} 278}
279 279
280/*! 280/*!
281 Add the category name as long as it doesn't already exist locally or 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). 282 globally. Return UID if added, 0 if conflicts (error).
283*/ 283*/
284 284
285int Categories::addCategory( const QString &appname, 285int Categories::addCategory( const QString &appname,
286 const QString &catname ) 286 const QString &catname )
287{ 287{
288 if ( mGlobalCats.contains(catname) ) 288 if ( mGlobalCats.contains(catname) )
289 return 0; 289 return 0;
290 290
291 QMap< QString, CategoryGroup >::Iterator 291 QMap< QString, CategoryGroup >::Iterator
292 appIt = mAppCats.find( appname ); 292 appIt = mAppCats.find( appname );
293 293
294 if ( appIt == mAppCats.end() ) { 294 if ( appIt == mAppCats.end() ) {
295 CategoryGroup newgroup; 295 CategoryGroup newgroup;
296 int uid = newgroup.add( catname ); 296 int uid = newgroup.add( catname );
297 mAppCats.insert( appname, newgroup ); 297 mAppCats.insert( appname, newgroup );
298 emit categoryAdded( *this, appname, uid ); 298 emit categoryAdded( *this, appname, uid );
299 return uid; 299 return uid;
300 } 300 }
301 301
302 CategoryGroup &cats = *appIt; 302 CategoryGroup &cats = *appIt;
303 int uid = cats.add( catname ); 303 int uid = cats.add( catname );
304 if ( !uid ) 304 if ( !uid )
305 return 0; 305 return 0;
306 emit categoryAdded( *this, appname, uid ); 306 emit categoryAdded( *this, appname, uid );
307 return uid; 307 return uid;
308} 308}
309 309
310/*! 310/*!
311 \internal 311 \internal
312*/ 312*/
313int Categories::addGlobalCategory( const QString &catname, int uid ) 313int Categories::addGlobalCategory( const QString &catname, int uid )
314{ 314{
315 mGlobalCats.add( uid, catname ); 315 mGlobalCats.add( uid, catname );
316 emit categoryAdded( *this, QString::null, uid ); 316 emit categoryAdded( *this, QString::null, uid );
317 return uid; 317 return uid;
318} 318}
319 319
320/*! 320/*!
321 Add the global category \a catname while checking that it doesn't 321 Add the global category \a catname while checking that it doesn't
322 already exist globally. Return UID if added, 0 if conflicts. 322 already exist globally. Return UID if added, 0 if conflicts.
323 323
324 \sa addCategory() 324 \sa addCategory()
325 */ 325 */
326int Categories::addGlobalCategory( const QString &catname ) 326int Categories::addGlobalCategory( const QString &catname )
327{ 327{
328 int uid = mGlobalCats.add( catname ); 328 int uid = mGlobalCats.add( catname );
329 if ( !uid ) 329 if ( !uid )
330 return 0; 330 return 0;
331 emit categoryAdded( *this, QString::null, uid ); 331 emit categoryAdded( *this, QString::null, uid );
332 return uid; 332 return uid;
333} 333}
334 334
335/*! 335/*!
336 336
337 Removes the \a catname from the application group. If it is not 337 Removes the \a catname from the application group. If it is not
338 found in the application group and \a checkGlobal is TRUE, then it 338 found in the application group and \a checkGlobal is TRUE, then it
339 attempts to remove it from the global list 339 attempts to remove it from the global list
340*/ 340*/
341bool Categories::removeCategory( const QString &appname, 341bool Categories::removeCategory( const QString &appname,
342 const QString &catname, 342 const QString &catname,
343 bool checkGlobal ) 343 bool checkGlobal )
344{ 344{
345 QMap< QString, CategoryGroup >::Iterator 345 QMap< QString, CategoryGroup >::Iterator
346 appIt = mAppCats.find( appname ); 346 appIt = mAppCats.find( appname );
347 if ( appIt != mAppCats.end() ) { 347 if ( appIt != mAppCats.end() ) {
348 CategoryGroup &cats = *appIt; 348 CategoryGroup &cats = *appIt;
349 int uid = cats.id( catname ); 349 int uid = cats.id( catname );
350 if ( cats.remove( uid ) ) { 350 if ( cats.remove( uid ) ) {
351 emit categoryRemoved( *this, appname, uid ); 351 emit categoryRemoved( *this, appname, uid );
352 return TRUE; 352 return TRUE;
353 } 353 }
354 } 354 }
355 if ( !checkGlobal ) 355 if ( !checkGlobal )
356 return FALSE; 356 return FALSE;
357 return removeGlobalCategory( catname ); 357 return removeGlobalCategory( catname );
358} 358}
359 359
360 360
361/*! 361/*!
362 Removes the \a uid from the application group \a appname. Returns TRUE 362 Removes the \a uid from the application group \a appname. Returns TRUE
363 if success, FALSE if not found. 363 if success, FALSE if not found.
364*/ 364*/
365bool Categories::removeCategory( const QString &appname, int uid ) 365bool Categories::removeCategory( const QString &appname, int uid )
366{ 366{
367 QMap< QString, CategoryGroup >::Iterator 367 QMap< QString, CategoryGroup >::Iterator
368 appIt = mAppCats.find( appname ); 368 appIt = mAppCats.find( appname );
369 if ( appIt != mAppCats.end() ) { 369 if ( appIt != mAppCats.end() ) {
370 CategoryGroup &cats = *appIt; 370 CategoryGroup &cats = *appIt;
371 if ( cats.remove( uid ) ) { 371 if ( cats.remove( uid ) ) {
372 emit categoryRemoved( *this, appname, uid ); 372 emit categoryRemoved( *this, appname, uid );
373 return TRUE; 373 return TRUE;
374 } 374 }
375 } 375 }
376 return FALSE; 376 return FALSE;
377} 377}
378 378
379/*! 379/*!
380 Removes the global category \a catname. Returns TRUE 380 Removes the global category \a catname. Returns TRUE
381 if success, FALSE if not found. 381 if success, FALSE if not found.
382*/ 382*/
383bool Categories::removeGlobalCategory( const QString &catname ) 383bool Categories::removeGlobalCategory( const QString &catname )
384{ 384{
385 int uid = mGlobalCats.id( catname ); 385 int uid = mGlobalCats.id( catname );
386 if ( mGlobalCats.remove( uid ) ) { 386 if ( mGlobalCats.remove( uid ) ) {
387 emit categoryRemoved( *this, QString::null, uid ); 387 emit categoryRemoved( *this, QString::null, uid );
388 return TRUE; 388 return TRUE;
389 } 389 }
390 return FALSE; 390 return FALSE;
391} 391}
392 392
393/*! 393/*!
394 Removes the global category \a uid. Returns TRUE 394 Removes the global category \a uid. Returns TRUE
395 if success, FALSE if not found. 395 if success, FALSE if not found.
396*/ 396*/
397bool Categories::removeGlobalCategory( int uid ) 397bool Categories::removeGlobalCategory( int uid )
398{ 398{
399 if ( mGlobalCats.remove( uid ) ) { 399 if ( mGlobalCats.remove( uid ) ) {
400 emit categoryRemoved( *this, QString::null, uid ); 400 emit categoryRemoved( *this, QString::null, uid );
401 return TRUE; 401 return TRUE;
402 } 402 }
403 return FALSE; 403 return FALSE;
404} 404}
405 405
406/*! 406/*!
407 Returns the sorted list of all categories that are associated with 407 Returns the sorted list of all categories that are associated with
408 the \a app. If \a includeGlobal is TRUE then the returned 408 the \a app. If \a includeGlobal is TRUE then the returned
409 categories will include the global category items. 409 categories will include the global category items.
410 */ 410 */
411QStringList Categories::labels( const QString &app, 411QStringList Categories::labels( const QString &app,
412 bool includeGlobal, 412 bool includeGlobal,
413 ExtraLabels extra ) const 413 ExtraLabels extra ) const
414{ 414{
415 QMap< QString, CategoryGroup >::ConstIterator 415 QMap< QString, CategoryGroup >::ConstIterator
416 appIt = mAppCats.find( app ); 416 appIt = mAppCats.find( app );
417 QStringList cats; 417 QStringList cats;
418 418
419 if ( appIt != mAppCats.end() ) 419 if ( appIt != mAppCats.end() )
420 cats += (*appIt).labels(); 420 cats += (*appIt).labels();
421 //else qDebug("Categories::labels didn't find app %s", app.latin1() ); 421 //else qDebug("Categories::labels didn't find app %s", app.latin1() );
422 if ( includeGlobal ) 422 if ( includeGlobal )
423 cats += mGlobalCats.labels(); 423 cats += mGlobalCats.labels();
424 424
425 cats.sort(); 425 cats.sort();
426 switch ( extra ) { 426 switch ( extra ) {
427 case NoExtra: break; 427 case NoExtra: break;
428 case AllUnfiled: 428 case AllUnfiled:
429 cats.append( tr("All") ); 429 cats.append( tr("All") );
430 cats.append( tr("Unfiled") ); 430 cats.append( tr("Unfiled") );
431 break; 431 break;
432 case AllLabel: 432 case AllLabel:
433 cats.append( tr("All") ); 433 cats.append( tr("All") );
434 break; 434 break;
435 case UnfiledLabel: 435 case UnfiledLabel:
436 cats.append( tr("Unfiled") ); 436 cats.append( tr("Unfiled") );
437 break; 437 break;
438 } 438 }
439 439
440 return cats; 440 return cats;
441} 441}
442 442
443/*! 443/*!
444 Returns the label associated with the id 444 Returns the label associated with the id
445*/ 445*/
446QString Categories::label( const QString &app, int id ) const 446QString Categories::label( const QString &app, int id ) const
447{ 447{
448 if ( mGlobalCats.contains( id ) ) 448 if ( mGlobalCats.contains( id ) )
449 return mGlobalCats.label( id ); 449 return mGlobalCats.label( id );
450 QMap< QString, CategoryGroup >::ConstIterator 450 QMap< QString, CategoryGroup >::ConstIterator
451 appIt = mAppCats.find( app ); 451 appIt = mAppCats.find( app );
452 if ( appIt == mAppCats.end() ) 452 if ( appIt == mAppCats.end() )
453 return QString::null; 453 return QString::null;
454 return (*appIt).label( id ); 454 return (*appIt).label( id );
455} 455}
456 456
457/*! 457/*!
458 Returns a single string associated with \a catids for display in a 458 Returns a single string associated with \a catids for display in a
459 combobox or any area that requires one string. If \a catids are empty 459 combobox or any area that requires one string. If \a catids are empty
460 then "Unfiled" will be returned. If multiple categories are 460 then "Unfiled" will be returned. If multiple categories are
461 assigned then the behavior depends on the DisplaySingle type. 461 assigned then the behavior depends on the DisplaySingle type.
462 462
463 If \a display is set to ShowMulti then " (multi)" appended to the 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 464 first string. If \a display is set to ShowAll, then a space
465 seperated string is returned with all categories. If ShowFirst is 465 seperated string is returned with all categories. If ShowFirst is
466 set, the just the first string is returned. 466 set, the just the first string is returned.
467*/ 467*/
468QString Categories::displaySingle( const QString &app, 468QString Categories::displaySingle( const QString &app,
469 const QArray<int> &catids, 469 const QArray<int> &catids,
470 DisplaySingle display ) const 470 DisplaySingle display ) const
471{ 471{
472 QStringList strs = labels( app, catids ); 472 QStringList strs = labels( app, catids );
473 if ( !strs.count() ) 473 if ( !strs.count() )
474 return tr("Unfiled"); 474 return tr("Unfiled");
475 strs.sort(); 475 strs.sort();
476 QString r; 476 QString r;
477 if ( strs.count() > 1 ) { 477 if ( strs.count() > 1 ) {
478 switch ( display ) { 478 switch ( display ) {
479 case ShowFirst: 479 case ShowFirst:
480 r = strs.first(); 480 r = strs.first();
481 break; 481 break;
482 case ShowMulti: 482 case ShowMulti:
483 r = strs.first() + tr(" (multi.)"); 483 r = strs.first() + tr(" (multi.)");
484 break; 484 break;
485 case ShowAll: 485 case ShowAll:
486 r = strs.join(" "); 486 r = strs.join(" ");
487 break; 487 break;
488 } 488 }
489 } 489 }
490 else r = strs.first(); 490 else r = strs.first();
491 return r; 491 return r;
492} 492}
493 493
494/*! 494/*!
495 495
496 Returns all ids associated with the application CategoryGroup \a app 496 Returns all ids associated with the application CategoryGroup \a app
497 and the passed in \a labels in that group. 497 and the passed in \a labels in that group.
498*/ 498*/
499QArray<int> Categories::ids( const QString &app, const QStringList &labels) const 499QArray<int> Categories::ids( const QString &app, const QStringList &labels) const
500{ 500{
501 QArray<int> results; 501 QArray<int> results;
502 QStringList::ConstIterator it; 502 QStringList::ConstIterator it;
503 int i; 503 int i;
504 504
505 for ( i=0, it=labels.begin(); it!=labels.end(); i++, ++it ) { 505 for ( i=0, it=labels.begin(); it!=labels.end(); i++, ++it ) {
506 int value = id( app, *it ); 506 int value = id( app, *it );
507 if ( value != 0 ) { 507 if ( value != 0 ) {
508 int tmp = results.size(); 508 int tmp = results.size();
509 results.resize( tmp + 1 ); 509 results.resize( tmp + 1 );
510 results[ tmp ] = value; 510 results[ tmp ] = value;
511 } 511 }
512 } 512 }
513 return results; 513 return results;
514} 514}
515 515
516/*! 516/*!
517 Returns the id associated with the app. If the id is not found in the 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. 518 application CategoryGroup, then it searches the global CategoryGroup.
519 If it is not found it either, 0 is returned. 519 If it is not found it either, 0 is returned.
520*/ 520*/
521int Categories::id( const QString &app, const QString &cat ) const 521int Categories::id( const QString &app, const QString &cat ) const
522{ 522{
523 if ( cat == tr("Unfiled") || cat.contains( tr(" (multi.)") ) ) 523 if ( cat == tr("Unfiled") || cat.contains( tr(" (multi.)") ) )
524 return 0; 524 return 0;
525 int uid = mGlobalCats.id( cat ); 525 int uid = mGlobalCats.id( cat );
526 if ( uid != 0 ) 526 if ( uid != 0 )
527 return uid; 527 return uid;
528 return mAppCats[app].id( cat ); 528 return mAppCats[app].id( cat );
529} 529}
530 530
531 531
532/*! 532/*!
533 Return TRUE if renaming succeeded; FALSE if \a appname or \a oldName 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 534 is not found, or if \a newName conflicts with an existing category
535 in the CategoryGroup. 535 in the CategoryGroup.
536 536
537 It will first search the CategoryGroup associated with \a appname 537 It will first search the CategoryGroup associated with \a appname
538 and if not found it will try to replace in global CategoryGroup. 538 and if not found it will try to replace in global CategoryGroup.
539 */ 539 */
540bool Categories::renameCategory( const QString &appname, 540bool Categories::renameCategory( const QString &appname,
541 const QString &oldName, 541 const QString &oldName,
542 const QString &newName ) 542 const QString &newName )
543{ 543{
544 QMap< QString, CategoryGroup >::Iterator 544 QMap< QString, CategoryGroup >::Iterator
545 appIt = mAppCats.find( appname ); 545 appIt = mAppCats.find( appname );
546 546
547 if ( appIt != mAppCats.end() ) { 547 if ( appIt != mAppCats.end() ) {
548 CategoryGroup &cats = *appIt; 548 CategoryGroup &cats = *appIt;
549 int id = cats.id( oldName ); 549 int id = cats.id( oldName );
550 if ( id != 0 && cats.rename( id, newName ) ) { 550 if ( id != 0 && cats.rename( id, newName ) ) {
551 emit categoryRenamed( *this, appname, id ); 551 emit categoryRenamed( *this, appname, id );
552 return TRUE; 552 return TRUE;
553 } 553 }
554 } 554 }
555 return renameGlobalCategory( oldName, newName ); 555 return renameGlobalCategory( oldName, newName );
556} 556}
557 557
558/*! 558/*!
559 Return TRUE if renaming succeeded; FALSE if \a appname or \a oldName 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 560 is not found, or if \a newName conflicts with an existing category
561 in the CategoryGroup. This function will only rename categories found 561 in the CategoryGroup. This function will only rename categories found
562 in the global CategoryGroup. 562 in the global CategoryGroup.
563 */ 563 */
564bool Categories::renameGlobalCategory( const QString &oldName, 564bool Categories::renameGlobalCategory( const QString &oldName,
565 const QString &newName ) 565 const QString &newName )
566{ 566{
567 int uid = mGlobalCats.id( oldName ); 567 int uid = mGlobalCats.id( oldName );
568 if ( uid != 0 && mGlobalCats.rename( uid, newName ) ) { 568 if ( uid != 0 && mGlobalCats.rename( uid, newName ) ) {
569 emit categoryRenamed( *this, QString::null, uid ); 569 emit categoryRenamed( *this, QString::null, uid );
570 return TRUE; 570 return TRUE;
571 } 571 }
572 return FALSE; 572 return FALSE;
573} 573}
574 574
575/*! 575/*!
576 Changes the grouping of a category. If a category was global and \a global 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. 577 is set to TRUE, then the \a catname will be moved to the \a appname group.
578*/ 578*/
579void Categories::setGlobal( const QString &appname, 579void Categories::setGlobal( const QString &appname,
580 const QString &catname, 580 const QString &catname,
581 bool global ) 581 bool global )
582{ 582{
583 // if in global and should be in app; then move it 583 // if in global and should be in app; then move it
584 if ( mGlobalCats.contains( catname ) && !global ) { 584 if ( mGlobalCats.contains( catname ) && !global ) {
585 mGlobalCats.remove( catname ); 585 mGlobalCats.remove( catname );
586 addCategory( appname, catname ); 586 addCategory( appname, catname );
587 return ; 587 return ;
588 } 588 }
589 589
590 // if in app and should be in global, then move it 590 // if in app and should be in global, then move it
591 if ( !global ) 591 if ( !global )
592 return; 592 return;
593 if ( removeCategory( appname, catname, FALSE ) ) 593 if ( removeCategory( appname, catname, FALSE ) )
594 addGlobalCategory( catname ); 594 addGlobalCategory( catname );
595} 595}
596 596
597/*! 597/*!
598 Returns TRUE if the \a catname is in the global CategoryGroup, FALSE if not. 598 Returns TRUE if the \a catname is in the global CategoryGroup, FALSE if not.
599*/ 599*/
600bool Categories::isGlobal( const QString &catname ) const 600bool Categories::isGlobal( const QString &catname ) const
601{ 601{
602 return mGlobalCats.contains( catname ); 602 return mGlobalCats.contains( catname );
603} 603}
604 604
605 605
606/*! 606/*!
607 Returns true if the \a catname is associated with any CategoryGroup, 607 Returns true if the \a catname is associated with any CategoryGroup,
608 including global. 608 including global.
609 */ 609 */
610bool Categories::exists( const QString &catname ) const 610bool Categories::exists( const QString &catname ) const
611{ 611{
612 if ( isGlobal(catname) ) 612 if ( isGlobal(catname) )
613 return TRUE; 613 return TRUE;
614 614
615 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 )
616 if ( exists( appsIt.key(), catname ) ) 616 if ( exists( appsIt.key(), catname ) )
617 return TRUE; 617 return TRUE;
618 618
619 return FALSE; 619 return FALSE;
620} 620}
621 621
622/*! 622/*!
623 Returns TRUE if the \a catname is associated with the \a appname 623 Returns TRUE if the \a catname is associated with the \a appname
624 CategoryGroup, FALSE if not found. 624 CategoryGroup, FALSE if not found.
625 */ 625 */
626bool Categories::exists( const QString &appname, 626bool Categories::exists( const QString &appname,
627 const QString &catname) const 627 const QString &catname) const
628{ 628{
629 QMap< QString, CategoryGroup >::ConstIterator 629 QMap< QString, CategoryGroup >::ConstIterator
630 appIt = mAppCats.find( appname ); 630 appIt = mAppCats.find( appname );
631 631
632 if ( appIt == mAppCats.end() ) 632 if ( appIt == mAppCats.end() )
633 return FALSE; 633 return FALSE;
634 634
635 return (*appIt).contains( catname ); 635 return (*appIt).contains( catname );
636} 636}
637 637
638/*! 638/*!
639 Saves the Categories database to the \a fname. See categoryFileName() 639 Saves the Categories database to the \a fname. See categoryFileName()
640 for the default file name string used for the shared category database. 640 for the default file name string used for the shared category database.
641 641
642 Returns FALSE if there is error writing the file or TRUE on success. 642 Returns FALSE if there is error writing the file or TRUE on success.
643 */ 643 */
644bool Categories::save( const QString &fname ) const 644bool Categories::save( const QString &fname ) const
645{ 645{
646 QString strNewFile = fname + ".new"; 646 QString strNewFile = fname + ".new";
647 QFile f( strNewFile ); 647 QFile f( strNewFile );
648 QString out; 648 QString out;
649 int total_written; 649 int total_written;
650 650
651 if ( !f.open( IO_WriteOnly|IO_Raw ) ) { 651 if ( !f.open( IO_WriteOnly|IO_Raw ) ) {
652 qWarning("Unable to write to %s", fname.latin1()); 652 qWarning("Unable to write to %s", fname.latin1());
653 return FALSE; 653 return FALSE;
654 } 654 }
655 655
656 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 656 out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
657 out += "<!DOCTYPE CategoryList>\n"; 657 out += "<!DOCTYPE CategoryList>\n";
658 658
659 out += "<Categories>\n"; 659 out += "<Categories>\n";
660 660
661 for ( QMap<int, QString>::ConstIterator git = mGlobalCats.idMap().begin(); 661 for ( QMap<int, QString>::ConstIterator git = mGlobalCats.idMap().begin();
662 git != mGlobalCats.idMap().end(); ++git ) 662 git != mGlobalCats.idMap().end(); ++git )
663 out += "<Category id=\"" + QString::number(git.key()) + "\"" + 663 out += "<Category id=\"" + QString::number(git.key()) + "\"" +
664 " name=\"" + escapeString(*git) + "\" />\n"; 664 " name=\"" + escapeString(*git) + "\" />\n";
665 665
666 for ( QMap<QString, CategoryGroup>::ConstIterator appsIt=mAppCats.begin(); 666 for ( QMap<QString, CategoryGroup>::ConstIterator appsIt=mAppCats.begin();
667 appsIt != mAppCats.end(); ++appsIt ) { 667 appsIt != mAppCats.end(); ++appsIt ) {
668 const QString &app = appsIt.key(); 668 const QString &app = appsIt.key();
669 const QMap<int, QString> &appcats = (*appsIt).idMap(); 669 const QMap<int, QString> &appcats = (*appsIt).idMap();
670 for ( QMap<int, QString>::ConstIterator appcatit = appcats.begin(); 670 for ( QMap<int, QString>::ConstIterator appcatit = appcats.begin();
671 appcatit != appcats.end(); ++appcatit ) 671 appcatit != appcats.end(); ++appcatit )
672 out += "<Category id=\"" + QString::number(appcatit.key()) + "\"" + 672 out += "<Category id=\"" + QString::number(appcatit.key()) + "\"" +
673 " app=\"" + escapeString(app) + "\"" + 673 " app=\"" + escapeString(app) + "\"" +
674 " name=\"" + escapeString(*appcatit) + "\" />\n"; 674 " name=\"" + escapeString(*appcatit) + "\" />\n";
675 } 675 }
676 out += "</Categories>\n"; 676 out += "</Categories>\n";
677 677
678 QCString cstr = out.utf8(); 678 QCString cstr = out.utf8();
679 total_written = f.writeBlock( cstr.data(), cstr.length() ); 679 total_written = f.writeBlock( cstr.data(), cstr.length() );
680 if ( total_written != int(cstr.length()) ) { 680 if ( total_written != int(cstr.length()) ) {
681 f.close(); 681 f.close();
682 QFile::remove( strNewFile ); 682 QFile::remove( strNewFile );
683 return FALSE; 683 return FALSE;
684 } 684 }
685 f.close(); 685 f.close();
686 686
687#ifdef Q_OS_WIN32 687#ifdef Q_OS_WIN32
688 QFile::remove( fname ); 688 QFile::remove( fname );
689#endif 689#endif
690 if ( ::rename( strNewFile.latin1(), fname.latin1() ) < 0 ) { 690 if ( ::rename( strNewFile.latin1(), fname.latin1() ) < 0 ) {
691 qWarning( "problem renaming file %s to %s", 691 qWarning( "problem renaming file %s to %s",
692 strNewFile.latin1(), fname.latin1()); 692 strNewFile.latin1(), fname.latin1());
693 // remove the tmp file... 693 // remove the tmp file...
694 QFile::remove( strNewFile ); 694 QFile::remove( strNewFile );
695 } 695 }
696 696
697 return TRUE; 697 return TRUE;
698} 698}
699 699
700/*! 700/*!
701 Loads the Categories database using \a fname. See categoryFileName() 701 Loads the Categories database using \a fname. See categoryFileName()
702 for the default file name string used for the shared category database. 702 for the default file name string used for the shared category database.
703 703
704 Returns FALSE if there is error reading the file or TRUE on success. 704 Returns FALSE if there is error reading the file or TRUE on success.
705 */ 705 */
706bool Categories::load( const QString &fname ) 706bool Categories::load( const QString &fname )
707{ 707{
708 QFile file( fname ); 708 QFile file( fname );
709 if ( !file.open( IO_ReadOnly ) ) { 709 if ( !file.open( IO_ReadOnly ) ) {
710 qWarning("Unable to open %s", fname.latin1()); 710 qWarning("Unable to open %s", fname.latin1());
711 711
712 addGlobalCategory(tr("Business")); 712 addGlobalCategory(tr("Business"));
713 addGlobalCategory(tr("Personal")); 713 addGlobalCategory(tr("Personal"));
714 save(fname); 714 save(fname);
715 715
716 return FALSE; 716 return FALSE;
717 } 717 }
718 718
719 clear(); 719 clear();
720 QByteArray ba = file.readAll(); 720 QByteArray ba = file.readAll();
721 QString data = QString::fromUtf8( ba.data(), ba.size() ); 721 QString data = QString::fromUtf8( ba.data(), ba.size() );
722 QChar *uc = (QChar *)data.unicode(); 722 QChar *uc = (QChar *)data.unicode();
723 int len = data.length(); 723 int len = data.length();
724 724
725 // QTime t; 725 // QTime t;
726 // t.start(); 726 // t.start();
727 QString name; 727 QString name;
728 QString id; 728 QString id;
729 QString app; 729 QString app;
730 int i = 0; 730 int i = 0;
731 while ( (i = data.find( "<Category ", i)) != -1 ) { 731 while ( (i = data.find( "<Category ", i)) != -1 ) {
732 732
733 i += 10; 733 i += 10;
734 name = QString::null; 734 name = QString::null;
735 app = QString::null; 735 app = QString::null;
736 while ( 1 ) { 736 while ( 1 ) {
737 // skip white space 737 // skip white space
738 while ( i < len && 738 while ( i < len &&
739 (uc[i] == ' ' || uc[i] == '\n' || uc[i] == '\r') ) 739 (uc[i] == ' ' || uc[i] == '\n' || uc[i] == '\r') )
740 i++; 740 i++;
741 // if at the end, then done 741 // if at the end, then done
742 if ( i >= len-2 || (uc[i] == '/' && uc[i+1] == '>') ) 742 if ( i >= len-2 || (uc[i] == '/' && uc[i+1] == '>') )
743 break; 743 break;
744 // we have another attribute read it. 744 // we have another attribute read it.
745 int j = i; 745 int j = i;
746 while ( j < len && uc[j] != '=' ) 746 while ( j < len && uc[j] != '=' )
747 j++; 747 j++;
748 QString attr = QConstString( uc+i, j-i ).string(); 748 QString attr = QConstString( uc+i, j-i ).string();
749 i = ++j; // skip = 749 i = ++j; // skip =
750 while ( i < len && uc[i] != '"' ) 750 while ( i < len && uc[i] != '"' )
751 i++; 751 i++;
752 j = ++i; 752 j = ++i;
753 while ( j < len && uc[j] != '"' ) 753 while ( j < len && uc[j] != '"' )
754 j++; 754 j++;
755 QString value = Qtopia::plainString( QConstString( uc+i, j-i ).string() ); 755 QString value = Qtopia::plainString( QConstString( uc+i, j-i ).string() );
756 i = j + 1; 756 i = j + 1;
757 757
758 // qDebug("attr='%s' value='%s'", attr.latin1(), value.latin1() ); 758 // qDebug("attr='%s' value='%s'", attr.latin1(), value.latin1() );
759 if ( attr == "id" ) 759 if ( attr == "id" )
760 id = value; 760 id = value;
761 else if ( attr == "app" ) 761 else if ( attr == "app" )
762 app = value; 762 app = value;
763 763
764 else if ( attr == "name" ) 764 else if ( attr == "name" )
765 name = value; 765 name = value;
766 } 766 }
767 767
768 if ( name.isNull() || id.isNull() ) { 768 if ( name.isNull() || id.isNull() ) {
769 qWarning("No name or id in the category"); 769 qWarning("No name or id in the category");
770 continue; 770 continue;
771 } 771 }
772 if ( app.isNull() ) 772 if ( app.isNull() )
773 mGlobalCats.add( id.toInt(), name ); 773 mGlobalCats.add( id.toInt(), name );
774 else 774 else
775 mAppCats[ app ].add( id.toInt(), name ); 775 mAppCats[ app ].add( id.toInt(), name );
776 } 776 }
777 777
778 return TRUE; 778 return TRUE;
779} 779}
780 780
781/*! 781/*!
782 Clear the categories in memory. Equivelent to creating an empty Categories 782 Clear the categories in memory. Equivelent to creating an empty Categories
783 object. 783 object.
784*/ 784*/
785void Categories::clear() 785void Categories::clear()
786{ 786{
787 mGlobalCats.clear(); 787 mGlobalCats.clear();
788 mAppCats.clear(); 788 mAppCats.clear();
789} 789}
790 790
791/*! 791/*!
792 Dump the contents to standard out. Used for debugging only. 792 Dump the contents to standard out. Used for debugging only.
793*/ 793*/
794void Categories::dump() const 794void Categories::dump() const
795{ 795{
796 qDebug("\tglobal categories = %s", mGlobalCats.labels().join(", ").latin1() ); 796 qDebug("\tglobal categories = %s", mGlobalCats.labels().join(", ").latin1() );
797 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 ) {
798 const QString &app = appsIt.key(); 798 const QString &app = appsIt.key();
799 QStringList appcats = (*appsIt).labels(); 799 QStringList appcats = (*appsIt).labels();
800 qDebug("\tapp = %s\tcategories = %s", app.latin1(), 800 qDebug("\tapp = %s\tcategories = %s", app.latin1(),
801 appcats.join(", ").latin1() ); 801 appcats.join(", ").latin1() );
802 802
803 } 803 }
804} 804}
805 805
806QStringList CheckedListView::checked() const 806QStringList CheckedListView::checked() const
807{ 807{
808 QStringList strs; 808 QStringList strs;
809 for ( QCheckListItem *i = (QCheckListItem *) firstChild(); 809 for ( QCheckListItem *i = (QCheckListItem *) firstChild();
810 i; i = (QCheckListItem *)i->nextSibling() ) 810 i; i = (QCheckListItem *)i->nextSibling() )
811 if ( i->isOn() ) 811 if ( i->isOn() )
812 strs += i->text( 0 ); 812 strs += i->text( 0 );
813 return strs; 813 return strs;
814} 814}
815 815
816void CheckedListView::addCheckableList( const QStringList &options ) 816void CheckedListView::addCheckableList( const QStringList &options )
817{ 817{
818 for ( QStringList::ConstIterator it = options.begin(); 818 for ( QStringList::ConstIterator it = options.begin();
819 it != options.end(); ++it ) { 819 it != options.end(); ++it ) {
820 (void) new QCheckListItem( this, *it, 820 (void) new QCheckListItem( this, *it,
821 QCheckListItem::CheckBox ); 821 QCheckListItem::CheckBox );
822 } 822 }
823} 823}
824 824
825void CheckedListView::setChecked( const QStringList &checked ) 825void CheckedListView::setChecked( const QStringList &checked )
826{ 826{
827 // iterate over all items 827 // iterate over all items
828 bool showingChecked = FALSE; 828 bool showingChecked = FALSE;
829 for ( QCheckListItem *i = (QCheckListItem *) firstChild(); 829 for ( QCheckListItem *i = (QCheckListItem *) firstChild();
830 i; i = (QCheckListItem *)i->nextSibling() ) 830 i; i = (QCheckListItem *)i->nextSibling() )
831 // see if the item should be checked by searching the 831 // see if the item should be checked by searching the
832 // checked list 832 // checked list
833 if ( checked.find( i->text( 0 ) ) != checked.end() ) { 833 if ( checked.find( i->text( 0 ) ) != checked.end() ) {
834 i->setOn( TRUE ); 834 i->setOn( TRUE );
835 // make sure it is showing at least one checked item 835 // make sure it is showing at least one checked item
836 if ( !showingChecked ) { 836 if ( !showingChecked ) {
837 ensureItemVisible( i ); 837 ensureItemVisible( i );
838 showingChecked = TRUE; 838 showingChecked = TRUE;
839 } 839 }
840 } 840 }
841 else 841 else
842 i->setOn( FALSE ); 842 i->setOn( FALSE );
843} 843}
844 844
845/*! \fn Categories &Categories::operator= ( const Categories &c ) 845/*! \fn Categories &Categories::operator= ( const Categories &c )
846 846
847 Performs deep copy. 847 Performs deep copy.
848 */ 848 */
849 849
850 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 851/*! \fn QStringList Categories::globalCategories() const
857 852
858 Returns list of all global category labels 853 Returns list of all global category labels
859*/ 854*/
860 855
861/*! \fn const QMap<QString, CategoryGroup> &Categories::appGroupMap() const 856/*! \fn const QMap<QString, CategoryGroup> &Categories::appGroupMap() const
862 857
863 Returns a map of application names to CategoryGroup. The CategoryGroup 858 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. 859 class defines a map of ids to category labels and category labels to ids.
865*/ 860*/
866 861
867/*! \fn const CategoryGroup &Categories::globalGroup() const 862/*! \fn const CategoryGroup &Categories::globalGroup() const
868 863
869 Returns the global CategoryGroup. The CategoryGroup 864 Returns the global CategoryGroup. The CategoryGroup
870 class defines a map of ids to category labels and category labels to ids. 865 class defines a map of ids to category labels and category labels to ids.
871*/ 866*/
872 867
873/*! \fn void Categories::categoryAdded( const Categories &cats, const QString &appname, int uid) 868/*! \fn void Categories::categoryAdded( const Categories &cats, const QString &appname, int uid)
874 869
875 Emitted if a category is added. 870 Emitted if a category is added.
876 871
877 \a cats is a const reference to this object 872 \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 873 \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 874 \a uid is the unique identifier associated with the added category
880 */ 875*/
881 876
882/*! \fn void Categories::categoryRemoved( const Categories &cats, const QString &appname, 877/*! \fn void Categories::categoryRemoved( const Categories &cats, const QString &appname,
883 int uid) 878 int uid)
884 879
885 Emitted if removed category is removed. 880 Emitted if removed category is removed.
886 881
887 \a cats is a const reference to this object 882 \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 883 \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 884 \a uid is the unique identifier associated with the removed category
890*/ 885*/
891 886
892 887
893/*! \fn void Categories::categoryRenamed( const Categories &cats, const QString &appname, 888/*! \fn void Categories::categoryRenamed( const Categories &cats, const QString &appname,
894 int uid) 889 int uid)
895 890
896 Emitted if \a uid in the \a appname CategoryGroup is renamed in \a cats 891 Emitted if \a uid in the \a appname CategoryGroup is renamed in \a cats
897 object. 892 object.
898 893
899 \a cats is a const reference to this object 894 \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 895 \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 896 \a uid is the unique identifier associated with the renamed category
902*/ 897*/
903 898
904/*! \fn Categories::Categories( QObject *parent=0, const char *name = 0 ) 899/*! \fn Categories::Categories( QObject *parent=0, const char *name = 0 )
905 900
906 Constructor for an empty Categories object. 901 Constructor for an empty Categories object.
907*/ 902*/
908 903
909/*! \fn Categories::Categories( const Categories &copyFrom ) 904/*! \fn Categories::Categories( const Categories &copyFrom )
910 905
911 Deep copy constructor 906 Deep copy constructor
912*/ 907*/
913 908
914/*! \fn Categories::~Categories() 909/*! \fn Categories::~Categories()
915 910
916 Empty destructor. Call save() before destruction if there are changes 911 Empty destructor. Call save() before destruction if there are changes
917 that need to be saved. 912 that need to be saved.
918*/ 913*/
919 914
920/*! \fn CategoryGroup::clear() 915/*! \fn CategoryGroup::clear()
921 \internal 916 \internal
922*/ 917*/
923 918
924/*! \fn const QMap<int, QString> &CategoryGroup::idMap() const 919/*! \fn const QMap<int, QString> &CategoryGroup::idMap() const
925 920
926 Returns a const reference to the id to label QMap 921 Returns a const reference to the id to label QMap
927*/ 922*/
928 923
929/*! \fn CategoryGroup::CategoryGroup() 924/*! \fn CategoryGroup::CategoryGroup()
930 \internal 925 \internal
931*/ 926*/
932 927
933/*! \fn CategoryGroup::CategoryGroup(const CategoryGroup &c) 928/*! \fn CategoryGroup::CategoryGroup(const CategoryGroup &c)
934 \internal 929 \internal
935*/ 930*/
936 931
diff --git a/library/backend/categories.h b/library/backend/categories.h
index ba65ee3..d5b3669 100644
--- a/library/backend/categories.h
+++ b/library/backend/categories.h
@@ -1,226 +1,226 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of 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
8** Software Foundation and appearing in the file LICENSE.GPL included 8** Software Foundation and appearing in the file LICENSE.GPL included
9** in the packaging of this file. 9** in the 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
12** THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A 12** THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
13** PARTICULAR PURPOSE. 13** PARTICULAR PURPOSE.
14** 14**
15** See http://www.trolltech.com/gpl/ for GPL licensing information. 15** See http://www.trolltech.com/gpl/ for GPL licensing information.
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 QTPALMTOP_CATEGORIES_H 22#ifndef QTPALMTOP_CATEGORIES_H
23#define QTPALMTOP_CATEGORIES_H 23#define QTPALMTOP_CATEGORIES_H
24 24
25#include <qstring.h> 25#include <qstring.h>
26#include <qstringlist.h> 26#include <qstringlist.h>
27#include <qmap.h> 27#include <qmap.h>
28#include <qlistview.h> 28#include <qlistview.h>
29#include <qarray.h> 29#include <qarray.h>
30#include "qpcglobal.h" 30#include "qpcglobal.h"
31#include "palmtopuidgen.h" 31#include "palmtopuidgen.h"
32 32
33class CategoryGroup; 33class CategoryGroup;
34 34
35#if defined(QPC_TEMPLATEDLL) 35#if defined(QPC_TEMPLATEDLL)
36// MOC_SKIP_BEGIN 36// MOC_SKIP_BEGIN
37template class QPC_EXPORT QMap<int, QString>; 37template class QPC_EXPORT QMap<int, QString>;
38template class QPC_EXPORT QMap<QString, int>; 38template class QPC_EXPORT QMap<QString, int>;
39template class QPC_EXPORT QMap< QString, CategoryGroup >; 39template class QPC_EXPORT QMap< QString, CategoryGroup >;
40// MOC_SKIP_END 40// MOC_SKIP_END
41#endif 41#endif
42 42
43class QPC_EXPORT CategoryGroup 43class QPC_EXPORT CategoryGroup
44{ 44{
45 friend class Categories; 45 friend class Categories;
46public: 46public:
47 CategoryGroup(): mIdLabelMap(), mLabelIdMap() { } 47 CategoryGroup(): mIdLabelMap(), mLabelIdMap() { }
48 CategoryGroup( const CategoryGroup &c ) : 48 CategoryGroup( const CategoryGroup &c ) :
49 mIdLabelMap( c.mIdLabelMap), mLabelIdMap( c.mLabelIdMap ) { } 49 mIdLabelMap( c.mIdLabelMap), mLabelIdMap( c.mLabelIdMap ) { }
50 50
51 void clear() { mIdLabelMap.clear(); mLabelIdMap.clear(); } 51 void clear() { mIdLabelMap.clear(); mLabelIdMap.clear(); }
52 52
53 int add( const QString &label ); 53 int add( const QString &label );
54 bool add( int uid, const QString &label ); 54 bool add( int uid, const QString &label );
55 55
56 bool remove( const QString &label ); 56 bool remove( const QString &label );
57 bool remove( int uid ); 57 bool remove( int uid );
58 58
59 bool rename( int uid, const QString &newLabel ); 59 bool rename( int uid, const QString &newLabel );
60 bool rename( const QString &oldLabel, const QString &newLabel ); 60 bool rename( const QString &oldLabel, const QString &newLabel );
61 61
62 bool contains(int id) const; 62 bool contains(int id) const;
63 bool contains(const QString &label) const; 63 bool contains(const QString &label) const;
64 64
65 /** Returns label associated with the uid or QString::null if 65 /** Returns label associated with the uid or QString::null if
66 * not found 66 * not found
67 */ 67 */
68 const QString &label(int id) const; 68 const QString &label(int id) const;
69 /** Returns the uid associated with label or 0 if not found */ 69 /** Returns the uid associated with label or 0 if not found */
70 int id(const QString &label) const; 70 int id(const QString &label) const;
71 71
72 /** Returns a sorted list of labels */ 72 /** Returns a sorted list of labels */
73 QStringList labels() const; 73 QStringList labels() const;
74 74
75 QStringList labels( const QArray<int> &catids ) const; 75 QStringList labels( const QArray<int> &catids ) const;
76 76
77 const QMap<int, QString> &idMap() const { return mIdLabelMap; } 77 const QMap<int, QString> &idMap() const { return mIdLabelMap; }
78 78
79private: 79private:
80 void insert( int uid, const QString &label ); 80 void insert( int uid, const QString &label );
81 QMap<int, QString> mIdLabelMap; 81 QMap<int, QString> mIdLabelMap;
82 QMap<QString, int> mLabelIdMap; 82 QMap<QString, int> mLabelIdMap;
83 83
84 static Qtopia::UidGen &uidGen() { return sUidGen; } 84 static Qtopia::UidGen &uidGen() { return sUidGen; }
85 static Qtopia::UidGen sUidGen; 85 static Qtopia::UidGen sUidGen;
86}; 86};
87 87
88/** Map from application name to categories */ 88/* Map from application name to categories */
89class QPC_EXPORT Categories : public QObject 89class QPC_EXPORT Categories : public QObject
90{ 90{
91 Q_OBJECT 91 Q_OBJECT
92public: 92public:
93 Categories( QObject *parent=0, const char *name = 0 ) 93 Categories( QObject *parent=0, const char *name = 0 )
94 : QObject( parent, name ), mGlobalCats(), mAppCats() { } 94 : QObject( parent, name ), mGlobalCats(), mAppCats() { }
95 Categories( const Categories &copyFrom ) : QObject( copyFrom.parent() ), 95 Categories( const Categories &copyFrom ) : QObject( copyFrom.parent() ),
96 mGlobalCats( copyFrom.mGlobalCats ), 96 mGlobalCats( copyFrom.mGlobalCats ),
97 mAppCats( copyFrom.mAppCats ) { } 97 mAppCats( copyFrom.mAppCats ) { }
98 virtual ~Categories() { } 98 virtual ~Categories() { }
99 99
100 Categories &operator= ( const Categories &c ) 100 Categories &operator= ( const Categories &c )
101{ mAppCats = c.mAppCats; mGlobalCats = c.mGlobalCats; return *this; } 101{ mAppCats = c.mAppCats; mGlobalCats = c.mGlobalCats; return *this; }
102 102
103 void clear(); 103 void clear();
104 104
105 /** Add the category name as long as it doesn't already exist 105 /** Add the category name as long as it doesn't already exist
106 * locally or globally. Return UID if added, 0 if conflicts 106 * locally or globally. Return UID if added, 0 if conflicts
107 * (error). 107 * (error).
108 */ 108 */
109 int addCategory( const QString &appname, const QString &catname); 109 int addCategory( const QString &appname, const QString &catname);
110 /** Add the category name as long as it doesn't already exist 110 /** Add the category name as long as it doesn't already exist
111 * locally or globally. Return UID if added, 0 if conflicts 111 * locally or globally. Return UID if added, 0 if conflicts
112 * (error). 112 * (error).
113 */ 113 */
114 int addCategory( const QString &appname, const QString &catname, int uid); 114 int addCategory( const QString &appname, const QString &catname, int uid);
115 /** Add the global category just checking that it doesn't 115 /** Add the global category just checking that it doesn't
116 * already exist globally. Return UID if added, 0 if conflicts. 116 * already exist globally. Return UID if added, 0 if conflicts.
117 */ 117 */
118 int addGlobalCategory( const QString &catname ); 118 int addGlobalCategory( const QString &catname );
119 /** Add the global category just checking that it doesn't 119 /** Add the global category just checking that it doesn't
120 * already exist globally. Return UID if added, 0 if conflicts. 120 * already exist globally. Return UID if added, 0 if conflicts.
121 */ 121 */
122 int addGlobalCategory( const QString &catname, int uid ); 122 int addGlobalCategory( const QString &catname, int uid );
123 /** Removes the category from the application; if it is not found 123 /** Removes the category from the application; if it is not found
124 * in the application, then it removes it from the global list 124 * in the application, then it removes it from the global list
125 */ 125 */
126 bool removeCategory( const QString &appName, const QString &catName, 126 bool removeCategory( const QString &appName, const QString &catName,
127 bool checkGlobal = TRUE); 127 bool checkGlobal = TRUE);
128 bool removeCategory( const QString &appName, int uid ); 128 bool removeCategory( const QString &appName, int uid );
129 bool removeGlobalCategory( const QString &catName ); 129 bool removeGlobalCategory( const QString &catName );
130 bool removeGlobalCategory( int uid ); 130 bool removeGlobalCategory( int uid );
131 131
132 QArray<int> ids( const QString &app, const QStringList &labels) const; 132 QArray<int> ids( const QString &app, const QStringList &labels) const;
133 133
134 /** Returns the id associated with the app */ 134 /** Returns the id associated with the app */
135 int id( const QString &app, const QString &cat ) const; 135 int id( const QString &app, const QString &cat ) const;
136 /** Returns the label associated with the id */ 136 /** Returns the label associated with the id */
137 QString label( const QString &app, int id ) const; 137 QString label( const QString &app, int id ) const;
138 138
139 enum ExtraLabels { NoExtra, AllUnfiled, AllLabel, UnfiledLabel }; 139 enum ExtraLabels { NoExtra, AllUnfiled, AllLabel, UnfiledLabel };
140 /** Returns the sorted list of all categories that are 140 /** Returns the sorted list of all categories that are
141 * associated with the app. 141 * associated with the app.
142 * If includeGlobal parameter is TRUE then the returned 142 * If includeGlobal parameter is TRUE then the returned
143 * categories will include the global category items. 143 * categories will include the global category items.
144 * If extra = NoExtra, then 144 * If extra = NoExtra, then
145 * If extra = AllUnfiled, then All and Unfiled will be prepended to 145 * If extra = AllUnfiled, then All and Unfiled will be prepended to
146 * the list 146 * the list
147 * If extra = AllLabel, then All is prepended 147 * If extra = AllLabel, then All is prepended
148 * If extra = UnfiledLabel, then Unfiled is prepended 148 * If extra = UnfiledLabel, then Unfiled is prepended
149 */ 149 */
150 QStringList labels( const QString &app, 150 QStringList labels( const QString &app,
151 bool includeGlobal = TRUE, 151 bool includeGlobal = TRUE,
152 ExtraLabels extra = NoExtra ) const; 152 ExtraLabels extra = NoExtra ) const;
153 153
154 enum DisplaySingle { ShowMulti, ShowAll, ShowFirst }; 154 enum DisplaySingle { ShowMulti, ShowAll, ShowFirst };
155 155
156 /** Returns a single string associated with the cat ids for display in 156 /** Returns a single string associated with the cat ids for display in
157 * a combobox or any area that requires one string. If catids are empty 157 * a combobox or any area that requires one string. If catids are empty
158 * then "Unfiled" will be returned. If multiple categories are assigned 158 * then "Unfiled" will be returned. If multiple categories are assigned
159 * then the behavior depends on the DisplaySingle type. 159 * then the behavior depends on the DisplaySingle type.
160 * If /a display is set to ShowMulti then " (multi)" appended to the 160 * If /a display is set to ShowMulti then " (multi)" appended to the
161 * first string. If /a display is set to ShowAll, then a space seperated 161 * first string. If /a display is set to ShowAll, then a space seperated
162 * string is returned with all categories. If ShowFirst is returned, 162 * string is returned with all categories. If ShowFirst is returned,
163 * the just the first string is returned. 163 * the just the first string is returned.
164 */ 164 */
165 QString displaySingle( const QString &app, 165 QString displaySingle( const QString &app,
166 const QArray<int> &catids, 166 const QArray<int> &catids,
167 DisplaySingle display ) const; 167 DisplaySingle display ) const;
168 168
169 QStringList globalCategories() const { return mGlobalCats.labels();} 169 QStringList globalCategories() const { return mGlobalCats.labels();}
170 170
171 bool renameCategory( const QString &appname, 171 bool renameCategory( const QString &appname,
172 const QString &oldName, 172 const QString &oldName,
173 const QString &newName ); 173 const QString &newName );
174 bool renameGlobalCategory( const QString &oldName, 174 bool renameGlobalCategory( const QString &oldName,
175 const QString &newName ); 175 const QString &newName );
176 176
177 void setGlobal( const QString &appname, const QString &catname, 177 void setGlobal( const QString &appname, const QString &catname,
178 bool value ); 178 bool value );
179 bool isGlobal( const QString &catname ) const; 179 bool isGlobal( const QString &catname ) const;
180 180
181 181
182 /** Returns true if the catname is associated with any application 182 /** Returns true if the catname is associated with any application
183 */ 183 */
184 bool exists( const QString &catname ) const; 184 bool exists( const QString &catname ) const;
185 bool exists( const QString &appname, const QString &catname) const; 185 bool exists( const QString &appname, const QString &catname) const;
186 186
187 bool save( const QString &fname ) const; 187 bool save( const QString &fname ) const;
188 bool load( const QString &fname ); 188 bool load( const QString &fname );
189 189
190 // for debugging 190 // for debugging
191 void dump() const; 191 void dump() const;
192 192
193 const QMap<QString, CategoryGroup> &appGroupMap() const{ return mAppCats; } 193 const QMap<QString, CategoryGroup> &appGroupMap() const{ return mAppCats; }
194 const CategoryGroup &globalGroup() const { return mGlobalCats; } 194 const CategoryGroup &globalGroup() const { return mGlobalCats; }
195 195
196signals: 196signals:
197 /** emitted if added a category; 197 /** emitted if added a category;
198 * the second param is the application the category was added to 198 * the second param is the application the category was added to
199 * or null if global 199 * or null if global
200 * the third param is the uid of the newly added category 200 * the third param is the uid of the newly added category
201 */ 201 */
202 void categoryAdded( const Categories &, const QString &, int ); 202 void categoryAdded( const Categories &, const QString &, int );
203 /** emitted if removed a category 203 /** emitted if removed a category
204 * the second param is the application the category was removed from 204 * the second param is the application the category was removed from
205 * or null if global 205 * or null if global
206 * the third param is the uid of the removed category 206 * the third param is the uid of the removed category
207 */ 207 */
208 void categoryRemoved( const Categories &, const QString &, int ); 208 void categoryRemoved( const Categories &, const QString &, int );
209 /** emitted if a category is renamed; the second param is the uid of 209 /** emitted if a category is renamed; the second param is the uid of
210 * the removed category */ 210 * the removed category */
211 void categoryRenamed( const Categories &, const QString &, int ); 211 void categoryRenamed( const Categories &, const QString &, int );
212 212
213private: 213private:
214 CategoryGroup mGlobalCats; 214 CategoryGroup mGlobalCats;
215 QMap< QString, CategoryGroup > mAppCats; 215 QMap< QString, CategoryGroup > mAppCats;
216}; 216};
217 217
218class QPC_EXPORT CheckedListView : public QListView 218class QPC_EXPORT CheckedListView : public QListView
219{ 219{
220public: 220public:
221 void addCheckableList( const QStringList &options ); 221 void addCheckableList( const QStringList &options );
222 void setChecked( const QStringList &checked ); 222 void setChecked( const QStringList &checked );
223 QStringList checked() const; 223 QStringList checked() const;
224}; 224};
225 225
226#endif 226#endif
diff --git a/library/backend/event.cpp b/library/backend/event.cpp
index d906f19..4c24ab3 100644
--- a/library/backend/event.cpp
+++ b/library/backend/event.cpp
@@ -1,432 +1,432 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 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** 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 <qtopia/timeconversion.h> 23#include <qtopia/timeconversion.h>
24#include <qtopia/stringutil.h> 24#include <qtopia/stringutil.h>
25#include <qtopia/private/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
32using namespace Qtopia; 32using namespace Qtopia;
33 33
34static void write( QString& buf, const Event::RepeatPattern &r ) 34static 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
72Qtopia::UidGen Event::sUidGen( Qtopia::UidGen::Qtopia ); 72Qtopia::UidGen Event::sUidGen( Qtopia::UidGen::Qtopia );
73 73
74/*! 74/*!
75 \class Event event.h 75 \class Event event.h
76 \brief The Event class holds the data of a calendar event. 76 \brief The Event class holds the data of a calendar event.
77 77
78 This data includes descriptive data of the event and schedualing information. 78 This data includes descriptive data of the event and schedualing information.
79 79
80 \ingroup qtopiaemb 80 \ingroup qtopiaemb
81 \ingroup qtopiadesktop 81 \ingroup qtopiadesktop
82*/ 82*/
83 83
84/*! 84/*!
85 \class Event::RepeatPattern 85 \class Event::RepeatPattern
86 \class The Event::RepeatPattern class is internal. 86 \class The Event::RepeatPattern class is internal.
87 \internal 87 \internal
88*/ 88*/
89 89
90/*! 90/*!
91 \enum Event::Days 91 \enum Event::Days
92 \internal 92 \internal
93*/ 93*/
94 94
95/*! 95/*!
96 \enum Event::Type 96 \enum Event::Type
97 \internal 97 \internal
98*/ 98*/
99 99
100/*! 100/*!
101 \enum Event::SoundTypeChoice 101 \enum Event::SoundTypeChoice
102 102
103 This enum type defines what kind of sound is made when an alarm occurs 103 This enum type defines what kind of sound is made when an alarm occurs
104 for an event. The currently defined types are: 104 for an event. The currently defined types are:
105 105
106 <ul> 106 <ul>
107 <li>\c Silent - No sound is produced. 107 <li>\c Silent - No sound is produced.
108 <li>\c Loud - A loud sound is produced. 108 <li>\c Loud - A loud sound is produced.
109 </ul> 109 </ul>
110*/ 110*/
111 111
112/*! 112/*!
113 \fn bool Event::operator<( const Event & ) const 113 \fn bool Event::operator<( const Event & ) const
114 \internal 114 \internal
115*/ 115*/
116 116
117/*! 117/*!
118 \fn bool Event::operator<=( const Event & ) const 118 \fn bool Event::operator<=( const Event & ) const
119 \internal 119 \internal
120*/ 120*/
121 121
122/*! 122/*!
123 \fn bool Event::operator!=( const Event & ) const 123 \fn bool Event::operator!=( const Event & ) const
124 \internal 124 \internal
125*/ 125*/
126 126
127/*! 127/*!
128 \fn bool Event::operator>( const Event & ) const 128 \fn bool Event::operator>( const Event & ) const
129 \internal 129 \internal
130*/ 130*/
131 131
132/*! 132/*!
133 \fn bool Event::operator>=( const Event & ) const 133 \fn bool Event::operator>=( const Event & ) const
134 \internal 134 \internal
135*/ 135*/
136 136
137/*! 137/*!
138 \enum Event::RepeatType 138 \enum Event::RepeatType
139 139
140 This enum defines how a event will repeat, if at all. 140 This enum defines how a event will repeat, if at all.
141 141
142 <ul> 142 <ul>
143 <li>\c NoRepeat - Event does not repeat. 143 <li>\c NoRepeat - Event does not repeat.
144 <li>\c Daily - Event occurs every n days. 144 <li>\c Daily - Event occurs every n days.
145 <li>\c Weekly - Event occurs every n weeks. 145 <li>\c Weekly - Event occurs every n weeks.
146 <li>\c MonthlyDay - Event occurs every n months. Event will always occur in 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. 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 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. 149 on the same day of the month as the first event.
150 <li>\c Yearly - Event occurs every n years. 150 <li>\c Yearly - Event occurs every n years.
151 </ul> 151 </ul>
152*/ 152*/
153 153
154/*! 154/*!
155 \fn bool Event::isAllDay() const 155 \fn bool Event::isAllDay() const
156 156
157 Returns TRUE if the event is an all day event. Otherwise returns FALSE. 157 Returns TRUE if the event is an all day event. Otherwise returns FALSE.
158*/ 158*/
159 159
160/*! 160/*!
161 \fn void Event::setAllDay(bool allday) 161 \fn void Event::setAllDay(bool allday)
162 162
163 If \a allday is TRUE, will set the event to be an all day event. 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. 164 Otherwise sets the event to not be an all day event.
165 165
166 \warning This function may affect the start and end times of the event. 166 \warning This function may affect the start and end times of the event.
167*/ 167*/
168 168
169/*! 169/*!
170 \fn QDateTime Event::start() const 170 \fn QDateTime Event::start(bool) const
171 171
172 Returns the start date and time of the first occurance of the event. 172 Returns the start date and time of the first occurance of the event.
173*/ 173*/
174 174
175/*! 175/*!
176 \fn QDateTime Event::end() const 176 \fn QDateTime Event::end(bool) const
177 177
178 Returns the end date and time of the first occurance of the event. 178 Returns the end date and time of the first occurance of the event.
179*/ 179*/
180 180
181/*! 181/*!
182 \fn time_t Event::startTime() const 182 \fn time_t Event::startTime() const
183 \internal 183 \internal
184*/ 184*/
185 185
186/*! 186/*!
187 \fn time_t Event::endTime() const 187 \fn time_t Event::endTime() const
188 \internal 188 \internal
189*/ 189*/
190 190
191/*! 191/*!
192 \fn void Event::setAlarm(int delay, SoundTypeChoice s) 192 \fn void Event::setAlarm(int delay, SoundTypeChoice s)
193 193
194 Sets the alarm delay of the event to \a delay and the sound type of the 194 Sets the alarm delay of the event to \a delay and the sound type of the
195 alarm to \a s. 195 alarm to \a s.
196*/ 196*/
197 197
198/*! 198/*!
199 \fn void Event::clearAlarm() 199 \fn void Event::clearAlarm()
200 200
201 Clears the alarm for the event. 201 Clears the alarm for the event.
202*/ 202*/
203 203
204/*! 204/*!
205 \fn int Event::alarmDelay() const 205 \fn int Event::alarmDelay() const
206 206
207 Returns the delay in minutes between the alarm for an event and the 207 Returns the delay in minutes between the alarm for an event and the
208 start of the event. 208 start of the event.
209*/ 209*/
210 210
211/*! 211/*!
212 \fn Event::RepeatType Event::repeatType() const 212 \fn Event::RepeatType Event::repeatType() const
213 213
214 Returns the repeat pattern type for the event. 214 Returns the repeat pattern type for the event.
215 215
216 \sa frequency() 216 \sa frequency()
217*/ 217*/
218 218
219/*! 219/*!
220 \fn int Event::weekOffset() const 220 \fn int Event::weekOffset() const
221 221
222 Returns the number of weeks from the start of the month that this event 222 Returns the number of weeks from the start of the month that this event
223 occurs. 223 occurs.
224*/ 224*/
225 225
226/*! 226/*!
227 \fn QDate Event::repeatTill() const 227 \fn QDate Event::repeatTill() const
228 228
229 Returns the date that the event will continue to repeat until. If the event 229 Returns the date that the event will continue to repeat until. If the event
230 repeats forever the value returned is undefined. 230 repeats forever the value returned is undefined.
231 231
232 \sa repeatForever() 232 \sa repeatForever()
233*/ 233*/
234 234
235/*! 235/*!
236 \fn bool Event::repeatForever() const 236 \fn bool Event::repeatForever() const
237 237
238 Returns FALSE if there is a date set for the event to continue until. 238 Returns FALSE if there is a date set for the event to continue until.
239 Otherwise returns TRUE. 239 Otherwise returns TRUE.
240*/ 240*/
241 241
242/*! 242/*!
243 \fn bool Event::doRepeat() const 243 \fn bool Event::doRepeat() const
244 \internal 244 \internal
245*/ 245*/
246 246
247/*! 247/*!
248 \fn bool Event::repeatOnWeekDay(int day) const 248 \fn bool Event::repeatOnWeekDay(int day) const
249 249
250 Returns TRUE if the event has a RepeatType of Weekly and is set to occur on 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. 251 \a day each week. Otherwise returns FALSE.
252 252
253 \sa QDate::dayName() 253 \sa QDate::dayName()
254*/ 254*/
255 255
256/*! 256/*!
257 \fn void Event::setRepeatOnWeekDay(int day, bool enable) 257 \fn void Event::setRepeatOnWeekDay(int day, bool enable)
258 258
259 If \a enable is TRUE then sets the event to occur on \a day each week. 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. 260 Otherwise sets the event not to occur on \a day.
261 261
262 \warning this function is only relavent for a event with RepeatType of 262 \warning this function is only relavent for a event with RepeatType of
263 Weekly. 263 Weekly.
264 264
265 \sa QDate::dayName() 265 \sa QDate::dayName()
266*/ 266*/
267 267
268/*! 268/*!
269 \fn int Event::frequency() const 269 \fn int Event::frequency() const
270 270
271 Returns how often the event repeats. 271 Returns how often the event repeats.
272 272
273 \sa repeatType() 273 \sa repeatType()
274*/ 274*/
275 275
276/*! 276/*!
277 \fn void Event::setRepeatType(RepeatType t) 277 \fn void Event::setRepeatType(RepeatType t)
278 278
279 Sets the repeat pattern type of the event to \a t. 279 Sets the repeat pattern type of the event to \a t.
280 280
281 \sa setFrequency() 281 \sa setFrequency()
282*/ 282*/
283 283
284/*! 284/*!
285 \fn void Event::setFrequency(int n) 285 \fn void Event::setFrequency(int n)
286 286
287 Sets how often the event occurs with in its repeat pattern. 287 Sets how often the event occurs with in its repeat pattern.
288 288
289 \sa setRepeatType() 289 \sa setRepeatType()
290*/ 290*/
291 291
292/*! 292/*!
293 \fn void Event::setRepeatTill(const QDate &d) 293 \fn void Event::setRepeatTill(const QDate &d)
294 294
295 Sets the event to repeat until \a d. 295 Sets the event to repeat until \a d.
296*/ 296*/
297 297
298/*! 298/*!
299 \fn void Event::setRepeatForever(bool enable) 299 \fn void Event::setRepeatForever(bool enable)
300 300
301 If \a enable is TRUE, sets the event to repeat forever. Otherwise 301 If \a enable is TRUE, sets the event to repeat forever. Otherwise
302 sets the event to stop repeating at some date. 302 sets the event to stop repeating at some date.
303 303
304 \warning This function may affect the specific date the event will repeat 304 \warning This function may affect the specific date the event will repeat
305 till. 305 till.
306*/ 306*/
307 307
308/*! 308/*!
309 \fn bool Event::match(const QRegExp &r) const 309 \fn bool Event::match(const QRegExp &r) const
310 310
311 Returns TRUE if the event matches the regular expression \a r. 311 Returns TRUE if the event matches the regular expression \a r.
312 Otherwise returns FALSE. 312 Otherwise returns FALSE.
313*/ 313*/
314 314
315/*! 315/*!
316 \fn char Event::day(int) 316 \fn char Event::day(int)
317 \internal 317 \internal
318*/ 318*/
319 319
320/*! 320/*!
321 Creates a new, empty event. 321 Creates a new, empty event.
322*/ 322*/
323Event::Event() : Record() 323Event::Event() : Record()
324{ 324{
325 startUTC = endUTC = time( 0 ); 325 startUTC = endUTC = time( 0 );
326 typ = Normal; 326 typ = Normal;
327 hAlarm = FALSE; 327 hAlarm = FALSE;
328 hRepeat = FALSE; 328 hRepeat = FALSE;
329 aMinutes = 0; 329 aMinutes = 0;
330 aSound = Silent; 330 aSound = Silent;
331 pattern.type = NoRepeat; 331 pattern.type = NoRepeat;
332 pattern.frequency = -1; 332 pattern.frequency = -1;
333} 333}
334 334
335/*! 335/*!
336 \internal 336 \internal
337*/ 337*/
338Event::Event( const QMap<int, QString> &map ) 338Event::Event( const QMap<int, QString> &map )
339{ 339{
340 setDescription( map[DatebookDescription] ); 340 setDescription( map[DatebookDescription] );
341 setLocation( map[Location] ); 341 setLocation( map[Location] );
342 setCategories( idsFromString( map[DatebookCategory] ) ); 342 setCategories( idsFromString( map[DatebookCategory] ) );
343 setTimeZone( map[TimeZone] ); 343 setTimeZone( map[TimeZone] );
344 setNotes( map[Note] ); 344 setNotes( map[Note] );
345 setStart( TimeConversion::fromUTC( map[StartDateTime].toUInt() ) ); 345 setStart( TimeConversion::fromUTC( map[StartDateTime].toUInt() ) );
346 setEnd( TimeConversion::fromUTC( map[EndDateTime].toUInt() ) ); 346 setEnd( TimeConversion::fromUTC( map[EndDateTime].toUInt() ) );
347 setType( (Event::Type) map[DatebookType].toInt() ); 347 setType( (Event::Type) map[DatebookType].toInt() );
348 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() );
349 Event::RepeatPattern p; 349 Event::RepeatPattern p;
350 p.type = (Event::RepeatType) map[ RepeatPatternType ].toInt(); 350 p.type = (Event::RepeatType) map[ RepeatPatternType ].toInt();
351 p.frequency = map[ RepeatPatternFrequency ].toInt(); 351 p.frequency = map[ RepeatPatternFrequency ].toInt();
352 p.position = map[ RepeatPatternPosition ].toInt(); 352 p.position = map[ RepeatPatternPosition ].toInt();
353 p.days = map[ RepeatPatternDays ].toInt(); 353 p.days = map[ RepeatPatternDays ].toInt();
354 p.hasEndDate = map[ RepeatPatternHasEndDate ].toInt(); 354 p.hasEndDate = map[ RepeatPatternHasEndDate ].toInt();
355 p.endDateUTC = map[ RepeatPatternEndDate ].toUInt(); 355 p.endDateUTC = map[ RepeatPatternEndDate ].toUInt();
356 setRepeat( p ); 356 setRepeat( p );
357 357
358 setUid( map[ DatebookUid ].toInt() ); 358 setUid( map[ DatebookUid ].toInt() );
359} 359}
360 360
361/*! 361/*!
362 Destroys an event. 362 Destroys an event.
363*/ 363*/
364Event::~Event() 364Event::~Event()
365{ 365{
366} 366}
367 367
368/*! 368/*!
369 \internal 369 \internal
370*/ 370*/
371int Event::week( const QDate& date ) 371int Event::week( const QDate& date )
372{ 372{
373 // Calculates the week this date is in within that 373 // Calculates the week this date is in within that
374 // month. Equals the "row" is is in in the month view 374 // month. Equals the "row" is is in in the month view
375 int week = 1; 375 int week = 1;
376 QDate tmp( date.year(), date.month(), 1 ); 376 QDate tmp( date.year(), date.month(), 1 );
377 377
378 if ( date.dayOfWeek() < tmp.dayOfWeek() ) 378 if ( date.dayOfWeek() < tmp.dayOfWeek() )
379 ++week; 379 ++week;
380 380
381 week += ( date.day() - 1 ) / 7; 381 week += ( date.day() - 1 ) / 7;
382 return week; 382 return week;
383} 383}
384 384
385/*! 385/*!
386 \internal 386 \internal
387*/ 387*/
388int Event::occurrence( const QDate& date ) 388int Event::occurrence( const QDate& date )
389{ 389{
390 // calculates the number of occurrances of this day of the 390 // calculates the number of occurrances of this day of the
391 // 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)
392 return ( date.day() - 1 ) / 7 + 1; 392 return ( date.day() - 1 ) / 7 + 1;
393} 393}
394 394
395/*! 395/*!
396 \internal 396 \internal
397*/ 397*/
398int Event::dayOfWeek( char day ) 398int Event::dayOfWeek( char day )
399{ 399{
400 int dayOfWeek = 1; 400 int dayOfWeek = 1;
401 char i = Event::MON; 401 char i = Event::MON;
402 while ( !( i & day ) && i <= Event::SUN ) { 402 while ( !( i & day ) && i <= Event::SUN ) {
403 i <<= 1; 403 i <<= 1;
404 ++dayOfWeek; 404 ++dayOfWeek;
405 } 405 }
406 return dayOfWeek; 406 return dayOfWeek;
407} 407}
408 408
409/*! 409/*!
410 \internal 410 \internal
411*/ 411*/
412int Event::monthDiff( const QDate& first, const QDate& second ) 412int Event::monthDiff( const QDate& first, const QDate& second )
413{ 413{
414 return ( second.year() - first.year() ) * 12 + 414 return ( second.year() - first.year() ) * 12 +
415 second.month() - first.month(); 415 second.month() - first.month();
416} 416}
417 417
418/*! 418/*!
419 \internal 419 \internal
420*/ 420*/
421QMap<int, QString> Event::toMap() const 421QMap<int, QString> Event::toMap() const
422{ 422{
423 QMap<int, QString> m; 423 QMap<int, QString> m;
424 424
425 if ( !description().isEmpty() ) 425 if ( !description().isEmpty() )
426 m.insert( DatebookDescription, description() ); 426 m.insert( DatebookDescription, description() );
427 if ( !location().isEmpty() ) 427 if ( !location().isEmpty() )
428 m.insert ( Location, location() ); 428 m.insert ( Location, location() );
429 if ( categories().count() ) 429 if ( categories().count() )
430 m.insert ( DatebookCategory, idsToString( categories() ) ); 430 m.insert ( DatebookCategory, idsToString( categories() ) );
431 if ( !timeZone().isEmpty() ) 431 if ( !timeZone().isEmpty() )
432 m.insert ( TimeZone, timeZone() ); 432 m.insert ( TimeZone, timeZone() );
diff --git a/library/backend/palmtoprecord.h b/library/backend/palmtoprecord.h
index 72f7d1c..15cdd6a 100644
--- a/library/backend/palmtoprecord.h
+++ b/library/backend/palmtoprecord.h
@@ -1,95 +1,107 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 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** 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 QTPALMTOP_RECORD_H 20#ifndef QTPALMTOP_RECORD_H
21#define QTPALMTOP_RECORD_H 21#define QTPALMTOP_RECORD_H
22#include <qglobal.h> 22#include <qglobal.h>
23#include "qpcglobal.h" 23#include "qpcglobal.h"
24#include "palmtopuidgen.h" 24#include "palmtopuidgen.h"
25#include <qarray.h> 25#include <qarray.h>
26#include <qmap.h> 26#include <qmap.h>
27 27
28#if defined(QPC_TEMPLATEDLL) 28#if defined(QPC_TEMPLATEDLL)
29// MOC_SKIP_BEGIN 29// MOC_SKIP_BEGIN
30QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<QString, QString>; 30QPC_TEMPLATEEXTERN template class QPC_EXPORT QMap<QString, QString>;
31// MOC_SKIP_END 31// MOC_SKIP_END
32#endif 32#endif
33 33
34class QRegExp; 34class QRegExp;
35/**
36 * @short Qtopia namespace
37 * The namespace of Qtopia
38 */
35namespace Qtopia { 39namespace Qtopia {
36 40
37class RecordPrivate; 41class RecordPrivate;
42/**
43 * @short The base class of all Records
44 *
45 * The base class for Records in Qtopia
46 * @see Task
47 * @see Event
48 * @see Contact
49 */
38class QPC_EXPORT Record 50class QPC_EXPORT Record
39{ 51{
40public: 52public:
41 Record() : mUid(0), mCats() { } 53 Record() : mUid(0), mCats() { }
42 Record( const Record &c ) :mUid( c.mUid ), mCats ( c.mCats ), customMap(c.customMap) { } 54 Record( const Record &c ) :mUid( c.mUid ), mCats ( c.mCats ), customMap(c.customMap) { }
43 virtual ~Record() { } 55 virtual ~Record() { }
44 56
45 Record &operator=( const Record &c ); 57 Record &operator=( const Record &c );
46 58
47 virtual bool match( const QRegExp & ) const { return FALSE; } 59 virtual bool match( const QRegExp & ) const { return FALSE; }
48 60
49 void setCategories( const QArray<int> &v ) { mCats = v; mCats.sort(); } 61 void setCategories( const QArray<int> &v ) { mCats = v; mCats.sort(); }
50 void setCategories( int single ); 62 void setCategories( int single );
51 const QArray<int> &categories() const { return mCats; } 63 const QArray<int> &categories() const { return mCats; }
52 64
53 void reassignCategoryId( int oldId, int newId ) 65 void reassignCategoryId( int oldId, int newId )
54 { 66 {
55 int index = mCats.find( oldId ); 67 int index = mCats.find( oldId );
56 if ( index >= 0 ) 68 if ( index >= 0 )
57 mCats[index] = newId; 69 mCats[index] = newId;
58 } 70 }
59 71
60 int uid() const { return mUid; }; 72 int uid() const { return mUid; };
61 virtual void setUid( int i ) { mUid = i; uidGen().store( mUid ); } 73 virtual void setUid( int i ) { mUid = i; uidGen().store( mUid ); }
62 bool isValidUid() const { return mUid != 0; } 74 bool isValidUid() const { return mUid != 0; }
63 void assignUid() { setUid( uidGen().generate() ); } 75 void assignUid() { setUid( uidGen().generate() ); }
64 76
65 virtual QString customField(const QString &) const; 77 virtual QString customField(const QString &) const;
66 virtual void setCustomField(const QString &, const QString &); 78 virtual void setCustomField(const QString &, const QString &);
67 virtual void removeCustomField(const QString &); 79 virtual void removeCustomField(const QString &);
68 80
69 virtual bool operator == ( const Record &r ) const 81 virtual bool operator == ( const Record &r ) const
70{ return mUid == r.mUid; } 82{ return mUid == r.mUid; }
71 virtual bool operator != ( const Record &r ) const 83 virtual bool operator != ( const Record &r ) const
72{ return mUid != r.mUid; } 84{ return mUid != r.mUid; }
73 85
74 // convenience methods provided for loading and saving to xml 86 // convenience methods provided for loading and saving to xml
75 static QString idsToString( const QArray<int> &ids ); 87 static QString idsToString( const QArray<int> &ids );
76 // convenience methods provided for loading and saving to xml 88 // convenience methods provided for loading and saving to xml
77 static QArray<int> idsFromString( const QString &str ); 89 static QArray<int> idsFromString( const QString &str );
78 90
79 // for debugging 91 // for debugging
80 static void dump( const QMap<int, QString> &map ); 92 static void dump( const QMap<int, QString> &map );
81 93
82protected: 94protected:
83 virtual UidGen &uidGen() = 0; 95 virtual UidGen &uidGen() = 0;
84 virtual QString customToXml() const; 96 virtual QString customToXml() const;
85private: 97private:
86 int mUid; 98 int mUid;
87 QArray<int> mCats; 99 QArray<int> mCats;
88 QMap<QString, QString> customMap; 100 QMap<QString, QString> customMap;
89 RecordPrivate *d; 101 RecordPrivate *d;
90}; 102};
91 103
92} 104}
93 105
94#endif 106#endif
95 107
diff --git a/library/datebookdb.cpp b/library/datebookdb.cpp
index 0fedfa8..2f33255 100644
--- a/library/datebookdb.cpp
+++ b/library/datebookdb.cpp
@@ -1,982 +1,982 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of 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 <qasciidict.h> 21#include <qasciidict.h>
22#include <qfile.h> 22#include <qfile.h>
23#include <qmessagebox.h> 23#include <qmessagebox.h>
24#include <qstring.h> 24#include <qstring.h>
25#include <qtextcodec.h> 25#include <qtextcodec.h>
26#include <qtextstream.h> 26#include <qtextstream.h>
27#include <qtl.h> 27#include <qtl.h>
28 28
29#include <qpe/alarmserver.h> 29#include <qpe/alarmserver.h>
30#include <qpe/global.h> 30#include <qpe/global.h>
31#include "datebookdb.h" 31#include "datebookdb.h"
32#include <qpe/stringutil.h> 32#include <qpe/stringutil.h>
33#include <qpe/timeconversion.h> 33#include <qpe/timeconversion.h>
34 34
35#include <errno.h> 35#include <errno.h>
36#include <stdlib.h> 36#include <stdlib.h>
37 37
38 38
39class DateBookDBPrivate 39class DateBookDBPrivate
40{ 40{
41public: 41public:
42 bool clean; // indcate whether we need to write to disk... 42 bool clean; // indcate whether we need to write to disk...
43}; 43};
44 44
45 45
46// Helper functions 46// Helper functions
47 47
48static QString dateBookJournalFile() 48static QString dateBookJournalFile()
49{ 49{
50 QString str = getenv("HOME"); 50 QString str = getenv("HOME");
51 return QString( str +"/.caljournal" ); 51 return QString( str +"/.caljournal" );
52} 52}
53 53
54static QString dateBookFilename() 54static QString dateBookFilename()
55{ 55{
56 return Global::applicationFileName("datebook","datebook.xml"); 56 return Global::applicationFileName("datebook","datebook.xml");
57} 57}
58 58
59/* Calculating the next event of a recuring event is actually 59/* Calculating the next event of a recuring event is actually
60 computationally inexpensive, esp. compared to checking each day 60 computationally inexpensive, esp. compared to checking each day
61 individually. There are bad worse cases for say the 29th of 61 individually. There are bad worse cases for say the 29th of
62 february or the 31st of some other months. However 62 february or the 31st of some other months. However
63 these are still bounded */ 63 these are still bounded */
64bool nextOccurance(const Event &e, const QDate &from, QDateTime &next) 64bool nextOccurance(const Event &e, const QDate &from, QDateTime &next)
65{ 65{
66 // easy checks, first are we too far in the future or too far in the past? 66 // easy checks, first are we too far in the future or too far in the past?
67 QDate tmpDate; 67 QDate tmpDate;
68 int freq = e.repeatPattern().frequency; 68 int freq = e.repeatPattern().frequency;
69 int diff, diff2, a; 69 int diff, diff2, a;
70 int iday, imonth, iyear; 70 int iday, imonth, iyear;
71 int dayOfWeek = 0; 71 int dayOfWeek = 0;
72 int firstOfWeek = 0; 72 int firstOfWeek = 0;
73 int weekOfMonth; 73 int weekOfMonth;
74 74
75 75
76 if (e.repeatPattern().hasEndDate && e.repeatPattern().endDate() < from) 76 if (e.repeatPattern().hasEndDate && e.repeatPattern().endDate() < from)
77 return FALSE; 77 return FALSE;
78 78
79 if (e.start() >= from) { 79 if (e.start() >= from) {
80 next = e.start(); 80 next = e.start();
81 return TRUE; 81 return TRUE;
82 } 82 }
83 83
84 switch ( e.repeatPattern().type ) { 84 switch ( e.repeatPattern().type ) {
85 case Event::Weekly: 85 case Event::Weekly:
86 /* weekly is just daily by 7 */ 86 /* weekly is just daily by 7 */
87 /* first convert the repeatPattern.Days() mask to the next 87 /* first convert the repeatPattern.Days() mask to the next
88 day of week valid after from */ 88 day of week valid after from */
89 dayOfWeek = from.dayOfWeek(); 89 dayOfWeek = from.dayOfWeek();
90 dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */ 90 dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */
91 91
92 /* this is done in case freq > 1 and from in week not 92 /* this is done in case freq > 1 and from in week not
93 for this round */ 93 for this round */
94 // firstOfWeek = 0; this is already done at decl. 94 // firstOfWeek = 0; this is already done at decl.
95 while(!((1 << firstOfWeek) & e.repeatPattern().days)) 95 while(!((1 << firstOfWeek) & e.repeatPattern().days))
96 firstOfWeek++; 96 firstOfWeek++;
97 97
98 /* there is at least one 'day', or there would be no event */ 98 /* there is at least one 'day', or there would be no event */
99 while(!((1 << (dayOfWeek % 7)) & e.repeatPattern().days)) 99 while(!((1 << (dayOfWeek % 7)) & e.repeatPattern().days))
100 dayOfWeek++; 100 dayOfWeek++;
101 101
102 dayOfWeek = dayOfWeek % 7; /* the actual day of week */ 102 dayOfWeek = dayOfWeek % 7; /* the actual day of week */
103 dayOfWeek -= e.start().date().dayOfWeek() -1; 103 dayOfWeek -= e.start().date().dayOfWeek() -1;
104 104
105 firstOfWeek = firstOfWeek % 7; /* the actual first of week */ 105 firstOfWeek = firstOfWeek % 7; /* the actual first of week */
106 firstOfWeek -= e.start().date().dayOfWeek() -1; 106 firstOfWeek -= e.start().date().dayOfWeek() -1;
107 107
108 // dayOfWeek may be negitive now 108 // dayOfWeek may be negitive now
109 // day of week is number of days to add to start day 109 // day of week is number of days to add to start day
110 110
111 freq *= 7; 111 freq *= 7;
112 // FALL-THROUGH !!!!! 112 // FALL-THROUGH !!!!!
113 case Event::Daily: 113 case Event::Daily:
114 // the add is for the possible fall through from weekly */ 114 // the add is for the possible fall through from weekly */
115 if(e.start().date().addDays(dayOfWeek) > from) { 115 if(e.start().date().addDays(dayOfWeek) > from) {
116 /* first week exception */ 116 /* first week exception */
117 next = QDateTime(e.start().date().addDays(dayOfWeek), 117 next = QDateTime(e.start().date().addDays(dayOfWeek),
118 e.start().time()); 118 e.start().time());
119 if ((next.date() > e.repeatPattern().endDate()) 119 if ((next.date() > e.repeatPattern().endDate())
120 && e.repeatPattern().hasEndDate) 120 && e.repeatPattern().hasEndDate)
121 return FALSE; 121 return FALSE;
122 return TRUE; 122 return TRUE;
123 } 123 }
124 /* if from is middle of a non-week */ 124 /* if from is middle of a non-week */
125 125
126 diff = e.start().date().addDays(dayOfWeek).daysTo(from) % freq; 126 diff = e.start().date().addDays(dayOfWeek).daysTo(from) % freq;
127 diff2 = e.start().date().addDays(firstOfWeek).daysTo(from) % freq; 127 diff2 = e.start().date().addDays(firstOfWeek).daysTo(from) % freq;
128 128
129 if(diff != 0) 129 if(diff != 0)
130 diff = freq - diff; 130 diff = freq - diff;
131 if(diff2 != 0) 131 if(diff2 != 0)
132 diff2 = freq - diff2; 132 diff2 = freq - diff2;
133 diff = QMIN(diff, diff2); 133 diff = QMIN(diff, diff2);
134 134
135 next = QDateTime(from.addDays(diff), e.start().time()); 135 next = QDateTime(from.addDays(diff), e.start().time());
136 if ( (next.date() > e.repeatPattern().endDate()) 136 if ( (next.date() > e.repeatPattern().endDate())
137 && e.repeatPattern().hasEndDate ) 137 && e.repeatPattern().hasEndDate )
138 return FALSE; 138 return FALSE;
139 return TRUE; 139 return TRUE;
140 case Event::MonthlyDay: 140 case Event::MonthlyDay:
141 iday = from.day(); 141 iday = from.day();
142 iyear = from.year(); 142 iyear = from.year();
143 imonth = from.month(); 143 imonth = from.month();
144 /* find equivelent day of month for this month */ 144 /* find equivelent day of month for this month */
145 dayOfWeek = e.start().date().dayOfWeek(); 145 dayOfWeek = e.start().date().dayOfWeek();
146 weekOfMonth = (e.start().date().day() - 1) / 7; 146 weekOfMonth = (e.start().date().day() - 1) / 7;
147 147
148 /* work out when the next valid month is */ 148 /* work out when the next valid month is */
149 a = from.year() - e.start().date().year(); 149 a = from.year() - e.start().date().year();
150 a *= 12; 150 a *= 12;
151 a = a + (imonth - e.start().date().month()); 151 a = a + (imonth - e.start().date().month());
152 /* a is e.start()monthsFrom(from); */ 152 /* a is e.start()monthsFrom(from); */
153 if(a % freq) { 153 if(a % freq) {
154 a = freq - (a % freq); 154 a = freq - (a % freq);
155 imonth = from.month() + a; 155 imonth = from.month() + a;
156 if (imonth > 12) { 156 if (imonth > 12) {
157 imonth--; 157 imonth--;
158 iyear += imonth / 12; 158 iyear += imonth / 12;
159 imonth = imonth % 12; 159 imonth = imonth % 12;
160 imonth++; 160 imonth++;
161 } 161 }
162 } 162 }
163 /* imonth is now the first month after or on 163 /* imonth is now the first month after or on
164 from that matches the frequency given */ 164 from that matches the frequency given */
165 165
166 /* find for this month */ 166 /* find for this month */
167 tmpDate = QDate( iyear, imonth, 1 ); 167 tmpDate = QDate( iyear, imonth, 1 );
168 168
169 iday = 1; 169 iday = 1;
170 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 170 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
171 iday += 7 * weekOfMonth; 171 iday += 7 * weekOfMonth;
172 while (iday > tmpDate.daysInMonth()) { 172 while (iday > tmpDate.daysInMonth()) {
173 imonth += freq; 173 imonth += freq;
174 if (imonth > 12) { 174 if (imonth > 12) {
175 imonth--; 175 imonth--;
176 iyear += imonth / 12; 176 iyear += imonth / 12;
177 imonth = imonth % 12; 177 imonth = imonth % 12;
178 imonth++; 178 imonth++;
179 } 179 }
180 tmpDate = QDate( iyear, imonth, 1 ); 180 tmpDate = QDate( iyear, imonth, 1 );
181 /* these loops could go for a while, check end case now */ 181 /* these loops could go for a while, check end case now */
182 if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 182 if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
183 return FALSE; 183 return FALSE;
184 iday = 1; 184 iday = 1;
185 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 185 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
186 iday += 7 * weekOfMonth; 186 iday += 7 * weekOfMonth;
187 } 187 }
188 tmpDate = QDate(iyear, imonth, iday); 188 tmpDate = QDate(iyear, imonth, iday);
189 189
190 if (tmpDate >= from) { 190 if (tmpDate >= from) {
191 next = QDateTime(tmpDate, e.start().time()); 191 next = QDateTime(tmpDate, e.start().time());
192 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 192 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
193 return FALSE; 193 return FALSE;
194 return TRUE; 194 return TRUE;
195 } 195 }
196 196
197 /* need to find the next iteration */ 197 /* need to find the next iteration */
198 do { 198 do {
199 imonth += freq; 199 imonth += freq;
200 if (imonth > 12) { 200 if (imonth > 12) {
201 imonth--; 201 imonth--;
202 iyear += imonth / 12; 202 iyear += imonth / 12;
203 imonth = imonth % 12; 203 imonth = imonth % 12;
204 imonth++; 204 imonth++;
205 } 205 }
206 tmpDate = QDate( iyear, imonth, 1 ); 206 tmpDate = QDate( iyear, imonth, 1 );
207 /* these loops could go for a while, check end case now */ 207 /* these loops could go for a while, check end case now */
208 if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 208 if ((tmpDate > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
209 return FALSE; 209 return FALSE;
210 iday = 1; 210 iday = 1;
211 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7; 211 iday += (7 + dayOfWeek - tmpDate.dayOfWeek()) % 7;
212 iday += 7 * weekOfMonth; 212 iday += 7 * weekOfMonth;
213 } while (iday > tmpDate.daysInMonth()); 213 } while (iday > tmpDate.daysInMonth());
214 tmpDate = QDate(iyear, imonth, iday); 214 tmpDate = QDate(iyear, imonth, iday);
215 215
216 next = QDateTime(tmpDate, e.start().time()); 216 next = QDateTime(tmpDate, e.start().time());
217 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 217 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
218 return FALSE; 218 return FALSE;
219 return TRUE; 219 return TRUE;
220 case Event::MonthlyDate: 220 case Event::MonthlyDate:
221 iday = e.start().date().day(); 221 iday = e.start().date().day();
222 iyear = from.year(); 222 iyear = from.year();
223 imonth = from.month(); 223 imonth = from.month();
224 224
225 a = from.year() - e.start().date().year(); 225 a = from.year() - e.start().date().year();
226 a *= 12; 226 a *= 12;
227 a = a + (imonth - e.start().date().month()); 227 a = a + (imonth - e.start().date().month());
228 /* a is e.start()monthsFrom(from); */ 228 /* a is e.start()monthsFrom(from); */
229 if(a % freq) { 229 if(a % freq) {
230 a = freq - (a % freq); 230 a = freq - (a % freq);
231 imonth = from.month() + a; 231 imonth = from.month() + a;
232 if (imonth > 12) { 232 if (imonth > 12) {
233 imonth--; 233 imonth--;
234 iyear += imonth / 12; 234 iyear += imonth / 12;
235 imonth = imonth % 12; 235 imonth = imonth % 12;
236 imonth++; 236 imonth++;
237 } 237 }
238 } 238 }
239 /* imonth is now the first month after or on 239 /* imonth is now the first month after or on
240 from that matches the frequencey given */ 240 from that matches the frequencey given */
241 241
242 /* this could go for a while, worse case, 4*12 iterations, probably */ 242 /* this could go for a while, worse case, 4*12 iterations, probably */
243 while(!QDate::isValid(iyear, imonth, iday) ) { 243 while(!QDate::isValid(iyear, imonth, iday) ) {
244 imonth += freq; 244 imonth += freq;
245 if (imonth > 12) { 245 if (imonth > 12) {
246 imonth--; 246 imonth--;
247 iyear += imonth / 12; 247 iyear += imonth / 12;
248 imonth = imonth % 12; 248 imonth = imonth % 12;
249 imonth++; 249 imonth++;
250 } 250 }
251 /* these loops could go for a while, check end case now */ 251 /* these loops could go for a while, check end case now */
252 if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 252 if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
253 return FALSE; 253 return FALSE;
254 } 254 }
255 255
256 if(QDate(iyear, imonth, iday) >= from) { 256 if(QDate(iyear, imonth, iday) >= from) {
257 /* done */ 257 /* done */
258 next = QDateTime(QDate(iyear, imonth, iday), 258 next = QDateTime(QDate(iyear, imonth, iday),
259 e.start().time()); 259 e.start().time());
260 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 260 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
261 return FALSE; 261 return FALSE;
262 return TRUE; 262 return TRUE;
263 } 263 }
264 264
265 /* ok, need to cycle */ 265 /* ok, need to cycle */
266 imonth += freq; 266 imonth += freq;
267 imonth--; 267 imonth--;
268 iyear += imonth / 12; 268 iyear += imonth / 12;
269 imonth = imonth % 12; 269 imonth = imonth % 12;
270 imonth++; 270 imonth++;
271 271
272 while(!QDate::isValid(iyear, imonth, iday) ) { 272 while(!QDate::isValid(iyear, imonth, iday) ) {
273 imonth += freq; 273 imonth += freq;
274 imonth--; 274 imonth--;
275 iyear += imonth / 12; 275 iyear += imonth / 12;
276 imonth = imonth % 12; 276 imonth = imonth % 12;
277 imonth++; 277 imonth++;
278 if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 278 if ((QDate(iyear, imonth, 1) > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
279 return FALSE; 279 return FALSE;
280 } 280 }
281 281
282 next = QDateTime(QDate(iyear, imonth, iday), e.start().time()); 282 next = QDateTime(QDate(iyear, imonth, iday), e.start().time());
283 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 283 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
284 return FALSE; 284 return FALSE;
285 return TRUE; 285 return TRUE;
286 case Event::Yearly: 286 case Event::Yearly:
287 iday = e.start().date().day(); 287 iday = e.start().date().day();
288 imonth = e.start().date().month(); 288 imonth = e.start().date().month();
289 iyear = from.year(); // after all, we want to start in this year 289 iyear = from.year(); // after all, we want to start in this year
290 290
291 diff = 1; 291 diff = 1;
292 if(imonth == 2 && iday > 28) { 292 if(imonth == 2 && iday > 28) {
293 /* leap year, and it counts, calculate actual frequency */ 293 /* leap year, and it counts, calculate actual frequency */
294 if(freq % 4) 294 if(freq % 4)
295 if (freq % 2) 295 if (freq % 2)
296 freq = freq * 4; 296 freq = freq * 4;
297 else 297 else
298 freq = freq * 2; 298 freq = freq * 2;
299 /* else divides by 4 already, leave freq alone */ 299 /* else divides by 4 already, leave freq alone */
300 diff = 4; 300 diff = 4;
301 } 301 }
302 302
303 a = from.year() - e.start().date().year(); 303 a = from.year() - e.start().date().year();
304 if(a % freq) { 304 if(a % freq) {
305 a = freq - (a % freq); 305 a = freq - (a % freq);
306 iyear = iyear + a; 306 iyear = iyear + a;
307 } 307 }
308 308
309 /* under the assumption we won't hit one of the special not-leap years twice */ 309 /* under the assumption we won't hit one of the special not-leap years twice */
310 if(!QDate::isValid(iyear, imonth, iday)) { 310 if(!QDate::isValid(iyear, imonth, iday)) {
311 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ 311 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */
312 iyear += freq; 312 iyear += freq;
313 } 313 }
314 314
315 if(QDate(iyear, imonth, iday) >= from) { 315 if(QDate(iyear, imonth, iday) >= from) {
316 next = QDateTime(QDate(iyear, imonth, iday), 316 next = QDateTime(QDate(iyear, imonth, iday),
317 e.start().time()); 317 e.start().time());
318 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 318 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
319 return FALSE; 319 return FALSE;
320 return TRUE; 320 return TRUE;
321 } 321 }
322 /* iyear == from.year(), need to advance again */ 322 /* iyear == from.year(), need to advance again */
323 iyear += freq; 323 iyear += freq;
324 /* under the assumption we won't hit one of the special not-leap years twice */ 324 /* under the assumption we won't hit one of the special not-leap years twice */
325 if(!QDate::isValid(iyear, imonth, iday)) { 325 if(!QDate::isValid(iyear, imonth, iday)) {
326 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */ 326 /* must have been skipping by leap years and hit one that wasn't, (e.g. 2100) */
327 iyear += freq; 327 iyear += freq;
328 } 328 }
329 329
330 next = QDateTime(QDate(iyear, imonth, iday), e.start().time()); 330 next = QDateTime(QDate(iyear, imonth, iday), e.start().time());
331 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate) 331 if ((next.date() > e.repeatPattern().endDate()) && e.repeatPattern().hasEndDate)
332 return FALSE; 332 return FALSE;
333 return TRUE; 333 return TRUE;
334 default: 334 default:
335 return FALSE; 335 return FALSE;
336 } 336 }
337} 337}
338 338
339static bool nextAlarm( const Event &ev, QDateTime& when, int& warn) 339static bool nextAlarm( const Event &ev, QDateTime& when, int& warn)
340{ 340{
341 QDateTime now = QDateTime::currentDateTime(); 341 QDateTime now = QDateTime::currentDateTime();
342 if ( ev.hasRepeat() ) { 342 if ( ev.hasRepeat() ) {
343 QDateTime ralarm; 343 QDateTime ralarm;
344 if (nextOccurance(ev, now.date(), ralarm)) { 344 if (nextOccurance(ev, now.date(), ralarm)) {
345 ralarm = ralarm.addSecs(-ev.alarmTime()*60); 345 ralarm = ralarm.addSecs(-ev.alarmTime()*60);
346 if ( ralarm > now ) { 346 if ( ralarm > now ) {
347 when = ralarm; 347 when = ralarm;
348 warn = ev.alarmTime(); 348 warn = ev.alarmTime();
349 } else if ( nextOccurance(ev, now.date().addDays(1), ralarm) ) { 349 } else if ( nextOccurance(ev, now.date().addDays(1), ralarm) ) {
350 ralarm = ralarm.addSecs( -ev.alarmTime()*60 ); 350 ralarm = ralarm.addSecs( -ev.alarmTime()*60 );
351 if ( ralarm > now ) { 351 if ( ralarm > now ) {
352 when = ralarm; 352 when = ralarm;
353 warn = ev.alarmTime(); 353 warn = ev.alarmTime();
354 } 354 }
355 } 355 }
356 } 356 }
357 } else { 357 } else {
358 warn = ev.alarmTime(); 358 warn = ev.alarmTime();
359 when = ev.start().addSecs( -ev.alarmTime()*60 ); 359 when = ev.start().addSecs( -ev.alarmTime()*60 );
360 } 360 }
361 return when > now; 361 return when > now;
362} 362}
363 363
364static void addEventAlarm( const Event &ev ) 364static void addEventAlarm( const Event &ev )
365{ 365{
366 QDateTime when; 366 QDateTime when;
367 int warn; 367 int warn;
368 if ( nextAlarm(ev,when,warn) ) 368 if ( nextAlarm(ev,when,warn) )
369 AlarmServer::addAlarm( when, 369 AlarmServer::addAlarm( when,
370 "QPE/Application/datebook", 370 "QPE/Application/datebook",
371 "alarm(QDateTime,int)", warn ); 371 "alarm(QDateTime,int)", warn );
372} 372}
373 373
374static void delEventAlarm( const Event &ev ) 374static void delEventAlarm( const Event &ev )
375{ 375{
376 QDateTime when; 376 QDateTime when;
377 int warn; 377 int warn;
378 if ( nextAlarm(ev,when,warn) ) 378 if ( nextAlarm(ev,when,warn) )
379 AlarmServer::deleteAlarm( when, 379 AlarmServer::deleteAlarm( when,
380 "QPE/Application/datebook", 380 "QPE/Application/datebook",
381 "alarm(QDateTime,int)", warn ); 381 "alarm(QDateTime,int)", warn );
382} 382}
383 383
384 384
385DateBookDB::DateBookDB() 385DateBookDB::DateBookDB()
386{ 386{
387 init(); 387 init();
388} 388}
389 389
390DateBookDB::~DateBookDB() 390DateBookDB::~DateBookDB()
391{ 391{
392 save(); 392 save();
393 eventList.clear(); 393 eventList.clear();
394 repeatEvents.clear(); 394 repeatEvents.clear();
395} 395}
396 396
397 397
398//#### Why is this code duplicated in getEffectiveEvents ????? 398//#### Why is this code duplicated in getEffectiveEvents ?????
399//#### Addendum. Don't use this function, lets faze it out if we can. 399//#### Addendum. Don't use this function, lets faze it out if we can.
400QValueList<Event> DateBookDB::getEvents( const QDate &from, const QDate &to ) 400QValueList<Event> DateBookDB::getEvents( const QDate &from, const QDate &to )
401{ 401{
402 QValueList<Event> tmpList; 402 QValueList<Event> tmpList;
403 tmpList = getNonRepeatingEvents( from, to ); 403 tmpList = getNonRepeatingEvents( from, to );
404 404
405 // check for repeating events... 405 // check for repeating events...
406 for (QValueList<Event>::ConstIterator it = repeatEvents.begin(); 406 for (QValueList<Event>::ConstIterator it = repeatEvents.begin();
407 it != repeatEvents.end(); ++it) { 407 it != repeatEvents.end(); ++it) {
408 QDate itDate = from; 408 QDate itDate = from;
409 QDateTime due; 409 QDateTime due;
410 410
411 /* create a false end date, to short circuit on hard 411 /* create a false end date, to short circuit on hard
412 MonthlyDay recurences */ 412 MonthlyDay recurences */
413 Event dummy_event = *it; 413 Event dummy_event = *it;
414 Event::RepeatPattern r = dummy_event.repeatPattern(); 414 Event::RepeatPattern r = dummy_event.repeatPattern();
415 if ( !r.hasEndDate || r.endDate() > to ) { 415 if ( !r.hasEndDate || r.endDate() > to ) {
416 r.setEndDate( to ); 416 r.setEndDate( to );
417 r.hasEndDate = TRUE; 417 r.hasEndDate = TRUE;
418 } 418 }
419 dummy_event.setRepeat(TRUE, r); 419 dummy_event.setRepeat(TRUE, r);
420 420
421 while (nextOccurance(dummy_event, itDate, due)) { 421 while (nextOccurance(dummy_event, itDate, due)) {
422 if (due.date() > to) 422 if (due.date() > to)
423 break; 423 break;
424 Event newEvent = *it; 424 Event newEvent = *it;
425 newEvent.setStart(due); 425 newEvent.setStart(due);
426 newEvent.setEnd(due.addSecs((*it).start().secsTo((*it).end()))); 426 newEvent.setEnd(due.addSecs((*it).start().secsTo((*it).end())));
427 427
428 tmpList.append(newEvent); 428 tmpList.append(newEvent);
429 itDate = due.date().addDays(1); /* the next event */ 429 itDate = due.date().addDays(1); /* the next event */
430 } 430 }
431 } 431 }
432 qHeapSort(tmpList); 432 qHeapSort(tmpList);
433 return tmpList; 433 return tmpList;
434} 434}
435 435
436QValueList<Event> DateBookDB::getEvents( const QDateTime &start ) 436QValueList<Event> DateBookDB::getEvents( const QDateTime &start )
437{ 437{
438 QValueList<Event> day = getEvents(start.date(),start.date()); 438 QValueList<Event> day = getEvents(start.date(),start.date());
439 439
440 QValueListConstIterator<Event> it; 440 QValueListConstIterator<Event> it;
441 QDateTime dtTmp; 441 QDateTime dtTmp;
442 QValueList<Event> tmpList; 442 QValueList<Event> tmpList;
443 for (it = day.begin(); it != day.end(); ++it ) { 443 for (it = day.begin(); it != day.end(); ++it ) {
444 dtTmp = (*it).start(TRUE); 444 dtTmp = (*it).start(TRUE);
445 if ( dtTmp == start ) 445 if ( dtTmp == start )
446 tmpList.append( *it ); 446 tmpList.append( *it );
447 } 447 }
448 return tmpList; 448 return tmpList;
449} 449}
450 450
451//#### Why is this code duplicated in getEvents ????? 451//#### Why is this code duplicated in getEvents ?????
452 452
453QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDate &from, 453QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDate &from,
454 const QDate &to ) 454 const QDate &to )
455{ 455{
456 QValueList<EffectiveEvent> tmpList; 456 QValueList<EffectiveEvent> tmpList;
457 QValueListIterator<Event> it; 457 QValueListIterator<Event> it;
458 458
459 EffectiveEvent effEv; 459 EffectiveEvent effEv;
460 QDateTime dtTmp, 460 QDateTime dtTmp,
461 dtEnd; 461 dtEnd;
462 462
463 for (it = eventList.begin(); it != eventList.end(); ++it ) { 463 for (it = eventList.begin(); it != eventList.end(); ++it ) {
464 if (!(*it).isValidUid()) 464 if (!(*it).isValidUid())
465 (*it).assignUid(); // FIXME: Hack to restore cleared uids 465 (*it).assignUid(); // FIXME: Hack to restore cleared uids
466 466
467 dtTmp = (*it).start(TRUE); 467 dtTmp = (*it).start(TRUE);
468 dtEnd = (*it).end(TRUE); 468 dtEnd = (*it).end(TRUE);
469 469
470 if ( dtTmp.date() >= from && dtTmp.date() <= to ) { 470 if ( dtTmp.date() >= from && dtTmp.date() <= to ) {
471 Event tmpEv = *it; 471 Event tmpEv = *it;
472 effEv.setEvent(tmpEv); 472 effEv.setEvent(tmpEv);
473 effEv.setDate( dtTmp.date() ); 473 effEv.setDate( dtTmp.date() );
474 effEv.setStart( dtTmp.time() ); 474 effEv.setStart( dtTmp.time() );
475 if ( dtTmp.date() != dtEnd.date() ) 475 if ( dtTmp.date() != dtEnd.date() )
476 effEv.setEnd( QTime(23, 59, 0) ); 476 effEv.setEnd( QTime(23, 59, 0) );
477 else 477 else
478 effEv.setEnd( dtEnd.time() ); 478 effEv.setEnd( dtEnd.time() );
479 tmpList.append( effEv ); 479 tmpList.append( effEv );
480 } 480 }
481 // we must also check for end date information... 481 // we must also check for end date information...
482 if ( dtEnd.date() != dtTmp.date() && dtEnd.date() >= from ) { 482 if ( dtEnd.date() != dtTmp.date() && dtEnd.date() >= from ) {
483 QDateTime dt = dtTmp.addDays( 1 ); 483 QDateTime dt = dtTmp.addDays( 1 );
484 dt.setTime( QTime(0, 0, 0) ); 484 dt.setTime( QTime(0, 0, 0) );
485 QDateTime dtStop; 485 QDateTime dtStop;
486 if ( dtEnd > to ) { 486 if ( dtEnd > to ) {
487 dtStop = to; 487 dtStop = to;
488 } else 488 } else
489 dtStop = dtEnd; 489 dtStop = dtEnd;
490 while ( dt <= dtStop ) { 490 while ( dt <= dtStop ) {
491 Event tmpEv = *it; 491 Event tmpEv = *it;
492 effEv.setEvent( tmpEv ); 492 effEv.setEvent( tmpEv );
493 effEv.setDate( dt.date() ); 493 effEv.setDate( dt.date() );
494 if ( dt >= from ) { 494 if ( dt >= from ) {
495 effEv.setStart( QTime(0, 0, 0) ); 495 effEv.setStart( QTime(0, 0, 0) );
496 if ( dt.date() == dtEnd.date() ) 496 if ( dt.date() == dtEnd.date() )
497 effEv.setEnd( dtEnd.time() ); 497 effEv.setEnd( dtEnd.time() );
498 else 498 else
499 effEv.setEnd( QTime(23, 59, 59) ); 499 effEv.setEnd( QTime(23, 59, 59) );
500 tmpList.append( effEv ); 500 tmpList.append( effEv );
501 } 501 }
502 dt = dt.addDays( 1 ); 502 dt = dt.addDays( 1 );
503 } 503 }
504 } 504 }
505 } 505 }
506 // check for repeating events... 506 // check for repeating events...
507 QDateTime repeat; 507 QDateTime repeat;
508 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) { 508 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) {
509 if (!(*it).isValidUid()) 509 if (!(*it).isValidUid())
510 (*it).assignUid(); // FIXME: Hack to restore cleared uids 510 (*it).assignUid(); // FIXME: Hack to restore cleared uids
511 511
512 /* create a false end date, to short circuit on hard 512 /* create a false end date, to short circuit on hard
513 MonthlyDay recurences */ 513 MonthlyDay recurences */
514 Event dummy_event = *it; 514 Event dummy_event = *it;
515 int duration = (*it).start().date().daysTo( (*it).end().date() ); 515 int duration = (*it).start().date().daysTo( (*it).end().date() );
516 QDate itDate = from.addDays(-duration); 516 QDate itDate = from.addDays(-duration);
517 517
518 Event::RepeatPattern r = dummy_event.repeatPattern(); 518 Event::RepeatPattern r = dummy_event.repeatPattern();
519 if ( !r.hasEndDate || r.endDate() > to ) { 519 if ( !r.hasEndDate || r.endDate() > to ) {
520 r.setEndDate( to ); 520 r.setEndDate( to );
521 r.hasEndDate = TRUE; 521 r.hasEndDate = TRUE;
522 } 522 }
523 dummy_event.setRepeat(TRUE, r); 523 dummy_event.setRepeat(TRUE, r);
524 524
525 while (nextOccurance(dummy_event, itDate, repeat)) { 525 while (nextOccurance(dummy_event, itDate, repeat)) {
526 if(repeat.date() > to) 526 if(repeat.date() > to)
527 break; 527 break;
528 effEv.setDate( repeat.date() ); 528 effEv.setDate( repeat.date() );
529 if ((*it).type() == Event::AllDay) { 529 if ((*it).type() == Event::AllDay) {
530 effEv.setStart( QTime(0,0,0) ); 530 effEv.setStart( QTime(0,0,0) );
531 effEv.setEnd( QTime(23,59,59) ); 531 effEv.setEnd( QTime(23,59,59) );
532 } else { 532 } else {
533 /* we only occur by days, not hours/minutes/seconds. Hence 533 /* we only occur by days, not hours/minutes/seconds. Hence
534 the actual end and start times will be the same for 534 the actual end and start times will be the same for
535 every repeated event. For multi day events this is 535 every repeated event. For multi day events this is
536 fixed up later if on wronge day span */ 536 fixed up later if on wronge day span */
537 effEv.setStart( (*it).start().time() ); 537 effEv.setStart( (*it).start().time() );
538 effEv.setEnd( (*it).end().time() ); 538 effEv.setEnd( (*it).end().time() );
539 } 539 }
540 if ( duration != 0 ) { 540 if ( duration != 0 ) {
541 // multi-day repeating events 541 // multi-day repeating events
542 QDate sub_it = QMAX( repeat.date(), from ); 542 QDate sub_it = QMAX( repeat.date(), from );
543 QDate startDate = repeat.date(); 543 QDate startDate = repeat.date();
544 QDate endDate = startDate.addDays( duration ); 544 QDate endDate = startDate.addDays( duration );
545 545
546 while ( sub_it <= endDate && sub_it <= to ) { 546 while ( sub_it <= endDate && sub_it <= to ) {
547 EffectiveEvent tmpEffEv = effEv; 547 EffectiveEvent tmpEffEv = effEv;
548 Event tmpEv = *it; 548 Event tmpEv = *it;
549 tmpEffEv.setEvent( tmpEv ); 549 tmpEffEv.setEvent( tmpEv );
550 550
551 if ( sub_it != startDate ) 551 if ( sub_it != startDate )
552 tmpEffEv.setStart( QTime(0,0,0) ); 552 tmpEffEv.setStart( QTime(0,0,0) );
553 if ( sub_it != endDate ) 553 if ( sub_it != endDate )
554 tmpEffEv.setEnd( QTime(23,59,59) ); 554 tmpEffEv.setEnd( QTime(23,59,59) );
555 tmpEffEv.setDate( sub_it ); 555 tmpEffEv.setDate( sub_it );
556 tmpEffEv.setEffectiveDates( startDate, endDate ); 556 tmpEffEv.setEffectiveDates( startDate, endDate );
557 tmpList.append( tmpEffEv ); 557 tmpList.append( tmpEffEv );
558 sub_it = sub_it.addDays( 1 ); 558 sub_it = sub_it.addDays( 1 );
559 } 559 }
560 itDate = endDate; 560 itDate = endDate;
561 } else { 561 } else {
562 Event tmpEv = *it; 562 Event tmpEv = *it;
563 effEv.setEvent( tmpEv ); 563 effEv.setEvent( tmpEv );
564 tmpList.append( effEv ); 564 tmpList.append( effEv );
565 itDate = repeat.date().addDays( 1 ); 565 itDate = repeat.date().addDays( 1 );
566 } 566 }
567 } 567 }
568 } 568 }
569 569
570 qHeapSort( tmpList ); 570 qHeapSort( tmpList );
571 return tmpList; 571 return tmpList;
572} 572}
573 573
574QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDateTime &dt) 574QValueList<EffectiveEvent> DateBookDB::getEffectiveEvents( const QDateTime &dt)
575{ 575{
576 QValueList<EffectiveEvent> day = getEffectiveEvents(dt.date(), dt.date()); 576 QValueList<EffectiveEvent> day = getEffectiveEvents(dt.date(), dt.date());
577 QValueListConstIterator<EffectiveEvent> it; 577 QValueListConstIterator<EffectiveEvent> it;
578 QValueList<EffectiveEvent> tmpList; 578 QValueList<EffectiveEvent> tmpList;
579 QDateTime dtTmp; 579 QDateTime dtTmp;
580 580
581 for (it = day.begin(); it != day.end(); ++it ) { 581 for (it = day.begin(); it != day.end(); ++it ) {
582 dtTmp = QDateTime( (*it).date(), (*it).start() ); 582 dtTmp = QDateTime( (*it).date(), (*it).start() );
583 // at the moment we don't have second granularity, be nice about that.. 583 // at the moment we don't have second granularity, be nice about that..
584 if ( QABS(dt.secsTo(dtTmp)) < 60 ) 584 if ( QABS(dt.secsTo(dtTmp)) < 60 )
585 tmpList.append( *it ); 585 tmpList.append( *it );
586 } 586 }
587 return tmpList; 587 return tmpList;
588} 588}
589 589
590void DateBookDB::addEvent( const Event &ev, bool doalarm ) 590void DateBookDB::addEvent( const Event &ev, bool doalarm )
591{ 591{
592 // write to the journal... 592 // write to the journal...
593 saveJournalEntry( ev, ACTION_ADD, -1, false ); 593 saveJournalEntry( ev, ACTION_ADD, -1, false );
594 addJFEvent( ev, doalarm ); 594 addJFEvent( ev, doalarm );
595 d->clean = false; 595 d->clean = false;
596} 596}
597 597
598void DateBookDB::addJFEvent( const Event &ev, bool doalarm ) 598void DateBookDB::addJFEvent( const Event &ev, bool doalarm )
599{ 599{
600 if ( doalarm && ev.hasAlarm() ) 600 if ( doalarm && ev.hasAlarm() )
601 addEventAlarm( ev ); 601 addEventAlarm( ev );
602 if ( ev.hasRepeat() ) 602 if ( ev.hasRepeat() )
603 repeatEvents.append( ev ); 603 repeatEvents.append( ev );
604 else 604 else
605 eventList.append( ev ); 605 eventList.append( ev );
606} 606}
607 607
608void DateBookDB::editEvent( const Event &old, Event &editedEv ) 608void DateBookDB::editEvent( const Event &old, Event &editedEv )
609{ 609{
610 int oldIndex=0; 610 int oldIndex=0;
611 bool oldHadRepeat = old.hasRepeat(); 611 bool oldHadRepeat = old.hasRepeat();
612 Event orig; 612 Event orig;
613 613
614 // write to the journal... 614 // write to the journal...
615 if ( oldHadRepeat ) { 615 if ( oldHadRepeat ) {
616 if ( origRepeat( old, orig ) ) // should work always... 616 if ( origRepeat( old, orig ) ) // should work always...
617 oldIndex = repeatEvents.findIndex( orig ); 617 oldIndex = repeatEvents.findIndex( orig );
618 } else 618 } else
619 oldIndex = eventList.findIndex( old ); 619 oldIndex = eventList.findIndex( old );
620 saveJournalEntry( editedEv, ACTION_REPLACE, oldIndex, oldHadRepeat ); 620 saveJournalEntry( editedEv, ACTION_REPLACE, oldIndex, oldHadRepeat );
621 621
622 // Delete old event 622 // Delete old event
623 if ( old.hasAlarm() ) 623 if ( old.hasAlarm() )
624 delEventAlarm( old ); 624 delEventAlarm( old );
625 if ( oldHadRepeat ) { 625 if ( oldHadRepeat ) {
626 if ( editedEv.hasRepeat() ) { // This mean that origRepeat was run above and 626 if ( editedEv.hasRepeat() ) { // This mean that origRepeat was run above and
627 // orig is initialized 627 // orig is initialized
628 // assumption, when someone edits a repeating event, they 628 // assumption, when someone edits a repeating event, they
629 // want to change them all, maybe not perfect, but it works 629 // want to change them all, maybe not perfect, but it works
630 // for the moment... 630 // for the moment...
631 repeatEvents.remove( orig ); 631 repeatEvents.remove( orig );
632 } else 632 } else
633 removeRepeat( old ); 633 removeRepeat( old );
634 } else { 634 } else {
635 QValueList<Event>::Iterator it = eventList.find( old ); 635 QValueList<Event>::Iterator it = eventList.find( old );
636 if ( it != eventList.end() ) 636 if ( it != eventList.end() )
637 eventList.remove( it ); 637 eventList.remove( it );
638 } 638 }
639 639
640 // Add new event 640 // Add new event
641 if ( editedEv.hasAlarm() ) 641 if ( editedEv.hasAlarm() )
642 addEventAlarm( editedEv ); 642 addEventAlarm( editedEv );
643 if ( editedEv.hasRepeat() ) 643 if ( editedEv.hasRepeat() )
644 repeatEvents.append( editedEv ); 644 repeatEvents.append( editedEv );
645 else 645 else
646 eventList.append( editedEv ); 646 eventList.append( editedEv );
647 647
648 d->clean = false; 648 d->clean = false;
649} 649}
650 650
651void DateBookDB::removeEvent( const Event &ev ) 651void DateBookDB::removeEvent( const Event &ev )
652{ 652{
653 // write to the journal... 653 // write to the journal...
654 saveJournalEntry( ev, ACTION_REMOVE, -1, false ); 654 saveJournalEntry( ev, ACTION_REMOVE, -1, false );
655 removeJFEvent( ev ); 655 removeJFEvent( ev );
656 d->clean = false; 656 d->clean = false;
657} 657}
658 658
659void DateBookDB::removeJFEvent( const Event&ev ) 659void DateBookDB::removeJFEvent( const Event&ev )
660{ 660{
661 if ( ev.hasAlarm() ) 661 if ( ev.hasAlarm() )
662 delEventAlarm( ev ); 662 delEventAlarm( ev );
663 if ( ev.hasRepeat() ) { 663 if ( ev.hasRepeat() ) {
664 removeRepeat( ev ); 664 removeRepeat( ev );
665 } else { 665 } else {
666 QValueList<Event>::Iterator it = eventList.find( ev ); 666 QValueList<Event>::Iterator it = eventList.find( ev );
667 if ( it != eventList.end() ) 667 if ( it != eventList.end() )
668 eventList.remove( it ); 668 eventList.remove( it );
669 } 669 }
670} 670}
671 671
672// also handles journaling... 672// also handles journaling...
673void DateBookDB::loadFile( const QString &strFile ) 673void DateBookDB::loadFile( const QString &strFile )
674{ 674{
675 675
676 QFile f( strFile ); 676 QFile f( strFile );
677 if ( !f.open( IO_ReadOnly ) ) 677 if ( !f.open( IO_ReadOnly ) )
678 return; 678 return;
679 679
680 enum Attribute { 680 enum Attribute {
681 FDescription = 0, 681 FDescription = 0,
682 FLocation, 682 FLocation,
683 FCategories, 683 FCategories,
684 FUid, 684 FUid,
685 FType, 685 FType,
686 FAlarm, 686 FAlarm,
687 FSound, 687 FSound,
688 FRType, 688 FRType,
689 FRWeekdays, 689 FRWeekdays,
690 FRPosition, 690 FRPosition,
691 FRFreq, 691 FRFreq,
692 FRHasEndDate, 692 FRHasEndDate,
693 FREndDate, 693 FREndDate,
694 FRStart, 694 FRStart,
695 FREnd, 695 FREnd,
696 FNote, 696 FNote,
697 FCreated, 697 FCreated,
698 FAction, 698 FAction,
699 FActionKey, 699 FActionKey,
700 FJournalOrigHadRepeat 700 FJournalOrigHadRepeat
701 }; 701 };
702 702
703 QAsciiDict<int> dict( 97 ); 703 QAsciiDict<int> dict( 97 );
704 dict.setAutoDelete( TRUE ); 704 dict.setAutoDelete( TRUE );
705 dict.insert( "description", new int(FDescription) ); 705 dict.insert( "description", new int(FDescription) );
706 dict.insert( "location", new int(FLocation) ); 706 dict.insert( "location", new int(FLocation) );
707 dict.insert( "categories", new int(FCategories) ); 707 dict.insert( "categories", new int(FCategories) );
708 dict.insert( "uid", new int(FUid) ); 708 dict.insert( "uid", new int(FUid) );
709 dict.insert( "type", new int(FType) ); 709 dict.insert( "type", new int(FType) );
710 dict.insert( "alarm", new int(FAlarm) ); 710 dict.insert( "alarm", new int(FAlarm) );
711 dict.insert( "sound", new int(FSound) ); 711 dict.insert( "sound", new int(FSound) );
712 dict.insert( "rtype", new int(FRType) ); 712 dict.insert( "rtype", new int(FRType) );
713 dict.insert( "rweekdays", new int(FRWeekdays) ); 713 dict.insert( "rweekdays", new int(FRWeekdays) );
714 dict.insert( "rposition", new int(FRPosition) ); 714 dict.insert( "rposition", new int(FRPosition) );
715 dict.insert( "rfreq", new int(FRFreq) ); 715 dict.insert( "rfreq", new int(FRFreq) );
716 dict.insert( "rhasenddate", new int(FRHasEndDate) ); 716 dict.insert( "rhasenddate", new int(FRHasEndDate) );
717 dict.insert( "enddt", new int(FREndDate) ); 717 dict.insert( "enddt", new int(FREndDate) );
718 dict.insert( "start", new int(FRStart) ); 718 dict.insert( "start", new int(FRStart) );
719 dict.insert( "end", new int(FREnd) ); 719 dict.insert( "end", new int(FREnd) );
720 dict.insert( "note", new int(FNote) ); 720 dict.insert( "note", new int(FNote) );
721 dict.insert( "created", new int(FCreated) ); 721 dict.insert( "created", new int(FCreated) );
722 dict.insert( "action", new int(FAction) ); 722 dict.insert( "action", new int(FAction) );
723 dict.insert( "actionkey", new int(FActionKey) ); 723 dict.insert( "actionkey", new int(FActionKey) );
724 dict.insert( "actionorig", new int (FJournalOrigHadRepeat) ); 724 dict.insert( "actionorig", new int (FJournalOrigHadRepeat) );
725 725
726 726
727 QByteArray ba = f.readAll(); 727 QByteArray ba = f.readAll();
728 char* dt = ba.data(); 728 char* dt = ba.data();
729 int len = ba.size(); 729 int len = ba.size();
730 int currentAction, 730 int currentAction,
731 journalKey, 731 journalKey,
732 origHadRepeat; // should be bool, but we need tri-state(not being used) 732 origHadRepeat; // should be bool, but we need tri-state(not being used)
733 733
734 int i = 0; 734 int i = 0;
735 char *point; 735 char *point;
736 // hack to get rid of segfaults after reading </DATEBOOK> 736 // hack to get rid of segfaults after reading </DATEBOOK>
737 while ( (dt+i != 0) && (( point = strstr( dt+i, "<event " ) ) != 0 )) { 737 while ( (dt+i != 0) && (( point = strstr( dt+i, "<event " ) ) != 0 )) {
738 i = point - dt; 738 i = point - dt;
739 // if we are reading in events in the general case, 739 // if we are reading in events in the general case,
740 // we are just adding them, so let the actions represent that... 740 // we are just adding them, so let the actions represent that...
741 currentAction = ACTION_ADD; 741 currentAction = ACTION_ADD;
742 journalKey = -1; 742 journalKey = -1;
743 origHadRepeat = -1; 743 origHadRepeat = -1;
744 // some temporary variables for dates and times ... 744 // some temporary variables for dates and times ...
745 //int startY = 0, startM = 0, startD = 0, starth = 0, startm = 0, starts = 0; 745 //int startY = 0, startM = 0, startD = 0, starth = 0, startm = 0, starts = 0;
746 //int endY = 0, endM = 0, endD = 0, endh = 0, endm = 0, ends = 0; 746 //int endY = 0, endM = 0, endD = 0, endh = 0, endm = 0, ends = 0;
747 //int enddtY = 0, enddtM = 0, enddtD = 0; 747 //int enddtY = 0, enddtM = 0, enddtD = 0;
748 748
749 // ... for the alarm settings ... 749 // ... for the alarm settings ...
750 int alarmTime = -1; Event::SoundTypeChoice alarmSound = Event::Silent; 750 int alarmTime = -1; Event::SoundTypeChoice alarmSound = Event::Silent;
751 // ... and for the recurrence 751 // ... and for the recurrence
752 Event::RepeatPattern rp; 752 Event::RepeatPattern rp;
753 Event e; 753 Event e;
754 754
755 i += 7; 755 i += 7;
756 756
757 while( 1 ) { 757 while( 1 ) {
758 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 758 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
759 ++i; 759 ++i;
760 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 760 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
761 break; 761 break;
762 // we have another attribute, read it. 762 // we have another attribute, read it.
763 int j = i; 763 int j = i;
764 while ( j < len && dt[j] != '=' ) 764 while ( j < len && dt[j] != '=' )
765 ++j; 765 ++j;
766 char *attr = dt+i; 766 char *attr = dt+i;
767 dt[j] = '\0'; 767 dt[j] = '\0';
768 i = ++j; // skip = 768 i = ++j; // skip =
769 while ( i < len && dt[i] != '"' ) 769 while ( i < len && dt[i] != '"' )
770 ++i; 770 ++i;
771 j = ++i; 771 j = ++i;
772 bool haveAmp = FALSE; 772 bool haveAmp = FALSE;
773 bool haveUtf = FALSE; 773 bool haveUtf = FALSE;
774 while ( j < len && dt[j] != '"' ) { 774 while ( j < len && dt[j] != '"' ) {
775 if ( dt[j] == '&' ) 775 if ( dt[j] == '&' )
776 haveAmp = TRUE; 776 haveAmp = TRUE;
777 if ( ((unsigned char)dt[j]) > 0x7f ) 777 if ( ((unsigned char)dt[j]) > 0x7f )
778 haveUtf = TRUE; 778 haveUtf = TRUE;
779 ++j; 779 ++j;
780 } 780 }
781 781
782 if ( i == j ) { 782 if ( i == j ) {
783 // leave out empty attributes 783 // leave out empty attributes
784 i = j + 1; 784 i = j + 1;
785 continue; 785 continue;
786 } 786 }
787 787
788 QString value = haveUtf ? QString::fromUtf8( dt+i, j-i ) 788 QString value = haveUtf ? QString::fromUtf8( dt+i, j-i )
789 : QString::fromLatin1( dt+i, j-i ); 789 : QString::fromLatin1( dt+i, j-i );
790 if ( haveAmp ) 790 if ( haveAmp )
791 value = Qtopia::plainString( value ); 791 value = Qtopia::plainString( value );
792 i = j + 1; 792 i = j + 1;
793 793
794 //qDebug("attr='%s' value='%s'", attr.data(), value.latin1() ); 794 //qDebug("attr='%s' value='%s'", attr.data(), value.latin1() );
795 int * find = dict[ attr ]; 795 int * find = dict[ attr ];
796#if 1 796#if 1
797 if ( !find ) { 797 if ( !find ) {
798 // custom field 798 // custom field
799 e.setCustomField(attr, value); 799 e.setCustomField(attr, value);
800 continue; 800 continue;
801 } 801 }
802 802
803 switch( *find ) { 803 switch( *find ) {
804 case FDescription: 804 case FDescription:
805 e.setDescription( value ); 805 e.setDescription( value );
806 break; 806 break;
807 case FLocation: 807 case FLocation:
808 e.setLocation( value ); 808 e.setLocation( value );
809 break; 809 break;
810 case FCategories: 810 case FCategories:
811 e.setCategories( Qtopia::Record::idsFromString( value ) ); 811 e.setCategories( Qtopia::Record::idsFromString( value ) );
812 break; 812 break;
813 case FUid: 813 case FUid:
814 e.setUid( value.toInt() ); 814 e.setUid( value.toInt() );
815 break; 815 break;
816 case FType: 816 case FType:
817 if ( value == "AllDay" ) 817 if ( value == "AllDay" )
818 e.setType( Event::AllDay ); 818 e.setType( Event::AllDay );
819 else 819 else
820 e.setType( Event::Normal ); 820 e.setType( Event::Normal );
821 break; 821 break;
822 case FAlarm: 822 case FAlarm:
823 alarmTime = value.toInt(); 823 alarmTime = value.toInt();
824 break; 824 break;
825 case FSound: 825 case FSound:
826 alarmSound = value == "loud" ? Event::Loud : Event::Silent; 826 alarmSound = value == "loud" ? Event::Loud : Event::Silent;
827 break; 827 break;
828 // recurrence stuff 828 // recurrence stuff
829 case FRType: 829 case FRType:
830 if ( value == "Daily" ) 830 if ( value == "Daily" )
831 rp.type = Event::Daily; 831 rp.type = Event::Daily;
832 else if ( value == "Weekly" ) 832 else if ( value == "Weekly" )
833 rp.type = Event::Weekly; 833 rp.type = Event::Weekly;
834 else if ( value == "MonthlyDay" ) 834 else if ( value == "MonthlyDay" )
835 rp.type = Event::MonthlyDay; 835 rp.type = Event::MonthlyDay;
836 else if ( value == "MonthlyDate" ) 836 else if ( value == "MonthlyDate" )
837 rp.type = Event::MonthlyDate; 837 rp.type = Event::MonthlyDate;
838 else if ( value == "Yearly" ) 838 else if ( value == "Yearly" )
839 rp.type = Event::Yearly; 839 rp.type = Event::Yearly;
840 else 840 else
841 rp.type = Event::NoRepeat; 841 rp.type = Event::NoRepeat;
842 break; 842 break;
843 case FRWeekdays: 843 case FRWeekdays:
844 // QtopiaDesktop 1.6 sometimes creates 'rweekdays="0"' 844 // QtopiaDesktop 1.6 sometimes creates 'rweekdays="0"'
845 // when it goes mad. This causes datebook to crash.. (se) 845 // when it goes mad. This causes datebook to crash.. (se)
846 if ( value.toInt() != 0 ) 846 if ( value.toInt() != 0 )
847 rp.days = value.toInt(); 847 rp.days = value.toInt();
848 else 848 else
849 rp.days = 1; 849 rp.days = 1;
850 break; 850 break;
851 case FRPosition: 851 case FRPosition:
852 rp.position = value.toInt(); 852 rp.position = value.toInt();
853 break; 853 break;
854 case FRFreq: 854 case FRFreq:
855 rp.frequency = value.toInt(); 855 rp.frequency = value.toInt();
856 break; 856 break;
857 case FRHasEndDate: 857 case FRHasEndDate:
858 rp.hasEndDate = value.toInt(); 858 rp.hasEndDate = value.toInt();
859 break; 859 break;
860 case FREndDate: { 860 case FREndDate: {
861 rp.endDateUTC = (time_t) value.toLong(); 861 rp.endDateUTC = (time_t) value.toLong();
862 break; 862 break;
863 } 863 }
864 case FRStart: { 864 case FRStart: {
865 e.setStart( (time_t) value.toLong() ); 865 e.setStart( (time_t) value.toLong() );
866 break; 866 break;
867 } 867 }
868 case FREnd: { 868 case FREnd: {
869 e.setEnd( (time_t) value.toLong() ); 869 e.setEnd( (time_t) value.toLong() );
870 break; 870 break;
871 } 871 }
872 case FNote: 872 case FNote:
873 e.setNotes( value ); 873 e.setNotes( value );
874 break; 874 break;
875 case FCreated: 875 case FCreated:
876 rp.createTime = value.toInt(); 876 rp.createTime = value.toInt();
877 break; 877 break;
878 case FAction: 878 case FAction:
879 currentAction = value.toInt(); 879 currentAction = value.toInt();
880 break; 880 break;
881 case FActionKey: 881 case FActionKey:
882 journalKey = value.toInt(); 882 journalKey = value.toInt();
883 break; 883 break;
884 case FJournalOrigHadRepeat: 884 case FJournalOrigHadRepeat:
885 origHadRepeat = value.toInt(); 885 origHadRepeat = value.toInt();
886 break; 886 break;
887 default: 887 default:
888 qDebug( "huh??? missing enum? -- attr.: %s", attr ); 888 qDebug( "huh??? missing enum? -- attr.: %s", attr );
889 break; 889 break;
890 } 890 }
891#endif 891#endif
892 } 892 }
893 // "post processing" (dates, times, alarm, recurrence) 893 // "post processing" (dates, times, alarm, recurrence)
894 // start date/time 894 // start date/time
895 e.setRepeat( rp.type != Event::NoRepeat, rp ); 895 e.setRepeat( rp.type != Event::NoRepeat, rp );
896 896
897 if ( alarmTime != -1 ) 897 if ( alarmTime != -1 )
898 e.setAlarm( TRUE, alarmTime, alarmSound ); 898 e.setAlarm( TRUE, alarmTime, alarmSound );
899 899
900 // now do our action based on the current action... 900 // now do our action based on the current action...
901 switch ( currentAction ) { 901 switch ( currentAction ) {
902 case ACTION_ADD: 902 case ACTION_ADD:
903 addJFEvent( e ); 903 addJFEvent( e );
904 break; 904 break;
905 case ACTION_REMOVE: 905 case ACTION_REMOVE:
906 removeJFEvent( e ); 906 removeJFEvent( e );
907 break; 907 break;
908 case ACTION_REPLACE: 908 case ACTION_REPLACE:
909 // be a little bit careful, 909 // be a little bit careful,
910 // in case of a messed up journal... 910 // in case of a messed up journal...
911 if ( journalKey > -1 && origHadRepeat > -1 ) { 911 if ( journalKey > -1 && origHadRepeat > -1 ) {
912 // get the original from proper list... 912 // get the original from proper list...
913 if ( origHadRepeat ) 913 if ( origHadRepeat )
914 removeJFEvent( *(repeatEvents.at(journalKey)) ); 914 removeJFEvent( *(repeatEvents.at(journalKey)) );
915 else 915 else
916 removeJFEvent( *(eventList.at(journalKey)) ); 916 removeJFEvent( *(eventList.at(journalKey)) );
917 addJFEvent( e ); 917 addJFEvent( e );
918 } 918 }
919 break; 919 break;
920 default: 920 default:
921 break; 921 break;
922 } 922 }
923 } 923 }
924 f.close(); 924 f.close();
925} 925}
926 926
927void DateBookDB::init() 927void DateBookDB::init()
928{ 928{
929 d = new DateBookDBPrivate; 929 d = new DateBookDBPrivate;
930 d->clean = false; 930 d->clean = false;
931 QString str = dateBookFilename(); 931 QString str = dateBookFilename();
932 if ( str.isNull() ) { 932 if ( str.isNull() ) {
933 QMessageBox::warning( 0, QObject::tr("Out of Space"), 933 QMessageBox::warning( 0, QObject::tr("Out of Space"),
934 QObject::tr("Unable to create start up files\n" 934 QObject::tr("Unable to create start up files\n"
935 "Please free up some space\n" 935 "Please free up some space\n"
936 "before entering data") ); 936 "before entering data") );
937 } 937 }
938 // continuing along, we call this datebook filename again, 938 // continuing along, we call this datebook filename again,
939 // because they may fix it before continuing, though it seems 939 // because they may fix it before continuing, though it seems
940 // pretty unlikely... 940 // pretty unlikely...
941 loadFile( dateBookFilename() ); 941 loadFile( dateBookFilename() );
942 942
943 if ( QFile::exists( dateBookJournalFile() ) ) { 943 if ( QFile::exists( dateBookJournalFile() ) ) {
944 // merge the journal 944 // merge the journal
945 loadFile( dateBookJournalFile() ); 945 loadFile( dateBookJournalFile() );
946 // save in our changes and remove the journal... 946 // save in our changes and remove the journal...
947 save(); 947 save();
948 } 948 }
949 d->clean = true; 949 d->clean = true;
950} 950}
951 951
952bool DateBookDB::save() 952bool DateBookDB::save()
953{ 953{
954 if ( d->clean == true ) 954 if ( d->clean == true )
955 return true; 955 return true;
956 QValueListIterator<Event> it; 956 QValueListIterator<Event> it;
957 int total_written; 957 int total_written;
958 QString strFileNew = dateBookFilename() + ".new"; 958 QString strFileNew = dateBookFilename() + ".new";
959 959
960 QFile f( strFileNew ); 960 QFile f( strFileNew );
961 if ( !f.open( IO_WriteOnly|IO_Raw ) ) 961 if ( !f.open( IO_WriteOnly|IO_Raw ) )
962 return FALSE; 962 return FALSE;
963 963
964 QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); 964 QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
965 buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n"; 965 buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n";
966 buf += "<events>\n"; 966 buf += "<events>\n";
967 QCString str = buf.utf8(); 967 QCString str = buf.utf8();
968 total_written = f.writeBlock( str.data(), str.length() ); 968 total_written = f.writeBlock( str.data(), str.length() );
969 if ( total_written != int(str.length()) ) { 969 if ( total_written != int(str.length()) ) {
970 f.close(); 970 f.close();
971 QFile::remove( strFileNew ); 971 QFile::remove( strFileNew );
972 return false; 972 return false;
973 } 973 }
974 974
975 for ( it = eventList.begin(); it != eventList.end(); ++it ) { 975 for ( it = eventList.begin(); it != eventList.end(); ++it ) {
976 buf = "<event"; 976 buf = "<event";
977 (*it).save( buf ); 977 (*it).save( buf );
978 buf += " />\n"; 978 buf += " />\n";
979 str = buf.utf8(); 979 str = buf.utf8();
980 total_written = f.writeBlock( str.data(), str.length() ); 980 total_written = f.writeBlock( str.data(), str.length() );
981 if ( total_written != int(str.length()) ) { 981 if ( total_written != int(str.length()) ) {
982 f.close(); 982 f.close();
diff --git a/library/finddialog.cpp b/library/finddialog.cpp
index d9f430a..ddf41a7 100644
--- a/library/finddialog.cpp
+++ b/library/finddialog.cpp
@@ -1,78 +1,85 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 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** 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// WARNING: Do *NOT* define this yourself. The SL5xxx from SHARP does NOT 21// WARNING: Do *NOT* define this yourself. The SL5xxx from SHARP does NOT
22// have this class. 22// have this class.
23#define QTOPIA_INTERNAL_FD 23#define QTOPIA_INTERNAL_FD
24 24
25#include "finddialog.h" 25#include "finddialog.h"
26#include "findwidget_p.h" 26#include "findwidget_p.h"
27 27
28#include <qlayout.h> 28#include <qlayout.h>
29#include <qpushbutton.h> 29#include <qpushbutton.h>
30 30
31/*!
32 \class FindDialog finddialog.h
33 \brief A simple FindDialog
34
35 A find dialog. FIXME!!!!
36
37*/
31FindDialog::FindDialog( const QString &appName, QWidget *parent, 38FindDialog::FindDialog( const QString &appName, QWidget *parent,
32 const char *name, bool modal ) 39 const char *name, bool modal )
33 : QDialog( parent, name, modal ) 40 : QDialog( parent, name, modal )
34{ 41{
35 setCaption( tr("Find") ); 42 setCaption( tr("Find") );
36 QVBoxLayout *vb; 43 QVBoxLayout *vb;
37 vb = new QVBoxLayout( this ); 44 vb = new QVBoxLayout( this );
38 fw = new FindWidget( appName, this, "Find Widget" ); 45 fw = new FindWidget( appName, this, "Find Widget" );
39 vb->addWidget( fw ); 46 vb->addWidget( fw );
40 QObject::connect( fw, SIGNAL(signalFindClicked(const QString&, 47 QObject::connect( fw, SIGNAL(signalFindClicked(const QString&,
41 bool,bool,int)), 48 bool,bool,int)),
42 this, SIGNAL(signalFindClicked(const QString&, 49 this, SIGNAL(signalFindClicked(const QString&,
43 bool,bool,int)) ); 50 bool,bool,int)) );
44 QObject::connect( fw, SIGNAL(signalFindClicked(const QString&,const QDate&, 51 QObject::connect( fw, SIGNAL(signalFindClicked(const QString&,const QDate&,
45 bool,bool,int)), 52 bool,bool,int)),
46 this, SIGNAL(signalFindClicked(const QString&, 53 this, SIGNAL(signalFindClicked(const QString&,
47 const QDate&,bool,bool,int)) ); 54 const QDate&,bool,bool,int)) );
48 d = 0; 55 d = 0;
49} 56}
50 57
51FindDialog::~FindDialog() 58FindDialog::~FindDialog()
52{ 59{
53} 60}
54 61
55QString FindDialog::findText() const 62QString FindDialog::findText() const
56{ 63{
57 return fw->findText(); 64 return fw->findText();
58} 65}
59 66
60void FindDialog::setUseDate( bool show ) 67void FindDialog::setUseDate( bool show )
61{ 68{
62 fw->setUseDate( show ); 69 fw->setUseDate( show );
63} 70}
64 71
65void FindDialog::setDate( const QDate &dt ) 72void FindDialog::setDate( const QDate &dt )
66{ 73{
67 fw->setDate( dt ); 74 fw->setDate( dt );
68} 75}
69 76
70void FindDialog::slotNotFound() 77void FindDialog::slotNotFound()
71{ 78{
72 fw->slotNotFound(); 79 fw->slotNotFound();
73} 80}
74 81
75void FindDialog::slotWrapAround() 82void FindDialog::slotWrapAround()
76{ 83{
77 fw->slotWrapAround(); 84 fw->slotWrapAround();
78} 85}
diff --git a/library/global.cpp b/library/global.cpp
index 68a3a75..ce39751 100644
--- a/library/global.cpp
+++ b/library/global.cpp
@@ -1,849 +1,849 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 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** 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#define QTOPIA_INTERNAL_LANGLIST 20#define QTOPIA_INTERNAL_LANGLIST
21#include <qpe/qpedebug.h> 21#include <qpe/qpedebug.h>
22#include <qpe/global.h> 22#include <qpe/global.h>
23#include <qpe/qdawg.h> 23#include <qpe/qdawg.h>
24#include <qpe/qpeapplication.h> 24#include <qpe/qpeapplication.h>
25#include <qpe/resource.h> 25#include <qpe/resource.h>
26#include <qpe/storage.h> 26#include <qpe/storage.h>
27#include <qpe/applnk.h> 27#include <qpe/applnk.h>
28#include <qpe/qcopenvelope_qws.h> 28#include <qpe/qcopenvelope_qws.h>
29 29
30#include <qfile.h> 30#include <qfile.h>
31#include <qlabel.h> 31#include <qlabel.h>
32#include <qtimer.h> 32#include <qtimer.h>
33#include <qmap.h> 33#include <qmap.h>
34#include <qdict.h> 34#include <qdict.h>
35#include <qdir.h> 35#include <qdir.h>
36#include <qmessagebox.h> 36#include <qmessagebox.h>
37#include <qregexp.h> 37#include <qregexp.h>
38 38
39#include <stdlib.h> 39#include <stdlib.h>
40#include <sys/stat.h> 40#include <sys/stat.h>
41#include <sys/wait.h> 41#include <sys/wait.h>
42#include <sys/types.h> 42#include <sys/types.h>
43#include <fcntl.h> 43#include <fcntl.h>
44#include <unistd.h> 44#include <unistd.h>
45#include <errno.h> 45#include <errno.h>
46 46
47#include <qwindowsystem_qws.h> // for qwsServer 47#include <qwindowsystem_qws.h> // for qwsServer
48#include <qdatetime.h> 48#include <qdatetime.h>
49 49
50#include <qfile.h> 50#include <qfile.h>
51 51
52namespace { 52namespace {
53 // checks if the storage should be searched 53 // checks if the storage should be searched
54 bool checkStorage(const QString &path ){ // this is a small Config replacement cause config is too limited -zecke 54 bool checkStorage(const QString &path ){ // this is a small Config replacement cause config is too limited -zecke
55 QFile file(path ); 55 QFile file(path );
56 if(!file.open(IO_ReadOnly ) ) 56 if(!file.open(IO_ReadOnly ) )
57 return true; 57 return true;
58 58
59 QByteArray array = file.readAll(); 59 QByteArray array = file.readAll();
60 QStringList list = QStringList::split('\n', QString( array ) ); 60 QStringList list = QStringList::split('\n', QString( array ) );
61 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it ){ 61 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it ){
62 if( (*it).startsWith("autocheck = 0" ) ){ 62 if( (*it).startsWith("autocheck = 0" ) ){
63 return false; 63 return false;
64 }else if( (*it).startsWith("autocheck = 1" ) ){ 64 }else if( (*it).startsWith("autocheck = 1" ) ){
65 return true; 65 return true;
66 } 66 }
67 } 67 }
68 return true; 68 return true;
69 } 69 }
70} 70}
71 71
72//#include "quickexec_p.h" 72//#include "quickexec_p.h"
73 73
74class Emitter : public QObject { 74class Emitter : public QObject {
75 Q_OBJECT 75 Q_OBJECT
76public: 76public:
77 Emitter( QWidget* receiver, const QString& document ) 77 Emitter( QWidget* receiver, const QString& document )
78 { 78 {
79 connect(this, SIGNAL(setDocument(const QString&)), 79 connect(this, SIGNAL(setDocument(const QString&)),
80 receiver, SLOT(setDocument(const QString&))); 80 receiver, SLOT(setDocument(const QString&)));
81 emit setDocument(document); 81 emit setDocument(document);
82 disconnect(this, SIGNAL(setDocument(const QString&)), 82 disconnect(this, SIGNAL(setDocument(const QString&)),
83 receiver, SLOT(setDocument(const QString&))); 83 receiver, SLOT(setDocument(const QString&)));
84 } 84 }
85 85
86signals: 86signals:
87 void setDocument(const QString&); 87 void setDocument(const QString&);
88}; 88};
89 89
90 90
91class StartingAppList : public QObject { 91class StartingAppList : public QObject {
92 Q_OBJECT 92 Q_OBJECT
93public: 93public:
94 static void add( const QString& name ); 94 static void add( const QString& name );
95 static bool isStarting( const QString name ); 95 static bool isStarting( const QString name );
96private slots: 96private slots:
97 void handleNewChannel( const QString &); 97 void handleNewChannel( const QString &);
98private: 98private:
99 StartingAppList( QObject *parent=0, const char* name=0 ) ; 99 StartingAppList( QObject *parent=0, const char* name=0 ) ;
100 100
101 QDict<QTime> dict; 101 QDict<QTime> dict;
102 static StartingAppList *appl; 102 static StartingAppList *appl;
103}; 103};
104 104
105StartingAppList* StartingAppList::appl = 0; 105StartingAppList* StartingAppList::appl = 0;
106 106
107StartingAppList::StartingAppList( QObject *parent, const char* name ) 107StartingAppList::StartingAppList( QObject *parent, const char* name )
108 :QObject( parent, name ) 108 :QObject( parent, name )
109{ 109{
110#if QT_VERSION >= 232 && defined(QWS) 110#if QT_VERSION >= 232 && defined(QWS)
111 connect( qwsServer, SIGNAL( newChannel(const QString&)), 111 connect( qwsServer, SIGNAL( newChannel(const QString&)),
112 this, SLOT( handleNewChannel(const QString&)) ); 112 this, SLOT( handleNewChannel(const QString&)) );
113 #endif 113#endif
114 dict.setAutoDelete( TRUE ); 114 dict.setAutoDelete( TRUE );
115} 115}
116 116
117void StartingAppList::add( const QString& name ) 117void StartingAppList::add( const QString& name )
118{ 118{
119#if QT_VERSION >= 232 && !defined(QT_NO_COP) 119#if QT_VERSION >= 232 && !defined(QT_NO_COP)
120 if ( !appl ) 120 if ( !appl )
121 appl = new StartingAppList; 121 appl = new StartingAppList;
122 QTime *t = new QTime; 122 QTime *t = new QTime;
123 t->start(); 123 t->start();
124 appl->dict.insert( "QPE/Application/" + name, t ); 124 appl->dict.insert( "QPE/Application/" + name, t );
125#endif 125#endif
126} 126}
127 127
128bool StartingAppList::isStarting( const QString name ) 128bool StartingAppList::isStarting( const QString name )
129{ 129{
130#if QT_VERSION >= 232 && !defined(QT_NO_COP) 130#if QT_VERSION >= 232 && !defined(QT_NO_COP)
131 if ( appl ) { 131 if ( appl ) {
132 QTime *t = appl->dict.find( "QPE/Application/" + name ); 132 QTime *t = appl->dict.find( "QPE/Application/" + name );
133 if ( !t ) 133 if ( !t )
134 return FALSE; 134 return FALSE;
135 if ( t->elapsed() > 10000 ) { 135 if ( t->elapsed() > 10000 ) {
136 // timeout in case of crash or something 136 // timeout in case of crash or something
137 appl->dict.remove( "QPE/Application/" + name ); 137 appl->dict.remove( "QPE/Application/" + name );
138 return FALSE; 138 return FALSE;
139 } 139 }
140 return TRUE; 140 return TRUE;
141 } 141 }
142#endif 142#endif
143 return FALSE; 143 return FALSE;
144} 144}
145 145
146void StartingAppList::handleNewChannel( const QString & name ) 146void StartingAppList::handleNewChannel( const QString & name )
147{ 147{
148#if QT_VERSION >= 232 && !defined(QT_NO_COP) 148#if QT_VERSION >= 232 && !defined(QT_NO_COP)
149 dict.remove( name ); 149 dict.remove( name );
150#endif 150#endif
151} 151}
152 152
153static bool docDirCreated = FALSE; 153static bool docDirCreated = FALSE;
154static QDawg* fixed_dawg = 0; 154static QDawg* fixed_dawg = 0;
155static QDict<QDawg> *named_dawg = 0; 155static QDict<QDawg> *named_dawg = 0;
156 156
157static QString qpeDir() 157static QString qpeDir()
158{ 158{
159 QString dir = getenv("OPIEDIR"); 159 QString dir = getenv("OPIEDIR");
160 if ( dir.isEmpty() ) dir = ".."; 160 if ( dir.isEmpty() ) dir = "..";
161 return dir; 161 return dir;
162} 162}
163 163
164static QString dictDir() 164static QString dictDir()
165{ 165{
166 return qpeDir() + "/etc/dict"; 166 return qpeDir() + "/etc/dict";
167} 167}
168 168
169/*! 169/*!
170 \class Global global.h 170 \class Global global.h
171 \brief The Global class provides application-wide global functions. 171 \brief The Global class provides application-wide global functions.
172 172
173 The Global functions are grouped as follows: 173 The Global functions are grouped as follows:
174 \tableofcontents 174 \tableofcontents
175 175
176 \section1 User Interface 176 \section1 User Interface
177 177
178 The statusMessage() function provides short-duration messages to the 178 The statusMessage() function provides short-duration messages to the
179 user. The showInputMethod() function shows the current input method, 179 user. The showInputMethod() function shows the current input method,
180 and hideInputMethod() hides the input method. 180 and hideInputMethod() hides the input method.
181 181
182 \section1 Document related 182 \section1 Document related
183 183
184 The findDocuments() function creates a set of \link doclnk.html 184 The findDocuments() function creates a set of \link doclnk.html
185 DocLnk\endlink objects in a particular folder. 185 DocLnk\endlink objects in a particular folder.
186 186
187 \section1 Filesystem related 187 \section1 Filesystem related
188 188
189 Global provides an applicationFileName() function that returns the 189 Global provides an applicationFileName() function that returns the
190 full path of an application-specific file. 190 full path of an application-specific file.
191 191
192 The execute() function runs an application. 192 The execute() function runs an application.
193 193
194 \section1 Word list related 194 \section1 Word list related
195 195
196 A list of words relevant to the current locale is maintained by the 196 A list of words relevant to the current locale is maintained by the
197 system. The list is held in a \link qdawg.html DAWG\endlink 197 system. The list is held in a \link qdawg.html DAWG\endlink
198 (implemented by the QDawg class). This list is used, for example, by 198 (implemented by the QDawg class). This list is used, for example, by
199 the pickboard input method. 199 the pickboard input method.
200 200
201 The global QDawg is returned by fixedDawg(); this cannot be updated. 201 The global QDawg is returned by fixedDawg(); this cannot be updated.
202 An updatable copy of the global QDawg is returned by addedDawg(). 202 An updatable copy of the global QDawg is returned by addedDawg().
203 Applications may have their own word lists stored in \l{QDawg}s 203 Applications may have their own word lists stored in \l{QDawg}s
204 which are returned by dawg(). Use addWords() to add words to the 204 which are returned by dawg(). Use addWords() to add words to the
205 updateable copy of the global QDawg or to named application 205 updateable copy of the global QDawg or to named application
206 \l{QDawg}s. 206 \l{QDawg}s.
207 207
208 \section1 Quoting 208 \section1 Quoting
209 209
210 The shellQuote() function quotes a string suitable for passing to a 210 The shellQuote() function quotes a string suitable for passing to a
211 shell. The stringQuote() function backslash escapes '\' and '"' 211 shell. The stringQuote() function backslash escapes '\' and '"'
212 characters. 212 characters.
213 213
214 \section1 Hardware 214 \section1 Hardware
215 215
216 The writeHWClock() function sets the hardware clock to the system 216 The writeHWClock() function sets the hardware clock to the system
217 clock's date and time. 217 clock's date and time.
218 218
219 \ingroup qtopiaemb 219 \ingroup qtopiaemb
220*/ 220*/
221 221
222/*! 222/*!
223 \internal 223 \internal
224*/ 224*/
225Global::Global() 225Global::Global()
226{ 226{
227} 227}
228 228
229/*! 229/*!
230 Returns the unchangeable QDawg that contains general 230 Returns the unchangeable QDawg that contains general
231 words for the current locale. 231 words for the current locale.
232 232
233 \sa addedDawg() 233 \sa addedDawg()
234*/ 234*/
235const QDawg& Global::fixedDawg() 235const QDawg& Global::fixedDawg()
236{ 236{
237 if ( !fixed_dawg ) { 237 if ( !fixed_dawg ) {
238 if ( !docDirCreated ) 238 if ( !docDirCreated )
239 createDocDir(); 239 createDocDir();
240 240
241 fixed_dawg = new QDawg; 241 fixed_dawg = new QDawg;
242 QString dawgfilename = dictDir() + "/dawg"; 242 QString dawgfilename = dictDir() + "/dawg";
243 QString words_lang; 243 QString words_lang;
244 QStringList langs = Global::languageList(); 244 QStringList langs = Global::languageList();
245 for (QStringList::ConstIterator it = langs.begin(); it!=langs.end(); ++it) { 245 for (QStringList::ConstIterator it = langs.begin(); it!=langs.end(); ++it) {
246 QString lang = *it; 246 QString lang = *it;
247 words_lang = dictDir() + "/words." + lang; 247 words_lang = dictDir() + "/words." + lang;
248 QString dawgfilename_lang = dawgfilename + "." + lang; 248 QString dawgfilename_lang = dawgfilename + "." + lang;
249 if ( QFile::exists(dawgfilename_lang) || 249 if ( QFile::exists(dawgfilename_lang) ||
250 QFile::exists(words_lang) ) { 250 QFile::exists(words_lang) ) {
251 dawgfilename = dawgfilename_lang; 251 dawgfilename = dawgfilename_lang;
252 break; 252 break;
253 } 253 }
254 } 254 }
255 QFile dawgfile(dawgfilename); 255 QFile dawgfile(dawgfilename);
256 256
257 if ( !dawgfile.exists() ) { 257 if ( !dawgfile.exists() ) {
258 QString fn = dictDir() + "/words"; 258 QString fn = dictDir() + "/words";
259 if ( QFile::exists(words_lang) ) 259 if ( QFile::exists(words_lang) )
260 fn = words_lang; 260 fn = words_lang;
261 QFile in(fn); 261 QFile in(fn);
262 if ( in.open(IO_ReadOnly) ) { 262 if ( in.open(IO_ReadOnly) ) {
263 fixed_dawg->createFromWords(&in); 263 fixed_dawg->createFromWords(&in);
264 dawgfile.open(IO_WriteOnly); 264 dawgfile.open(IO_WriteOnly);
265 fixed_dawg->write(&dawgfile); 265 fixed_dawg->write(&dawgfile);
266 dawgfile.close(); 266 dawgfile.close();
267 } 267 }
268 } else { 268 } else {
269 fixed_dawg->readFile(dawgfilename); 269 fixed_dawg->readFile(dawgfilename);
270 } 270 }
271 } 271 }
272 272
273 return *fixed_dawg; 273 return *fixed_dawg;
274} 274}
275 275
276/*! 276/*!
277 Returns the changeable QDawg that contains general 277 Returns the changeable QDawg that contains general
278 words for the current locale. 278 words for the current locale.
279 279
280 \sa fixedDawg() 280 \sa fixedDawg()
281*/ 281*/
282const QDawg& Global::addedDawg() 282const QDawg& Global::addedDawg()
283{ 283{
284 return dawg("local"); 284 return dawg("local");
285} 285}
286 286
287/*! 287/*!
288 Returns the QDawg with the given \a name. 288 Returns the QDawg with the given \a name.
289 This is an application-specific word list. 289 This is an application-specific word list.
290 290
291 \a name should not contain "/". 291 \a name should not contain "/".
292*/ 292*/
293const QDawg& Global::dawg(const QString& name) 293const QDawg& Global::dawg(const QString& name)
294{ 294{
295 createDocDir(); 295 createDocDir();
296 if ( !named_dawg ) 296 if ( !named_dawg )
297 named_dawg = new QDict<QDawg>; 297 named_dawg = new QDict<QDawg>;
298 QDawg* r = named_dawg->find(name); 298 QDawg* r = named_dawg->find(name);
299 if ( !r ) { 299 if ( !r ) {
300 r = new QDawg; 300 r = new QDawg;
301 named_dawg->insert(name,r); 301 named_dawg->insert(name,r);
302 QString dawgfilename = applicationFileName("Dictionary", name ) + ".dawg"; 302 QString dawgfilename = applicationFileName("Dictionary", name ) + ".dawg";
303 QFile dawgfile(dawgfilename); 303 QFile dawgfile(dawgfilename);
304 if ( dawgfile.open(IO_ReadOnly) ) 304 if ( dawgfile.open(IO_ReadOnly) )
305 r->readFile(dawgfilename); 305 r->readFile(dawgfilename);
306 } 306 }
307 return *r; 307 return *r;
308} 308}
309 309
310/*! 310/*!
311 \overload 311 \overload
312 Adds \a wordlist to the addedDawg(). 312 Adds \a wordlist to the addedDawg().
313 313
314 Note that the addition of words persists between program executions 314 Note that the addition of words persists between program executions
315 (they are saved in the dictionary files), so you should confirm the 315 (they are saved in the dictionary files), so you should confirm the
316 words with the user before adding them. 316 words with the user before adding them.
317*/ 317*/
318void Global::addWords(const QStringList& wordlist) 318void Global::addWords(const QStringList& wordlist)
319{ 319{
320 addWords("local",wordlist); 320 addWords("local",wordlist);
321} 321}
322 322
323/*! 323/*!
324 \overload 324 \overload
325 Adds \a wordlist to the addedDawg(). 325 Adds \a wordlist to the addedDawg().
326 326
327 Note that the addition of words persists between program executions 327 Note that the addition of words persists between program executions
328 (they are saved in the dictionary files), so you should confirm the 328 (they are saved in the dictionary files), so you should confirm the
329 words with the user before adding them. 329 words with the user before adding them.
330*/ 330*/
331void Global::addWords(const QString& dictname, const QStringList& wordlist) 331void Global::addWords(const QString& dictname, const QStringList& wordlist)
332{ 332{
333 QDawg& d = (QDawg&)dawg(dictname); 333 QDawg& d = (QDawg&)dawg(dictname);
334 QStringList all = d.allWords() + wordlist; 334 QStringList all = d.allWords() + wordlist;
335 d.createFromWords(all); 335 d.createFromWords(all);
336 336
337 QString dawgfilename = applicationFileName("Dictionary", dictname) + ".dawg"; 337 QString dawgfilename = applicationFileName("Dictionary", dictname) + ".dawg";
338 QFile dawgfile(dawgfilename); 338 QFile dawgfile(dawgfilename);
339 if ( dawgfile.open(IO_WriteOnly) ) { 339 if ( dawgfile.open(IO_WriteOnly) ) {
340 d.write(&dawgfile); 340 d.write(&dawgfile);
341 dawgfile.close(); 341 dawgfile.close();
342 } 342 }
343 343
344 // #### Re-read the dawg here if we use mmap(). 344 // #### Re-read the dawg here if we use mmap().
345 345
346 // #### Signal other processes to re-read. 346 // #### Signal other processes to re-read.
347} 347}
348 348
349 349
350/*! 350/*!
351 Returns the full path for the application called \a appname, with the 351 Returns the full path for the application called \a appname, with the
352 given \a filename. Returns QString::null if there was a problem creating 352 given \a filename. Returns QString::null if there was a problem creating
353 the directory tree for \a appname. 353 the directory tree for \a appname.
354 If \a filename contains "/", it is the caller's responsibility to 354 If \a filename contains "/", it is the caller's responsibility to
355 ensure that those directories exist. 355 ensure that those directories exist.
356*/ 356*/
357QString Global::applicationFileName(const QString& appname, const QString& filename) 357QString Global::applicationFileName(const QString& appname, const QString& filename)
358{ 358{
359 QDir d; 359 QDir d;
360 QString r = getenv("HOME"); 360 QString r = getenv("HOME");
361 r += "/Applications/"; 361 r += "/Applications/";
362 if ( !QFile::exists( r ) ) 362 if ( !QFile::exists( r ) )
363 if ( d.mkdir(r) == false ) 363 if ( d.mkdir(r) == false )
364 return QString::null; 364 return QString::null;
365 r += appname; 365 r += appname;
366 if ( !QFile::exists( r ) ) 366 if ( !QFile::exists( r ) )
367 if ( d.mkdir(r) == false ) 367 if ( d.mkdir(r) == false )
368 return QString::null; 368 return QString::null;
369 r += "/"; r += filename; 369 r += "/"; r += filename;
370 return r; 370 return r;
371} 371}
372 372
373/*! 373/*!
374 \internal 374 \internal
375*/ 375*/
376void Global::createDocDir() 376void Global::createDocDir()
377{ 377{
378 if ( !docDirCreated ) { 378 if ( !docDirCreated ) {
379 docDirCreated = TRUE; 379 docDirCreated = TRUE;
380 mkdir( QPEApplication::documentDir().latin1(), 0755 ); 380 mkdir( QPEApplication::documentDir().latin1(), 0755 );
381 } 381 }
382} 382}
383 383
384 384
385/*! 385/*!
386 Displays a status \a message to the user. This usually appears 386 Displays a status \a message to the user. This usually appears
387 in the taskbar for a short amount of time, then disappears. 387 in the taskbar for a short amount of time, then disappears.
388*/ 388*/
389void Global::statusMessage(const QString& message) 389void Global::statusMessage(const QString& message)
390{ 390{
391#if!defined(QT_NO_COP) 391#if !defined(QT_NO_COP)
392 QCopEnvelope e( "QPE/TaskBar", "message(QString)" ); 392 QCopEnvelope e( "QPE/TaskBar", "message(QString)" );
393 e << message; 393 e << message;
394#endif 394#endif
395} 395}
396 396
397/*! 397/*!
398 \internal 398 \internal
399*/ 399*/
400void Global::applyStyle() 400void Global::applyStyle()
401{ 401{
402#if !defined(QT_NO_COP) 402#if !defined(QT_NO_COP)
403 QCopChannel::send( "QPE/System", "applyStyle()" ); 403 QCopChannel::send( "QPE/System", "applyStyle()" );
404#else 404#else
405 ((QPEApplication *)qApp)->applyStyle(); // apply without needing QCop for floppy version 405 ((QPEApplication *)qApp)->applyStyle(); // apply without needing QCop for floppy version
406#endif 406#endif
407} 407}
408 408
409/*! 409/*!
410 \internal 410 \internal
411*/ 411*/
412QWidget *Global::shutdown( bool ) 412QWidget *Global::shutdown( bool )
413{ 413{
414#if !defined(QT_NO_COP) 414#if !defined(QT_NO_COP)
415 QCopChannel::send( "QPE/System", "shutdown()" ); 415 QCopChannel::send( "QPE/System", "shutdown()" );
416#endif 416#endif
417 return 0; 417 return 0;
418} 418}
419 419
420/*! 420/*!
421 \internal 421 \internal
422*/ 422*/
423QWidget *Global::restart( bool ) 423QWidget *Global::restart( bool )
424{ 424{
425#if !defined(QT_NO_COP) 425#if !defined(QT_NO_COP)
426 QCopChannel::send( "QPE/System", "restart()" ); 426 QCopChannel::send( "QPE/System", "restart()" );
427#endif 427#endif
428 return 0; 428 return 0;
429} 429}
430 430
431/*! 431/*!
432 Explicitly show the current input method. 432 Explicitly show the current input method.
433 433
434 Input methods are indicated in the taskbar by a small icon. If the 434 Input methods are indicated in the taskbar by a small icon. If the
435 input method is activated (shown) then it takes up some proportion 435 input method is activated (shown) then it takes up some proportion
436 of the bottom of the screen, to allow the user to interact (input 436 of the bottom of the screen, to allow the user to interact (input
437 characters) with it. 437 characters) with it.
438 438
439 \sa hideInputMethod() 439 \sa hideInputMethod()
440*/ 440*/
441void Global::showInputMethod() 441void Global::showInputMethod()
442{ 442{
443#if !defined(QT_NO_COP) 443#if !defined(QT_NO_COP)
444 QCopChannel::send( "QPE/TaskBar", "showInputMethod()" ); 444 QCopChannel::send( "QPE/TaskBar", "showInputMethod()" );
445#endif 445#endif
446} 446}
447 447
448/*! 448/*!
449 Explicitly hide the current input method. 449 Explicitly hide the current input method.
450 450
451 The current input method is still indicated in the taskbar, but no 451 The current input method is still indicated in the taskbar, but no
452 longer takes up screen space, and can no longer be interacted with. 452 longer takes up screen space, and can no longer be interacted with.
453 453
454 \sa showInputMethod() 454 \sa showInputMethod()
455*/ 455*/
456void Global::hideInputMethod() 456void Global::hideInputMethod()
457{ 457{
458#if !defined(QT_NO_COP) 458#if !defined(QT_NO_COP)
459 QCopChannel::send( "QPE/TaskBar", "hideInputMethod()" ); 459 QCopChannel::send( "QPE/TaskBar", "hideInputMethod()" );
460#endif 460#endif
461} 461}
462 462
463 463
464/*! 464/*!
465 \internal 465 \internal
466*/ 466*/
467bool Global::isBuiltinCommand( const QString &name ) 467bool Global::isBuiltinCommand( const QString &name )
468{ 468{
469 if(!builtin) 469 if(!builtin)
470 return FALSE; // yes, it can happen 470 return FALSE; // yes, it can happen
471 for (int i = 0; builtin[i].file; i++) { 471 for (int i = 0; builtin[i].file; i++) {
472 if ( builtin[i].file == name ) { 472 if ( builtin[i].file == name ) {
473 return TRUE; 473 return TRUE;
474 } 474 }
475 } 475 }
476 return FALSE; 476 return FALSE;
477} 477}
478 478
479Global::Command* Global::builtin=0; 479Global::Command* Global::builtin=0;
480QGuardedPtr<QWidget> *Global::running=0; 480QGuardedPtr<QWidget> *Global::running=0;
481 481
482/*! 482/*!
483 \class Global::Command 483 \class Global::Command
484 \brief The Global::Command class is internal. 484 \brief The Global::Command class is internal.
485 \internal 485 \internal
486*/ 486*/
487 487
488/*! 488/*!
489 \internal 489 \internal
490*/ 490*/
491void Global::setBuiltinCommands( Command* list ) 491void Global::setBuiltinCommands( Command* list )
492{ 492{
493 if ( running ) 493 if ( running )
494 delete [] running; 494 delete [] running;
495 495
496 builtin = list; 496 builtin = list;
497 int count = 0; 497 int count = 0;
498 if (!builtin) 498 if (!builtin)
499 return; 499 return;
500 while ( builtin[count].file ) 500 while ( builtin[count].file )
501 count++; 501 count++;
502 502
503 running = new QGuardedPtr<QWidget> [ count ]; 503 running = new QGuardedPtr<QWidget> [ count ];
504} 504}
505 505
506/*! 506/*!
507 \internal 507 \internal
508*/ 508*/
509void Global::setDocument( QWidget* receiver, const QString& document ) 509void Global::setDocument( QWidget* receiver, const QString& document )
510{ 510{
511 Emitter emitter(receiver,document); 511 Emitter emitter(receiver,document);
512} 512}
513 513
514/*! 514/*!
515 \internal 515 \internal
516*/ 516*/
517bool Global::terminateBuiltin( const QString& n ) 517bool Global::terminateBuiltin( const QString& n )
518{ 518{
519 if (!builtin) 519 if (!builtin)
520 return FALSE; 520 return FALSE;
521 for (int i = 0; builtin[i].file; i++) { 521 for (int i = 0; builtin[i].file; i++) {
522 if ( builtin[i].file == n ) { 522 if ( builtin[i].file == n ) {
523 delete running[i]; 523 delete running[i];
524 return TRUE; 524 return TRUE;
525 } 525 }
526 } 526 }
527 return FALSE; 527 return FALSE;
528} 528}
529 529
530/*! 530/*!
531 \internal 531 \internal
532*/ 532*/
533void Global::terminate( const AppLnk* app ) 533void Global::terminate( const AppLnk* app )
534{ 534{
535 //if ( terminateBuiltin(app->exec()) ) return; // maybe? haven't tried this 535 //if ( terminateBuiltin(app->exec()) ) return; // maybe? haven't tried this
536 536
537#ifndef QT_NO_COP 537#ifndef QT_NO_COP
538 QCString channel = "QPE/Application/" + app->exec().utf8(); 538 QCString channel = "QPE/Application/" + app->exec().utf8();
539 if ( QCopChannel::isRegistered(channel) ) { 539 if ( QCopChannel::isRegistered(channel) ) {
540 QCopEnvelope e(channel, "quit()"); 540 QCopEnvelope e(channel, "quit()");
541 } 541 }
542#endif 542#endif
543} 543}
544 544
545/*! 545/*!
546 Low-level function to run command \a c. 546 Low-level function to run command \a c.
547 547
548 \warning Do not use this function. Use execute instead. 548 \warning Do not use this function. Use execute instead.
549 549
550 \sa execute() 550 \sa execute()
551*/ 551*/
552void Global::invoke(const QString &c) 552void Global::invoke(const QString &c)
553{ 553{
554 // Convert the command line in to a list of arguments 554 // Convert the command line in to a list of arguments
555 QStringList list = QStringList::split(QRegExp(" *"),c); 555 QStringList list = QStringList::split(QRegExp(" *"),c);
556 556
557#if !defined(QT_NO_COP) 557#if !defined(QT_NO_COP)
558 QString ap=list[0]; 558 QString ap=list[0];
559 // see if the application is already running 559 // see if the application is already running
560 // XXX should lock file /tmp/qcop-msg-ap 560 // XXX should lock file /tmp/qcop-msg-ap
561 if ( QCopChannel::isRegistered( ("QPE/Application/" + ap).latin1() ) ) { 561 if ( QCopChannel::isRegistered( ("QPE/Application/" + ap).latin1() ) ) {
562 // If the channel is already register, the app is already running, so show it. 562 // If the channel is already register, the app is already running, so show it.
563 { QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "raise()" ); } 563 { QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "raise()" ); }
564 564
565 QCopEnvelope e("QPE/System", "notBusy(QString)" ); 565 QCopEnvelope e("QPE/System", "notBusy(QString)" );
566 e << ap; 566 e << ap;
567 return; 567 return;
568 } 568 }
569 // XXX should unlock file /tmp/qcop-msg-ap 569 // XXX should unlock file /tmp/qcop-msg-ap
570 //see if it is being started 570 //see if it is being started
571 if ( StartingAppList::isStarting( ap ) ) { 571 if ( StartingAppList::isStarting( ap ) ) {
572 QCopEnvelope e("QPE/System", "notBusy(QString)" ); 572 QCopEnvelope e("QPE/System", "notBusy(QString)" );
573 e << ap; 573 e << ap;
574 return; 574 return;
575 } 575 }
576 576
577#endif 577#endif
578 578
579#ifdef QT_NO_QWS_MULTIPROCESS 579#ifdef QT_NO_QWS_MULTIPROCESS
580 QMessageBox::warning( 0, "Error", "Could not find the application " + c, "Ok", 0, 0, 0, 1 ); 580 QMessageBox::warning( 0, "Error", "Could not find the application " + c, "Ok", 0, 0, 0, 1 );
581#else 581#else
582 582
583 QStrList slist; 583 QStrList slist;
584 unsigned int j; 584 unsigned int j;
585 for ( j = 0; j < list.count(); j++ ) 585 for ( j = 0; j < list.count(); j++ )
586 slist.append( list[j].utf8() ); 586 slist.append( list[j].utf8() );
587 587
588 const char **args = new (const char *)[slist.count() + 1]; 588 const char **args = new (const char *)[slist.count() + 1];
589 for ( j = 0; j < slist.count(); j++ ) 589 for ( j = 0; j < slist.count(); j++ )
590 args[j] = slist.at(j); 590 args[j] = slist.at(j);
591 args[j] = NULL; 591 args[j] = NULL;
592 592
593#if !defined(QT_NO_COP) 593#if !defined(QT_NO_COP)
594 // an attempt to show a wait... 594 // an attempt to show a wait...
595 // more logic should be used, but this will be fine for the moment... 595 // more logic should be used, but this will be fine for the moment...
596 QCopEnvelope ( "QPE/System", "busy()" ); 596 QCopEnvelope ( "QPE/System", "busy()" );
597#endif 597#endif
598 598
599#ifdef HAVE_QUICKEXEC 599#ifdef HAVE_QUICKEXEC
600 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".so"; 600 QString libexe = qpeDir()+"/binlib/lib"+args[0] + ".so";
601 qDebug("libfile = %s", libexe.latin1() ); 601 qDebug("libfile = %s", libexe.latin1() );
602 if ( QFile::exists( libexe ) ) { 602 if ( QFile::exists( libexe ) ) {
603 qDebug("calling quickexec %s", libexe.latin1() ); 603 qDebug("calling quickexec %s", libexe.latin1() );
604 quickexecv( libexe.utf8().data(), (const char **)args ); 604 quickexecv( libexe.utf8().data(), (const char **)args );
605 } else 605 } else
606#endif 606#endif
607 { 607 {
608 bool success = false; 608 bool success = false;
609 int pfd [2]; 609 int pfd [2];
610 if ( ::pipe ( pfd ) < 0 ) 610 if ( ::pipe ( pfd ) < 0 )
611 pfd [0] = pfd [1] = -1; 611 pfd [0] = pfd [1] = -1;
612 612
613 pid_t pid = ::fork ( ); 613 pid_t pid = ::fork ( );
614 614
615 if ( pid == 0 ) { // child 615 if ( pid == 0 ) { // child
616 for ( int fd = 3; fd < 100; fd++ ) { 616 for ( int fd = 3; fd < 100; fd++ ) {
617 if ( fd != pfd [1] ) 617 if ( fd != pfd [1] )
618 ::close ( fd ); 618 ::close ( fd );
619 } 619 }
620 ::setpgid ( ::getpid ( ), ::getppid ( )); 620 ::setpgid ( ::getpid ( ), ::getppid ( ));
621 621
622 // Closing of fd[1] indicates that the execvp succeeded! 622 // Closing of fd[1] indicates that the execvp succeeded!
623 if ( pfd [1] >= 0 ) 623 if ( pfd [1] >= 0 )
624 ::fcntl ( pfd [1], F_SETFD, FD_CLOEXEC ); 624 ::fcntl ( pfd [1], F_SETFD, FD_CLOEXEC );
625 625
626 // Try bindir first, so that foo/bar works too 626 // Try bindir first, so that foo/bar works too
627 ::execv ( qpeDir ( ) + "/bin/" + args [0], (char * const *) args ); 627 ::execv ( qpeDir ( ) + "/bin/" + args [0], (char * const *) args );
628 ::execvp ( args [0], (char * const *) args ); 628 ::execvp ( args [0], (char * const *) args );
629 629
630 char resultByte = 1; 630 char resultByte = 1;
631 if ( pfd [1] >= 0 ) 631 if ( pfd [1] >= 0 )
632 ::write ( pfd [1], &resultByte, 1 ); 632 ::write ( pfd [1], &resultByte, 1 );
633 ::_exit ( -1 ); 633 ::_exit ( -1 );
634 } 634 }
635 else if ( pid > 0 ) { 635 else if ( pid > 0 ) {
636 success = true; 636 success = true;
637 637
638 if ( pfd [1] >= 0 ) 638 if ( pfd [1] >= 0 )
639 ::close ( pfd [1] ); 639 ::close ( pfd [1] );
640 if ( pfd [0] >= 0 ) { 640 if ( pfd [0] >= 0 ) {
641 while ( true ) { 641 while ( true ) {
642 char resultByte; 642 char resultByte;
643 int n = ::read ( pfd [0], &resultByte, 1 ); 643 int n = ::read ( pfd [0], &resultByte, 1 );
644 if ( n == 1 ) { 644 if ( n == 1 ) {
645 success = false; 645 success = false;
646 break; 646 break;
647 } 647 }
648 if (( n == -1 ) && (( errno == ECHILD ) || ( errno == EINTR ))) 648 if (( n == -1 ) && (( errno == ECHILD ) || ( errno == EINTR )))
649 continue; 649 continue;
650 650
651 break; // success 651 break; // success
652 } 652 }
653 ::close ( pfd [0] ); 653 ::close ( pfd [0] );
654 } 654 }
655 } 655 }
656 if ( success ) 656 if ( success )
657 StartingAppList::add( list[0] ); 657 StartingAppList::add( list[0] );
658 else 658 else
659 QMessageBox::warning( 0, "Error", "Could not start the application " + c, "Ok", 0, 0, 0, 1 ); 659 QMessageBox::warning( 0, "Error", "Could not start the application " + c, "Ok", 0, 0, 0, 1 );
660 } 660 }
661#endif //QT_NO_QWS_MULTIPROCESS 661#endif //QT_NO_QWS_MULTIPROCESS
662} 662}
663 663
664 664
665/*! 665/*!
666 Executes the application identfied by \a c, passing \a 666 Executes the application identfied by \a c, passing \a
667 document if it isn't null. 667 document if it isn't null.
668 668
669 Note that a better approach might be to send a QCop message to the 669 Note that a better approach might be to send a QCop message to the
670 application's QPE/Application/\e{appname} channel. 670 application's QPE/Application/\e{appname} channel.
671*/ 671*/
672void Global::execute( const QString &c, const QString& document ) 672void Global::execute( const QString &c, const QString& document )
673{ 673{
674 if ( qApp->type() != QApplication::GuiServer ) { 674 if ( qApp->type() != QApplication::GuiServer ) {
675 // ask the server to do the work 675 // ask the server to do the work
676#if !defined(QT_NO_COP) 676#if !defined(QT_NO_COP)
677 if ( document.isNull() ) { 677 if ( document.isNull() ) {
678 QCopEnvelope e( "QPE/System", "execute(QString)" ); 678 QCopEnvelope e( "QPE/System", "execute(QString)" );
679 e << c; 679 e << c;
680 } else { 680 } else {
681 QCopEnvelope e( "QPE/System", "execute(QString,QString)" ); 681 QCopEnvelope e( "QPE/System", "execute(QString,QString)" );
682 e << c << document; 682 e << c << document;
683 } 683 }
684#endif 684#endif
685 return; 685 return;
686 } 686 }
687 687
688 // Attempt to execute the app using a builtin class for the app first 688 // Attempt to execute the app using a builtin class for the app first
689 // else try and find it in the bin directory 689 // else try and find it in the bin directory
690 if (builtin) { 690 if (builtin) {
691 for (int i = 0; builtin[i].file; i++) { 691 for (int i = 0; builtin[i].file; i++) {
692 if ( builtin[i].file == c ) { 692 if ( builtin[i].file == c ) {
693 if ( running[i] ) { 693 if ( running[i] ) {
694 if ( !document.isNull() && builtin[i].documentary ) 694 if ( !document.isNull() && builtin[i].documentary )
695 setDocument(running[i], document); 695 setDocument(running[i], document);
696 running[i]->raise(); 696 running[i]->raise();
697 running[i]->show(); 697 running[i]->show();
698 running[i]->setActiveWindow(); 698 running[i]->setActiveWindow();
699 } else { 699 } else {
700 running[i] = builtin[i].func( builtin[i].maximized ); 700 running[i] = builtin[i].func( builtin[i].maximized );
701 } 701 }
702#ifndef QT_NO_COP 702#ifndef QT_NO_COP
703 QCopEnvelope e("QPE/System", "notBusy(QString)" ); 703 QCopEnvelope e("QPE/System", "notBusy(QString)" );
704 e << c; // that was quick ;-) 704 e << c; // that was quick ;-)
705#endif 705#endif
706 return; 706 return;
707 } 707 }
708 } 708 }
709 } 709 }
710 710
711 //Global::invoke(c, document); 711 //Global::invoke(c, document);
712 712
713 // Convert the command line in to a list of arguments 713 // Convert the command line in to a list of arguments
714 QStringList list = QStringList::split(QRegExp(" *"),c); 714 QStringList list = QStringList::split(QRegExp(" *"),c);
715 715
716#if !defined(QT_NO_COP) 716#if !defined(QT_NO_COP)
717 QString ap=list[0]; 717 QString ap=list[0];
718 718
719 qDebug("executing %s", ap.latin1() ); 719 qDebug("executing %s", ap.latin1() );
720 720
721 /* if need be, sending a qcop message will result in an invoke, see 721 /* if need be, sending a qcop message will result in an invoke, see
722 preceeding function */ 722 preceeding function */
723 invoke( ap ); 723 invoke( ap );
724 //{ QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "raise()" ); } 724 //{ QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "raise()" ); }
725 if ( !document.isEmpty() ) { 725 if ( !document.isEmpty() ) {
726 QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "setDocument(QString)" ); 726 QCopEnvelope env( ("QPE/Application/" + ap).latin1(), "setDocument(QString)" );
727 env << document; 727 env << document;
728 } 728 }
729#endif 729#endif
730} 730}
731 731
732/*! 732/*!
733 Returns the string \a s with the characters '\', '"', and '$' quoted 733 Returns the string \a s with the characters '\', '"', and '$' quoted
734 by a preceeding '\'. 734 by a preceeding '\'.
735 735
736 \sa stringQuote() 736 \sa stringQuote()
737*/ 737*/
738QString Global::shellQuote(const QString& s) 738QString Global::shellQuote(const QString& s)
739{ 739{
740 QString r="\""; 740 QString r="\"";
741 for (int i=0; i<(int)s.length(); i++) { 741 for (int i=0; i<(int)s.length(); i++) {
742 char c = s[i].latin1(); 742 char c = s[i].latin1();
743 switch (c) { 743 switch (c) {
744 case '\\': case '"': case '$': 744 case '\\': case '"': case '$':
745 r+="\\"; 745 r+="\\";
746 } 746 }
747 r += s[i]; 747 r += s[i];
748 } 748 }
749 r += "\""; 749 r += "\"";
750 return r; 750 return r;
751} 751}
752 752
753/*! 753/*!
754 Returns the string \a s with the characters '\' and '"' quoted by a 754 Returns the string \a s with the characters '\' and '"' quoted by a
755 preceeding '\'. 755 preceeding '\'.
756 756
757 \sa shellQuote() 757 \sa shellQuote()
758*/ 758*/
759QString Global::stringQuote(const QString& s) 759QString Global::stringQuote(const QString& s)
760{ 760{
761 QString r="\""; 761 QString r="\"";
762 for (int i=0; i<(int)s.length(); i++) { 762 for (int i=0; i<(int)s.length(); i++) {
763 char c = s[i].latin1(); 763 char c = s[i].latin1();
764 switch (c) { 764 switch (c) {
765 case '\\': case '"': 765 case '\\': case '"':
766 r+="\\"; 766 r+="\\";
767 } 767 }
768 r += s[i]; 768 r += s[i];
769 } 769 }
770 r += "\""; 770 r += "\"";
771 return r; 771 return r;
772} 772}
773 773
774/*! 774/*!
775 Finds all documents on the system's document directories which 775 Finds all documents on the system's document directories which
776 match the filter \a mimefilter, and appends the resulting DocLnk 776 match the filter \a mimefilter, and appends the resulting DocLnk
777 objects to \a folder. 777 objects to \a folder.
778*/ 778*/
779void Global::findDocuments(DocLnkSet* folder, const QString &mimefilter) 779void Global::findDocuments(DocLnkSet* folder, const QString &mimefilter)
780{ 780{
781 QString homedocs = QString(getenv("HOME")) + "/Documents"; 781 QString homedocs = QString(getenv("HOME")) + "/Documents";
782 DocLnkSet d(homedocs,mimefilter); 782 DocLnkSet d(homedocs,mimefilter);
783 folder->appendFrom(d); 783 folder->appendFrom(d);
784 /** let's do intellegint way of searching these files 784 /** let's do intellegint way of searching these files
785 * a) the user don't want to check mediums global 785 * a) the user don't want to check mediums global
786 * b) the user wants to check but use the global options for it 786 * b) the user wants to check but use the global options for it
787 * c) the user wants to check it but not this medium 787 * c) the user wants to check it but not this medium
788 * d) the user wants to check and this medium as well 788 * d) the user wants to check and this medium as well
789 * 789 *
790 * In all cases we need to apply a different mimefilter to 790 * In all cases we need to apply a different mimefilter to
791 * the medium. 791 * the medium.
792 * a) mimefilter.isEmpty() we need to apply the responding filter 792 * a) mimefilter.isEmpty() we need to apply the responding filter
793 * either the global or the one on the medium 793 * either the global or the one on the medium
794 * 794 *
795 * b) mimefilter is set to an application we need to find out if the 795 * b) mimefilter is set to an application we need to find out if the
796 * mimetypes are included in the mime mask of the medium 796 * mimetypes are included in the mime mask of the medium
797 */ 797 */
798 StorageInfo storage; 798 StorageInfo storage;
799 const QList<FileSystem> &fs = storage.fileSystems(); 799 const QList<FileSystem> &fs = storage.fileSystems();
800 QListIterator<FileSystem> it ( fs ); 800 QListIterator<FileSystem> it ( fs );
801 for ( ; it.current(); ++it ) { 801 for ( ; it.current(); ++it ) {
802 if ( (*it)->isRemovable() ) { // let's find out if we should search on it 802 if ( (*it)->isRemovable() ) { // let's find out if we should search on it
803 // this is a candidate look at the cf and see if we should search on it 803 // this is a candidate look at the cf and see if we should search on it
804 QString path = (*it)->path(); 804 QString path = (*it)->path();
805 if( !checkStorage((*it)->path() + "/.opiestorage.cf" ) ) 805 if( !checkStorage((*it)->path() + "/.opiestorage.cf" ) )
806 continue; 806 continue;
807 DocLnkSet ide( path, mimefilter ); 807 DocLnkSet ide( path, mimefilter );
808 folder->appendFrom(ide); 808 folder->appendFrom(ide);
809 } else if ( (*it)->disk() == "/dev/mtdblock6" || (*it)->disk() == "tmpfs" ) { 809 } else if ( (*it)->disk() == "/dev/mtdblock6" || (*it)->disk() == "tmpfs" ) {
810 QString path = (*it)->path() + "/Documents"; 810 QString path = (*it)->path() + "/Documents";
811 DocLnkSet ide( path, mimefilter ); 811 DocLnkSet ide( path, mimefilter );
812 folder->appendFrom(ide); 812 folder->appendFrom(ide);
813 } 813 }
814 } 814 }
815} 815}
816 816
817QStringList Global::languageList() 817QStringList Global::languageList()
818{ 818{
819 QString lang = getenv("LANG"); 819 QString lang = getenv("LANG");
820 QStringList langs; 820 QStringList langs;
821 langs.append(lang); 821 langs.append(lang);
822 int i = lang.find("."); 822 int i = lang.find(".");
823 if ( i > 0 ) 823 if ( i > 0 )
824 lang = lang.left( i ); 824 lang = lang.left( i );
825 i = lang.find( "_" ); 825 i = lang.find( "_" );
826 if ( i > 0 ) 826 if ( i > 0 )
827 langs.append(lang.left(i)); 827 langs.append(lang.left(i));
828 return langs; 828 return langs;
829} 829}
830 830
831QStringList Global::helpPath() 831QStringList Global::helpPath()
832{ 832{
833 QStringList path; 833 QStringList path;
834 QStringList langs = Global::languageList(); 834 QStringList langs = Global::languageList();
835 for (QStringList::ConstIterator it = langs.fromLast(); it!=langs.end(); --it) { 835 for (QStringList::ConstIterator it = langs.fromLast(); it!=langs.end(); --it) {
836 QString lang = *it; 836 QString lang = *it;
837 if ( !lang.isEmpty() ) 837 if ( !lang.isEmpty() )
838 path += QPEApplication::qpeDir() + "/help/" + lang + "/html"; 838 path += QPEApplication::qpeDir() + "/help/" + lang + "/html";
839 } 839 }
840 path += QPEApplication::qpeDir() + "/pics"; 840 path += QPEApplication::qpeDir() + "/pics";
841 path += QPEApplication::qpeDir() + "/help/html"; 841 path += QPEApplication::qpeDir() + "/help/html";
842 path += QPEApplication::qpeDir() + "/docs"; 842 path += QPEApplication::qpeDir() + "/docs";
843 843
844 844
845 return path; 845 return path;
846} 846}
847 847
848 848
849#include "global.moc" 849#include "global.moc"
diff --git a/library/qpeapplication.cpp b/library/qpeapplication.cpp
index c562f6c..2ef60d5 100644
--- a/library/qpeapplication.cpp
+++ b/library/qpeapplication.cpp
@@ -197,513 +197,513 @@ public:
197 if (forceshow) 197 if (forceshow)
198 show_mx(mw, nomax); 198 show_mx(mw, nomax);
199 } 199 }
200 else if ( keep_running ) { 200 else if ( keep_running ) {
201 show_mx(mw, nomax); 201 show_mx(mw, nomax);
202 } 202 }
203 } 203 }
204 204
205 void loadTextCodecs() 205 void loadTextCodecs()
206 { 206 {
207 QString path = QPEApplication::qpeDir() + "/plugins/textcodecs"; 207 QString path = QPEApplication::qpeDir() + "/plugins/textcodecs";
208 QDir dir( path, "lib*.so" ); 208 QDir dir( path, "lib*.so" );
209 QStringList list; 209 QStringList list;
210 if ( dir. exists ( )) 210 if ( dir. exists ( ))
211 list = dir.entryList(); 211 list = dir.entryList();
212 QStringList::Iterator it; 212 QStringList::Iterator it;
213 for ( it = list.begin(); it != list.end(); ++it ) { 213 for ( it = list.begin(); it != list.end(); ++it ) {
214 TextCodecInterface *iface = 0; 214 TextCodecInterface *iface = 0;
215 QLibrary *lib = new QLibrary( path + "/" + *it ); 215 QLibrary *lib = new QLibrary( path + "/" + *it );
216 if ( lib->queryInterface( IID_QtopiaTextCodec, (QUnknownInterface**)&iface ) == QS_OK && iface ) { 216 if ( lib->queryInterface( IID_QtopiaTextCodec, (QUnknownInterface**)&iface ) == QS_OK && iface ) {
217 QValueList<int> mibs = iface->mibEnums(); 217 QValueList<int> mibs = iface->mibEnums();
218 for (QValueList<int>::ConstIterator i = mibs.begin(); i != mibs.end(); ++i) { 218 for (QValueList<int>::ConstIterator i = mibs.begin(); i != mibs.end(); ++i) {
219 (void)iface->createForMib(*i); 219 (void)iface->createForMib(*i);
220 // ### it exists now; need to remember if we can delete it 220 // ### it exists now; need to remember if we can delete it
221 } 221 }
222 } 222 }
223 else { 223 else {
224 lib->unload(); 224 lib->unload();
225 delete lib; 225 delete lib;
226 } 226 }
227 } 227 }
228 } 228 }
229 229
230 void loadImageCodecs() 230 void loadImageCodecs()
231 { 231 {
232 QString path = QPEApplication::qpeDir() + "/plugins/imagecodecs"; 232 QString path = QPEApplication::qpeDir() + "/plugins/imagecodecs";
233 QDir dir( path, "lib*.so" ); 233 QDir dir( path, "lib*.so" );
234 QStringList list; 234 QStringList list;
235 if ( dir. exists ( )) 235 if ( dir. exists ( ))
236 list = dir.entryList(); 236 list = dir.entryList();
237 QStringList::Iterator it; 237 QStringList::Iterator it;
238 for ( it = list.begin(); it != list.end(); ++it ) { 238 for ( it = list.begin(); it != list.end(); ++it ) {
239 ImageCodecInterface *iface = 0; 239 ImageCodecInterface *iface = 0;
240 QLibrary *lib = new QLibrary( path + "/" + *it ); 240 QLibrary *lib = new QLibrary( path + "/" + *it );
241 if ( lib->queryInterface( IID_QtopiaImageCodec, (QUnknownInterface**)&iface ) == QS_OK && iface ) { 241 if ( lib->queryInterface( IID_QtopiaImageCodec, (QUnknownInterface**)&iface ) == QS_OK && iface ) {
242 QStringList formats = iface->keys(); 242 QStringList formats = iface->keys();
243 for (QStringList::ConstIterator i = formats.begin(); i != formats.end(); ++i) { 243 for (QStringList::ConstIterator i = formats.begin(); i != formats.end(); ++i) {
244 (void)iface->installIOHandler(*i); 244 (void)iface->installIOHandler(*i);
245 // ### it exists now; need to remember if we can delete it 245 // ### it exists now; need to remember if we can delete it
246 } 246 }
247 } 247 }
248 else { 248 else {
249 lib->unload(); 249 lib->unload();
250 delete lib; 250 delete lib;
251 } 251 }
252 } 252 }
253 } 253 }
254 QString styleName; 254 QString styleName;
255 QString decorationName; 255 QString decorationName;
256}; 256};
257 257
258class ResourceMimeFactory : public QMimeSourceFactory 258class ResourceMimeFactory : public QMimeSourceFactory
259{ 259{
260public: 260public:
261 ResourceMimeFactory() 261 ResourceMimeFactory()
262 { 262 {
263 setFilePath( Global::helpPath() ); 263 setFilePath( Global::helpPath() );
264 setExtensionType( "html", "text/html;charset=UTF-8" ); 264 setExtensionType( "html", "text/html;charset=UTF-8" );
265 } 265 }
266 266
267 const QMimeSource* data( const QString& abs_name ) const 267 const QMimeSource* data( const QString& abs_name ) const
268 { 268 {
269 const QMimeSource * r = QMimeSourceFactory::data( abs_name ); 269 const QMimeSource * r = QMimeSourceFactory::data( abs_name );
270 if ( !r ) { 270 if ( !r ) {
271 int sl = abs_name.length(); 271 int sl = abs_name.length();
272 do { 272 do {
273 sl = abs_name.findRev( '/', sl - 1 ); 273 sl = abs_name.findRev( '/', sl - 1 );
274 QString name = sl >= 0 ? abs_name.mid( sl + 1 ) : abs_name; 274 QString name = sl >= 0 ? abs_name.mid( sl + 1 ) : abs_name;
275 int dot = name.findRev( '.' ); 275 int dot = name.findRev( '.' );
276 if ( dot >= 0 ) 276 if ( dot >= 0 )
277 name = name.left( dot ); 277 name = name.left( dot );
278 QImage img = Resource::loadImage( name ); 278 QImage img = Resource::loadImage( name );
279 if ( !img.isNull() ) 279 if ( !img.isNull() )
280 r = new QImageDrag( img ); 280 r = new QImageDrag( img );
281 } 281 }
282 while ( !r && sl > 0 ); 282 while ( !r && sl > 0 );
283 } 283 }
284 return r; 284 return r;
285 } 285 }
286}; 286};
287 287
288static int muted = 0; 288static int muted = 0;
289static int micMuted = 0; 289static int micMuted = 0;
290 290
291static void setVolume( int t = 0, int percent = -1 ) 291static void setVolume( int t = 0, int percent = -1 )
292{ 292{
293 switch ( t ) { 293 switch ( t ) {
294 case 0: { 294 case 0: {
295 Config cfg( "qpe" ); 295 Config cfg( "qpe" );
296 cfg.setGroup( "Volume" ); 296 cfg.setGroup( "Volume" );
297 if ( percent < 0 ) 297 if ( percent < 0 )
298 percent = cfg.readNumEntry( "VolumePercent", 50 ); 298 percent = cfg.readNumEntry( "VolumePercent", 50 );
299 int fd = 0; 299 int fd = 0;
300 if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) { 300 if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
301 int vol = muted ? 0 : percent; 301 int vol = muted ? 0 : percent;
302 // set both channels to same volume 302 // set both channels to same volume
303 vol |= vol << 8; 303 vol |= vol << 8;
304 ioctl( fd, MIXER_WRITE( 0 ), &vol ); 304 ioctl( fd, MIXER_WRITE( 0 ), &vol );
305 ::close( fd ); 305 ::close( fd );
306 } 306 }
307 } 307 }
308 break; 308 break;
309 } 309 }
310} 310}
311 311
312static void setMic( int t = 0, int percent = -1 ) 312static void setMic( int t = 0, int percent = -1 )
313{ 313{
314 switch ( t ) { 314 switch ( t ) {
315 case 0: { 315 case 0: {
316 Config cfg( "qpe" ); 316 Config cfg( "qpe" );
317 cfg.setGroup( "Volume" ); 317 cfg.setGroup( "Volume" );
318 if ( percent < 0 ) 318 if ( percent < 0 )
319 percent = cfg.readNumEntry( "Mic", 50 ); 319 percent = cfg.readNumEntry( "Mic", 50 );
320 320
321 int fd = 0; 321 int fd = 0;
322 int mic = micMuted ? 0 : percent; 322 int mic = micMuted ? 0 : percent;
323 if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) { 323 if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
324 ioctl( fd, MIXER_WRITE( SOUND_MIXER_MIC ), &mic ); 324 ioctl( fd, MIXER_WRITE( SOUND_MIXER_MIC ), &mic );
325 ::close( fd ); 325 ::close( fd );
326 } 326 }
327 } 327 }
328 break; 328 break;
329 } 329 }
330} 330}
331 331
332 332
333static void setBass( int t = 0, int percent = -1 ) 333static void setBass( int t = 0, int percent = -1 )
334{ 334{
335 switch ( t ) { 335 switch ( t ) {
336 case 0: { 336 case 0: {
337 Config cfg( "qpe" ); 337 Config cfg( "qpe" );
338 cfg.setGroup( "Volume" ); 338 cfg.setGroup( "Volume" );
339 if ( percent < 0 ) 339 if ( percent < 0 )
340 percent = cfg.readNumEntry( "BassPercent", 50 ); 340 percent = cfg.readNumEntry( "BassPercent", 50 );
341 341
342 int fd = 0; 342 int fd = 0;
343 int bass = percent; 343 int bass = percent;
344 if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) { 344 if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
345 ioctl( fd, MIXER_WRITE( SOUND_MIXER_BASS ), &bass ); 345 ioctl( fd, MIXER_WRITE( SOUND_MIXER_BASS ), &bass );
346 ::close( fd ); 346 ::close( fd );
347 } 347 }
348 } 348 }
349 break; 349 break;
350 } 350 }
351} 351}
352 352
353 353
354static void setTreble( int t = 0, int percent = -1 ) 354static void setTreble( int t = 0, int percent = -1 )
355{ 355{
356 switch ( t ) { 356 switch ( t ) {
357 case 0: { 357 case 0: {
358 Config cfg( "qpe" ); 358 Config cfg( "qpe" );
359 cfg.setGroup( "Volume" ); 359 cfg.setGroup( "Volume" );
360 if ( percent < 0 ) 360 if ( percent < 0 )
361 percent = cfg.readNumEntry( "TreblePercent", 50 ); 361 percent = cfg.readNumEntry( "TreblePercent", 50 );
362 362
363 int fd = 0; 363 int fd = 0;
364 int treble = percent; 364 int treble = percent;
365 if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) { 365 if ( ( fd = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
366 ioctl( fd, MIXER_WRITE( SOUND_MIXER_TREBLE ), &treble ); 366 ioctl( fd, MIXER_WRITE( SOUND_MIXER_TREBLE ), &treble );
367 ::close( fd ); 367 ::close( fd );
368 } 368 }
369 } 369 }
370 break; 370 break;
371 } 371 }
372} 372}
373 373
374 374
375/*! 375/*!
376 \class QPEApplication qpeapplication.h 376 \class QPEApplication qpeapplication.h
377 \brief The QPEApplication class implements various system services 377 \brief The QPEApplication class implements various system services
378 that are available to all Qtopia applications. 378 that are available to all Qtopia applications.
379 379
380 Simply by using QPEApplication instead of QApplication, a standard Qt 380 Simply by using QPEApplication instead of QApplication, a standard Qt
381 application becomes a Qtopia application. It automatically follows 381 application becomes a Qtopia application. It automatically follows
382 style changes, quits and raises, and in the 382 style changes, quits and raises, and in the
383 case of \link docwidget.html document-oriented\endlink applications, 383 case of \link docwidget.html document-oriented\endlink applications,
384 changes the currently displayed document in response to the environment. 384 changes the currently displayed document in response to the environment.
385 385
386 To create a \link docwidget.html document-oriented\endlink 386 To create a \link docwidget.html document-oriented\endlink
387 application use showMainDocumentWidget(); to create a 387 application use showMainDocumentWidget(); to create a
388 non-document-oriented application use showMainWidget(). The 388 non-document-oriented application use showMainWidget(). The
389 keepRunning() function indicates whether the application will 389 keepRunning() function indicates whether the application will
390 continue running after it's processed the last \link qcop.html 390 continue running after it's processed the last \link qcop.html
391 QCop\endlink message. This can be changed using setKeepRunning(). 391 QCop\endlink message. This can be changed using setKeepRunning().
392 392
393 A variety of signals are emitted when certain events occur, for 393 A variety of signals are emitted when certain events occur, for
394 example, timeChanged(), clockChanged(), weekChanged(), 394 example, timeChanged(), clockChanged(), weekChanged(),
395 dateFormatChanged() and volumeChanged(). If the application receives 395 dateFormatChanged() and volumeChanged(). If the application receives
396 a \link qcop.html QCop\endlink message on the application's 396 a \link qcop.html QCop\endlink message on the application's
397 QPE/Application/\e{appname} channel, the appMessage() signal is 397 QPE/Application/\e{appname} channel, the appMessage() signal is
398 emitted. There are also flush() and reload() signals, which 398 emitted. There are also flush() and reload() signals, which
399 are emitted when synching begins and ends respectively - upon these 399 are emitted when synching begins and ends respectively - upon these
400 signals, the application should save and reload any data 400 signals, the application should save and reload any data
401 files that are involved in synching. Most of these signals will initially 401 files that are involved in synching. Most of these signals will initially
402 be received and unfiltered through the appMessage() signal. 402 be received and unfiltered through the appMessage() signal.
403 403
404 This class also provides a set of useful static functions. The 404 This class also provides a set of useful static functions. The
405 qpeDir() and documentDir() functions return the respective paths. 405 qpeDir() and documentDir() functions return the respective paths.
406 The grabKeyboard() and ungrabKeyboard() functions are used to 406 The grabKeyboard() and ungrabKeyboard() functions are used to
407 control whether the application takes control of the device's 407 control whether the application takes control of the device's
408 physical buttons (e.g. application launch keys). The stylus' mode of 408 physical buttons (e.g. application launch keys). The stylus' mode of
409 operation is set with setStylusOperation() and retrieved with 409 operation is set with setStylusOperation() and retrieved with
410 stylusOperation(). There are also setInputMethodHint() and 410 stylusOperation(). There are also setInputMethodHint() and
411 inputMethodHint() functions. 411 inputMethodHint() functions.
412 412
413 \ingroup qtopiaemb 413 \ingroup qtopiaemb
414*/ 414*/
415 415
416/*! 416/*!
417 \fn void QPEApplication::clientMoused() 417 \fn void QPEApplication::clientMoused()
418 418
419 \internal 419 \internal
420*/ 420*/
421 421
422/*! 422/*!
423 \fn void QPEApplication::timeChanged(); 423 \fn void QPEApplication::timeChanged();
424 This signal is emitted when the time changes outside the normal 424 This signal is emitted when the time changes outside the normal
425 passage of time, i.e. if the time is set backwards or forwards. 425 passage of time, i.e. if the time is set backwards or forwards.
426*/ 426*/
427 427
428/*! 428/*!
429 \fn void QPEApplication::clockChanged( bool ampm ); 429 \fn void QPEApplication::clockChanged( bool ampm );
430 430
431 This signal is emitted when the user changes the clock's style. If 431 This signal is emitted when the user changes the clock's style. If
432 \a ampm is TRUE, the user wants a 12-hour AM/PM clock, otherwise, 432 \a ampm is TRUE, the user wants a 12-hour AM/PM clock, otherwise,
433 they want a 24-hour clock. 433 they want a 24-hour clock.
434*/ 434*/
435 435
436/*! 436/*!
437 \fn void QPEApplication::volumeChanged( bool muted ) 437 \fn void QPEApplication::volumeChanged( bool muted )
438 438
439 This signal is emitted whenever the mute state is changed. If \a 439 This signal is emitted whenever the mute state is changed. If \a
440 muted is TRUE, then sound output has been muted. 440 muted is TRUE, then sound output has been muted.
441*/ 441*/
442 442
443/*! 443/*!
444 \fn void QPEApplication::weekChanged( bool startOnMonday ) 444 \fn void QPEApplication::weekChanged( bool startOnMonday )
445 445
446 This signal is emitted if the week start day is changed. If \a 446 This signal is emitted if the week start day is changed. If \a
447 startOnMonday is TRUE then the first day of the week is Monday; if 447 startOnMonday is TRUE then the first day of the week is Monday; if
448 \a startOnMonday is FALSE then the first day of the week is 448 \a startOnMonday is FALSE then the first day of the week is
449 Sunday. 449 Sunday.
450*/ 450*/
451 451
452/*! 452/*!
453 \fn void QPEApplication::dateFormatChanged() 453 \fn void QPEApplication::dateFormatChanged(DateFormat)
454 454
455 This signal is emitted whenever the date format is changed. 455 This signal is emitted whenever the date format is changed.
456*/ 456*/
457 457
458/*! 458/*!
459 \fn void QPEApplication::flush() 459 \fn void QPEApplication::flush()
460 460
461 ### 461 ###
462*/ 462*/
463 463
464/*! 464/*!
465 \fn void QPEApplication::reload() 465 \fn void QPEApplication::reload()
466 466
467*/ 467*/
468 468
469/*! 469/*!
470 \fn void QPEApplication::appMessage( const QCString& msg, const QByteArray& data ) 470 \fn void QPEApplication::appMessage( const QCString& msg, const QByteArray& data )
471 471
472 This signal is emitted when a message is received on this 472 This signal is emitted when a message is received on this
473 application's QPE/Application/<i>appname</i> \link qcop.html 473 application's QPE/Application/<i>appname</i> \link qcop.html
474 QCop\endlink channel. 474 QCop\endlink channel.
475 475
476 The slot to which you connect this signal uses \a msg and \a data 476 The slot to which you connect this signal uses \a msg and \a data
477 in the following way: 477 in the following way:
478 478
479\code 479\code
480 void MyWidget::receive( const QCString& msg, const QByteArray& data ) 480 void MyWidget::receive( const QCString& msg, const QByteArray& data )
481 { 481 {
482 QDataStream stream( data, IO_ReadOnly ); 482 QDataStream stream( data, IO_ReadOnly );
483 if ( msg == "someMessage(int,int,int)" ) { 483 if ( msg == "someMessage(int,int,int)" ) {
484 int a,b,c; 484 int a,b,c;
485 stream >> a >> b >> c; 485 stream >> a >> b >> c;
486 ... 486 ...
487 } else if ( msg == "otherMessage(QString)" ) { 487 } else if ( msg == "otherMessage(QString)" ) {
488 ... 488 ...
489 } 489 }
490 } 490 }
491\endcode 491\endcode
492 492
493 \sa qcop.html 493 \sa qcop.html
494 Note that messages received here may be processed by qpe application 494 Note that messages received here may be processed by qpe application
495 and emitted as signals, such as flush() and reload(). 495 and emitted as signals, such as flush() and reload().
496*/ 496*/
497 497
498/*! 498/*!
499 Constructs a QPEApplication just as you would construct 499 Constructs a QPEApplication just as you would construct
500 a QApplication, passing \a argc, \a argv, and \a t. 500 a QApplication, passing \a argc, \a argv, and \a t.
501 501
502 For applications, \a t should be the default, GuiClient. Only 502 For applications, \a t should be the default, GuiClient. Only
503 the Qtopia server passes GuiServer. 503 the Qtopia server passes GuiServer.
504*/ 504*/
505QPEApplication::QPEApplication( int & argc, char **argv, Type t ) 505QPEApplication::QPEApplication( int & argc, char **argv, Type t )
506 : QApplication( argc, argv, t ) 506 : QApplication( argc, argv, t )
507{ 507{
508 d = new QPEApplicationData; 508 d = new QPEApplicationData;
509 d->loadTextCodecs(); 509 d->loadTextCodecs();
510 d->loadImageCodecs(); 510 d->loadImageCodecs();
511 int dw = desktop() ->width(); 511 int dw = desktop() ->width();
512 512
513 if ( dw < 200 ) { 513 if ( dw < 200 ) {
514 setFont( QFont( "helvetica", 8 ) ); 514 setFont( QFont( "helvetica", 8 ) );
515 AppLnk::setSmallIconSize( 10 ); 515 AppLnk::setSmallIconSize( 10 );
516 AppLnk::setBigIconSize( 28 ); 516 AppLnk::setBigIconSize( 28 );
517 } 517 }
518 else if ( dw > 600 ) { 518 else if ( dw > 600 ) {
519 setFont( QFont( "helvetica", 18 ) ); 519 setFont( QFont( "helvetica", 18 ) );
520 AppLnk::setSmallIconSize( 24 ); 520 AppLnk::setSmallIconSize( 24 );
521 AppLnk::setBigIconSize( 48 ); 521 AppLnk::setBigIconSize( 48 );
522 } 522 }
523 else if ( dw > 200 ) { 523 else if ( dw > 200 ) {
524 setFont( QFont( "helvetica", 10 ) ); 524 setFont( QFont( "helvetica", 10 ) );
525 AppLnk::setSmallIconSize( 14 ); 525 AppLnk::setSmallIconSize( 14 );
526 AppLnk::setBigIconSize( 32 ); 526 AppLnk::setBigIconSize( 32 );
527 } 527 }
528 528
529 529
530 QMimeSourceFactory::setDefaultFactory( new ResourceMimeFactory ); 530 QMimeSourceFactory::setDefaultFactory( new ResourceMimeFactory );
531 531
532 connect( this, SIGNAL( lastWindowClosed() ), this, SLOT( hideOrQuit() ) ); 532 connect( this, SIGNAL( lastWindowClosed() ), this, SLOT( hideOrQuit() ) );
533#if defined(Q_WS_QWS) && !defined(QT_NO_COP) 533#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
534 534
535 QString qcopfn( "/tmp/qcop-msg-" ); 535 QString qcopfn( "/tmp/qcop-msg-" );
536 qcopfn += QString( argv[ 0 ] ); // append command name 536 qcopfn += QString( argv[ 0 ] ); // append command name
537 537
538 QFile f( qcopfn ); 538 QFile f( qcopfn );
539 if ( f.open( IO_ReadOnly ) ) { 539 if ( f.open( IO_ReadOnly ) ) {
540 flock( f.handle(), LOCK_EX ); 540 flock( f.handle(), LOCK_EX );
541 } 541 }
542 542
543 sysChannel = new QCopChannel( "QPE/System", this ); 543 sysChannel = new QCopChannel( "QPE/System", this );
544 connect( sysChannel, SIGNAL( received( const QCString &, const QByteArray & ) ), 544 connect( sysChannel, SIGNAL( received( const QCString &, const QByteArray & ) ),
545 this, SLOT( systemMessage( const QCString &, const QByteArray & ) ) ); 545 this, SLOT( systemMessage( const QCString &, const QByteArray & ) ) );
546 546
547 QCString channel = QCString( argv[ 0 ] ); 547 QCString channel = QCString( argv[ 0 ] );
548 channel.replace( QRegExp( ".*/" ), "" ); 548 channel.replace( QRegExp( ".*/" ), "" );
549 d->appName = channel; 549 d->appName = channel;
550 channel = "QPE/Application/" + channel; 550 channel = "QPE/Application/" + channel;
551 pidChannel = new QCopChannel( channel, this ); 551 pidChannel = new QCopChannel( channel, this );
552 connect( pidChannel, SIGNAL( received( const QCString &, const QByteArray & ) ), 552 connect( pidChannel, SIGNAL( received( const QCString &, const QByteArray & ) ),
553 this, SLOT( pidMessage( const QCString &, const QByteArray & ) ) ); 553 this, SLOT( pidMessage( const QCString &, const QByteArray & ) ) );
554 554
555 if ( f.isOpen() ) { 555 if ( f.isOpen() ) {
556 d->keep_running = FALSE; 556 d->keep_running = FALSE;
557 QDataStream ds( &f ); 557 QDataStream ds( &f );
558 QCString channel, message; 558 QCString channel, message;
559 QByteArray data; 559 QByteArray data;
560 while ( !ds.atEnd() ) { 560 while ( !ds.atEnd() ) {
561 ds >> channel >> message >> data; 561 ds >> channel >> message >> data;
562 d->enqueueQCop( channel, message, data ); 562 d->enqueueQCop( channel, message, data );
563 } 563 }
564 564
565 flock( f.handle(), LOCK_UN ); 565 flock( f.handle(), LOCK_UN );
566 f.close(); 566 f.close();
567 f.remove(); 567 f.remove();
568 } 568 }
569 569
570 for ( int a = 0; a < argc; a++ ) { 570 for ( int a = 0; a < argc; a++ ) {
571 if ( qstrcmp( argv[ a ], "-preload" ) == 0 ) { 571 if ( qstrcmp( argv[ a ], "-preload" ) == 0 ) {
572 argv[ a ] = argv[ a + 1 ]; 572 argv[ a ] = argv[ a + 1 ];
573 a++; 573 a++;
574 d->preloaded = TRUE; 574 d->preloaded = TRUE;
575 argc -= 1; 575 argc -= 1;
576 } 576 }
577 else if ( qstrcmp( argv[ a ], "-preload-show" ) == 0 ) { 577 else if ( qstrcmp( argv[ a ], "-preload-show" ) == 0 ) {
578 argv[ a ] = argv[ a + 1 ]; 578 argv[ a ] = argv[ a + 1 ];
579 a++; 579 a++;
580 d->preloaded = TRUE; 580 d->preloaded = TRUE;
581 d->forceshow = TRUE; 581 d->forceshow = TRUE;
582 argc -= 1; 582 argc -= 1;
583 } 583 }
584 } 584 }
585 585
586 /* overide stored arguments */ 586 /* overide stored arguments */
587 setArgs( argc, argv ); 587 setArgs( argc, argv );
588 588
589#endif 589#endif
590 590
591 // qwsSetDecoration( new QPEDecoration() ); 591 // qwsSetDecoration( new QPEDecoration() );
592 592
593#ifndef QT_NO_TRANSLATION 593#ifndef QT_NO_TRANSLATION
594 594
595 QStringList langs = Global::languageList(); 595 QStringList langs = Global::languageList();
596 for ( QStringList::ConstIterator it = langs.begin(); it != langs.end(); ++it ) { 596 for ( QStringList::ConstIterator it = langs.begin(); it != langs.end(); ++it ) {
597 QString lang = *it; 597 QString lang = *it;
598 598
599 QTranslator * trans; 599 QTranslator * trans;
600 QString tfn; 600 QString tfn;
601 601
602 trans = new QTranslator( this ); 602 trans = new QTranslator( this );
603 tfn = qpeDir() + "/i18n/" + lang + "/libqpe.qm"; 603 tfn = qpeDir() + "/i18n/" + lang + "/libqpe.qm";
604 if ( trans->load( tfn ) ) 604 if ( trans->load( tfn ) )
605 installTranslator( trans ); 605 installTranslator( trans );
606 else 606 else
607 delete trans; 607 delete trans;
608 608
609 trans = new QTranslator( this ); 609 trans = new QTranslator( this );
610 tfn = qpeDir() + "/i18n/" + lang + "/" + d->appName + ".qm"; 610 tfn = qpeDir() + "/i18n/" + lang + "/" + d->appName + ".qm";
611 if ( trans->load( tfn ) ) 611 if ( trans->load( tfn ) )
612 installTranslator( trans ); 612 installTranslator( trans );
613 else 613 else
614 delete trans; 614 delete trans;
615 615
616 //###language/font hack; should look it up somewhere 616 //###language/font hack; should look it up somewhere
617#ifdef QWS 617#ifdef QWS
618 618
619 if ( lang == "ja" || lang == "zh_CN" || lang == "zh_TW" || lang == "ko" ) { 619 if ( lang == "ja" || lang == "zh_CN" || lang == "zh_TW" || lang == "ko" ) {
620 QFont fn = FontManager::unicodeFont( FontManager::Proportional ); 620 QFont fn = FontManager::unicodeFont( FontManager::Proportional );
621 setFont( fn ); 621 setFont( fn );
622 } 622 }
623#endif 623#endif
624 624
625 } 625 }
626#endif 626#endif
627 627
628 applyStyle(); 628 applyStyle();
629 629
630 if ( type() == GuiServer ) { 630 if ( type() == GuiServer ) {
631 setVolume(); 631 setVolume();
632 } 632 }
633 633
634 installEventFilter( this ); 634 installEventFilter( this );
635 635
636 QPEMenuToolFocusManager::initialize(); 636 QPEMenuToolFocusManager::initialize();
637 637
638#ifdef QT_NO_QWS_CURSOR 638#ifdef QT_NO_QWS_CURSOR
639 // if we have no cursor, probably don't want tooltips 639 // if we have no cursor, probably don't want tooltips
640 QToolTip::setEnabled( FALSE ); 640 QToolTip::setEnabled( FALSE );
641#endif 641#endif
642} 642}
643 643
644static QPtrDict<void>* inputMethodDict = 0; 644static QPtrDict<void>* inputMethodDict = 0;
645static void createInputMethodDict() 645static void createInputMethodDict()
646{ 646{
647 if ( !inputMethodDict ) 647 if ( !inputMethodDict )
648 inputMethodDict = new QPtrDict<void>; 648 inputMethodDict = new QPtrDict<void>;
649} 649}
650 650
651/*! 651/*!
652 Returns the currently set hint to the system as to whether 652 Returns the currently set hint to the system as to whether
653 widget \a w has any use for text input methods. 653 widget \a w has any use for text input methods.
654 654
655 655
656 \sa setInputMethodHint() InputMethodHint 656 \sa setInputMethodHint() InputMethodHint
657*/ 657*/
658QPEApplication::InputMethodHint QPEApplication::inputMethodHint( QWidget * w ) 658QPEApplication::InputMethodHint QPEApplication::inputMethodHint( QWidget * w )
659{ 659{
660 if ( inputMethodDict && w ) 660 if ( inputMethodDict && w )
661 return ( InputMethodHint ) ( int ) inputMethodDict->find( w ); 661 return ( InputMethodHint ) ( int ) inputMethodDict->find( w );
662 return Normal; 662 return Normal;
663} 663}
664 664
665/*! 665/*!
666 \enum QPEApplication::InputMethodHint 666 \enum QPEApplication::InputMethodHint
667 667
668 \value Normal the application sometimes needs text input (the default). 668 \value Normal the application sometimes needs text input (the default).
669 \value AlwaysOff the application never needs text input. 669 \value AlwaysOff the application never needs text input.
670 \value AlwaysOn the application always needs text input. 670 \value AlwaysOn the application always needs text input.
671*/ 671*/
672 672
673/*! 673/*!
674 Hints to the system that widget \a w has use for text input methods 674 Hints to the system that widget \a w has use for text input methods
675 as specified by \a mode. 675 as specified by \a mode.
676 676
677 \sa inputMethodHint() InputMethodHint 677 \sa inputMethodHint() InputMethodHint
678*/ 678*/
679void QPEApplication::setInputMethodHint( QWidget * w, InputMethodHint mode ) 679void QPEApplication::setInputMethodHint( QWidget * w, InputMethodHint mode )
680{ 680{
681 createInputMethodDict(); 681 createInputMethodDict();
682 if ( mode == Normal ) { 682 if ( mode == Normal ) {
683 inputMethodDict->remove 683 inputMethodDict->remove
684 ( w ); 684 ( w );
685 } 685 }
686 else { 686 else {
687 inputMethodDict->insert( w, ( void* ) mode ); 687 inputMethodDict->insert( w, ( void* ) mode );
688 } 688 }
689} 689}
690 690
691class HackDialog : public QDialog 691class HackDialog : public QDialog
692{ 692{
693public: 693public:
694 void acceptIt() 694 void acceptIt()
695 { 695 {
696 accept(); 696 accept();
697 } 697 }
698 void rejectIt() 698 void rejectIt()
699 { 699 {
700 reject(); 700 reject();
701 } 701 }
702}; 702};
703 703
704 704
705void QPEApplication::mapToDefaultAction( QWSKeyEvent * ke, int key ) 705void QPEApplication::mapToDefaultAction( QWSKeyEvent * ke, int key )
706{ 706{
707 // specialised actions for certain widgets. May want to 707 // specialised actions for certain widgets. May want to
708 // add more stuff here. 708 // add more stuff here.
709 if ( activePopupWidget() && activePopupWidget() ->inherits( "QListBox" ) 709 if ( activePopupWidget() && activePopupWidget() ->inherits( "QListBox" )
@@ -1515,292 +1515,293 @@ QPEApplication::StylusMode QPEApplication::stylusOperation( QWidget* w )
1515/*! 1515/*!
1516 \enum QPEApplication::StylusMode 1516 \enum QPEApplication::StylusMode
1517 1517
1518 \value LeftOnly the stylus only generates LeftButton 1518 \value LeftOnly the stylus only generates LeftButton
1519 events (the default). 1519 events (the default).
1520 \value RightOnHold the stylus generates RightButton events 1520 \value RightOnHold the stylus generates RightButton events
1521 if the user uses the press-and-hold gesture. 1521 if the user uses the press-and-hold gesture.
1522 1522
1523 \sa setStylusOperation() stylusOperation() 1523 \sa setStylusOperation() stylusOperation()
1524*/ 1524*/
1525 1525
1526/*! 1526/*!
1527 Causes widget \a w to receive mouse events according to the stylus 1527 Causes widget \a w to receive mouse events according to the stylus
1528 \a mode. 1528 \a mode.
1529 1529
1530 \sa stylusOperation() StylusMode 1530 \sa stylusOperation() StylusMode
1531*/ 1531*/
1532void QPEApplication::setStylusOperation( QWidget * w, StylusMode mode ) 1532void QPEApplication::setStylusOperation( QWidget * w, StylusMode mode )
1533{ 1533{
1534 createDict(); 1534 createDict();
1535 if ( mode == LeftOnly ) { 1535 if ( mode == LeftOnly ) {
1536 stylusDict->remove 1536 stylusDict->remove
1537 ( w ); 1537 ( w );
1538 w->removeEventFilter( qApp ); 1538 w->removeEventFilter( qApp );
1539 } 1539 }
1540 else { 1540 else {
1541 stylusDict->insert( w, ( void* ) mode ); 1541 stylusDict->insert( w, ( void* ) mode );
1542 connect( w, SIGNAL( destroyed() ), qApp, SLOT( removeSenderFromStylusDict() ) ); 1542 connect( w, SIGNAL( destroyed() ), qApp, SLOT( removeSenderFromStylusDict() ) );
1543 w->installEventFilter( qApp ); 1543 w->installEventFilter( qApp );
1544 } 1544 }
1545} 1545}
1546 1546
1547 1547
1548/*! 1548/*!
1549 \reimp 1549 \reimp
1550*/ 1550*/
1551bool QPEApplication::eventFilter( QObject *o, QEvent *e ) 1551bool QPEApplication::eventFilter( QObject *o, QEvent *e )
1552{ 1552{
1553 if ( stylusDict && e->type() >= QEvent::MouseButtonPress && e->type() <= QEvent::MouseMove ) { 1553 if ( stylusDict && e->type() >= QEvent::MouseButtonPress && e->type() <= QEvent::MouseMove ) {
1554 QMouseEvent * me = ( QMouseEvent* ) e; 1554 QMouseEvent * me = ( QMouseEvent* ) e;
1555 StylusMode mode = (StylusMode)(int)stylusDict->find(o); 1555 StylusMode mode = (StylusMode)(int)stylusDict->find(o);
1556 switch (mode) { 1556 switch (mode) {
1557 case RightOnHold: 1557 case RightOnHold:
1558 switch ( me->type() ) { 1558 switch ( me->type() ) {
1559 case QEvent::MouseButtonPress: 1559 case QEvent::MouseButtonPress:
1560 if ( me->button() == LeftButton ) { 1560 if ( me->button() == LeftButton ) {
1561 d->presstimer = startTimer(500); // #### pref. 1561 d->presstimer = startTimer(500); // #### pref.
1562 d->presswidget = (QWidget*)o; 1562 d->presswidget = (QWidget*)o;
1563 d->presspos = me->pos(); 1563 d->presspos = me->pos();
1564 d->rightpressed = FALSE; 1564 d->rightpressed = FALSE;
1565 } 1565 }
1566 break; 1566 break;
1567 case QEvent::MouseMove: 1567 case QEvent::MouseMove:
1568 if (d->presstimer && (me->pos() - d->presspos).manhattanLength() > 8) { 1568 if (d->presstimer && (me->pos() - d->presspos).manhattanLength() > 8) {
1569 killTimer(d->presstimer); 1569 killTimer(d->presstimer);
1570 d->presstimer = 0; 1570 d->presstimer = 0;
1571 } 1571 }
1572 break; 1572 break;
1573 case QEvent::MouseButtonRelease: 1573 case QEvent::MouseButtonRelease:
1574 if ( me->button() == LeftButton ) { 1574 if ( me->button() == LeftButton ) {
1575 if ( d->presstimer ) { 1575 if ( d->presstimer ) {
1576 killTimer(d->presstimer); 1576 killTimer(d->presstimer);
1577 d->presstimer = 0; 1577 d->presstimer = 0;
1578 } 1578 }
1579 if ( d->rightpressed && d->presswidget ) { 1579 if ( d->rightpressed && d->presswidget ) {
1580 // Right released 1580 // Right released
1581 postEvent( d->presswidget, 1581 postEvent( d->presswidget,
1582 new QMouseEvent( QEvent::MouseButtonRelease, me->pos(), 1582 new QMouseEvent( QEvent::MouseButtonRelease, me->pos(),
1583 RightButton, LeftButton + RightButton ) ); 1583 RightButton, LeftButton + RightButton ) );
1584 // Left released, off-widget 1584 // Left released, off-widget
1585 postEvent( d->presswidget, 1585 postEvent( d->presswidget,
1586 new QMouseEvent( QEvent::MouseMove, QPoint( -1, -1), 1586 new QMouseEvent( QEvent::MouseMove, QPoint( -1, -1),
1587 LeftButton, LeftButton ) ); 1587 LeftButton, LeftButton ) );
1588 postEvent( d->presswidget, 1588 postEvent( d->presswidget,
1589 new QMouseEvent( QEvent::MouseButtonRelease, QPoint( -1, -1), 1589 new QMouseEvent( QEvent::MouseButtonRelease, QPoint( -1, -1),
1590 LeftButton, LeftButton ) ); 1590 LeftButton, LeftButton ) );
1591 d->rightpressed = FALSE; 1591 d->rightpressed = FALSE;
1592 return TRUE; // don't send the real Left release 1592 return TRUE; // don't send the real Left release
1593 } 1593 }
1594 } 1594 }
1595 break; 1595 break;
1596 default: 1596 default:
1597 break; 1597 break;
1598 } 1598 }
1599 break; 1599 break;
1600 default: 1600 default:
1601 ; 1601 ;
1602 } 1602 }
1603 } 1603 }
1604 else if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) { 1604 else if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) {
1605 QKeyEvent *ke = (QKeyEvent *)e; 1605 QKeyEvent *ke = (QKeyEvent *)e;
1606 if ( ke->key() == Key_Enter ) { 1606 if ( ke->key() == Key_Enter ) {
1607 if ( o->isA( "QRadioButton" ) || o->isA( "QCheckBox" ) ) { 1607 if ( o->isA( "QRadioButton" ) || o->isA( "QCheckBox" ) ) {
1608 postEvent( o, new QKeyEvent( e->type(), Key_Space, ' ', 1608 postEvent( o, new QKeyEvent( e->type(), Key_Space, ' ',
1609 ke->state(), " ", ke->isAutoRepeat(), ke->count() ) ); 1609 ke->state(), " ", ke->isAutoRepeat(), ke->count() ) );
1610 return TRUE; 1610 return TRUE;
1611 } 1611 }
1612 } 1612 }
1613 } 1613 }
1614 return FALSE; 1614 return FALSE;
1615} 1615}
1616 1616
1617/*! 1617/*!
1618 \reimp 1618 \reimp
1619*/ 1619*/
1620void QPEApplication::timerEvent( QTimerEvent *e ) 1620void QPEApplication::timerEvent( QTimerEvent *e )
1621{ 1621{
1622 if ( e->timerId() == d->presstimer && d->presswidget ) { 1622 if ( e->timerId() == d->presstimer && d->presswidget ) {
1623 // Right pressed 1623 // Right pressed
1624 postEvent( d->presswidget, 1624 postEvent( d->presswidget,
1625 new QMouseEvent( QEvent::MouseButtonPress, d->presspos, 1625 new QMouseEvent( QEvent::MouseButtonPress, d->presspos,
1626 RightButton, LeftButton ) ); 1626 RightButton, LeftButton ) );
1627 killTimer( d->presstimer ); 1627 killTimer( d->presstimer );
1628 d->presstimer = 0; 1628 d->presstimer = 0;
1629 d->rightpressed = TRUE; 1629 d->rightpressed = TRUE;
1630 } 1630 }
1631} 1631}
1632 1632
1633void QPEApplication::removeSenderFromStylusDict() 1633void QPEApplication::removeSenderFromStylusDict()
1634{ 1634{
1635 stylusDict->remove 1635 stylusDict->remove
1636 ( ( void* ) sender() ); 1636 ( ( void* ) sender() );
1637 if ( d->presswidget == sender() ) 1637 if ( d->presswidget == sender() )
1638 d->presswidget = 0; 1638 d->presswidget = 0;
1639} 1639}
1640 1640
1641/*! 1641/*!
1642 \internal 1642 \internal
1643*/ 1643*/
1644bool QPEApplication::keyboardGrabbed() const 1644bool QPEApplication::keyboardGrabbed() const
1645{ 1645{
1646 return d->kbgrabbed; 1646 return d->kbgrabbed;
1647} 1647}
1648 1648
1649 1649
1650/*! 1650/*!
1651 Reverses the effect of grabKeyboard(). This is called automatically 1651 Reverses the effect of grabKeyboard(). This is called automatically
1652 on program exit. 1652 on program exit.
1653*/ 1653*/
1654void QPEApplication::ungrabKeyboard() 1654void QPEApplication::ungrabKeyboard()
1655{ 1655{
1656 ((QPEApplication *) qApp )-> d-> kbgrabbed = false; 1656 ((QPEApplication *) qApp )-> d-> kbgrabbed = false;
1657} 1657}
1658 1658
1659/*! 1659/*!
1660 Grabs the physical keyboard keys, e.g. the application's launching 1660 Grabs the physical keyboard keys, e.g. the application's launching
1661 keys. Instead of launching applications when these keys are pressed 1661 keys. Instead of launching applications when these keys are pressed
1662 the signals emitted are sent to this application instead. Some games 1662 the signals emitted are sent to this application instead. Some games
1663 programs take over the launch keys in this way to make interaction 1663 programs take over the launch keys in this way to make interaction
1664 easier. 1664 easier.
1665 1665
1666 \sa ungrabKeyboard() 1666 \sa ungrabKeyboard()
1667*/ 1667*/
1668void QPEApplication::grabKeyboard() 1668void QPEApplication::grabKeyboard()
1669{ 1669{
1670 ((QPEApplication *) qApp )-> d-> kbgrabbed = true; 1670 ((QPEApplication *) qApp )-> d-> kbgrabbed = true;
1671} 1671}
1672 1672
1673/*! 1673/*!
1674 \reimp 1674 \reimp
1675*/ 1675*/
1676int QPEApplication::exec() 1676int QPEApplication::exec()
1677{ 1677{
1678#ifndef QT_NO_COP 1678#ifndef QT_NO_COP
1679 d->sendQCopQ(); 1679 d->sendQCopQ();
1680#endif 1680#endif
1681 1681
1682 if ( d->keep_running ) 1682 if ( d->keep_running )
1683 //|| d->qpe_main_widget && d->qpe_main_widget->isVisible() ) 1683 //|| d->qpe_main_widget && d->qpe_main_widget->isVisible() )
1684 return QApplication::exec(); 1684 return QApplication::exec();
1685 1685
1686#ifndef QT_NO_COP 1686#ifndef QT_NO_COP
1687 1687
1688 { 1688 {
1689 QCopEnvelope e( "QPE/System", "closing(QString)" ); 1689 QCopEnvelope e( "QPE/System", "closing(QString)" );
1690 e << d->appName; 1690 e << d->appName;
1691 } 1691 }
1692#endif 1692#endif
1693 processEvents(); 1693 processEvents();
1694 return 0; 1694 return 0;
1695} 1695}
1696 1696
1697/*! 1697/*!
1698 \internal 1698 \internal
1699 External request for application to quit. Quits if possible without 1699 External request for application to quit. Quits if possible without
1700 loosing state. 1700 loosing state.
1701*/ 1701*/
1702void QPEApplication::tryQuit() 1702void QPEApplication::tryQuit()
1703{ 1703{
1704 if ( activeModalWidget() || strcmp( argv() [ 0 ], "embeddedkonsole" ) == 0 ) 1704 if ( activeModalWidget() || strcmp( argv() [ 0 ], "embeddedkonsole" ) == 0 )
1705 return ; // Inside modal loop or konsole. Too hard to save state. 1705 return ; // Inside modal loop or konsole. Too hard to save state.
1706#ifndef QT_NO_COP 1706#ifndef QT_NO_COP
1707 1707
1708 { 1708 {
1709 QCopEnvelope e( "QPE/System", "closing(QString)" ); 1709 QCopEnvelope e( "QPE/System", "closing(QString)" );
1710 e << d->appName; 1710 e << d->appName;
1711 } 1711 }
1712#endif 1712#endif
1713 processEvents(); 1713 processEvents();
1714 1714
1715 quit(); 1715 quit();
1716} 1716}
1717 1717
1718/*! 1718/*!
1719 \internal 1719 \internal
1720 User initiated quit. Makes the window 'Go Away'. If preloaded this means 1720 User initiated quit. Makes the window 'Go Away'. If preloaded this means
1721 hiding the window. If not it means quitting the application. 1721 hiding the window. If not it means quitting the application.
1722 As this is user initiated we don't need to check state. 1722 As this is user initiated we don't need to check state.
1723*/ 1723*/
1724void QPEApplication::hideOrQuit() 1724void QPEApplication::hideOrQuit()
1725{ 1725{
1726 processEvents(); 1726 processEvents();
1727 1727
1728 // If we are a preloaded application we don't actually quit, so emit 1728 // If we are a preloaded application we don't actually quit, so emit
1729 // a System message indicating we're quasi-closing. 1729 // a System message indicating we're quasi-closing.
1730 if ( d->preloaded && d->qpe_main_widget ) 1730 if ( d->preloaded && d->qpe_main_widget )
1731#ifndef QT_NO_COP 1731#ifndef QT_NO_COP
1732 1732
1733 { 1733 {
1734 QCopEnvelope e("QPE/System", "fastAppHiding(QString)" ); 1734 QCopEnvelope e("QPE/System", "fastAppHiding(QString)" );
1735 e << d->appName; 1735 e << d->appName;
1736 d->qpe_main_widget->hide(); 1736 d->qpe_main_widget->hide();
1737 } 1737 }
1738#endif 1738#endif
1739 else 1739 else
1740 quit(); 1740 quit();
1741} 1741}
1742 1742
1743 1743
1744#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) 1744#if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX)
1745 1745
1746// The libraries with the skiff package (and possibly others) have 1746// The libraries with the skiff package (and possibly others) have
1747// completely useless implementations of builtin new and delete that 1747// completely useless implementations of builtin new and delete that
1748// use about 50% of your CPU. Here we revert to the simple libc 1748// use about 50% of your CPU. Here we revert to the simple libc
1749// functions. 1749// functions.
1750 1750
1751void* operator new[]( size_t size ) 1751void* operator new[]( size_t size )
1752{ 1752{
1753 return malloc( size ); 1753 return malloc( size );
1754} 1754}
1755 1755
1756void* operator new( size_t size ) 1756void* operator new( size_t size )
1757{ 1757{
1758 return malloc( size ); 1758 return malloc( size );
1759} 1759}
1760 1760
1761void operator delete[]( void* p ) 1761void operator delete[]( void* p )
1762{ 1762{
1763 free( p ); 1763 free( p );
1764} 1764}
1765 1765
1766void operator delete[]( void* p, size_t /*size*/ ) 1766void operator delete[]( void* p, size_t /*size*/ )
1767{ 1767{
1768 free( p ); 1768 free( p );
1769} 1769}
1770 1770
1771
1771void operator delete( void* p ) 1772void operator delete( void* p )
1772{ 1773{
1773 free( p ); 1774 free( p );
1774} 1775}
1775 1776
1776void operator delete( void* p, size_t /*size*/ ) 1777void operator delete( void* p, size_t /*size*/ )
1777{ 1778{
1778 free( p ); 1779 free( p );
1779} 1780}
1780 1781
1781#endif 1782#endif
1782 1783
1783#if ( QT_VERSION <= 230 ) && !defined(SINGLE_APP) 1784#if ( QT_VERSION <= 230 ) && !defined(SINGLE_APP)
1784#include <qwidgetlist.h> 1785#include <qwidgetlist.h>
1785#ifdef QWS 1786#ifdef QWS
1786#include <qgfx_qws.h> 1787#include <qgfx_qws.h>
1787extern QRect qt_maxWindowRect; 1788extern QRect qt_maxWindowRect;
1788void qt_setMaxWindowRect(const QRect& r ) 1789void qt_setMaxWindowRect(const QRect& r )
1789{ 1790{
1790 qt_maxWindowRect = qt_screen->mapFromDevice( r, 1791 qt_maxWindowRect = qt_screen->mapFromDevice( r,
1791 qt_screen->mapToDevice( QSize( qt_screen->width(), qt_screen->height() ) ) ); 1792 qt_screen->mapToDevice( QSize( qt_screen->width(), qt_screen->height() ) ) );
1792 // Re-resize any maximized windows 1793 // Re-resize any maximized windows
1793 QWidgetList* l = QApplication::topLevelWidgets(); 1794 QWidgetList* l = QApplication::topLevelWidgets();
1794 if ( l ) { 1795 if ( l ) {
1795 QWidget * w = l->first(); 1796 QWidget * w = l->first();
1796 while ( w ) { 1797 while ( w ) {
1797 if ( w->isVisible() && w->isMaximized() ) { 1798 if ( w->isVisible() && w->isMaximized() ) {
1798 w->showMaximized(); 1799 w->showMaximized();
1799 } 1800 }
1800 w = l->next(); 1801 w = l->next();
1801 } 1802 }
1802 delete l; 1803 delete l;
1803 } 1804 }
1804} 1805}
1805#endif 1806#endif
1806#endif 1807#endif
diff --git a/library/storage.cpp b/library/storage.cpp
index f4c1c02..12f9df9 100644
--- a/library/storage.cpp
+++ b/library/storage.cpp
@@ -1,261 +1,261 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) Holger 'zecke' Freyther <freyther@kde.org> 2** Copyright (C) Holger 'zecke' Freyther <freyther@kde.org>
3** Copyright (C) Lorn Potter <llornkcor@handhelds.org> 3** Copyright (C) Lorn Potter <llornkcor@handhelds.org>
4** Copyright (C) 2000 Trolltech AS. All rights reserved. 4** Copyright (C) 2000 Trolltech AS. All rights reserved.
5** 5**
6** This file is part of Opie Environment. 6** This file is part of Opie Environment.
7** 7**
8** This file may be distributed and/or modified under the terms of the 8** This file may be distributed and/or modified under the terms of the
9** GNU General Public License version 2 as published by the Free Software 9** GNU General Public License version 2 as published by the Free Software
10** Foundation and appearing in the file LICENSE.GPL included in the 10** Foundation and appearing in the file LICENSE.GPL included in the
11** packaging of this file. 11** packaging of this file.
12** 12**
13** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 13** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
14** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 14** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15** 15**
16** See http://www.trolltech.com/gpl/ for GPL licensing information. 16** See http://www.trolltech.com/gpl/ for GPL licensing information.
17** 17**
18** Contact info@trolltech.com if any conditions of this licensing are 18** Contact info@trolltech.com if any conditions of this licensing are
19** not clear to you. 19** not clear to you.
20** 20**
21**********************************************************************/ 21**********************************************************************/
22 22
23#include <qpe/storage.h> 23#include <qpe/storage.h>
24#ifdef QT_QWS_SL5XXX 24#ifdef QT_QWS_SL5XXX
25#include <qpe/custom.h> 25#include <qpe/custom.h>
26#endif 26#endif
27 27
28#include <qfile.h> 28#include <qfile.h>
29#include <qtimer.h> 29#include <qtimer.h>
30#include <qcopchannel_qws.h> 30#include <qcopchannel_qws.h>
31 31
32#include <stdio.h> 32#include <stdio.h>
33 33
34#if defined(_OS_LINUX_) || defined(Q_OS_LINUX) 34#if defined(_OS_LINUX_) || defined(Q_OS_LINUX)
35#include <sys/vfs.h> 35#include <sys/vfs.h>
36#include <mntent.h> 36#include <mntent.h>
37#endif 37#endif
38 38
39#include <qstringlist.h> 39#include <qstringlist.h>
40 40
41#include <sys/vfs.h> 41#include <sys/vfs.h>
42#include <mntent.h> 42#include <mntent.h>
43 43
44 44
45static bool isCF(const QString& m) 45static bool isCF(const QString& m)
46{ 46{
47 FILE* f = fopen("/var/run/stab", "r"); 47 FILE* f = fopen("/var/run/stab", "r");
48 if (!f) f = fopen("/var/state/pcmcia/stab", "r"); 48 if (!f) f = fopen("/var/state/pcmcia/stab", "r");
49 if (!f) f = fopen("/var/lib/pcmcia/stab", "r"); 49 if (!f) f = fopen("/var/lib/pcmcia/stab", "r");
50 if ( f ) { 50 if ( f ) {
51 char line[1024]; 51 char line[1024];
52 char devtype[80]; 52 char devtype[80];
53 char devname[80]; 53 char devname[80];
54 while ( fgets( line, 1024, f ) ) { 54 while ( fgets( line, 1024, f ) ) {
55 // 0 ide ide-cs 0 hda 3 0 55 // 0 ide ide-cs 0 hda 3 0
56 if ( sscanf(line,"%*d %s %*s %*s %s", devtype, devname )==2 ) 56 if ( sscanf(line,"%*d %s %*s %*s %s", devtype, devname )==2 )
57 { 57 {
58 if ( QString(devtype) == "ide" && m.find(devname)>0 ) { 58 if ( QString(devtype) == "ide" && m.find(devname)>0 ) {
59 fclose(f); 59 fclose(f);
60 return TRUE; 60 return TRUE;
61 } 61 }
62 } 62 }
63 } 63 }
64 fclose(f); 64 fclose(f);
65 } 65 }
66 return FALSE; 66 return FALSE;
67} 67}
68 68
69StorageInfo::StorageInfo( QObject *parent ) 69StorageInfo::StorageInfo( QObject *parent )
70 : QObject( parent ) 70 : QObject( parent )
71{ 71{
72 mFileSystems.setAutoDelete( TRUE ); 72 mFileSystems.setAutoDelete( TRUE );
73 channel = new QCopChannel( "QPE/Card", this ); 73 channel = new QCopChannel( "QPE/Card", this );
74 connect( channel, SIGNAL(received(const QCString &, const QByteArray &)), 74 connect( channel, SIGNAL(received(const QCString &, const QByteArray &)),
75 this, SLOT(cardMessage( const QCString &, const QByteArray &)) ); 75 this, SLOT(cardMessage( const QCString &, const QByteArray &)) );
76 update(); 76 update();
77} 77}
78 78
79const FileSystem *StorageInfo::fileSystemOf( const QString &filename ) 79const FileSystem *StorageInfo::fileSystemOf( const QString &filename )
80{ 80{
81 for (QListIterator<FileSystem> i(mFileSystems); i.current(); ++i) { 81 for (QListIterator<FileSystem> i(mFileSystems); i.current(); ++i) {
82 if ( filename.startsWith( (*i)->path() ) ) 82 if ( filename.startsWith( (*i)->path() ) )
83 return (*i); 83 return (*i);
84 } 84 }
85 return 0; 85 return 0;
86} 86}
87 87
88 88
89void StorageInfo::cardMessage( const QCString& msg, const QByteArray& ) 89void StorageInfo::cardMessage( const QCString& msg, const QByteArray& )
90{ 90{
91 if ( msg == "mtabChanged()" ) 91 if ( msg == "mtabChanged()" )
92 update(); 92 update();
93} 93}
94// cause of the lack of a d pointer we need 94// cause of the lack of a d pointer we need
95// to store informations in a config file :( 95// to store informations in a config file :(
96void StorageInfo::update() 96void StorageInfo::update()
97{ 97{
98 //qDebug("StorageInfo::updating"); 98 //qDebug("StorageInfo::updating");
99#if defined(_OS_LINUX_) || defined(Q_OS_LINUX) 99#if defined(_OS_LINUX_) || defined(Q_OS_LINUX)
100 struct mntent *me; 100 struct mntent *me;
101 FILE *mntfp = setmntent( "/etc/mtab", "r" ); 101 FILE *mntfp = setmntent( "/etc/mtab", "r" );
102 102
103 QStringList curdisks; 103 QStringList curdisks;
104 QStringList curopts; 104 QStringList curopts;
105 QStringList curfs; 105 QStringList curfs;
106 bool rebuild = FALSE; 106 bool rebuild = FALSE;
107 int n=0; 107 int n=0;
108 if ( mntfp ) { 108 if ( mntfp ) {
109 while ( (me = getmntent( mntfp )) != 0 ) { 109 while ( (me = getmntent( mntfp )) != 0 ) {
110 QString fs = me->mnt_fsname; 110 QString fs = me->mnt_fsname;
111 if ( fs.left(7)=="/dev/hd" || fs.left(7)=="/dev/sd" 111 if ( fs.left(7)=="/dev/hd" || fs.left(7)=="/dev/sd"
112 || fs.left(8)=="/dev/mtd" || fs.left(9) == "/dev/mmcd" 112 || fs.left(8)=="/dev/mtd" || fs.left(9) == "/dev/mmcd"
113 || fs.left( 14 ) == "/dev/mmc/part1" 113 || fs.left( 14 ) == "/dev/mmc/part1"
114 || fs.left(5)=="tmpfs" || fs.left(9)=="/dev/root" ) 114 || fs.left(5)=="tmpfs" || fs.left(9)=="/dev/root" )
115 { 115 {
116 n++; 116 n++;
117 curdisks.append(fs); 117 curdisks.append(fs);
118 curopts.append( me->mnt_opts ); 118 curopts.append( me->mnt_opts );
119 //qDebug("-->fs %s opts %s", fs.latin1(), me->mnt_opts ); 119 //qDebug("-->fs %s opts %s", fs.latin1(), me->mnt_opts );
120 curfs.append( me->mnt_dir ); 120 curfs.append( me->mnt_dir );
121 bool found = FALSE; 121 bool found = FALSE;
122 for (QListIterator<FileSystem> i(mFileSystems); i.current(); ++i) { 122 for (QListIterator<FileSystem> i(mFileSystems); i.current(); ++i) {
123 if ( (*i)->disk() == fs ) { 123 if ( (*i)->disk() == fs ) {
124 found = TRUE; 124 found = TRUE;
125 break; 125 break;
126 } 126 }
127 } 127 }
128 if ( !found ) 128 if ( !found )
129 rebuild = TRUE; 129 rebuild = TRUE;
130 } 130 }
131 } 131 }
132 endmntent( mntfp ); 132 endmntent( mntfp );
133 } 133 }
134 if ( rebuild || n != (int)mFileSystems.count() ) { 134 if ( rebuild || n != (int)mFileSystems.count() ) {
135 mFileSystems.clear(); 135 mFileSystems.clear();
136 QStringList::ConstIterator it=curdisks.begin(); 136 QStringList::ConstIterator it=curdisks.begin();
137 QStringList::ConstIterator fsit=curfs.begin(); 137 QStringList::ConstIterator fsit=curfs.begin();
138 QStringList::ConstIterator optsIt=curopts.begin(); 138 QStringList::ConstIterator optsIt=curopts.begin();
139 for (; it!=curdisks.end(); ++it, ++fsit, ++optsIt) { 139 for (; it!=curdisks.end(); ++it, ++fsit, ++optsIt) {
140 QString opts = *optsIt; 140 QString opts = *optsIt;
141 141
142 QString disk = *it; 142 QString disk = *it;
143 QString humanname; 143 QString humanname;
144 bool removable = FALSE; 144 bool removable = FALSE;
145 if ( isCF(disk) ) { 145 if ( isCF(disk) ) {
146 humanname = tr("CF Card"); 146 humanname = tr("CF Card");
147 removable = TRUE; 147 removable = TRUE;
148 } else if ( disk == "/dev/hda1" ) { 148 } else if ( disk == "/dev/hda1" ) {
149 humanname = tr("Hard Disk"); 149 humanname = tr("Hard Disk");
150 } else if ( disk.left(9) == "/dev/mmcd" ) { 150 } else if ( disk.left(9) == "/dev/mmcd" ) {
151 humanname = tr("SD Card"); 151 humanname = tr("SD Card");
152 removable = TRUE; 152 removable = TRUE;
153 } else if ( disk.left( 14 ) == "/dev/mmc/part1" ) { 153 } else if ( disk.left( 14 ) == "/dev/mmc/part1" ) {
154 humanname = tr("MMC Card"); 154 humanname = tr("MMC Card");
155 removable = TRUE; 155 removable = TRUE;
156 } else if ( disk.left(7) == "/dev/hd" ) 156 } else if ( disk.left(7) == "/dev/hd" )
157 humanname = tr("Hard Disk") + " " + disk; 157 humanname = tr("Hard Disk") + " " + disk;
158 else if ( disk.left(7) == "/dev/sd" ) 158 else if ( disk.left(7) == "/dev/sd" )
159 humanname = tr("SCSI Hard Disk") + " " + disk; 159 humanname = tr("SCSI Hard Disk") + " " + disk;
160 else if ( disk.left(14) == "/dev/mtdblock6" ) //openzaurus ramfs 160 else if ( disk.left(14) == "/dev/mtdblock6" ) //openzaurus ramfs
161 humanname = tr("Internal Memory"); 161 humanname = tr("Internal Memory");
162 else if ( disk == "/dev/mtdblock1" || humanname == "/dev/mtdblock/1" ) 162 else if ( disk == "/dev/mtdblock1" || humanname == "/dev/mtdblock/1" )
163 humanname = tr("Internal Storage"); 163 humanname = tr("Internal Storage");
164 else if ( disk.left(14) == "/dev/mtdblock/" ) 164 else if ( disk.left(14) == "/dev/mtdblock/" )
165 humanname = tr("Internal Storage") + " " + disk; 165 humanname = tr("Internal Storage") + " " + disk;
166 else if ( disk.left(13) == "/dev/mtdblock" ) 166 else if ( disk.left(13) == "/dev/mtdblock" )
167 humanname = tr("Internal Storage") + " " + disk; 167 humanname = tr("Internal Storage") + " " + disk;
168 else if ( disk.left(9) == "/dev/root" ) 168 else if ( disk.left(9) == "/dev/root" )
169 humanname = tr("Internal Storage") + " " + disk; 169 humanname = tr("Internal Storage") + " " + disk;
170 else if ( disk.left(5) == "tmpfs" ) //ipaqs /mnt/ramfs 170 else if ( disk.left(5) == "tmpfs" ) //ipaqs /mnt/ramfs
171 humanname = tr("Internal Memory"); 171 humanname = tr("Internal Memory");
172 FileSystem *fs = new FileSystem( disk, *fsit, humanname, removable, opts ); 172 FileSystem *fs = new FileSystem( disk, *fsit, humanname, removable, opts );
173 mFileSystems.append( fs ); 173 mFileSystems.append( fs );
174 } 174 }
175 emit disksChanged(); 175 emit disksChanged();
176 } else { 176 } else {
177 // just update them 177 // just update them
178 for (QListIterator<FileSystem> i(mFileSystems); i.current(); ++i) 178 for (QListIterator<FileSystem> i(mFileSystems); i.current(); ++i)
179 i.current()->update(); 179 i.current()->update();
180 } 180 }
181#endif 181#endif
182} 182}
183 183
184bool deviceTab( const char *device) { 184bool deviceTab( const char *device) {
185 QString name = device; 185 QString name = device;
186 bool hasDevice=false; 186 bool hasDevice=false;
187 struct mntent *me; 187 struct mntent *me;
188 FILE *mntfp = setmntent( "/etc/mtab", "r" ); 188 FILE *mntfp = setmntent( "/etc/mtab", "r" );
189 if ( mntfp ) { 189 if ( mntfp ) {
190 while ( (me = getmntent( mntfp )) != 0 ) { 190 while ( (me = getmntent( mntfp )) != 0 ) {
191 QString deviceName = me->mnt_fsname; 191 QString deviceName = me->mnt_fsname;
192// qDebug(deviceName); 192// qDebug(deviceName);
193 if( deviceName.left(name.length()) == name) { 193 if( deviceName.left(name.length()) == name) {
194 hasDevice = true; 194 hasDevice = true;
195 } 195 }
196 } 196 }
197 } 197 }
198 endmntent( mntfp ); 198 endmntent( mntfp );
199 return hasDevice; 199 return hasDevice;
200} 200}
201 201
202/*! 202/*!
203 * @fn hasCf() 203 * @fn static bool StorageInfo::hasCf()
204 * @brief returns whether device has Cf mounted 204 * @brief returns whether device has Cf mounted
205 * 205 *
206 */ 206 */
207bool StorageInfo::hasCf() 207bool StorageInfo::hasCf()
208{ 208{
209 return deviceTab("/dev/hd"); 209 return deviceTab("/dev/hd");
210} 210}
211 211
212/*! 212/*!
213 * @fn hasSd() 213 * @fn static bool StorageInfo::hasSd()
214 * @brief returns whether device has SD mounted 214 * @brief returns whether device has SD mounted
215 * 215 *
216 */ 216 */
217bool StorageInfo::hasSd() 217bool StorageInfo::hasSd()
218{ 218{
219 return deviceTab("/dev/mmcd"); 219 return deviceTab("/dev/mmcd");
220} 220}
221 221
222/*! 222/*!
223 * @fn hasMmc() 223 * @fn static bool StorageInfo::hasMmc()
224 * @brief reutrns whether device has mmc mounted 224 * @brief reutrns whether device has mmc mounted
225 * 225 *
226 */ 226 */
227bool StorageInfo::hasMmc() 227bool StorageInfo::hasMmc()
228{ 228{
229 bool hasMmc=false; 229 bool hasMmc=false;
230 if( deviceTab("/dev/mmc/part")) 230 if( deviceTab("/dev/mmc/part"))
231 hasMmc=true; 231 hasMmc=true;
232 if( deviceTab("/dev/mmcd")) 232 if( deviceTab("/dev/mmcd"))
233 hasMmc=true; 233 hasMmc=true;
234 return hasMmc; 234 return hasMmc;
235} 235}
236 236
237 237
238//--------------------------------------------------------------------------- 238//---------------------------------------------------------------------------
239 239
240FileSystem::FileSystem( const QString &disk, const QString &path, const QString &name, bool rem, const QString &o ) 240FileSystem::FileSystem( const QString &disk, const QString &path, const QString &name, bool rem, const QString &o )
241 : fsdisk( disk ), fspath( path ), humanname( name ), blkSize(512), totalBlks(0), availBlks(0), removable( rem ), opts( o ) 241 : fsdisk( disk ), fspath( path ), humanname( name ), blkSize(512), totalBlks(0), availBlks(0), removable( rem ), opts( o )
242{ 242{
243 update(); 243 update();
244} 244}
245 245
246void FileSystem::update() 246void FileSystem::update()
247{ 247{
248#if defined(_OS_LINUX_) || defined(Q_OS_LINUX) 248#if defined(_OS_LINUX_) || defined(Q_OS_LINUX)
249 struct statfs fs; 249 struct statfs fs;
250 if ( !statfs( fspath.latin1(), &fs ) ) { 250 if ( !statfs( fspath.latin1(), &fs ) ) {
251 blkSize = fs.f_bsize; 251 blkSize = fs.f_bsize;
252 totalBlks = fs.f_blocks; 252 totalBlks = fs.f_blocks;
253 availBlks = fs.f_bavail; 253 availBlks = fs.f_bavail;
254 } else { 254 } else {
255 blkSize = 0; 255 blkSize = 0;
256 totalBlks = 0; 256 totalBlks = 0;
257 availBlks = 0; 257 availBlks = 0;
258 } 258 }
259#endif 259#endif
260} 260}
261 261