summaryrefslogtreecommitdiff
path: root/library
authorzecke <zecke>2003-04-16 10:57:59 (UTC)
committer zecke <zecke>2003-04-16 10:57:59 (UTC)
commiteeb29547890a2d162de66d7d5b98d3840a7e2d79 (patch) (unidiff)
tree973c6de7aae2fd5ba368efb87fa24234f0e12aa3 /library
parentdfa2d294b3af09bf3757a3c2294a925093e72fc6 (diff)
downloadopie-eeb29547890a2d162de66d7d5b98d3840a7e2d79.zip
opie-eeb29547890a2d162de66d7d5b98d3840a7e2d79.tar.gz
opie-eeb29547890a2d162de66d7d5b98d3840a7e2d79.tar.bz2
Fix API docu
Diffstat (limited to 'library') (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
@@ -1,1481 +1,1497 @@
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#define QTOPIA_INTERNAL_MIMEEXT 21#define QTOPIA_INTERNAL_MIMEEXT
22#define QTOPIA_INTERNAL_PRELOADACCESS 22#define QTOPIA_INTERNAL_PRELOADACCESS
23#define QTOPIA_INTERNAL_APPLNKASSIGN 23#define QTOPIA_INTERNAL_APPLNKASSIGN
24 24
25#include "applnk.h" 25#include "applnk.h"
26 26
27#include <qpe/qpeapplication.h> 27#include <qpe/qpeapplication.h>
28#include <qpe/categories.h> 28#include <qpe/categories.h>
29#include <qpe/categoryselect.h> 29#include <qpe/categoryselect.h>
30#include <qpe/qcopenvelope_qws.h> 30#include <qpe/qcopenvelope_qws.h>
31#include <qpe/global.h> 31#include <qpe/global.h>
32#include <qpe/mimetype.h> 32#include <qpe/mimetype.h>
33#include <qpe/config.h> 33#include <qpe/config.h>
34#include <qpe/storage.h> 34#include <qpe/storage.h>
35#include <qpe/resource.h> 35#include <qpe/resource.h>
36 36
37#include <qdict.h> 37#include <qdict.h>
38#include <qdir.h> 38#include <qdir.h>
39#include <qregexp.h> 39#include <qregexp.h>
40 40
41#include <qgfx_qws.h> 41#include <qgfx_qws.h>
42 42
43#include <stdlib.h> 43#include <stdlib.h>
44 44
45int AppLnk::lastId = 5000; 45int AppLnk::lastId = 5000;
46 46
47static int smallSize = 14; 47static int smallSize = 14;
48static int bigSize = 32; 48static int bigSize = 32;
49 49
50static QString safeFileName(const QString& n) 50static QString safeFileName(const QString& n)
51{ 51{
52 QString safename=n; 52 QString safename=n;
53 safename.replace(QRegExp("[^0-9A-Za-z.]"),"_"); 53 safename.replace(QRegExp("[^0-9A-Za-z.]"),"_");
54 safename.replace(QRegExp("^[^A-Za-z]*"),""); 54 safename.replace(QRegExp("^[^A-Za-z]*"),"");
55 if ( safename.isEmpty() ) 55 if ( safename.isEmpty() )
56 safename = "_"; 56 safename = "_";
57 return safename; 57 return safename;
58} 58}
59 59
60static bool prepareDirectories(const QString& lf) 60static bool prepareDirectories(const QString& lf)
61{ 61{
62 if ( !QFile::exists(lf) ) { 62 if ( !QFile::exists(lf) ) {
63 // May need to create directories 63 // May need to create directories
64 QFileInfo fi(lf); 64 QFileInfo fi(lf);
65 if ( system(("mkdir -p "+fi.dirPath(TRUE))) ) 65 if ( system(("mkdir -p "+fi.dirPath(TRUE))) )
66 return FALSE; 66 return FALSE;
67 } 67 }
68 return TRUE; 68 return TRUE;
69} 69}
70 70
71class AppLnkPrivate 71class AppLnkPrivate
72{ 72{
73public: 73public:
74 /* the size of the Pixmap */ 74 /* the size of the Pixmap */
75 enum Size {Normal = 0, Big }; 75 enum Size {Normal = 0, Big };
76 AppLnkPrivate() { 76 AppLnkPrivate() {
77 /* we want one normal and one big item */ 77 /* we want one normal and one big item */
78 78
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() ) {
592 int n = 1; 608 int n = 1;
593 QString nn; 609 QString nn;
594 while (QFile::exists((nn=that->mLinkFile+"_"+QString::number(n))+".desktop")) { 610 while (QFile::exists((nn=that->mLinkFile+"_"+QString::number(n))+".desktop")) {
595 n++; 611 n++;
596 /* just to be sure */ 612 /* just to be sure */
597 AppLnk lnk(nn ); 613 AppLnk lnk(nn );
598 if (lnk.file() == that->file() ) 614 if (lnk.file() == that->file() )
599 break; 615 break;
600 } 616 }
601 that->mLinkFile = nn; 617 that->mLinkFile = nn;
602 } 618 }
603 } 619 }
604 that->mLinkFile += ".desktop"; 620 that->mLinkFile += ".desktop";
605 storeLink(); 621 storeLink();
606 } 622 }
607 return that->mLinkFile; 623 return that->mLinkFile;
608 } 624 }
609 return mLinkFile; 625 return mLinkFile;
610} 626}
611 627
612/*! 628/*!
613 Copies \a copy. 629 Copies \a copy.
614*/ 630*/
615AppLnk::AppLnk( const AppLnk &copy ) 631AppLnk::AppLnk( const AppLnk &copy )
616{ 632{
617 mName = copy.mName; 633 mName = copy.mName;
618 mPixmap = copy.mPixmap; 634 mPixmap = copy.mPixmap;
619 mBigPixmap = copy.mBigPixmap; 635 mBigPixmap = copy.mBigPixmap;
620 mExec = copy.mExec; 636 mExec = copy.mExec;
621 mType = copy.mType; 637 mType = copy.mType;
622 mRotation = copy.mRotation; 638 mRotation = copy.mRotation;
623 mComment = copy.mComment; 639 mComment = copy.mComment;
624 mFile = copy.mFile; 640 mFile = copy.mFile;
625 mLinkFile = copy.mLinkFile; 641 mLinkFile = copy.mLinkFile;
626 mIconFile = copy.mIconFile; 642 mIconFile = copy.mIconFile;
627 mMimeTypes = copy.mMimeTypes; 643 mMimeTypes = copy.mMimeTypes;
628 mMimeTypeIcons = copy.mMimeTypeIcons; 644 mMimeTypeIcons = copy.mMimeTypeIcons;
629 mId = 0; 645 mId = 0;
630 d = new AppLnkPrivate(); 646 d = new AppLnkPrivate();
631 d->mCat = copy.d->mCat; 647 d->mCat = copy.d->mCat;
632 d->mCatList = copy.d->mCatList; 648 d->mCatList = copy.d->mCatList;
633 d->mPixmaps = copy.d->mPixmaps; 649 d->mPixmaps = copy.d->mPixmaps;
634} 650}
635 651
636/*! 652/*!
637 Destroys the AppLnk. Note that if the AppLnk is currently a member 653 Destroys the AppLnk. Note that if the AppLnk is currently a member
638 of an AppLnkSet, this will produce a run-time warning. 654 of an AppLnkSet, this will produce a run-time warning.
639 655
640 \sa AppLnkSet::add() AppLnkSet::remove() 656 \sa AppLnkSet::add() AppLnkSet::remove()
641*/ 657*/
642AppLnk::~AppLnk() 658AppLnk::~AppLnk()
643{ 659{
644 if ( mId ) 660 if ( mId )
645 qWarning("Deleting AppLnk that is in an AppLnkSet"); 661 qWarning("Deleting AppLnk that is in an AppLnkSet");
646 if ( d ) 662 if ( d )
647 delete d; 663 delete d;
648} 664}
649 665
650/*! 666/*!
651 \overload 667 \overload
652 Executes the application associated with this AppLnk. 668 Executes the application associated with this AppLnk.
653 669
654 \sa exec() 670 \sa exec()
655*/ 671*/
656void AppLnk::execute() const 672void AppLnk::execute() const
657{ 673{
658 execute(QStringList()); 674 execute(QStringList());
659} 675}
660 676
661/*! 677/*!
662 Executes the application associated with this AppLnk, with 678 Executes the application associated with this AppLnk, with
663 \a args as arguments. 679 \a args as arguments.
664 680
665 \sa exec() 681 \sa exec()
666*/ 682*/
667void AppLnk::execute(const QStringList& args) const 683void AppLnk::execute(const QStringList& args) const
668{ 684{
669#ifdef Q_WS_QWS 685#ifdef Q_WS_QWS
670 if ( !mRotation.isEmpty() ) { 686 if ( !mRotation.isEmpty() ) {
671 // ######## this will only work in the server 687 // ######## this will only work in the server
672 int rot = QPEApplication::defaultRotation(); 688 int rot = QPEApplication::defaultRotation();
673 rot = (rot+mRotation.toInt())%360; 689 rot = (rot+mRotation.toInt())%360;
674 QCString old = getenv("QWS_DISPLAY"); 690 QCString old = getenv("QWS_DISPLAY");
675 setenv("QWS_DISPLAY", QString("Transformed:Rot%1:0").arg(rot), 1); 691 setenv("QWS_DISPLAY", QString("Transformed:Rot%1:0").arg(rot), 1);
676 invoke(args); 692 invoke(args);
677 setenv("QWS_DISPLAY", old.data(), 1); 693 setenv("QWS_DISPLAY", old.data(), 1);
678 } else 694 } else
679#endif 695#endif
680 invoke(args); 696 invoke(args);
681} 697}
682 698
683/*! 699/*!
684 Invokes the application associated with this AppLnk, with 700 Invokes the application associated with this AppLnk, with
685 \a args as arguments. Rotation is not taken into account by 701 \a args as arguments. Rotation is not taken into account by
686 this function, so you should not call it directly. 702 this function, so you should not call it directly.
687 703
688 \sa execute() 704 \sa execute()
689*/ 705*/
690void AppLnk::invoke(const QStringList& args) const 706void AppLnk::invoke(const QStringList& args) const
691{ 707{
692 Global::execute( exec(), args[0] ); 708 Global::execute( exec(), args[0] );
693} 709}
694 710
695/*! 711/*!
696 Sets the Exec property to \a exec. 712 Sets the Exec property to \a exec.
697 713
698 \sa exec() name() 714 \sa exec() name()
699*/ 715*/
700void AppLnk::setExec( const QString& exec ) 716void AppLnk::setExec( const QString& exec )
701{ 717{
702 mExec = exec; 718 mExec = exec;
703} 719}
704 720
705#if 0 // this was inlined for better BC 721#if 0 // this was inlined for better BC
706/*! 722/*!
707 Sets the Rotation property to \a rot. 723 Sets the Rotation property to \a rot.
708 724
709 \sa rotation() 725 \sa rotation()
710*/ 726*/
711void AppLnk::setRotation ( const QString &rot ) 727void AppLnk::setRotation ( const QString &rot )
712{ 728{
713 mRotation = rot; 729 mRotation = rot;
714} 730}
715#endif 731#endif
716 732
717/*! 733/*!
718 Sets the Name property to \a docname. 734 Sets the Name property to \a docname.
719 735
720 \sa name() 736 \sa name()
721*/ 737*/
722void AppLnk::setName( const QString& docname ) 738void AppLnk::setName( const QString& docname )
723{ 739{
724 mName = docname; 740 mName = docname;
725} 741}
726 742
727/*! 743/*!
728 Sets the File property to \a filename. 744 Sets the File property to \a filename.
729 745
730 \sa file() name() 746 \sa file() name()
731*/ 747*/
732void AppLnk::setFile( const QString& filename ) 748void AppLnk::setFile( const QString& filename )
733{ 749{
734 mFile = filename; 750 mFile = filename;
735} 751}
736 752
737/*! 753/*!
738 Sets the LinkFile property to \a filename. 754 Sets the LinkFile property to \a filename.
739 755
740 \sa linkFile() 756 \sa linkFile()
741*/ 757*/
742void AppLnk::setLinkFile( const QString& filename ) 758void AppLnk::setLinkFile( const QString& filename )
743{ 759{
744 mLinkFile = filename; 760 mLinkFile = filename;
745} 761}
746 762
747/*! 763/*!
748 Sets the Comment property to \a comment. 764 Sets the Comment property to \a comment.
749 765
750 This text is displayed in the 'Details Dialog', for example if the 766 This text is displayed in the 'Details Dialog', for example if the
751 user uses the 'press-and-hold' gesture. 767 user uses the 'press-and-hold' gesture.
752 768
753 \sa comment() 769 \sa comment()
754*/ 770*/
755void AppLnk::setComment( const QString& comment ) 771void AppLnk::setComment( const QString& comment )
756{ 772{
757 mComment = comment; 773 mComment = comment;
758} 774}
759 775
760/*! 776/*!
761 Sets the Type property to \a type. 777 Sets the Type property to \a type.
762 778
763 For applications, games and settings the type should be \c 779 For applications, games and settings the type should be \c
764 Application; for documents the type should be the document's MIME 780 Application; for documents the type should be the document's MIME
765 type. 781 type.
766 782
767 \sa type() 783 \sa type()
768*/ 784*/
769void AppLnk::setType( const QString& type ) 785void AppLnk::setType( const QString& type )
770{ 786{
771 mType = type; 787 mType = type;
772} 788}
773 789
774/*! 790/*!
775 \fn QString AppLnk::icon() const 791 \fn QString AppLnk::icon() const
776 792
777 Returns the Icon property. 793 Returns the Icon property.
778 794
779 \sa setIcon() 795 \sa setIcon()
780*/ 796*/
781 797
782/*! 798/*!
783 Sets the Icon property to \a iconname. This is the filename from 799 Sets the Icon property to \a iconname. This is the filename from
784 which the pixmap() and bigPixmap() are obtained. 800 which the pixmap() and bigPixmap() are obtained.
785 801
786 \sa icon() setSmallIconSize() setBigIconSize() 802 \sa icon() setSmallIconSize() setBigIconSize()
787*/ 803*/
788void AppLnk::setIcon( const QString& iconname ) 804void AppLnk::setIcon( const QString& iconname )
789{ 805{
790 mIconFile = iconname; 806 mIconFile = iconname;
791 QImage unscaledIcon = Resource::loadImage( mIconFile ); 807 QImage unscaledIcon = Resource::loadImage( mIconFile );
792 d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) ); 808 d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
793 d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) ); 809 d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
794} 810}
795 811
796/*! 812/*!
797 Sets the Categories property to \a c. 813 Sets the Categories property to \a c.
798 814
799 See the CategoryWidget for more details. 815 See the CategoryWidget for more details.
800 816
801 \sa categories() 817 \sa categories()
802*/ 818*/
803void AppLnk::setCategories( const QArray<int>& c ) 819void AppLnk::setCategories( const QArray<int>& c )
804{ 820{
805 d->mCat = c; 821 d->mCat = c;
806 d->updateCatListFromArray(); 822 d->updateCatListFromArray();
807} 823}
808 824
809/*! 825/*!
810 \fn QStringList AppLnk::mimeTypeIcons() const 826 \fn QStringList AppLnk::mimeTypeIcons() const
811 827
812 Returns the MimeTypeIcons property of the AppLnk. 828 Returns the MimeTypeIcons property of the AppLnk.
813*/ 829*/
814 830
815/*! 831/*!
816 Attempts to ensure that the link file for this AppLnk exists, 832 Attempts to ensure that the link file for this AppLnk exists,
817 including creating any required directories. Returns TRUE if 833 including creating any required directories. Returns TRUE if
818 successful; otherwise returns FALSE. 834 successful; otherwise returns FALSE.
819 835
820 You should not need to use this function. 836 You should not need to use this function.
821*/ 837*/
822bool AppLnk::ensureLinkExists() const 838bool AppLnk::ensureLinkExists() const
823{ 839{
824 QString lf = linkFile(); 840 QString lf = linkFile();
825 return prepareDirectories(lf); 841 return prepareDirectories(lf);
826} 842}
827 843
828/*! 844/*!
829 Commits the AppLnk to disk. Returns TRUE if the operation succeeded; 845 Commits the AppLnk to disk. Returns TRUE if the operation succeeded;
830 otherwise returns FALSE. 846 otherwise returns FALSE.
831 847
832 In addition, the "linkChanged(QString)" message is sent to the 848 In addition, the "linkChanged(QString)" message is sent to the
833 "QPE/System" \link qcop.html QCop\endlink channel. 849 "QPE/System" \link qcop.html QCop\endlink channel.
834*/ 850*/
835bool AppLnk::writeLink() const 851bool AppLnk::writeLink() const
836{ 852{
837 // Only re-writes settable parts 853 // Only re-writes settable parts
838 QString lf = linkFile(); 854 QString lf = linkFile();
839 if ( !ensureLinkExists() ) 855 if ( !ensureLinkExists() )
840 return FALSE; 856 return FALSE;
841 storeLink(); 857 storeLink();
842 return TRUE; 858 return TRUE;
843} 859}
844 860
845/*! 861/*!
846 \internal 862 \internal
847*/ 863*/
848void AppLnk::storeLink() const 864void AppLnk::storeLink() const
849{ 865{
850 Config config( mLinkFile, Config::File ); 866 Config config( mLinkFile, Config::File );
851 config.setGroup("Desktop Entry"); 867 config.setGroup("Desktop Entry");
852 config.writeEntry("Name",mName); 868 config.writeEntry("Name",mName);
853 if ( !mIconFile.isNull() ) config.writeEntry("Icon",mIconFile); 869 if ( !mIconFile.isNull() ) config.writeEntry("Icon",mIconFile);
854 config.writeEntry("Type",type()); 870 config.writeEntry("Type",type());
855 if(!rotation().isEmpty()) 871 if(!rotation().isEmpty())
856 config.writeEntry("Rotation",rotation()); 872 config.writeEntry("Rotation",rotation());
857 else 873 else
858 config.removeEntry("Rotation"); 874 config.removeEntry("Rotation");
859 if ( !mComment.isNull() ) config.writeEntry("Comment",mComment); 875 if ( !mComment.isNull() ) config.writeEntry("Comment",mComment);
860 QString f = file(); 876 QString f = file();
861 int i = 0; 877 int i = 0;
862 while ( i < (int)f.length() && i < (int)mLinkFile.length() && f[i] == mLinkFile[i] ) 878 while ( i < (int)f.length() && i < (int)mLinkFile.length() && f[i] == mLinkFile[i] )
863 i++; 879 i++;
864 while ( i && f[i] != '/' ) 880 while ( i && f[i] != '/' )
865 i--; 881 i--;
866 // simple case where in the same directory 882 // simple case where in the same directory
867 if ( mLinkFile.find( '/', i + 1 ) < 0 ) 883 if ( mLinkFile.find( '/', i + 1 ) < 0 )
868 f = f.mid(i+1); 884 f = f.mid(i+1);
869 // ### could do relative ie ../../otherDocs/file.doc 885 // ### could do relative ie ../../otherDocs/file.doc
870 config.writeEntry("File",f); 886 config.writeEntry("File",f);
871 config.writeEntry( "Categories", d->mCatList, ';' ); 887 config.writeEntry( "Categories", d->mCatList, ';' );
872 888
873#ifndef QT_NO_COP 889#ifndef QT_NO_COP
874 QCopEnvelope e("QPE/System", "linkChanged(QString)"); 890 QCopEnvelope e("QPE/System", "linkChanged(QString)");
875 e << mLinkFile; 891 e << mLinkFile;
876#endif 892#endif
877} 893}
878 894
879/*! 895/*!
880 Sets the property named \a key to \a value. 896 Sets the property named \a key to \a value.
881 897
882 \sa property() 898 \sa property()
883*/ 899*/
884void AppLnk::setProperty(const QString& key, const QString& value) 900void AppLnk::setProperty(const QString& key, const QString& value)
885{ 901{
886 if ( ensureLinkExists() ) { 902 if ( ensureLinkExists() ) {
887 Config cfg(linkFile(), Config::File); 903 Config cfg(linkFile(), Config::File);
888 cfg.writeEntry(key,value); 904 cfg.writeEntry(key,value);
889 } 905 }
890} 906}
891 907
892/*! 908/*!
893 Returns the property named \a key. 909 Returns the property named \a key.
894 910
895 \sa setProperty() 911 \sa setProperty()
896*/ 912*/
897QString AppLnk::property(const QString& key) const 913QString AppLnk::property(const QString& key) const
898{ 914{
899 QString lf = linkFile(); 915 QString lf = linkFile();
900 if ( !QFile::exists(lf) ) 916 if ( !QFile::exists(lf) )
901 return QString::null; 917 return QString::null;
902 Config cfg(lf, Config::File); 918 Config cfg(lf, Config::File);
903 return cfg.readEntry(key); 919 return cfg.readEntry(key);
904} 920}
905 921
906bool AppLnk::isPreloaded() const { 922bool AppLnk::isPreloaded() const {
907 // Preload information is stored in the Launcher config in v1.5. 923 // Preload information is stored in the Launcher config in v1.5.
908 Config cfg("Launcher"); 924 Config cfg("Launcher");
909 cfg.setGroup("Preload"); 925 cfg.setGroup("Preload");
910 QStringList apps = cfg.readListEntry("Apps",','); 926 QStringList apps = cfg.readListEntry("Apps",',');
911 if (apps.contains(exec())) 927 if (apps.contains(exec()))
912 return true; 928 return true;
913 return false; 929 return false;
914} 930}
915 931
916void AppLnk::setPreloaded(bool yesNo) { 932void AppLnk::setPreloaded(bool yesNo) {
917 // Preload information is stored in the Launcher config in v1.5. 933 // Preload information is stored in the Launcher config in v1.5.
918 Config cfg("Launcher"); 934 Config cfg("Launcher");
919 cfg.setGroup("Preload"); 935 cfg.setGroup("Preload");
920 QStringList apps = cfg.readListEntry("Apps", ','); 936 QStringList apps = cfg.readListEntry("Apps", ',');
921 if (apps.contains(exec()) && !yesNo) 937 if (apps.contains(exec()) && !yesNo)
922 apps.remove(exec()); 938 apps.remove(exec());
923 else if (yesNo && !apps.contains(exec())) 939 else if (yesNo && !apps.contains(exec()))
924 apps.append(exec()); 940 apps.append(exec());
925 cfg.writeEntry("Apps", apps, ','); 941 cfg.writeEntry("Apps", apps, ',');
926} 942}
927 943
928 944
929/*! 945/*!
930 Deletes both the linkFile() and the file() associated with this AppLnk. 946 Deletes both the linkFile() and the file() associated with this AppLnk.
931 947
932 \sa removeLinkFile() 948 \sa removeLinkFile()
933*/ 949*/
934void AppLnk::removeFiles() 950void AppLnk::removeFiles()
935{ 951{
936 bool valid = isValid(); 952 bool valid = isValid();
937 if ( !valid || !linkFileKnown() || QFile::remove(linkFile()) ) { 953 if ( !valid || !linkFileKnown() || QFile::remove(linkFile()) ) {
938 if ( QFile::remove(file()) ) { 954 if ( QFile::remove(file()) ) {
939#ifndef QT_NO_COP 955#ifndef QT_NO_COP
940 QCopEnvelope e("QPE/System", "linkChanged(QString)"); 956 QCopEnvelope e("QPE/System", "linkChanged(QString)");
941 if ( linkFileKnown() ) 957 if ( linkFileKnown() )
942 e << linkFile(); 958 e << linkFile();
943 else 959 else
944 e << file(); 960 e << file();
945#endif 961#endif
946 } else if ( valid ) { 962 } else if ( valid ) {
947 // restore link 963 // restore link
948 writeLink(); 964 writeLink();
949 } 965 }
950 } 966 }
951} 967}
952 968
953/*! 969/*!
954 Deletes the linkFile(), leaving any file() untouched. 970 Deletes the linkFile(), leaving any file() untouched.
955 971
956 \sa removeFiles() 972 \sa removeFiles()
957*/ 973*/
958void AppLnk::removeLinkFile() 974void AppLnk::removeLinkFile()
959{ 975{
960 if ( isValid() && linkFileKnown() && QFile::remove(linkFile()) ) { 976 if ( isValid() && linkFileKnown() && QFile::remove(linkFile()) ) {
961#ifndef QT_NO_COP 977#ifndef QT_NO_COP
962 QCopEnvelope e("QPE/System", "linkChanged(QString)"); 978 QCopEnvelope e("QPE/System", "linkChanged(QString)");
963 e << linkFile(); 979 e << linkFile();
964#endif 980#endif
965 } 981 }
966} 982}
967 983
968class AppLnkSetPrivate { 984class AppLnkSetPrivate {
969public: 985public:
970 AppLnkSetPrivate() 986 AppLnkSetPrivate()
971 { 987 {
972 typPix.setAutoDelete(TRUE); 988 typPix.setAutoDelete(TRUE);
973 typPixBig.setAutoDelete(TRUE); 989 typPixBig.setAutoDelete(TRUE);
974 typName.setAutoDelete(TRUE); 990 typName.setAutoDelete(TRUE);
975 } 991 }
976 992
977 QDict<QPixmap> typPix; 993 QDict<QPixmap> typPix;
978 QDict<QPixmap> typPixBig; 994 QDict<QPixmap> typPixBig;
979 QDict<QString> typName; 995 QDict<QString> typName;
980}; 996};
981 997
982/*! 998/*!
983 \class AppLnkSet applnk.h 999 \class AppLnkSet applnk.h
984 \brief The AppLnkSet class is a set of AppLnk objects. 1000 \brief The AppLnkSet class is a set of AppLnk objects.
985*/ 1001*/
986 1002
987/*! 1003/*!
988 \fn QStringList AppLnkSet::types() const 1004 \fn QStringList AppLnkSet::types() const
989 1005
990 Returns the list of \link applnk.html#Types types\endlink in the set. 1006 Returns the list of \link applnk.html#Types types\endlink in the set.
991 1007
992 For applications, games and settings the type is \c Application; 1008 For applications, games and settings the type is \c Application;
993 for documents the type is the document's MIME type. 1009 for documents the type is the document's MIME type.
994 1010
995 \sa AppLnk::type(), typeName(), typePixmap(), typeBigPixmap() 1011 \sa AppLnk::type(), typeName(), typePixmap(), typeBigPixmap()
996*/ 1012*/
997 1013
998/*! 1014/*!
999 \fn const QList<AppLnk>& AppLnkSet::children() const 1015 \fn const QList<AppLnk>& AppLnkSet::children() const
1000 1016
1001 Returns the members of the set. 1017 Returns the members of the set.
1002*/ 1018*/
1003 1019
1004/*! 1020/*!
1005 Constructs an empty AppLnkSet. 1021 Constructs an empty AppLnkSet.
1006*/ 1022*/
1007AppLnkSet::AppLnkSet() : 1023AppLnkSet::AppLnkSet() :
1008 d(new AppLnkSetPrivate) 1024 d(new AppLnkSetPrivate)
1009{ 1025{
1010} 1026}
1011 1027
1012/*! 1028/*!
1013 Constructs an AppLnkSet that contains AppLnk objects representing 1029 Constructs an AppLnkSet that contains AppLnk objects representing
1014 all the files in the given \a directory (and any subdirectories 1030 all the files in the given \a directory (and any subdirectories
1015 recursively). 1031 recursively).
1016 1032
1017 \omit 1033 \omit
1018 The directories may contain ".directory" files which override 1034 The directories may contain ".directory" files which override
1019 any AppLnk::type() values for AppLnk objects found in the directory. 1035 any AppLnk::type() values for AppLnk objects found in the directory.
1020 This allows simple localization of application types. 1036 This allows simple localization of application types.
1021 \endomit 1037 \endomit
1022*/ 1038*/
1023AppLnkSet::AppLnkSet( const QString &directory ) : 1039AppLnkSet::AppLnkSet( const QString &directory ) :
1024 d(new AppLnkSetPrivate) 1040 d(new AppLnkSetPrivate)
1025{ 1041{
1026 QDir dir( directory ); 1042 QDir dir( directory );
1027 mFile = directory; 1043 mFile = directory;
1028 findChildren(directory,QString::null,QString::null); 1044 findChildren(directory,QString::null,QString::null);
1029} 1045}
1030 1046
1031/*! 1047/*!
1032 Detaches all AppLnk objects from the set. The set become empty and 1048 Detaches all AppLnk objects from the set. The set become empty and
1033 the caller becomes responsible for deleting the AppLnk objects. 1049 the caller becomes responsible for deleting the AppLnk objects.
1034*/ 1050*/
1035void AppLnkSet::detachChildren() 1051void AppLnkSet::detachChildren()
1036{ 1052{
1037 QListIterator<AppLnk> it( mApps ); 1053 QListIterator<AppLnk> it( mApps );
1038 for ( ; it.current(); ) { 1054 for ( ; it.current(); ) {
1039 AppLnk* a = *it; 1055 AppLnk* a = *it;
1040 ++it; 1056 ++it;
1041 a->mId = 0; 1057 a->mId = 0;
1042 } 1058 }
1043 mApps.clear(); 1059 mApps.clear();
1044} 1060}
1045 1061
1046/*! 1062/*!
1047 Destroys the set, deleting all the AppLnk objects it contains. 1063 Destroys the set, deleting all the AppLnk objects it contains.
1048 1064
1049 \sa detachChildren() 1065 \sa detachChildren()
1050*/ 1066*/
1051AppLnkSet::~AppLnkSet() 1067AppLnkSet::~AppLnkSet()
1052{ 1068{
1053 QListIterator<AppLnk> it( mApps ); 1069 QListIterator<AppLnk> it( mApps );
1054 for ( ; it.current(); ) { 1070 for ( ; it.current(); ) {
1055 AppLnk* a = *it; 1071 AppLnk* a = *it;
1056 ++it; 1072 ++it;
1057 a->mId = 0; 1073 a->mId = 0;
1058 delete a; 1074 delete a;
1059 } 1075 }
1060 delete d; 1076 delete d;
1061} 1077}
1062 1078
1063void AppLnkSet::findChildren(const QString &dr, const QString& typ, const QString& typName, int depth) 1079void AppLnkSet::findChildren(const QString &dr, const QString& typ, const QString& typName, int depth)
1064{ 1080{
1065 depth++; 1081 depth++;
1066 if ( depth > 10 ) 1082 if ( depth > 10 )
1067 return; 1083 return;
1068 1084
1069 QDir dir( dr ); 1085 QDir dir( dr );
1070 QString typNameLocal = typName; 1086 QString typNameLocal = typName;
1071 1087
1072 if ( dir.exists( ".directory" ) ) { 1088 if ( dir.exists( ".directory" ) ) {
1073 Config config( dr + "/.directory", Config::File ); 1089 Config config( dr + "/.directory", Config::File );
1074 config.setGroup( "Desktop Entry" ); 1090 config.setGroup( "Desktop Entry" );
1075 typNameLocal = config.readEntry( "Name", typNameLocal ); 1091 typNameLocal = config.readEntry( "Name", typNameLocal );
1076 if ( !typ.isEmpty() ) { 1092 if ( !typ.isEmpty() ) {
1077 QString iconFile = config.readEntry( "Icon", "AppsIcon" ); 1093 QString iconFile = config.readEntry( "Icon", "AppsIcon" );
1078 QImage unscaledIcon = Resource::loadImage( iconFile ); 1094 QImage unscaledIcon = Resource::loadImage( iconFile );
1079 QPixmap pm, bpm; 1095 QPixmap pm, bpm;
1080 pm.convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) ); 1096 pm.convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
1081 bpm.convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) ); 1097 bpm.convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
1082 d->typPix.insert(typ, new QPixmap(pm)); 1098 d->typPix.insert(typ, new QPixmap(pm));
1083 d->typPixBig.insert(typ, new QPixmap(bpm)); 1099 d->typPixBig.insert(typ, new QPixmap(bpm));
1084 d->typName.insert(typ, new QString(typNameLocal)); 1100 d->typName.insert(typ, new QString(typNameLocal));
1085 } 1101 }
1086 } 1102 }
1087 1103
1088 const QFileInfoList *list = dir.entryInfoList(); 1104 const QFileInfoList *list = dir.entryInfoList();
1089 if ( list ) { 1105 if ( list ) {
1090 QFileInfo* fi; 1106 QFileInfo* fi;
1091 bool cadded=FALSE; 1107 bool cadded=FALSE;
1092 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) { 1108 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) {
1093 QString bn = fi->fileName(); 1109 QString bn = fi->fileName();
1094 if ( bn[0] != '.' && bn != "CVS" ) { 1110 if ( bn[0] != '.' && bn != "CVS" ) {
1095 if ( fi->isDir() ) { 1111 if ( fi->isDir() ) {
1096 QString c = typ.isNull() ? bn : typ+"/"+bn; 1112 QString c = typ.isNull() ? bn : typ+"/"+bn;
1097 QString d = typNameLocal.isNull() ? bn : typNameLocal+"/"+bn; 1113 QString d = typNameLocal.isNull() ? bn : typNameLocal+"/"+bn;
1098 findChildren(fi->filePath(), c, d, depth ); 1114 findChildren(fi->filePath(), c, d, depth );
1099 } else { 1115 } else {
1100 if ( fi->extension(FALSE) == "desktop" ) { 1116 if ( fi->extension(FALSE) == "desktop" ) {
1101 AppLnk* app = new AppLnk( fi->filePath() ); 1117 AppLnk* app = new AppLnk( fi->filePath() );
1102#ifdef QT_NO_QWS_MULTIPROCESS 1118#ifdef QT_NO_QWS_MULTIPROCESS
1103 if ( !Global::isBuiltinCommand( app->exec() ) ) 1119 if ( !Global::isBuiltinCommand( app->exec() ) )
1104 delete app; 1120 delete app;
1105 else 1121 else
1106#endif 1122#endif
1107 { 1123 {
1108 if ( !typ.isEmpty() ) { 1124 if ( !typ.isEmpty() ) {
1109 if ( !cadded ) { 1125 if ( !cadded ) {
1110 typs.append(typ); 1126 typs.append(typ);
1111 cadded = TRUE; 1127 cadded = TRUE;
1112 } 1128 }
1113 app->setType(typ); 1129 app->setType(typ);
1114 } 1130 }
1115 add(app); 1131 add(app);
1116 } 1132 }
1117 } 1133 }
1118 } 1134 }
1119 } 1135 }
1120 } 1136 }
1121 } 1137 }
1122} 1138}
1123 1139
1124/*! 1140/*!
1125 Adds AppLnk \a f to the set. The set takes responsibility for 1141 Adds AppLnk \a f to the set. The set takes responsibility for
1126 deleting \a f. 1142 deleting \a f.
1127 1143
1128 \sa remove() 1144 \sa remove()
1129*/ 1145*/
1130void AppLnkSet::add( AppLnk *f ) 1146void AppLnkSet::add( AppLnk *f )
1131{ 1147{
1132 if ( f->mId == 0 ) { 1148 if ( f->mId == 0 ) {
1133 AppLnk::lastId++; 1149 AppLnk::lastId++;
1134 f->mId = AppLnk::lastId; 1150 f->mId = AppLnk::lastId;
1135 mApps.append( f ); 1151 mApps.append( f );
1136 } else { 1152 } else {
1137 qWarning("Attempt to add an AppLnk twice"); 1153 qWarning("Attempt to add an AppLnk twice");
1138 } 1154 }
1139} 1155}
1140 1156
1141/*! 1157/*!
1142 Removes AppLnk \a f to the set. The caller becomes responsible for 1158 Removes AppLnk \a f to the set. The caller becomes responsible for
1143 deleting \a f. Returns TRUE if \a f was in the set; otherwise 1159 deleting \a f. Returns TRUE if \a f was in the set; otherwise
1144 returns FALSE. 1160 returns FALSE.
1145 1161
1146 \sa add() 1162 \sa add()
1147*/ 1163*/
1148bool AppLnkSet::remove( AppLnk *f ) 1164bool AppLnkSet::remove( AppLnk *f )
1149{ 1165{
1150 if ( mApps.remove( f ) ) { 1166 if ( mApps.remove( f ) ) {
1151 f->mId = 0; 1167 f->mId = 0;
1152 return TRUE; 1168 return TRUE;
1153 } 1169 }
1154 return FALSE; 1170 return FALSE;
1155} 1171}
1156 1172
1157 1173
1158/*! 1174/*!
1159 Returns the localized name for type \a t. 1175 Returns the localized name for type \a t.
1160 1176
1161 For applications, games and settings the type is \c Application; 1177 For applications, games and settings the type is \c Application;
1162 for documents the type is the document's MIME type. 1178 for documents the type is the document's MIME type.
1163*/ 1179*/
1164QString AppLnkSet::typeName( const QString& t ) const 1180QString AppLnkSet::typeName( const QString& t ) const
1165{ 1181{
1166 QString *st = d->typName.find(t); 1182 QString *st = d->typName.find(t);
1167 return st ? *st : QString::null; 1183 return st ? *st : QString::null;
1168} 1184}
1169 1185
1170/*! 1186/*!
1171 Returns the small pixmap associated with type \a t. 1187 Returns the small pixmap associated with type \a t.
1172 1188
1173 For applications, games and settings the type is \c Application; 1189 For applications, games and settings the type is \c Application;
1174 for documents the type is the document's MIME type. 1190 for documents the type is the document's MIME type.
1175*/ 1191*/
1176QPixmap AppLnkSet::typePixmap( const QString& t ) const 1192QPixmap AppLnkSet::typePixmap( const QString& t ) const
1177{ 1193{
1178 QPixmap *pm = d->typPix.find(t); 1194 QPixmap *pm = d->typPix.find(t);
1179 return pm ? *pm : QPixmap(); 1195 return pm ? *pm : QPixmap();
1180} 1196}
1181 1197
1182/*! 1198/*!
1183 Returns the large pixmap associated with type \a t. 1199 Returns the large pixmap associated with type \a t.
1184 1200
1185 For applications, games and settings the type is \c Application; 1201 For applications, games and settings the type is \c Application;
1186 for documents the type is the document's MIME type. 1202 for documents the type is the document's MIME type.
1187*/ 1203*/
1188QPixmap AppLnkSet::typeBigPixmap( const QString& t ) const 1204QPixmap AppLnkSet::typeBigPixmap( const QString& t ) const
1189{ 1205{
1190 QPixmap *pm = d->typPixBig.find(t); 1206 QPixmap *pm = d->typPixBig.find(t);
1191 return pm ? *pm : QPixmap(); 1207 return pm ? *pm : QPixmap();
1192} 1208}
1193 1209
1194/*! 1210/*!
1195 Returns the AppLnk with the given \a id. 1211 Returns the AppLnk with the given \a id.
1196*/ 1212*/
1197const AppLnk *AppLnkSet::find( int id ) const 1213const AppLnk *AppLnkSet::find( int id ) const
1198{ 1214{
1199 QListIterator<AppLnk> it( children() ); 1215 QListIterator<AppLnk> it( children() );
1200 1216
1201 for ( ; it.current(); ++it ) { 1217 for ( ; it.current(); ++it ) {
1202 const AppLnk *app = it.current(); 1218 const AppLnk *app = it.current();
1203 if ( app->id() == id ) 1219 if ( app->id() == id )
1204 return app; 1220 return app;
1205 } 1221 }
1206 1222
1207 return 0; 1223 return 0;
1208} 1224}
1209 1225
1210/*! 1226/*!
1211 Returns the AppLnk with the given \a exec attribute. 1227 Returns the AppLnk with the given \a exec attribute.
1212*/ 1228*/
1213const AppLnk *AppLnkSet::findExec( const QString& exec ) const 1229const AppLnk *AppLnkSet::findExec( const QString& exec ) const
1214{ 1230{
1215 QListIterator<AppLnk> it( children() ); 1231 QListIterator<AppLnk> it( children() );
1216 1232
1217 for ( ; it.current(); ++it ) { 1233 for ( ; it.current(); ++it ) {
1218 const AppLnk *app = it.current(); 1234 const AppLnk *app = it.current();
1219 if ( app->exec() == exec ) 1235 if ( app->exec() == exec )
1220 return app; 1236 return app;
1221 } 1237 }
1222 1238
1223 return 0; 1239 return 0;
1224} 1240}
1225 1241
1226/*! 1242/*!
1227 \class DocLnkSet applnk.h 1243 \class DocLnkSet applnk.h
1228 \brief The DocLnkSet class is a set of DocLnk objects. 1244 \brief The DocLnkSet class is a set of DocLnk objects.
1229*/ 1245*/
1230 1246
1231/*! 1247/*!
1232 \fn const QList<DocLnk>& DocLnkSet::children() const 1248 \fn const QList<DocLnk>& DocLnkSet::children() const
1233 1249
1234 Returns the members of the set. 1250 Returns the members of the set.
1235*/ 1251*/
1236 1252
1237/*! 1253/*!
1238 Constructs an empty DocLnkSet. 1254 Constructs an empty DocLnkSet.
1239 1255
1240 \sa appendFrom() 1256 \sa appendFrom()
1241*/ 1257*/
1242DocLnkSet::DocLnkSet() 1258DocLnkSet::DocLnkSet()
1243{ 1259{
1244} 1260}
1245 1261
1246/*! 1262/*!
1247 Constructs a DocLnkSet that contains DocLnk objects representing all 1263 Constructs a DocLnkSet that contains DocLnk objects representing all
1248 the files in the \a directory (and any subdirectories, recursively). 1264 the files in the \a directory (and any subdirectories, recursively).
1249 1265
1250 If \a mimefilter is not null, 1266 If \a mimefilter is not null,
1251 only documents with a MIME type matching \a mimefilter are selected. 1267 only documents with a MIME type matching \a mimefilter are selected.
1252 The value may contain multiple wild-card patterns separated by ";", 1268 The value may contain multiple wild-card patterns separated by ";",
1253 such as \c{*o/mpeg;audio/x-wav}. 1269 such as \c{*o/mpeg;audio/x-wav}.
1254 1270
1255 See also \link applnk.html#files-and-links Files and Links\endlink. 1271 See also \link applnk.html#files-and-links Files and Links\endlink.
1256 1272
1257*/ 1273*/
1258DocLnkSet::DocLnkSet( const QString &directory, const QString& mimefilter ) : 1274DocLnkSet::DocLnkSet( const QString &directory, const QString& mimefilter ) :
1259 AppLnkSet() 1275 AppLnkSet()
1260{ 1276{
1261 QDir dir( directory ); 1277 QDir dir( directory );
1262 mFile = dir.dirName(); 1278 mFile = dir.dirName();
1263 QDict<void> reference; 1279 QDict<void> reference;
1264 1280
1265 QStringList subFilter = QStringList::split(";", mimefilter); 1281 QStringList subFilter = QStringList::split(";", mimefilter);
1266 QValueList<QRegExp> mimeFilters; 1282 QValueList<QRegExp> mimeFilters;
1267 for( QStringList::Iterator it = subFilter.begin(); it != subFilter.end(); ++ it ) 1283 for( QStringList::Iterator it = subFilter.begin(); it != subFilter.end(); ++ it )
1268 mimeFilters.append( QRegExp(*it, FALSE, TRUE) ); 1284 mimeFilters.append( QRegExp(*it, FALSE, TRUE) );
1269 1285
1270 findChildren(directory, mimeFilters, reference); 1286 findChildren(directory, mimeFilters, reference);
1271 1287
1272 const QList<DocLnk> &list = children(); 1288 const QList<DocLnk> &list = children();
1273 for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) { 1289 for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) {
1274 reference.remove( (*it)->file() ); 1290 reference.remove( (*it)->file() );
1275 } 1291 }
1276 1292
1277 for ( QDictIterator<void> dit(reference); dit.current(); ++dit ) { 1293 for ( QDictIterator<void> dit(reference); dit.current(); ++dit ) {
1278 if ( dit.current() == (void*)2 ) { 1294 if ( dit.current() == (void*)2 ) {
1279 // Unreferenced, make an unwritten link 1295 // Unreferenced, make an unwritten link
1280 DocLnk* dl = new DocLnk; 1296 DocLnk* dl = new DocLnk;
1281 QFileInfo fi( dit.currentKey() ); 1297 QFileInfo fi( dit.currentKey() );
1282 dl->setFile(fi.filePath()); 1298 dl->setFile(fi.filePath());
1283 dl->setName(fi.baseName()); 1299 dl->setName(fi.baseName());
1284 // #### default to current path? 1300 // #### default to current path?
1285 // dl->setCategories( ... ); 1301 // dl->setCategories( ... );
1286 bool match = mimefilter.isNull(); 1302 bool match = mimefilter.isNull();
1287 if ( !match ) 1303 if ( !match )
1288 for( QValueList<QRegExp>::Iterator it = mimeFilters.begin(); it != mimeFilters.end() && !match; ++ it ) 1304 for( QValueList<QRegExp>::Iterator it = mimeFilters.begin(); it != mimeFilters.end() && !match; ++ it )
1289 if ( (*it).match(dl->type()) >= 0 ) 1305 if ( (*it).match(dl->type()) >= 0 )
1290 match = TRUE; 1306 match = TRUE;
1291 if ( match /* && dl->type() != "application/octet-stream" */ 1307 if ( match /* && dl->type() != "application/octet-stream" */
1292 && !!dl->exec() ) 1308 && !!dl->exec() )
1293 add(dl); 1309 add(dl);
1294 else 1310 else
1295 delete dl; 1311 delete dl;
1296 } 1312 }
1297 } 1313 }
1298} 1314}
1299 1315
1300// other becomes empty 1316// other becomes empty
1301/*! 1317/*!
1302 Transfers all DocLnk objects from \a other to this set. \a other becomes 1318 Transfers all DocLnk objects from \a other to this set. \a other becomes
1303 empty. 1319 empty.
1304*/ 1320*/
1305void DocLnkSet::appendFrom( DocLnkSet& other ) 1321void DocLnkSet::appendFrom( DocLnkSet& other )
1306{ 1322{
1307 if ( &other == this ) 1323 if ( &other == this )
1308 return; 1324 return;
1309 QListIterator<AppLnk> it( other.mApps ); 1325 QListIterator<AppLnk> it( other.mApps );
1310 for ( ; it.current(); ) { 1326 for ( ; it.current(); ) {
1311 mApps.append(*it); 1327 mApps.append(*it);
1312 ++it; 1328 ++it;
1313 } 1329 }
1314 other.mApps.clear(); 1330 other.mApps.clear();
1315} 1331}
1316 1332
1317void DocLnkSet::findChildren(const QString &dr, const QValueList<QRegExp> &mimeFilters, QDict<void> &reference, int depth) 1333void DocLnkSet::findChildren(const QString &dr, const QValueList<QRegExp> &mimeFilters, QDict<void> &reference, int depth)
1318{ 1334{
1319 depth++; 1335 depth++;
1320 if ( depth > 10 ) 1336 if ( depth > 10 )
1321 return; 1337 return;
1322 1338
1323 QDir dir( dr ); 1339 QDir dir( dr );
1324 1340
1325 /* Opie got a different approach 1341 /* Opie got a different approach
1326 * I guess it's geek vs. consumer 1342 * I guess it's geek vs. consumer
1327 * in this case to be discussed 1343 * in this case to be discussed
1328 */ 1344 */
1329 if ( dir.exists( ".Qtopia-ignore" ) ) 1345 if ( dir.exists( ".Qtopia-ignore" ) )
1330 return; 1346 return;
1331 1347
1332 const QFileInfoList *list = dir.entryInfoList(); 1348 const QFileInfoList *list = dir.entryInfoList();
1333 if ( list ) { 1349 if ( list ) {
1334 QFileInfo* fi; 1350 QFileInfo* fi;
1335 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) { 1351 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) {
1336 QString bn = fi->fileName(); 1352 QString bn = fi->fileName();
1337 if ( bn[0] != '.' ) { 1353 if ( bn[0] != '.' ) {
1338 if ( fi->isDir() ) { 1354 if ( fi->isDir() ) {
1339 if ( bn != "CVS" && bn != "Qtopia" && bn != "QtPalmtop" ) 1355 if ( bn != "CVS" && bn != "Qtopia" && bn != "QtPalmtop" )
1340 findChildren(fi->filePath(), mimeFilters, reference, depth); 1356 findChildren(fi->filePath(), mimeFilters, reference, depth);
1341 } else { 1357 } else {
1342 if ( fi->extension(FALSE) == "desktop" ) { 1358 if ( fi->extension(FALSE) == "desktop" ) {
1343 DocLnk* dl = new DocLnk( fi->filePath() ); 1359 DocLnk* dl = new DocLnk( fi->filePath() );
1344 QFileInfo fi2(dl->file()); 1360 QFileInfo fi2(dl->file());
1345 bool match = FALSE; 1361 bool match = FALSE;
1346 if ( !fi2.exists() ) { 1362 if ( !fi2.exists() ) {
1347 dir.remove( dl->file() ); 1363 dir.remove( dl->file() );
1348 } 1364 }
1349 if ( mimeFilters.count() == 0 ) { 1365 if ( mimeFilters.count() == 0 ) {
1350 add( dl ); 1366 add( dl );
1351 match = TRUE; 1367 match = TRUE;
1352 } else { 1368 } else {
1353 for( QValueList<QRegExp>::ConstIterator it = mimeFilters.begin(); it != mimeFilters.end(); ++ it ) { 1369 for( QValueList<QRegExp>::ConstIterator it = mimeFilters.begin(); it != mimeFilters.end(); ++ it ) {
1354 if ( (*it).match(dl->type()) >= 0 ) { 1370 if ( (*it).match(dl->type()) >= 0 ) {
1355 add(dl); 1371 add(dl);
1356 match = TRUE; 1372 match = TRUE;
1357 } 1373 }
1358 } 1374 }
1359 } 1375 }
1360 if ( !match ) 1376 if ( !match )
1361 delete dl; 1377 delete dl;
1362 } else { 1378 } else {
1363 if ( !reference.find(fi->fileName()) ) 1379 if ( !reference.find(fi->fileName()) )
1364 reference.insert(fi->filePath(), (void*)2); 1380 reference.insert(fi->filePath(), (void*)2);
1365 } 1381 }
1366 } 1382 }
1367 } 1383 }
1368 } 1384 }
1369 } 1385 }
1370} 1386}
1371 1387
1372/*! 1388/*!
1373 \class DocLnk applnk.h 1389 \class DocLnk applnk.h
1374 \brief The DocLnk class represents loaded document references. 1390 \brief The DocLnk class represents loaded document references.
1375*/ 1391*/
1376 1392
1377/*! 1393/*!
1378 \fn DocLnk::DocLnk( const DocLnk &o ) 1394 \fn DocLnk::DocLnk( const DocLnk &o )
1379 1395
1380 Copies \a o. 1396 Copies \a o.
1381*/ 1397*/
1382 1398
1383/*! 1399/*!
1384 Constructs a DocLnk from a valid .desktop \a file or a new .desktop 1400 Constructs a DocLnk from a valid .desktop \a file or a new .desktop
1385 \a file for other files. 1401 \a file for other files.
1386*/ 1402*/
1387DocLnk::DocLnk( const QString &file ) : 1403DocLnk::DocLnk( const QString &file ) :
1388 AppLnk(file) 1404 AppLnk(file)
1389{ 1405{
1390 init(file); 1406 init(file);
1391} 1407}
1392 1408
1393/*! 1409/*!
1394 Constructs a DocLnk from a valid .desktop \a file or a new .desktop 1410 Constructs a DocLnk from a valid .desktop \a file or a new .desktop
1395 \a file for other files. If \a may_be_desktopfile is TRUE, then an 1411 \a file for other files. If \a may_be_desktopfile is TRUE, then an
1396 attempt is made to read \a file as a .desktop file; if that fails it 1412 attempt is made to read \a file as a .desktop file; if that fails it
1397 is read as a normal file. 1413 is read as a normal file.
1398*/ 1414*/
1399DocLnk::DocLnk( const QString &file, bool may_be_desktopfile ) : 1415DocLnk::DocLnk( const QString &file, bool may_be_desktopfile ) :
1400 AppLnk(may_be_desktopfile ? file : QString::null) 1416 AppLnk(may_be_desktopfile ? file : QString::null)
1401{ 1417{
1402 init(file); 1418 init(file);
1403} 1419}
1404 1420
1405void DocLnk::init(const QString &file) 1421void DocLnk::init(const QString &file)
1406{ 1422{
1407 if ( isValid() ) { 1423 if ( isValid() ) {
1408#ifndef FORCED_DIR_STRUCTURE_WAY 1424#ifndef FORCED_DIR_STRUCTURE_WAY
1409 if ( mType.isNull() ) 1425 if ( mType.isNull() )
1410 // try to infer it 1426 // try to infer it
1411#endif 1427#endif
1412 { 1428 {
1413 int s0 = file.findRev('/'); 1429 int s0 = file.findRev('/');
1414 if ( s0 > 0 ) { 1430 if ( s0 > 0 ) {
1415 int s1 = file.findRev('/',s0-1); 1431 int s1 = file.findRev('/',s0-1);
1416 if ( s1 > 0 ) { 1432 if ( s1 > 0 ) {
1417 int s2 = file.findRev('/',s1-1); 1433 int s2 = file.findRev('/',s1-1);
1418 if ( s2 > 0 ) { 1434 if ( s2 > 0 ) {
1419 mType = file.mid(s2+1,s0-s2-1); 1435 mType = file.mid(s2+1,s0-s2-1);
1420 } 1436 }
1421 } 1437 }
1422 } 1438 }
1423 } 1439 }
1424 } else if ( QFile::exists(file) ) { 1440 } else if ( QFile::exists(file) ) {
1425 QString n = file; 1441 QString n = file;
1426 n.replace(QRegExp(".*/"),""); 1442 n.replace(QRegExp(".*/"),"");
1427 n.replace(QRegExp("\\..*"),""); 1443 n.replace(QRegExp("\\..*"),"");
1428 setName( n ); 1444 setName( n );
1429 setFile( file ); 1445 setFile( file );
1430 } 1446 }
1431 MimeType mt(mType); 1447 MimeType mt(mType);
1432 if( mt.application() ) 1448 if( mt.application() )
1433 mExec = mt.application()->exec(); 1449 mExec = mt.application()->exec();
1434} 1450}
1435 1451
1436/*! 1452/*!
1437 Constructs an invalid DocLnk. 1453 Constructs an invalid DocLnk.
1438*/ 1454*/
1439DocLnk::DocLnk() 1455DocLnk::DocLnk()
1440{ 1456{
1441} 1457}
1442 1458
1443/*! 1459/*!
1444 Destroys the DocLnk. Just like AppLnk objects, a run-time error 1460 Destroys the DocLnk. Just like AppLnk objects, a run-time error
1445 occurs if the DocLnk is a member of a DocLnkSet (or AppLnkSet). 1461 occurs if the DocLnk is a member of a DocLnkSet (or AppLnkSet).
1446*/ 1462*/
1447DocLnk::~DocLnk() 1463DocLnk::~DocLnk()
1448{ 1464{
1449} 1465}
1450 1466
1451/*! 1467/*!
1452 \reimp 1468 \reimp
1453*/ 1469*/
1454QString DocLnk::exec() const 1470QString DocLnk::exec() const
1455{ 1471{
1456 MimeType mt(type()); 1472 MimeType mt(type());
1457 const AppLnk* app = mt.application(); 1473 const AppLnk* app = mt.application();
1458 if ( app ) 1474 if ( app )
1459 return app->exec(); 1475 return app->exec();
1460 else 1476 else
1461 return QString::null; 1477 return QString::null;
1462} 1478}
1463 1479
1464/*! 1480/*!
1465 \reimp 1481 \reimp
1466*/ 1482*/
1467void DocLnk::invoke(const QStringList& args) const 1483void DocLnk::invoke(const QStringList& args) const
1468{ 1484{
1469 MimeType mt(type()); 1485 MimeType mt(type());
1470 const AppLnk* app = mt.application(); 1486 const AppLnk* app = mt.application();
1471 if ( app ) { 1487 if ( app ) {
1472 QStringList a = args; 1488 QStringList a = args;
1473 if ( linkFileKnown() && QFile::exists( linkFile() ) ) 1489 if ( linkFileKnown() && QFile::exists( linkFile() ) )
1474 a.append(linkFile()); 1490 a.append(linkFile());
1475 else 1491 else
1476 a.append(file()); 1492 a.append(file());
1477 app->execute(a); 1493 app->execute(a);
1478 } 1494 }
1479} 1495}
1480 1496
1481 1497
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
@@ -1,936 +1,931 @@
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#include <qtopia/private/categories.h> 20#include <qtopia/private/categories.h>
21#include <qtopia/stringutil.h> 21#include <qtopia/stringutil.h>
22#include <qfile.h> 22#include <qfile.h>
23#include <qcstring.h> 23#include <qcstring.h>
24#include <qtextstream.h> 24#include <qtextstream.h>
25 25
26using namespace Qtopia; 26using namespace Qtopia;
27 27
28/*********************************************************** 28/***********************************************************
29 * 29 *
30 * CategoryGroup 30 * CategoryGroup
31 * 31 *
32 **********************************************************/ 32 **********************************************************/
33 33
34#ifdef PALMTOPCENTER 34#ifdef PALMTOPCENTER
35UidGen CategoryGroup::sUidGen( UidGen::PalmtopCenter ); 35UidGen CategoryGroup::sUidGen( UidGen::PalmtopCenter );
36#else 36#else
37UidGen CategoryGroup::sUidGen( UidGen::Qtopia ); 37UidGen CategoryGroup::sUidGen( UidGen::Qtopia );
38#endif 38#endif
39 39
40/*! \class CategoryGroup categories.h 40/*! \class CategoryGroup categories.h
41 \brief Helper class that is used by Categories 41 \brief Helper class that is used by Categories
42 42
43 CategoryGroup is a group of categories that is associated with an 43 CategoryGroup is a group of categories that is associated with an
44 application or global set. Mainly it defines a map of ids to 44 application or global set. Mainly it defines a map of ids to
45 category labels and category labels to ids. Lookups can be done with 45 category labels and category labels to ids. Lookups can be done with
46 labels or unique idenifiers. 46 labels or unique idenifiers.
47 47
48 \ingroup qtopiaemb 48 \ingroup qtopiaemb
49 \ingroup qtopiadesktop 49 \ingroup qtopiadesktop
50 \warning Categories API will likely change between Qtopia 1.5 and Qtopia 3 50 \warning Categories API will likely change between Qtopia 1.5 and Qtopia 3
51 \sa Categories::appGroupMap(), Categories::globalGroup() 51 \sa Categories::appGroupMap(), Categories::globalGroup()
52 */ 52 */
53 53
54/*! Add \a label and return the UID. If failure, then 0 is returned. Note 54/*! Add \a label and return the UID. If failure, then 0 is returned. Note
55 that All and Unfiled are reserved labels. 55 that All and Unfiled are reserved labels.
56 \internal 56 \internal
57*/ 57*/
58int CategoryGroup::add( const QString &label ) 58int CategoryGroup::add( const QString &label )
59{ 59{
60 if ( label == QObject::tr("All") || label == QObject::tr("Unfiled") ) 60 if ( label == QObject::tr("All") || label == QObject::tr("Unfiled") )
61 return 0; 61 return 0;
62 62
63 QMap<QString,int>::Iterator findIt = mLabelIdMap.find( label ); 63 QMap<QString,int>::Iterator findIt = mLabelIdMap.find( label );
64 if ( findIt != mLabelIdMap.end() ) 64 if ( findIt != mLabelIdMap.end() )
65 return 0; 65 return 0;
66 int newUid = uidGen().generate(); 66 int newUid = uidGen().generate();
67 insert( newUid, label ); 67 insert( newUid, label );
68 return newUid; 68 return newUid;
69} 69}
70 70
71void CategoryGroup::insert( int uid, const QString &label ) 71void CategoryGroup::insert( int uid, const QString &label )
72{ 72{
73 uidGen().store( uid ); 73 uidGen().store( uid );
74 mIdLabelMap[uid] = label; 74 mIdLabelMap[uid] = label;
75 mLabelIdMap[label] = uid; 75 mLabelIdMap[label] = uid;
76} 76}
77 77
78/*! \internal 78/*! \internal
79 */ 79 */
80bool CategoryGroup::add( int uid, const QString &label ) 80bool CategoryGroup::add( int uid, const QString &label )
81{ 81{
82 if ( label == QObject::tr("All") || label == QObject::tr("Unfiled") ) 82 if ( label == QObject::tr("All") || label == QObject::tr("Unfiled") )
83 return FALSE; 83 return FALSE;
84 84
85 QMap<QString,int>::ConstIterator labelIt = mLabelIdMap.find( label ); 85 QMap<QString,int>::ConstIterator labelIt = mLabelIdMap.find( label );
86 if ( labelIt != mLabelIdMap.end() ) 86 if ( labelIt != mLabelIdMap.end() )
87 return FALSE; 87 return FALSE;
88 QMap<int,QString>::ConstIterator idIt = mIdLabelMap.find( uid ); 88 QMap<int,QString>::ConstIterator idIt = mIdLabelMap.find( uid );
89 if ( idIt != mIdLabelMap.end() ) 89 if ( idIt != mIdLabelMap.end() )
90 return FALSE; 90 return FALSE;
91 insert( uid, label ); 91 insert( uid, label );
92 return TRUE; 92 return TRUE;
93} 93}
94 94
95/*! Returns TRUE if \a label was removed from the group, FALSE if not. 95/*! Returns TRUE if \a label was removed from the group, FALSE if not.
96 \internal 96 \internal
97 */ 97 */
98bool CategoryGroup::remove( const QString &label ) 98bool CategoryGroup::remove( const QString &label )
99{ 99{
100 QMap<QString,int>::Iterator findIt = mLabelIdMap.find( label ); 100 QMap<QString,int>::Iterator findIt = mLabelIdMap.find( label );
101 if ( findIt == mLabelIdMap.end() ) 101 if ( findIt == mLabelIdMap.end() )
102 return FALSE; 102 return FALSE;
103 103
104 mIdLabelMap.remove( *findIt ); 104 mIdLabelMap.remove( *findIt );
105 mLabelIdMap.remove( findIt ); 105 mLabelIdMap.remove( findIt );
106 106
107 return TRUE; 107 return TRUE;
108} 108}
109 109
110/*! Returns TRUE if \a uid was removed from the group, FALSE if not. 110/*! Returns TRUE if \a uid was removed from the group, FALSE if not.
111 \internal 111 \internal
112 */ 112 */
113bool CategoryGroup::remove( int uid ) 113bool CategoryGroup::remove( int uid )
114{ 114{
115 QMap<int,QString>::Iterator idIt = mIdLabelMap.find( uid ); 115 QMap<int,QString>::Iterator idIt = mIdLabelMap.find( uid );
116 if ( idIt == mIdLabelMap.end() ) 116 if ( idIt == mIdLabelMap.end() )
117 return FALSE; 117 return FALSE;
118 118
119 mLabelIdMap.remove( *idIt ); 119 mLabelIdMap.remove( *idIt );
120 mIdLabelMap.remove( idIt ); 120 mIdLabelMap.remove( idIt );
121 121
122 return TRUE; 122 return TRUE;
123} 123}
124 124
125/*! \internal 125/*! \internal
126 */ 126 */
127bool CategoryGroup::rename( int uid, const QString &newLabel ) 127bool CategoryGroup::rename( int uid, const QString &newLabel )
128{ 128{
129 if ( newLabel == QObject::tr("All") || newLabel == QObject::tr("Unfiled") ) 129 if ( newLabel == QObject::tr("All") || newLabel == QObject::tr("Unfiled") )
130 return FALSE; 130 return FALSE;
131 131
132 QMap<int, QString>::Iterator idIt = mIdLabelMap.find( uid ); 132 QMap<int, QString>::Iterator idIt = mIdLabelMap.find( uid );
133 if ( idIt == mIdLabelMap.end() ) 133 if ( idIt == mIdLabelMap.end() )
134 return FALSE; 134 return FALSE;
135 135
136 mLabelIdMap.remove( *idIt ); 136 mLabelIdMap.remove( *idIt );
137 mLabelIdMap[newLabel] = uid; 137 mLabelIdMap[newLabel] = uid;
138 *idIt = newLabel; 138 *idIt = newLabel;
139 139
140 return TRUE; 140 return TRUE;
141} 141}
142 142
143/*! \internal 143/*! \internal
144 */ 144 */
145bool CategoryGroup::rename( const QString &oldLabel, const QString &newLabel ) 145bool CategoryGroup::rename( const QString &oldLabel, const QString &newLabel )
146{ 146{
147 return rename( id(oldLabel), newLabel ); 147 return rename( id(oldLabel), newLabel );
148} 148}
149 149
150/*! Returns TRUE if \a uid is stored in this group, FALSE if not. */ 150/*! Returns TRUE if \a uid is stored in this group, FALSE if not. */
151bool CategoryGroup::contains(int uid) const 151bool CategoryGroup::contains(int uid) const
152{ 152{
153 return ( mIdLabelMap.find( uid ) != mIdLabelMap.end() ); 153 return ( mIdLabelMap.find( uid ) != mIdLabelMap.end() );
154} 154}
155 155
156/*! Returns TRUE if \a label is stored in this group, FALSE if not. */ 156/*! Returns TRUE if \a label is stored in this group, FALSE if not. */
157bool CategoryGroup::contains(const QString &label) const 157bool CategoryGroup::contains(const QString &label) const
158{ 158{
159 return ( mLabelIdMap.find( label ) != mLabelIdMap.end() ); 159 return ( mLabelIdMap.find( label ) != mLabelIdMap.end() );
160} 160}
161 161
162/*! Returns label associated with the \a uid or QString::null if 162/*! Returns label associated with the \a uid or QString::null if
163 not found 163 not found
164 */ 164 */
165const QString &CategoryGroup::label(int uid) const 165const QString &CategoryGroup::label(int uid) const
166{ 166{
167 QMap<int,QString>::ConstIterator idIt = mIdLabelMap.find( uid ); 167 QMap<int,QString>::ConstIterator idIt = mIdLabelMap.find( uid );
168 if ( idIt == mIdLabelMap.end() ) 168 if ( idIt == mIdLabelMap.end() )
169 return QString::null; 169 return QString::null;
170 return *idIt; 170 return *idIt;
171} 171}
172 172
173/*! Returns the uid associated with \a label or 0 if not found */ 173/*! Returns the uid associated with \a label or 0 if not found */
174int CategoryGroup::id(const QString &label) const 174int CategoryGroup::id(const QString &label) const
175{ 175{
176 QMap<QString,int>::ConstIterator labelIt = mLabelIdMap.find( label ); 176 QMap<QString,int>::ConstIterator labelIt = mLabelIdMap.find( label );
177 if ( labelIt == mLabelIdMap.end() ) 177 if ( labelIt == mLabelIdMap.end() )
178 return 0; 178 return 0;
179 return *labelIt; 179 return *labelIt;
180} 180}
181 181
182/*! Returns a list of all labels stored in this group. */ 182/*! Returns a list of all labels stored in this group. */
183QStringList CategoryGroup::labels() const 183QStringList CategoryGroup::labels() const
184{ 184{
185 QStringList labels; 185 QStringList labels;
186 for ( QMap<int, QString>::ConstIterator it = mIdLabelMap.begin(); 186 for ( QMap<int, QString>::ConstIterator it = mIdLabelMap.begin();
187 it != mIdLabelMap.end(); ++it ) 187 it != mIdLabelMap.end(); ++it )
188 labels += *it; 188 labels += *it;
189 // ### I don't think this is the place for this... 189 // ### I don't think this is the place for this...
190// labels.sort(); 190// labels.sort();
191 return labels; 191 return labels;
192} 192}
193 193
194/*! Returns a list of all labels associated with the \a catids */ 194/*! Returns a list of all labels associated with the \a catids */
195QStringList CategoryGroup::labels(const QArray<int> &catids ) const 195QStringList CategoryGroup::labels(const QArray<int> &catids ) const
196{ 196{
197 QStringList labels; 197 QStringList labels;
198 if ( catids.count() == 0 ) 198 if ( catids.count() == 0 )
199 return labels; 199 return labels;
200 for ( QMap<int, QString>::ConstIterator it = mIdLabelMap.begin(); 200 for ( QMap<int, QString>::ConstIterator it = mIdLabelMap.begin();
201 it != mIdLabelMap.end(); ++it ) 201 it != mIdLabelMap.end(); ++it )
202 if ( catids.find( it.key() ) != -1 ) 202 if ( catids.find( it.key() ) != -1 )
203 labels += *it; 203 labels += *it;
204 return labels; 204 return labels;
205} 205}
206 206
207/*********************************************************** 207/***********************************************************
208 * 208 *
209 * Categories 209 * Categories
210 * 210 *
211 **********************************************************/ 211 **********************************************************/
212 212
213/*! 213/*!
214 \class Categories categories.h 214 \class Categories categories.h
215 \brief The Categories class is a database that groups categories and maps ids to names. 215 \brief The Categories class is a database that groups categories and maps ids to names.
216 216
217 The Categories class is the low level Categories accessor class. To 217 The Categories class is the low level Categories accessor class. To
218 add a category menu and filter for your application, see CategoryMenu. 218 add a category menu and filter for your application, see CategoryMenu.
219 219
220 The Categories class allows the developer to add, remove, and rename 220 The Categories class allows the developer to add, remove, and rename
221 categories. Categories can be created for an individual application 221 categories. Categories can be created for an individual application
222 such as Todo List or to be used for all applications. Categories 222 such as Todo List or to be used for all applications. Categories
223 that can be used by all applications are called global 223 that can be used by all applications are called global
224 categories. Each PalmtopRecord subclass stores categories as an 224 categories. Each PalmtopRecord subclass stores categories as an
225 QArray<int> using PalmtopRecord::setCategories() and 225 QArray<int> using PalmtopRecord::setCategories() and
226 PalmtopRecord::categories(). This allows each record to be assigned 226 PalmtopRecord::categories(). This allows each record to be assigned
227 to multiple categories. This also allows the user to rename a 227 to multiple categories. This also allows the user to rename a
228 category and for it to update automatically in all records. 228 category and for it to update automatically in all records.
229 229
230 This class provides several methods to convert between a category id 230 This class provides several methods to convert between a category id
231 and it's associated string such as id(), ids(), label() and labels(). A 231 and it's associated string such as id(), ids(), label() and labels(). A
232 helper class called CategoryGroup is used to access categories of a 232 helper class called CategoryGroup is used to access categories of a
233 single application group, such as Todo List. Global categories can 233 single application group, such as Todo List. Global categories can
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,1354 +1,1354 @@
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() );
433 if ( !notes().isEmpty() ) 433 if ( !notes().isEmpty() )
434 m.insert ( Note, notes() ); 434 m.insert ( Note, notes() );
435 435
436 m.insert ( StartDateTime, QString::number( TimeConversion::toUTC( start() ) ) ); 436 m.insert ( StartDateTime, QString::number( TimeConversion::toUTC( start() ) ) );
437 m.insert ( EndDateTime, QString::number( TimeConversion::toUTC( end() ) ) ); 437 m.insert ( EndDateTime, QString::number( TimeConversion::toUTC( end() ) ) );
438 m.insert ( DatebookType, QString::number( (int)type() ) ); 438 m.insert ( DatebookType, QString::number( (int)type() ) );
439 m.insert ( HasAlarm, ( hasAlarm() ? "1" : "0" ) ); 439 m.insert ( HasAlarm, ( hasAlarm() ? "1" : "0" ) );
440 m.insert ( SoundType, QString::number( (int)alarmSound() ) ); 440 m.insert ( SoundType, QString::number( (int)alarmSound() ) );
441 m.insert ( AlarmTime, QString::number( alarmTime() ) ); 441 m.insert ( AlarmTime, QString::number( alarmTime() ) );
442 m.insert ( RepeatPatternType, QString::number( static_cast<int>( repeatPattern().type ) ) ); 442 m.insert ( RepeatPatternType, QString::number( static_cast<int>( repeatPattern().type ) ) );
443 m.insert ( RepeatPatternFrequency, QString::number( repeatPattern().frequency ) ); 443 m.insert ( RepeatPatternFrequency, QString::number( repeatPattern().frequency ) );
444 m.insert ( RepeatPatternPosition, QString::number( repeatPattern().position ) ); 444 m.insert ( RepeatPatternPosition, QString::number( repeatPattern().position ) );
445 m.insert ( RepeatPatternDays, QString::number( repeatPattern().days ) ); 445 m.insert ( RepeatPatternDays, QString::number( repeatPattern().days ) );
446 m.insert ( RepeatPatternHasEndDate, QString::number( static_cast<int>( repeatPattern().hasEndDate ) ) ); 446 m.insert ( RepeatPatternHasEndDate, QString::number( static_cast<int>( repeatPattern().hasEndDate ) ) );
447 m.insert ( RepeatPatternEndDate, QString::number( repeatPattern().endDateUTC ) ); 447 m.insert ( RepeatPatternEndDate, QString::number( repeatPattern().endDateUTC ) );
448 448
449 m.insert( DatebookUid, QString::number( uid()) ); 449 m.insert( DatebookUid, QString::number( uid()) );
450 450
451 return m; 451 return m;
452} 452}
453 453
454/*! 454/*!
455 \internal 455 \internal
456*/ 456*/
457void Event::setRepeat( const RepeatPattern &p ) 457void Event::setRepeat( const RepeatPattern &p )
458{ 458{
459 setRepeat( p.type != NoRepeat, p ); 459 setRepeat( p.type != NoRepeat, p );
460} 460}
461 461
462/*! 462/*!
463 Sets the description of the event to \a s. 463 Sets the description of the event to \a s.
464*/ 464*/
465void Event::setDescription( const QString &s ) 465void Event::setDescription( const QString &s )
466{ 466{
467 descript = s; 467 descript = s;
468} 468}
469 469
470/*! 470/*!
471 Sets the location of the event to \a s. 471 Sets the location of the event to \a s.
472*/ 472*/
473void Event::setLocation( const QString &s ) 473void Event::setLocation( const QString &s )
474{ 474{
475 locat = s; 475 locat = s;
476} 476}
477 477
478// void Event::setCategory( const QString &s ) 478// void Event::setCategory( const QString &s )
479// { 479// {
480// categ = s; 480// categ = s;
481// } 481// }
482 482
483/*! 483/*!
484 \internal 484 \internal
485*/ 485*/
486void Event::setType( Type t ) 486void Event::setType( Type t )
487{ 487{
488 typ = t; 488 typ = t;
489} 489}
490 490
491/*! 491/*!
492 Sets the start date and time of the first or only occurance of this event 492 Sets the start date and time of the first or only occurance of this event
493 to the date and time \a d. \a d should be in local time. 493 to the date and time \a d. \a d should be in local time.
494*/ 494*/
495void Event::setStart( const QDateTime &d ) 495void Event::setStart( const QDateTime &d )
496{ 496{
497 startUTC = TimeConversion::toUTC( d ); 497 startUTC = TimeConversion::toUTC( d );
498} 498}
499 499
500/*! 500/*!
501 \internal 501 \internal
502*/ 502*/
503void Event::setStart( time_t time ) 503void Event::setStart( time_t time )
504{ 504{
505 startUTC = time; 505 startUTC = time;
506} 506}
507 507
508/*! 508/*!
509 Sets the end date and time of the first or only occurance of this event 509 Sets the end date and time of the first or only occurance of this event
510 to the date and time \a d. \a d should be in local time. 510 to the date and time \a d. \a d should be in local time.
511*/ 511*/
512void Event::setEnd( const QDateTime &d ) 512void Event::setEnd( const QDateTime &d )
513{ 513{
514 endUTC = TimeConversion::toUTC( d ); 514 endUTC = TimeConversion::toUTC( d );
515} 515}
516 516
517/*! 517/*!
518 \internal 518 \internal
519*/ 519*/
520void Event::setEnd( time_t time ) 520void Event::setEnd( time_t time )
521{ 521{
522 endUTC = time; 522 endUTC = time;
523} 523}
524 524
525/*! 525/*!
526 \internal 526 \internal
527*/ 527*/
528void Event::setTimeZone( const QString &z ) 528void Event::setTimeZone( const QString &z )
529{ 529{
530 tz = z; 530 tz = z;
531} 531}
532 532
533/*! 533/*!
534 \internal 534 \internal
535*/ 535*/
536void Event::setAlarm( bool b, int minutes, SoundTypeChoice s ) 536void Event::setAlarm( bool b, int minutes, SoundTypeChoice s )
537{ 537{
538 hAlarm = b; 538 hAlarm = b;
539 aMinutes = minutes; 539 aMinutes = minutes;
540 aSound = s; 540 aSound = s;
541} 541}
542 542
543/*! 543/*!
544 \internal 544 \internal
545*/ 545*/
546void Event::setRepeat( bool b, const RepeatPattern &p ) 546void Event::setRepeat( bool b, const RepeatPattern &p )
547{ 547{
548 hRepeat = b; 548 hRepeat = b;
549 pattern = p; 549 pattern = p;
550} 550}
551 551
552/*! 552/*!
553 Sets the notes for the event to \a n. 553 Sets the notes for the event to \a n.
554*/ 554*/
555void Event::setNotes( const QString &n ) 555void Event::setNotes( const QString &n )
556{ 556{
557 note = n; 557 note = n;
558} 558}
559 559
560/*! 560/*!
561 Returns the description of the event. 561 Returns the description of the event.
562*/ 562*/
563const QString &Event::description() const 563const QString &Event::description() const
564{ 564{
565 return descript; 565 return descript;
566} 566}
567 567
568/*! 568/*!
569 Returns the location of the event. 569 Returns the location of the event.
570*/ 570*/
571const QString &Event::location() const 571const QString &Event::location() const
572{ 572{
573 return locat; 573 return locat;
574} 574}
575 575
576// QString Event::category() const 576// QString Event::category() const
577// { 577// {
578// return categ; 578// return categ;
579// } 579// }
580 580
581/*! 581/*!
582 \internal 582 \internal
583*/ 583*/
584Event::Type Event::type() const 584Event::Type Event::type() const
585{ 585{
586 return typ; 586 return typ;
587} 587}
588/* 588/*
589QDateTime Event::start() const { 589QDateTime Event::start() const {
590 return start( TRUE ); 590 return start( TRUE );
591} 591}
592*/ 592*/
593/*! 593/*!
594 \internal 594 \internal
595*/ 595*/
596QDateTime Event::start( bool actual ) const 596QDateTime Event::start( bool actual ) const
597{ 597{
598 QDateTime dt = TimeConversion::fromUTC( startUTC ); 598 QDateTime dt = TimeConversion::fromUTC( startUTC );
599 599
600 if ( actual && typ == AllDay ) { 600 if ( actual && typ == AllDay ) {
601 QTime t = dt.time(); 601 QTime t = dt.time();
602 t.setHMS( 0, 0, 0 ); 602 t.setHMS( 0, 0, 0 );
603 dt.setTime( t ); 603 dt.setTime( t );
604 } 604 }
605 return dt; 605 return dt;
606} 606}
607/* 607/*
608QDateTime Event::end() const { 608QDateTime Event::end() const {
609 return end( TRUE ); 609 return end( TRUE );
610} 610}
611*/ 611*/
612/*! 612/*!
613 \internal 613 \internal
614*/ 614*/
615QDateTime Event::end( bool actual ) const 615QDateTime Event::end( bool actual ) const
616{ 616{
617 /* small work around... */ 617 /* small work around... */
618 if ( actual && typ == AllDay ) { 618 if ( actual && typ == AllDay ) {
619 return QDateTime( TimeConversion::fromUTC( startUTC ).date(), QTime(23, 59, 59 ) ); 619 return QDateTime( TimeConversion::fromUTC( startUTC ).date(), QTime(23, 59, 59 ) );
620 } 620 }
621 return TimeConversion::fromUTC( endUTC ); 621 return TimeConversion::fromUTC( endUTC );
622} 622}
623 623
624/*! 624/*!
625 \internal 625 \internal
626*/ 626*/
627const QString &Event::timeZone() const 627const QString &Event::timeZone() const
628{ 628{
629 return tz; 629 return tz;
630} 630}
631 631
632/*! 632/*!
633 \internal 633 \internal
634*/ 634*/
635bool Event::hasAlarm() const 635bool Event::hasAlarm() const
636{ 636{
637 return hAlarm; 637 return hAlarm;
638} 638}
639 639
640/*! 640/*!
641 \internal 641 \internal
642*/ 642*/
643int Event::alarmTime() const 643int Event::alarmTime() const
644{ 644{
645 return aMinutes; 645 return aMinutes;
646} 646}
647 647
648/*! 648/*!
649 Returns the sound type for the alarm of this event. 649 Returns the sound type for the alarm of this event.
650*/ 650*/
651Event::SoundTypeChoice Event::alarmSound() const 651Event::SoundTypeChoice Event::alarmSound() const
652{ 652{
653 return aSound; 653 return aSound;
654} 654}
655 655
656/*! 656/*!
657 \internal 657 \internal
658*/ 658*/
659bool Event::hasRepeat() const 659bool Event::hasRepeat() const
660{ 660{
661 return doRepeat(); 661 return doRepeat();
662} 662}
663 663
664/*! 664/*!
665 \internal 665 \internal
666*/ 666*/
667const Event::RepeatPattern &Event::repeatPattern() const 667const Event::RepeatPattern &Event::repeatPattern() const
668{ 668{
669 return pattern; 669 return pattern;
670} 670}
671 671
672/*! 672/*!
673 \internal 673 \internal
674*/ 674*/
675Event::RepeatPattern &Event::repeatPattern() 675Event::RepeatPattern &Event::repeatPattern()
676{ 676{
677 return pattern; 677 return pattern;
678} 678}
679 679
680/*! 680/*!
681 Returns the notes for the event. 681 Returns the notes for the event.
682*/ 682*/
683const QString &Event::notes() const 683const QString &Event::notes() const
684{ 684{
685 return note; 685 return note;
686} 686}
687 687
688/*! 688/*!
689 \internal 689 \internal
690*/ 690*/
691bool Event::operator==( const Event &e ) const 691bool Event::operator==( const Event &e ) const
692{ 692{
693 if ( uid() && e.uid() == uid() ) 693 if ( uid() && e.uid() == uid() )
694 return TRUE; 694 return TRUE;
695 return ( e.descript == descript && 695 return ( e.descript == descript &&
696 e.locat == locat && 696 e.locat == locat &&
697 e.categ == categ && 697 e.categ == categ &&
698 e.typ == typ && 698 e.typ == typ &&
699 e.startUTC == startUTC && 699 e.startUTC == startUTC &&
700 e.endUTC == endUTC && 700 e.endUTC == endUTC &&
701 e.tz == tz && 701 e.tz == tz &&
702 e.hAlarm == hAlarm && 702 e.hAlarm == hAlarm &&
703 e.aMinutes == aMinutes && 703 e.aMinutes == aMinutes &&
704 e.aSound == aSound && 704 e.aSound == aSound &&
705 e.hRepeat == hRepeat && 705 e.hRepeat == hRepeat &&
706 e.pattern == pattern && 706 e.pattern == pattern &&
707 e.note == note ); 707 e.note == note );
708} 708}
709 709
710/*! 710/*!
711 \internal 711 \internal
712 Appends the contact information to \a buf. 712 Appends the contact information to \a buf.
713*/ 713*/
714void Event::save( QString& buf ) 714void Event::save( QString& buf )
715{ 715{
716 buf += " description=\"" + Qtopia::escapeString(descript) + "\""; 716 buf += " description=\"" + Qtopia::escapeString(descript) + "\"";
717 if ( !locat.isEmpty() ) 717 if ( !locat.isEmpty() )
718 buf += " location=\"" + Qtopia::escapeString(locat) + "\""; 718 buf += " location=\"" + Qtopia::escapeString(locat) + "\"";
719 // save the categoies differently.... 719 // save the categoies differently....
720 QString strCats = idsToString( categories() ); 720 QString strCats = idsToString( categories() );
721 buf += " categories=\"" + Qtopia::escapeString(strCats) + "\""; 721 buf += " categories=\"" + Qtopia::escapeString(strCats) + "\"";
722 buf += " uid=\"" + QString::number( uid() ) + "\""; 722 buf += " uid=\"" + QString::number( uid() ) + "\"";
723 if ( (Type)typ != Normal ) 723 if ( (Type)typ != Normal )
724 buf += " type=\"AllDay\""; 724 buf += " type=\"AllDay\"";
725 if ( hAlarm ) { 725 if ( hAlarm ) {
726 buf += " alarm=\"" + QString::number( aMinutes ) + "\" sound=\""; 726 buf += " alarm=\"" + QString::number( aMinutes ) + "\" sound=\"";
727 if ( aSound == Event::Loud ) 727 if ( aSound == Event::Loud )
728 buf += "loud"; 728 buf += "loud";
729 else 729 else
730 buf += "silent"; 730 buf += "silent";
731 buf += "\""; 731 buf += "\"";
732 } 732 }
733 if ( hRepeat ) 733 if ( hRepeat )
734 write( buf, pattern ); 734 write( buf, pattern );
735 735
736 buf += " start=\"" 736 buf += " start=\""
737 + QString::number( startUTC ) 737 + QString::number( startUTC )
738 + "\""; 738 + "\"";
739 739
740 buf += " end=\"" 740 buf += " end=\""
741 + QString::number( endUTC ) 741 + QString::number( endUTC )
742 + "\""; 742 + "\"";
743 743
744 if ( !note.isEmpty() ) 744 if ( !note.isEmpty() )
745 buf += " note=\"" + Qtopia::escapeString( note ) + "\""; 745 buf += " note=\"" + Qtopia::escapeString( note ) + "\"";
746 buf += customToXml(); 746 buf += customToXml();
747} 747}
748 748
749/*! 749/*!
750 \internal 750 \internal
751*/ 751*/
752bool Event::RepeatPattern::operator==( const Event::RepeatPattern &right ) const 752bool Event::RepeatPattern::operator==( const Event::RepeatPattern &right ) const
753{ 753{
754 // *sigh* 754 // *sigh*
755 return ( type == right.type 755 return ( type == right.type
756 && frequency == right.frequency 756 && frequency == right.frequency
757 && position == right.position 757 && position == right.position
758 && days == right.days 758 && days == right.days
759 && hasEndDate == right.hasEndDate 759 && hasEndDate == right.hasEndDate
760 && endDateUTC == right.endDateUTC 760 && endDateUTC == right.endDateUTC
761 && createTime == right.createTime ); 761 && createTime == right.createTime );
762} 762}
763 763
764/*! 764/*!
765 \class EffectiveEvent 765 \class EffectiveEvent
766 \brief The EffectiveEvent class the data for a single occurance of an event. 766 \brief The EffectiveEvent class the data for a single occurance of an event.
767 767
768 This class describes the event for a single occurance of it. For example if 768 This class describes the event for a single occurance of it. For example if
769 an Event occurs every week, the effective event might represent the third 769 an Event occurs every week, the effective event might represent the third
770 occurance of this Event. 770 occurance of this Event.
771 771
772 \ingroup qtopiaemb 772 \ingroup qtopiaemb
773 \ingroup qtopiadesktop 773 \ingroup qtopiadesktop
774 \warning This class will be phased out in Qtopia 3.x 774 \warning This class will be phased out in Qtopia 3.x
775*/ 775*/
776 776
777/*! 777/*!
778 \enum EffectiveEvent::Position 778 \enum EffectiveEvent::Position
779 \internal 779 \internal
780*/ 780*/
781 781
782/*! 782/*!
783 \fn EffectiveEvent &EffectiveEvent::operator=(const EffectiveEvent &) 783 \fn EffectiveEvent &EffectiveEvent::operator=(const EffectiveEvent &)
784 \internal 784 \internal
785*/ 785*/
786 786
787class EffectiveEventPrivate 787class EffectiveEventPrivate
788{ 788{
789public: 789public:
790 //currently the existence of the d pointer means multi-day repeating, 790 //currently the existence of the d pointer means multi-day repeating,
791 //msut be changed if we use the d pointer for anything else. 791 //msut be changed if we use the d pointer for anything else.
792 QDate startDate; 792 QDate startDate;
793 QDate endDate; 793 QDate endDate;
794}; 794};
795 795
796/*! 796/*!
797 \internal 797 \internal
798*/ 798*/
799EffectiveEvent::EffectiveEvent() 799EffectiveEvent::EffectiveEvent()
800{ 800{
801 mDate = QDate::currentDate(); 801 mDate = QDate::currentDate();
802 mStart = mEnd = QTime::currentTime(); 802 mStart = mEnd = QTime::currentTime();
803 d = 0; 803 d = 0;
804} 804}
805 805
806/*! 806/*!
807 \internal 807 \internal
808*/ 808*/
809EffectiveEvent::EffectiveEvent( const Event &e, const QDate &date, Position pos ) 809EffectiveEvent::EffectiveEvent( const Event &e, const QDate &date, Position pos )
810{ 810{
811 mEvent = e; 811 mEvent = e;
812 mDate = date; 812 mDate = date;
813 if ( pos & Start ) 813 if ( pos & Start )
814 mStart = e.start( TRUE ).time(); 814 mStart = e.start( TRUE ).time();
815 else 815 else
816 mStart = QTime( 0, 0, 0 ); 816 mStart = QTime( 0, 0, 0 );
817 817
818 if ( pos & End ) 818 if ( pos & End )
819 mEnd = e.end( TRUE ).time(); 819 mEnd = e.end( TRUE ).time();
820 else 820 else
821 mEnd = QTime( 23, 59, 59 ); 821 mEnd = QTime( 23, 59, 59 );
822 d = 0; 822 d = 0;
823} 823}
824 824
825/*! 825/*!
826 \internal 826 \internal
827*/ 827*/
828EffectiveEvent::~EffectiveEvent() 828EffectiveEvent::~EffectiveEvent()
829{ 829{
830 delete d; 830 delete d;
831} 831}
832 832
833/*! 833/*!
834 \internal 834 \internal
835*/ 835*/
836EffectiveEvent::EffectiveEvent( const EffectiveEvent &e ) 836EffectiveEvent::EffectiveEvent( const EffectiveEvent &e )
837{ 837{
838 d = 0; 838 d = 0;
839 *this = e; 839 *this = e;
840} 840}
841 841
842EffectiveEvent& EffectiveEvent::operator=( const EffectiveEvent & e ) 842EffectiveEvent& EffectiveEvent::operator=( const EffectiveEvent & e )
843{ 843{
844 if ( &e == this ) 844 if ( &e == this )
845 return *this; 845 return *this;
846 delete d; 846 delete d;
847 if ( e.d ) { 847 if ( e.d ) {
848 d = new EffectiveEventPrivate; 848 d = new EffectiveEventPrivate;
849 d->startDate = e.d->startDate; 849 d->startDate = e.d->startDate;
850 d->endDate = e.d->endDate; 850 d->endDate = e.d->endDate;
851 } else { 851 } else {
852 d = 0; 852 d = 0;
853 } 853 }
854 mEvent = e.mEvent; 854 mEvent = e.mEvent;
855 mDate = e.mDate; 855 mDate = e.mDate;
856 mStart = e.mStart; 856 mStart = e.mStart;
857 mEnd = e.mEnd; 857 mEnd = e.mEnd;
858 858
859 return *this; 859 return *this;
860 860
861} 861}
862 862
863// QString EffectiveEvent::category() const 863// QString EffectiveEvent::category() const
864// { 864// {
865// return mEvent.category(); 865// return mEvent.category();
866// } 866// }
867 867
868/*! 868/*!
869 Returns the description of the event for this effective event. 869 Returns the description of the event for this effective event.
870*/ 870*/
871const QString &EffectiveEvent::description( ) const 871const QString &EffectiveEvent::description( ) const
872{ 872{
873 return mEvent.description(); 873 return mEvent.description();
874} 874}
875 875
876/*! 876/*!
877\internal 877\internal
878*/ 878*/
879const QString &EffectiveEvent::location( ) const 879const QString &EffectiveEvent::location( ) const
880{ 880{
881 return mEvent.location(); 881 return mEvent.location();
882} 882}
883 883
884/*! 884/*!
885\internal 885\internal
886*/ 886*/
887const QString &EffectiveEvent::notes() const 887const QString &EffectiveEvent::notes() const
888{ 888{
889 return mEvent.notes(); 889 return mEvent.notes();
890} 890}
891 891
892/*! 892/*!
893 Returns the event associated with this effective event. 893 Returns the event associated with this effective event.
894*/ 894*/
895const Event &EffectiveEvent::event() const 895const Event &EffectiveEvent::event() const
896{ 896{
897 return mEvent; 897 return mEvent;
898} 898}
899 899
900/*! 900/*!
901 \internal 901 \internal
902*/ 902*/
903const QTime &EffectiveEvent::end() const 903const QTime &EffectiveEvent::end() const
904{ 904{
905 return mEnd; 905 return mEnd;
906} 906}
907 907
908/*! 908/*!
909 \internal 909 \internal
910*/ 910*/
911const QTime &EffectiveEvent::start() const 911const QTime &EffectiveEvent::start() const
912{ 912{
913 return mStart; 913 return mStart;
914} 914}
915 915
916/*! 916/*!
917 Returns the date the effective event occurs on. 917 Returns the date the effective event occurs on.
918*/ 918*/
919const QDate &EffectiveEvent::date() const 919const QDate &EffectiveEvent::date() const
920{ 920{
921 return mDate; 921 return mDate;
922} 922}
923 923
924/*! 924/*!
925 \internal 925 \internal
926*/ 926*/
927int EffectiveEvent::length() const 927int EffectiveEvent::length() const
928{ 928{
929 return (mEnd.hour() * 60 - mStart.hour() * 60) 929 return (mEnd.hour() * 60 - mStart.hour() * 60)
930 + QABS(mStart.minute() - mEnd.minute() ); 930 + QABS(mStart.minute() - mEnd.minute() );
931} 931}
932 932
933/*! 933/*!
934 \internal 934 \internal
935*/ 935*/
936void EffectiveEvent::setDate( const QDate &dt ) 936void EffectiveEvent::setDate( const QDate &dt )
937{ 937{
938 mDate = dt; 938 mDate = dt;
939} 939}
940 940
941/*! 941/*!
942 \internal 942 \internal
943*/ 943*/
944void EffectiveEvent::setStart( const QTime &start ) 944void EffectiveEvent::setStart( const QTime &start )
945{ 945{
946 mStart = start; 946 mStart = start;
947} 947}
948 948
949/*! 949/*!
950 \internal 950 \internal
951*/ 951*/
952void EffectiveEvent::setEnd( const QTime &end ) 952void EffectiveEvent::setEnd( const QTime &end )
953{ 953{
954 mEnd = end; 954 mEnd = end;
955} 955}
956 956
957/*! 957/*!
958 \internal 958 \internal
959*/ 959*/
960void EffectiveEvent::setEvent( Event e ) 960void EffectiveEvent::setEvent( Event e )
961{ 961{
962 mEvent = e; 962 mEvent = e;
963} 963}
964 964
965/*! 965/*!
966 \internal 966 \internal
967*/ 967*/
968bool EffectiveEvent::operator<( const EffectiveEvent &e ) const 968bool EffectiveEvent::operator<( const EffectiveEvent &e ) const
969{ 969{
970 if ( mDate < e.date() ) 970 if ( mDate < e.date() )
971 return TRUE; 971 return TRUE;
972 if ( mDate == e.date() ) 972 if ( mDate == e.date() )
973 return ( mStart < e.start() ); 973 return ( mStart < e.start() );
974 else 974 else
975 return FALSE; 975 return FALSE;
976} 976}
977 977
978/*! 978/*!
979 \internal 979 \internal
980*/ 980*/
981bool EffectiveEvent::operator<=( const EffectiveEvent &e ) const 981bool EffectiveEvent::operator<=( const EffectiveEvent &e ) const
982{ 982{
983 return (mDate <= e.date() ); 983 return (mDate <= e.date() );
984} 984}
985 985
986/*! 986/*!
987 \internal 987 \internal
988*/ 988*/
989bool EffectiveEvent::operator==( const EffectiveEvent &e ) const 989bool EffectiveEvent::operator==( const EffectiveEvent &e ) const
990{ 990{
991 return ( mDate == e.date() 991 return ( mDate == e.date()
992 && mStart == e.start() 992 && mStart == e.start()
993 && mEnd == e.end() 993 && mEnd == e.end()
994 && mEvent == e.event() ); 994 && mEvent == e.event() );
995} 995}
996 996
997/*! 997/*!
998 \internal 998 \internal
999*/ 999*/
1000bool EffectiveEvent::operator!=( const EffectiveEvent &e ) const 1000bool EffectiveEvent::operator!=( const EffectiveEvent &e ) const
1001{ 1001{
1002 return !(*this == e); 1002 return !(*this == e);
1003} 1003}
1004 1004
1005/*! 1005/*!
1006 \internal 1006 \internal
1007*/ 1007*/
1008bool EffectiveEvent::operator>( const EffectiveEvent &e ) const 1008bool EffectiveEvent::operator>( const EffectiveEvent &e ) const
1009{ 1009{
1010 return !(*this <= e ); 1010 return !(*this <= e );
1011} 1011}
1012 1012
1013/*! 1013/*!
1014 \internal 1014 \internal
1015*/ 1015*/
1016bool EffectiveEvent::operator>=(const EffectiveEvent &e) const 1016bool EffectiveEvent::operator>=(const EffectiveEvent &e) const
1017{ 1017{
1018 return !(*this < e); 1018 return !(*this < e);
1019} 1019}
1020 1020
1021/*! 1021/*!
1022 \internal 1022 \internal
1023*/ 1023*/
1024void EffectiveEvent::setEffectiveDates( const QDate &from, const QDate &to ) 1024void EffectiveEvent::setEffectiveDates( const QDate &from, const QDate &to )
1025{ 1025{
1026 if ( !from.isValid() ) { 1026 if ( !from.isValid() ) {
1027 delete d; 1027 delete d;
1028 d = 0; 1028 d = 0;
1029 return; 1029 return;
1030 } 1030 }
1031 if ( !d ) 1031 if ( !d )
1032 d = new EffectiveEventPrivate; 1032 d = new EffectiveEventPrivate;
1033 d->startDate = from; 1033 d->startDate = from;
1034 d->endDate = to; 1034 d->endDate = to;
1035} 1035}
1036 1036
1037/*! 1037/*!
1038 \internal 1038 \internal
1039*/ 1039*/
1040QDate EffectiveEvent::startDate() const 1040QDate EffectiveEvent::startDate() const
1041{ 1041{
1042 if ( d ) 1042 if ( d )
1043 return d->startDate; 1043 return d->startDate;
1044 else if ( mEvent.hasRepeat() ) 1044 else if ( mEvent.hasRepeat() )
1045 return mDate; // single day, since multi-day should have a d pointer 1045 return mDate; // single day, since multi-day should have a d pointer
1046 else 1046 else
1047 return mEvent.start().date(); 1047 return mEvent.start().date();
1048} 1048}
1049 1049
1050/*! 1050/*!
1051 \internal 1051 \internal
1052*/ 1052*/
1053QDate EffectiveEvent::endDate() const 1053QDate EffectiveEvent::endDate() const
1054{ 1054{
1055 if ( d ) 1055 if ( d )
1056 return d->endDate; 1056 return d->endDate;
1057 else if ( mEvent.hasRepeat() ) 1057 else if ( mEvent.hasRepeat() )
1058 return mDate; // single day, since multi-day should have a d pointer 1058 return mDate; // single day, since multi-day should have a d pointer
1059 else 1059 else
1060 return mEvent.end().date(); 1060 return mEvent.end().date();
1061} 1061}
1062 1062
1063/*! 1063/*!
1064 \internal 1064 \internal
1065*/ 1065*/
1066int EffectiveEvent::size() const 1066int EffectiveEvent::size() const
1067{ 1067{
1068 return ( mEnd.hour() - mStart.hour() ) * 3600 1068 return ( mEnd.hour() - mStart.hour() ) * 3600
1069 + (mEnd.minute() - mStart.minute() * 60 1069 + (mEnd.minute() - mStart.minute() * 60
1070 + mEnd.second() - mStart.second() ); 1070 + mEnd.second() - mStart.second() );
1071} 1071}
1072 1072
1073 1073
1074// vcal conversion code 1074// vcal conversion code
1075static inline VObject *safeAddPropValue( VObject *o, const char *prop, const QString &value ) 1075static inline VObject *safeAddPropValue( VObject *o, const char *prop, const QString &value )
1076{ 1076{
1077 VObject *ret = 0; 1077 VObject *ret = 0;
1078 if ( o && !value.isEmpty() ) 1078 if ( o && !value.isEmpty() )
1079 ret = addPropValue( o, prop, value.latin1() ); 1079 ret = addPropValue( o, prop, value.latin1() );
1080 return ret; 1080 return ret;
1081} 1081}
1082 1082
1083static inline VObject *safeAddProp( VObject *o, const char *prop) 1083static inline VObject *safeAddProp( VObject *o, const char *prop)
1084{ 1084{
1085 VObject *ret = 0; 1085 VObject *ret = 0;
1086 if ( o ) 1086 if ( o )
1087 ret = addProp( o, prop ); 1087 ret = addProp( o, prop );
1088 return ret; 1088 return ret;
1089} 1089}
1090 1090
1091/* 1091/*
1092 * Until we support vCal/iCal right 1092 * Until we support vCal/iCal right
1093 * we will make DTSTART and other things 1093 * we will make DTSTART and other things
1094 * be floating in the sense of 1094 * be floating in the sense of
1095 * RFC 2445 1095 * RFC 2445
1096 */ 1096 */
1097namespace { 1097namespace {
1098/* 1098/*
1099 * Convert QDateTime to iso8601 but take 1099 * Convert QDateTime to iso8601 but take
1100 * local time and do not use the Z at the end 1100 * local time and do not use the Z at the end
1101 * 1101 *
1102 */ 1102 */
1103 QCString toISOLocal( const QDateTime& dt ) { 1103 QCString toISOLocal( const QDateTime& dt ) {
1104 QCString str; 1104 QCString str;
1105 /* 1105 /*
1106 * year month day T Hour Minute Second 1106 * year month day T Hour Minute Second
1107 * 4 2 2 2 2 2 digits 1107 * 4 2 2 2 2 2 digits
1108 */ 1108 */
1109 str.sprintf("%04d%02d%02dT%02d%02d%02d", 1109 str.sprintf("%04d%02d%02dT%02d%02d%02d",
1110 dt.date().year(), 1110 dt.date().year(),
1111 dt.date().month(), 1111 dt.date().month(),
1112 dt.date().day(), 1112 dt.date().day(),
1113 dt.time().hour(), 1113 dt.time().hour(),
1114 dt.time().minute(), 1114 dt.time().minute(),
1115 dt.time().second() ); 1115 dt.time().second() );
1116 1116
1117 qWarning("Str ist %s", str.data() ); 1117 qWarning("Str ist %s", str.data() );
1118 1118
1119 return str; 1119 return str;
1120 } 1120 }
1121 1121
1122 1122
1123}; 1123};
1124 1124
1125static VObject *createVObject( const Event &e ) 1125static VObject *createVObject( const Event &e )
1126{ 1126{
1127 VObject *vcal = newVObject( VCCalProp ); 1127 VObject *vcal = newVObject( VCCalProp );
1128 safeAddPropValue( vcal, VCVersionProp, "1.0" ); 1128 safeAddPropValue( vcal, VCVersionProp, "1.0" );
1129 VObject *event = safeAddProp( vcal, VCEventProp ); 1129 VObject *event = safeAddProp( vcal, VCEventProp );
1130 1130
1131 safeAddPropValue( event, VCDTstartProp, toISOLocal( e.start() ) ); 1131 safeAddPropValue( event, VCDTstartProp, toISOLocal( e.start() ) );
1132 safeAddPropValue( event, VCDTendProp, toISOLocal( e.end() ) ); 1132 safeAddPropValue( event, VCDTendProp, toISOLocal( e.end() ) );
1133 safeAddPropValue( event, "X-Qtopia-NOTES", e.description() ); 1133 safeAddPropValue( event, "X-Qtopia-NOTES", e.description() );
1134 safeAddPropValue( event, VCDescriptionProp, e.description() ); 1134 safeAddPropValue( event, VCDescriptionProp, e.description() );
1135 safeAddPropValue( event, VCLocationProp, e.location() ); 1135 safeAddPropValue( event, VCLocationProp, e.location() );
1136 1136
1137 if ( e.hasAlarm() ) { 1137 if ( e.hasAlarm() ) {
1138 VObject *alarm = safeAddProp( event, VCAAlarmProp ); 1138 VObject *alarm = safeAddProp( event, VCAAlarmProp );
1139 QDateTime dt = e.start(); 1139 QDateTime dt = e.start();
1140 dt = dt.addSecs( -e.alarmTime()*60 ); 1140 dt = dt.addSecs( -e.alarmTime()*60 );
1141 safeAddPropValue( alarm, VCRunTimeProp, toISOLocal( dt ) ); 1141 safeAddPropValue( alarm, VCRunTimeProp, toISOLocal( dt ) );
1142 safeAddPropValue( alarm, VCAudioContentProp, 1142 safeAddPropValue( alarm, VCAudioContentProp,
1143 (e.alarmSound() == Event::Silent ? "silent" : "alarm" ) ); 1143 (e.alarmSound() == Event::Silent ? "silent" : "alarm" ) );
1144 } 1144 }
1145 1145
1146 safeAddPropValue( event, "X-Qtopia-TIMEZONE", e.timeZone() ); 1146 safeAddPropValue( event, "X-Qtopia-TIMEZONE", e.timeZone() );
1147 1147
1148 if ( e.type() == Event::AllDay ) 1148 if ( e.type() == Event::AllDay )
1149 safeAddPropValue( event, "X-Qtopia-AllDay", e.timeZone() ); 1149 safeAddPropValue( event, "X-Qtopia-AllDay", e.timeZone() );
1150 1150
1151 // ### repeat missing 1151 // ### repeat missing
1152 1152
1153 // ### categories missing 1153 // ### categories missing
1154 1154
1155 return vcal; 1155 return vcal;
1156} 1156}
1157 1157
1158 1158
1159static Event parseVObject( VObject *obj ) 1159static Event parseVObject( VObject *obj )
1160{ 1160{
1161 Event e; 1161 Event e;
1162 1162
1163 bool haveAlarm = FALSE; 1163 bool haveAlarm = FALSE;
1164 bool haveStart = FALSE; 1164 bool haveStart = FALSE;
1165 bool haveEnd = FALSE; 1165 bool haveEnd = FALSE;
1166 QDateTime alarmTime; 1166 QDateTime alarmTime;
1167 Event::SoundTypeChoice soundType = Event::Silent; 1167 Event::SoundTypeChoice soundType = Event::Silent;
1168 1168
1169 VObjectIterator it; 1169 VObjectIterator it;
1170 initPropIterator( &it, obj ); 1170 initPropIterator( &it, obj );
1171 while( moreIteration( &it ) ) { 1171 while( moreIteration( &it ) ) {
1172 VObject *o = nextVObject( &it ); 1172 VObject *o = nextVObject( &it );
1173 QCString name = vObjectName( o ); 1173 QCString name = vObjectName( o );
1174 QCString value = vObjectStringZValue( o ); 1174 QCString value = vObjectStringZValue( o );
1175 if ( name == VCDTstartProp ) { 1175 if ( name == VCDTstartProp ) {
1176 e.setStart( TimeConversion::fromISO8601( value ) ); 1176 e.setStart( TimeConversion::fromISO8601( value ) );
1177 haveStart = TRUE; 1177 haveStart = TRUE;
1178 } 1178 }
1179 else if ( name == VCDTendProp ) { 1179 else if ( name == VCDTendProp ) {
1180 e.setEnd( TimeConversion::fromISO8601( value ) ); 1180 e.setEnd( TimeConversion::fromISO8601( value ) );
1181 haveEnd = TRUE; 1181 haveEnd = TRUE;
1182 } 1182 }
1183 else if ( name == "X-Qtopia-NOTES" ) { 1183 else if ( name == "X-Qtopia-NOTES" ) {
1184 e.setNotes( value ); 1184 e.setNotes( value );
1185 } 1185 }
1186 else if ( name == VCDescriptionProp ) { 1186 else if ( name == VCDescriptionProp ) {
1187 e.setDescription( value ); 1187 e.setDescription( value );
1188 } 1188 }
1189 else if ( name == VCLocationProp ) { 1189 else if ( name == VCLocationProp ) {
1190 e.setLocation( value ); 1190 e.setLocation( value );
1191 } 1191 }
1192 else if ( name == VCAudioContentProp ) { 1192 else if ( name == VCAudioContentProp ) {
1193 haveAlarm = TRUE; 1193 haveAlarm = TRUE;
1194 VObjectIterator nit; 1194 VObjectIterator nit;
1195 initPropIterator( &nit, o ); 1195 initPropIterator( &nit, o );
1196 while( moreIteration( &nit ) ) { 1196 while( moreIteration( &nit ) ) {
1197 VObject *o = nextVObject( &nit ); 1197 VObject *o = nextVObject( &nit );
1198 QCString name = vObjectName( o ); 1198 QCString name = vObjectName( o );
1199 QCString value = vObjectStringZValue( o ); 1199 QCString value = vObjectStringZValue( o );
1200 if ( name == VCRunTimeProp ) 1200 if ( name == VCRunTimeProp )
1201 alarmTime = TimeConversion::fromISO8601( value ); 1201 alarmTime = TimeConversion::fromISO8601( value );
1202 else if ( name == VCAudioContentProp ) { 1202 else if ( name == VCAudioContentProp ) {
1203 if ( value == "silent" ) 1203 if ( value == "silent" )
1204 soundType = Event::Silent; 1204 soundType = Event::Silent;
1205 else 1205 else
1206 soundType = Event::Loud; 1206 soundType = Event::Loud;
1207 } 1207 }
1208 } 1208 }
1209 } 1209 }
1210 else if ( name == "X-Qtopia-TIMEZONE") { 1210 else if ( name == "X-Qtopia-TIMEZONE") {
1211 e.setTimeZone( value ); 1211 e.setTimeZone( value );
1212 } 1212 }
1213 else if ( name == "X-Qtopia-AllDay" ) { 1213 else if ( name == "X-Qtopia-AllDay" ) {
1214 e.setType( Event::AllDay ); 1214 e.setType( Event::AllDay );
1215 } 1215 }
1216#if 0 1216#if 0
1217 else { 1217 else {
1218 printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) ); 1218 printf("Name: %s, value=%s\n", name.data(), vObjectStringZValue( o ) );
1219 VObjectIterator nit; 1219 VObjectIterator nit;
1220 initPropIterator( &nit, o ); 1220 initPropIterator( &nit, o );
1221 while( moreIteration( &nit ) ) { 1221 while( moreIteration( &nit ) ) {
1222 VObject *o = nextVObject( &nit ); 1222 VObject *o = nextVObject( &nit );
1223 QCString name = vObjectName( o ); 1223 QCString name = vObjectName( o );
1224 QString value = vObjectStringZValue( o ); 1224 QString value = vObjectStringZValue( o );
1225 printf(" subprop: %s = %s\n", name.data(), value.latin1() ); 1225 printf(" subprop: %s = %s\n", name.data(), value.latin1() );
1226 } 1226 }
1227 } 1227 }
1228#endif 1228#endif
1229 } 1229 }
1230 1230
1231 if ( !haveStart && !haveEnd ) 1231 if ( !haveStart && !haveEnd )
1232 e.setStart( QDateTime::currentDateTime() ); 1232 e.setStart( QDateTime::currentDateTime() );
1233 1233
1234 if ( !haveEnd ) { 1234 if ( !haveEnd ) {
1235 e.setType( Event::AllDay ); 1235 e.setType( Event::AllDay );
1236 e.setEnd( e.start() ); 1236 e.setEnd( e.start() );
1237 } 1237 }
1238 1238
1239 if ( haveAlarm ) { 1239 if ( haveAlarm ) {
1240 int minutes = alarmTime.secsTo( e.start() ) / 60; 1240 int minutes = alarmTime.secsTo( e.start() ) / 60;
1241 e.setAlarm( TRUE, minutes, soundType ); 1241 e.setAlarm( TRUE, minutes, soundType );
1242 } 1242 }
1243 return e; 1243 return e;
1244} 1244}
1245 1245
1246 1246
1247/*! 1247/*!
1248 Writes the list of \a events as a set of VCards to the file \a filename. 1248 Writes the list of \a events as a set of VCards to the file \a filename.
1249*/ 1249*/
1250void Event::writeVCalendar( const QString &filename, const QValueList<Event> &events) 1250void Event::writeVCalendar( const QString &filename, const QValueList<Event> &events)
1251{ 1251{
1252 1252
1253 QFileDirect f( filename.utf8().data() ); 1253 QFileDirect f( filename.utf8().data() );
1254 1254
1255 if ( !f.open( IO_WriteOnly ) ) { 1255 if ( !f.open( IO_WriteOnly ) ) {
1256 1256
1257 qWarning("Unable to open vcard write"); 1257 qWarning("Unable to open vcard write");
1258 1258
1259 return; 1259 return;
1260 1260
1261 } 1261 }
1262 1262
1263 1263
1264 QValueList<Event>::ConstIterator it; 1264 QValueList<Event>::ConstIterator it;
1265 for( it = events.begin(); it != events.end(); ++it ) { 1265 for( it = events.begin(); it != events.end(); ++it ) {
1266 VObject *obj = createVObject( *it ); 1266 VObject *obj = createVObject( *it );
1267 writeVObject( f.directHandle() , obj ); 1267 writeVObject( f.directHandle() , obj );
1268 cleanVObject( obj ); 1268 cleanVObject( obj );
1269 } 1269 }
1270 1270
1271 1271
1272 cleanStrTbl(); 1272 cleanStrTbl();
1273} 1273}
1274 1274
1275/*! 1275/*!
1276 Writes \a event as a VCard to the file \a filename. 1276 Writes \a event as a VCard to the file \a filename.
1277*/ 1277*/
1278void Event::writeVCalendar( const QString &filename, const Event &event) 1278void Event::writeVCalendar( const QString &filename, const Event &event)
1279{ 1279{
1280 1280
1281 QFileDirect f( filename.utf8().data() ); 1281 QFileDirect f( filename.utf8().data() );
1282 1282
1283 if ( !f.open( IO_WriteOnly ) ) { 1283 if ( !f.open( IO_WriteOnly ) ) {
1284 1284
1285 qWarning("Unable to open vcard write"); 1285 qWarning("Unable to open vcard write");
1286 1286
1287 return; 1287 return;
1288 1288
1289 } 1289 }
1290 1290
1291 1291
1292 VObject *obj = createVObject( event ); 1292 VObject *obj = createVObject( event );
1293 writeVObject( f.directHandle() , obj ); 1293 writeVObject( f.directHandle() , obj );
1294 cleanVObject( obj ); 1294 cleanVObject( obj );
1295 1295
1296 cleanStrTbl(); 1296 cleanStrTbl();
1297} 1297}
1298 1298
1299/*! 1299/*!
1300 Returns the set of events read as VCards from the file \a filename. 1300 Returns the set of events read as VCards from the file \a filename.
1301*/ 1301*/
1302QValueList<Event> Event::readVCalendar( const QString &filename ) 1302QValueList<Event> Event::readVCalendar( const QString &filename )
1303{ 1303{
1304 VObject *obj = Parse_MIME_FromFileName( (char *)filename.utf8().data() ); 1304 VObject *obj = Parse_MIME_FromFileName( (char *)filename.utf8().data() );
1305 1305
1306 QValueList<Event> events; 1306 QValueList<Event> events;
1307 1307
1308 while ( obj ) { 1308 while ( obj ) {
1309 QCString name = vObjectName( obj ); 1309 QCString name = vObjectName( obj );
1310 if ( name == VCCalProp ) { 1310 if ( name == VCCalProp ) {
1311 VObjectIterator nit; 1311 VObjectIterator nit;
1312 initPropIterator( &nit, obj ); 1312 initPropIterator( &nit, obj );
1313 while( moreIteration( &nit ) ) { 1313 while( moreIteration( &nit ) ) {
1314 VObject *o = nextVObject( &nit ); 1314 VObject *o = nextVObject( &nit );
1315 QCString name = vObjectName( o ); 1315 QCString name = vObjectName( o );
1316 if ( name == VCEventProp ) 1316 if ( name == VCEventProp )
1317 events.append( parseVObject( o ) ); 1317 events.append( parseVObject( o ) );
1318 } 1318 }
1319 } else if ( name == VCEventProp ) { 1319 } else if ( name == VCEventProp ) {
1320 // shouldn't happen, but just to be sure 1320 // shouldn't happen, but just to be sure
1321 events.append( parseVObject( obj ) ); 1321 events.append( parseVObject( obj ) );
1322 } 1322 }
1323 VObject *t = obj; 1323 VObject *t = obj;
1324 obj = nextVObjectInList(obj); 1324 obj = nextVObjectInList(obj);
1325 cleanVObject( t ); 1325 cleanVObject( t );
1326 } 1326 }
1327 1327
1328 return events; 1328 return events;
1329} 1329}
1330 1330
1331bool Event::match( const QRegExp &r ) const 1331bool Event::match( const QRegExp &r ) const
1332{ 1332{
1333 bool returnMe; 1333 bool returnMe;
1334 returnMe = false; 1334 returnMe = false;
1335 1335
1336 if ( descript.find( r ) > -1 ) 1336 if ( descript.find( r ) > -1 )
1337 returnMe = true; 1337 returnMe = true;
1338 else if ( locat.find( r ) > -1 ) 1338 else if ( locat.find( r ) > -1 )
1339 returnMe = true; 1339 returnMe = true;
1340 else if ( TimeConversion::fromUTC( startUTC ).toString().find( r ) > -1 ) 1340 else if ( TimeConversion::fromUTC( startUTC ).toString().find( r ) > -1 )
1341 returnMe = true; 1341 returnMe = true;
1342 else if ( TimeConversion::fromUTC( endUTC ).toString().find( r ) > -1 ) 1342 else if ( TimeConversion::fromUTC( endUTC ).toString().find( r ) > -1 )
1343 returnMe = true; 1343 returnMe = true;
1344 else if ( tz.find( r ) > -1 ) 1344 else if ( tz.find( r ) > -1 )
1345 returnMe = true; 1345 returnMe = true;
1346 else if ( note.find( r ) > -1 ) 1346 else if ( note.find( r ) > -1 )
1347 returnMe = true; 1347 returnMe = true;
1348 else if ( doRepeat() ) { 1348 else if ( doRepeat() ) {
1349 if ( pattern.hasEndDate ) 1349 if ( pattern.hasEndDate )
1350 if ( TimeConversion::fromUTC( pattern.endDateUTC ).toString().find(r) > -1 ) 1350 if ( TimeConversion::fromUTC( pattern.endDateUTC ).toString().find(r) > -1 )
1351 returnMe = true; 1351 returnMe = true;
1352 } 1352 }
1353 return returnMe; 1353 return returnMe;
1354} 1354}
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,1136 +1,1136 @@
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();
983 QFile::remove( strFileNew ); 983 QFile::remove( strFileNew );
984 return false; 984 return false;
985 } 985 }
986 } 986 }
987 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) { 987 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) {
988 buf = "<event"; 988 buf = "<event";
989 (*it).save( buf ); 989 (*it).save( buf );
990 buf += " />\n"; 990 buf += " />\n";
991 str = buf.utf8(); 991 str = buf.utf8();
992 total_written = f.writeBlock( str.data(), str.length() ); 992 total_written = f.writeBlock( str.data(), str.length() );
993 if ( total_written != int(str.length()) ) { 993 if ( total_written != int(str.length()) ) {
994 f.close(); 994 f.close();
995 QFile::remove( strFileNew ); 995 QFile::remove( strFileNew );
996 return false; 996 return false;
997 } 997 }
998 } 998 }
999 buf = "</events>\n</DATEBOOK>\n"; 999 buf = "</events>\n</DATEBOOK>\n";
1000 str = buf.utf8(); 1000 str = buf.utf8();
1001 total_written = f.writeBlock( str.data(), str.length() ); 1001 total_written = f.writeBlock( str.data(), str.length() );
1002 if ( total_written != int(str.length()) ) { 1002 if ( total_written != int(str.length()) ) {
1003 f.close(); 1003 f.close();
1004 QFile::remove( strFileNew ); 1004 QFile::remove( strFileNew );
1005 return false; 1005 return false;
1006 } 1006 }
1007 f.close(); 1007 f.close();
1008 1008
1009 // now rename... I like to use the systemcall 1009 // now rename... I like to use the systemcall
1010 if ( ::rename( strFileNew, dateBookFilename() ) < 0 ) { 1010 if ( ::rename( strFileNew, dateBookFilename() ) < 0 ) {
1011 qWarning( "problem renaming file %s to %s errno %d", 1011 qWarning( "problem renaming file %s to %s errno %d",
1012 strFileNew.latin1(), dateBookFilename().latin1(), errno ); 1012 strFileNew.latin1(), dateBookFilename().latin1(), errno );
1013 // remove the file, otherwise it will just stick around... 1013 // remove the file, otherwise it will just stick around...
1014 QFile::remove( strFileNew ); 1014 QFile::remove( strFileNew );
1015 } 1015 }
1016 1016
1017 // may as well remove the journal file... 1017 // may as well remove the journal file...
1018 QFile::remove( dateBookJournalFile() ); 1018 QFile::remove( dateBookJournalFile() );
1019 d->clean = true; 1019 d->clean = true;
1020 return true; 1020 return true;
1021} 1021}
1022 1022
1023void DateBookDB::reload() 1023void DateBookDB::reload()
1024{ 1024{
1025 QValueList<Event>::Iterator it = eventList.begin(); 1025 QValueList<Event>::Iterator it = eventList.begin();
1026 for ( ; it != eventList.end(); ++it ) { 1026 for ( ; it != eventList.end(); ++it ) {
1027 if ( (*it).hasAlarm() ) 1027 if ( (*it).hasAlarm() )
1028 delEventAlarm( *it ); 1028 delEventAlarm( *it );
1029 if ( (*it).hasRepeat() ) 1029 if ( (*it).hasRepeat() )
1030 removeRepeat( *it ); 1030 removeRepeat( *it );
1031 } 1031 }
1032 eventList.clear(); 1032 eventList.clear();
1033 repeatEvents.clear(); // should be a NOP 1033 repeatEvents.clear(); // should be a NOP
1034 init(); 1034 init();
1035} 1035}
1036 1036
1037bool DateBookDB::removeRepeat( const Event &ev ) 1037bool DateBookDB::removeRepeat( const Event &ev )
1038{ 1038{
1039 time_t removeMe = ev.repeatPattern().createTime; 1039 time_t removeMe = ev.repeatPattern().createTime;
1040 QValueListIterator<Event> it; 1040 QValueListIterator<Event> it;
1041 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) { 1041 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) {
1042 if ( removeMe == (*it).repeatPattern().createTime ) { 1042 if ( removeMe == (*it).repeatPattern().createTime ) {
1043 repeatEvents.remove( *it ); 1043 repeatEvents.remove( *it );
1044 // best break, or we are going into undefined territory! 1044 // best break, or we are going into undefined territory!
1045 return TRUE; 1045 return TRUE;
1046 } 1046 }
1047 } 1047 }
1048 return FALSE; 1048 return FALSE;
1049} 1049}
1050 1050
1051bool DateBookDB::origRepeat( const Event &ev, Event &orig ) const 1051bool DateBookDB::origRepeat( const Event &ev, Event &orig ) const
1052{ 1052{
1053 time_t removeMe = ev.repeatPattern().createTime; 1053 time_t removeMe = ev.repeatPattern().createTime;
1054 QValueListConstIterator<Event> it; 1054 QValueListConstIterator<Event> it;
1055 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) { 1055 for ( it = repeatEvents.begin(); it != repeatEvents.end(); ++it ) {
1056 if ( removeMe == (*it).repeatPattern().createTime ) { 1056 if ( removeMe == (*it).repeatPattern().createTime ) {
1057 orig = (*it); 1057 orig = (*it);
1058 return TRUE; 1058 return TRUE;
1059 } 1059 }
1060 } 1060 }
1061 return FALSE; 1061 return FALSE;
1062} 1062}
1063 1063
1064void DateBookDB::saveJournalEntry( const Event &ev, journal_action action ) 1064void DateBookDB::saveJournalEntry( const Event &ev, journal_action action )
1065{ 1065{
1066 saveJournalEntry( ev, action, -1, false ); 1066 saveJournalEntry( ev, action, -1, false );
1067} 1067}
1068 1068
1069bool DateBookDB::saveJournalEntry( const Event &evOld, journal_action action, 1069bool DateBookDB::saveJournalEntry( const Event &evOld, journal_action action,
1070 int key, bool origHadRepeat ) 1070 int key, bool origHadRepeat )
1071{ 1071{
1072 bool status = false; 1072 bool status = false;
1073 Event ev = evOld; 1073 Event ev = evOld;
1074 // write our log based on the action 1074 // write our log based on the action
1075 QFile f( dateBookJournalFile() ); 1075 QFile f( dateBookJournalFile() );
1076 if ( !f.open( IO_WriteOnly|IO_Append ) ) 1076 if ( !f.open( IO_WriteOnly|IO_Append ) )
1077 return false; 1077 return false;
1078 QString buf = "<event"; 1078 QString buf = "<event";
1079 ev.save( buf ); 1079 ev.save( buf );
1080 buf += " action="; 1080 buf += " action=";
1081 buf += "\"" + QString::number(action) + "\""; 1081 buf += "\"" + QString::number(action) + "\"";
1082 buf += " actionkey=\"" + QString::number(key) + "\""; 1082 buf += " actionkey=\"" + QString::number(key) + "\"";
1083 buf += " actionorig=\"" + QString::number(origHadRepeat) +"\""; 1083 buf += " actionorig=\"" + QString::number(origHadRepeat) +"\"";
1084 buf += " />\n"; 1084 buf += " />\n";
1085 QString str = buf.utf8(); 1085 QString str = buf.utf8();
1086 status = ( f.writeBlock( str.data(), str.length() ) == int(str.length()) ); 1086 status = ( f.writeBlock( str.data(), str.length() ) == int(str.length()) );
1087 f.close(); 1087 f.close();
1088 return status; 1088 return status;
1089} 1089}
1090 1090
1091QValueList<Event> DateBookDB::getRawRepeats() const 1091QValueList<Event> DateBookDB::getRawRepeats() const
1092{ 1092{
1093 return repeatEvents; 1093 return repeatEvents;
1094} 1094}
1095 1095
1096QValueList<Event> DateBookDB::getNonRepeatingEvents( const QDate &from, 1096QValueList<Event> DateBookDB::getNonRepeatingEvents( const QDate &from,
1097 const QDate &to ) const 1097 const QDate &to ) const
1098{ 1098{
1099 QValueListConstIterator<Event> it; 1099 QValueListConstIterator<Event> it;
1100 QDateTime dtTmp, dtEnd; 1100 QDateTime dtTmp, dtEnd;
1101 QValueList<Event> tmpList; 1101 QValueList<Event> tmpList;
1102 for (it = eventList.begin(); it != eventList.end(); ++it ) { 1102 for (it = eventList.begin(); it != eventList.end(); ++it ) {
1103 dtTmp = (*it).start(TRUE); 1103 dtTmp = (*it).start(TRUE);
1104 dtEnd = (*it).end(TRUE); 1104 dtEnd = (*it).end(TRUE);
1105 1105
1106 if ( dtTmp.date() >= from && dtTmp.date() <= to ) { 1106 if ( dtTmp.date() >= from && dtTmp.date() <= to ) {
1107 Event e = *it; 1107 Event e = *it;
1108 if ( dtTmp.date() != dtEnd.date() ) 1108 if ( dtTmp.date() != dtEnd.date() )
1109 e.setEnd( QDateTime(dtTmp.date(), QTime(23, 59, 0)) ); 1109 e.setEnd( QDateTime(dtTmp.date(), QTime(23, 59, 0)) );
1110 tmpList.append( e ); 1110 tmpList.append( e );
1111 } 1111 }
1112 // we must also check for end date information... 1112 // we must also check for end date information...
1113 if ( dtEnd.date() != dtTmp.date() && dtEnd.date() >= from ) { 1113 if ( dtEnd.date() != dtTmp.date() && dtEnd.date() >= from ) {
1114 QDateTime dt = dtTmp.addDays( 1 ); 1114 QDateTime dt = dtTmp.addDays( 1 );
1115 dt.setTime( QTime(0, 0, 0) ); 1115 dt.setTime( QTime(0, 0, 0) );
1116 QDateTime dtStop; 1116 QDateTime dtStop;
1117 if ( dtEnd > to ) { 1117 if ( dtEnd > to ) {
1118 dtStop = to; 1118 dtStop = to;
1119 } else 1119 } else
1120 dtStop = dtEnd; 1120 dtStop = dtEnd;
1121 while ( dt <= dtStop ) { 1121 while ( dt <= dtStop ) {
1122 Event ev = *it; 1122 Event ev = *it;
1123 if ( dt >= from ) { 1123 if ( dt >= from ) {
1124 ev.setStart( QDateTime(dt.date(), QTime(0, 0, 0)) ); 1124 ev.setStart( QDateTime(dt.date(), QTime(0, 0, 0)) );
1125 if ( dt.date() == dtEnd.date() ) 1125 if ( dt.date() == dtEnd.date() )
1126 ev.setEnd( QDateTime(dt.date(), dtEnd.time()) ); 1126 ev.setEnd( QDateTime(dt.date(), dtEnd.time()) );
1127 else 1127 else
1128 ev.setEnd( QDateTime(dt.date(), QTime(23, 59, 0)) ); 1128 ev.setEnd( QDateTime(dt.date(), QTime(23, 59, 0)) );
1129 tmpList.append( ev ); 1129 tmpList.append( ev );
1130 } 1130 }
1131 dt = dt.addDays( 1 ); 1131 dt = dt.addDays( 1 );
1132 } 1132 }
1133 } 1133 }
1134 } 1134 }
1135 return tmpList; 1135 return tmpList;
1136} 1136}
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
@@ -1,1806 +1,1807 @@
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** $Id$ 19** $Id$
20** 20**
21**********************************************************************/ 21**********************************************************************/
22#define QTOPIA_INTERNAL_LANGLIST 22#define QTOPIA_INTERNAL_LANGLIST
23#include <stdlib.h> 23#include <stdlib.h>
24#include <unistd.h> 24#include <unistd.h>
25#include <linux/limits.h> // needed for some toolchains (PATH_MAX) 25#include <linux/limits.h> // needed for some toolchains (PATH_MAX)
26#include <qfile.h> 26#include <qfile.h>
27#ifdef Q_WS_QWS 27#ifdef Q_WS_QWS
28#ifndef QT_NO_COP 28#ifndef QT_NO_COP
29#if QT_VERSION <= 231 29#if QT_VERSION <= 231
30#define private public 30#define private public
31#define sendLocally processEvent 31#define sendLocally processEvent
32#include "qcopenvelope_qws.h" 32#include "qcopenvelope_qws.h"
33#undef private 33#undef private
34#else 34#else
35#include "qcopenvelope_qws.h" 35#include "qcopenvelope_qws.h"
36#endif 36#endif
37#endif 37#endif
38#include <qwindowsystem_qws.h> 38#include <qwindowsystem_qws.h>
39#endif 39#endif
40#include <qtextstream.h> 40#include <qtextstream.h>
41#include <qpalette.h> 41#include <qpalette.h>
42#include <qbuffer.h> 42#include <qbuffer.h>
43#include <qptrdict.h> 43#include <qptrdict.h>
44#include <qregexp.h> 44#include <qregexp.h>
45#include <qdir.h> 45#include <qdir.h>
46#include <qlabel.h> 46#include <qlabel.h>
47#include <qdialog.h> 47#include <qdialog.h>
48#include <qdragobject.h> 48#include <qdragobject.h>
49#include <qtextcodec.h> 49#include <qtextcodec.h>
50#include <qevent.h> 50#include <qevent.h>
51#include <qtooltip.h> 51#include <qtooltip.h>
52#include <qsignal.h> 52#include <qsignal.h>
53#include "qpeapplication.h" 53#include "qpeapplication.h"
54#include "qpestyle.h" 54#include "qpestyle.h"
55#include "styleinterface.h" 55#include "styleinterface.h"
56#if QT_VERSION >= 300 56#if QT_VERSION >= 300
57#include <qstylefactory.h> 57#include <qstylefactory.h>
58#else 58#else
59#include <qplatinumstyle.h> 59#include <qplatinumstyle.h>
60#include <qwindowsstyle.h> 60#include <qwindowsstyle.h>
61#include <qmotifstyle.h> 61#include <qmotifstyle.h>
62#include <qmotifplusstyle.h> 62#include <qmotifplusstyle.h>
63#include "lightstyle.h" 63#include "lightstyle.h"
64 64
65#include <qpe/qlibrary.h> 65#include <qpe/qlibrary.h>
66#endif 66#endif
67#include "global.h" 67#include "global.h"
68#include "resource.h" 68#include "resource.h"
69#if QT_VERSION <= 230 && defined(QT_NO_CODECS) 69#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
70#include "qutfcodec.h" 70#include "qutfcodec.h"
71#endif 71#endif
72#include "config.h" 72#include "config.h"
73#include "network.h" 73#include "network.h"
74#ifdef QWS 74#ifdef QWS
75#include "fontmanager.h" 75#include "fontmanager.h"
76#endif 76#endif
77 77
78#include "alarmserver.h" 78#include "alarmserver.h"
79#include "applnk.h" 79#include "applnk.h"
80#include "qpemenubar.h" 80#include "qpemenubar.h"
81#include "textcodecinterface.h" 81#include "textcodecinterface.h"
82#include "imagecodecinterface.h" 82#include "imagecodecinterface.h"
83 83
84#include <unistd.h> 84#include <unistd.h>
85#include <sys/file.h> 85#include <sys/file.h>
86#include <sys/ioctl.h> 86#include <sys/ioctl.h>
87#include <sys/soundcard.h> 87#include <sys/soundcard.h>
88 88
89#include "qt_override_p.h" 89#include "qt_override_p.h"
90 90
91 91
92class QPEApplicationData 92class QPEApplicationData
93{ 93{
94public: 94public:
95 QPEApplicationData ( ) 95 QPEApplicationData ( )
96 : presstimer( 0 ), presswidget( 0 ), rightpressed( false ), kbgrabbed( false ), 96 : presstimer( 0 ), presswidget( 0 ), rightpressed( false ), kbgrabbed( false ),
97 notbusysent( false ), preloaded( false ), forceshow( false ), nomaximize( false ), 97 notbusysent( false ), preloaded( false ), forceshow( false ), nomaximize( false ),
98 keep_running( true ), qpe_main_widget( 0 ) 98 keep_running( true ), qpe_main_widget( 0 )
99 99
100 { 100 {
101 qcopq.setAutoDelete( TRUE ); 101 qcopq.setAutoDelete( TRUE );
102 } 102 }
103 103
104 int presstimer; 104 int presstimer;
105 QWidget* presswidget; 105 QWidget* presswidget;
106 QPoint presspos; 106 QPoint presspos;
107 107
108 bool rightpressed : 1; 108 bool rightpressed : 1;
109 bool kbgrabbed : 1; 109 bool kbgrabbed : 1;
110 bool notbusysent : 1; 110 bool notbusysent : 1;
111 bool preloaded : 1; 111 bool preloaded : 1;
112 bool forceshow : 1; 112 bool forceshow : 1;
113 bool nomaximize : 1; 113 bool nomaximize : 1;
114 bool keep_running : 1; 114 bool keep_running : 1;
115 115
116 QString appName; 116 QString appName;
117 struct QCopRec 117 struct QCopRec
118 { 118 {
119 QCopRec( const QCString &ch, const QCString &msg, 119 QCopRec( const QCString &ch, const QCString &msg,
120 const QByteArray &d ) : 120 const QByteArray &d ) :
121 channel( ch ), message( msg ), data( d ) 121 channel( ch ), message( msg ), data( d )
122 { } 122 { }
123 123
124 QCString channel; 124 QCString channel;
125 QCString message; 125 QCString message;
126 QByteArray data; 126 QByteArray data;
127 }; 127 };
128 QWidget* qpe_main_widget; 128 QWidget* qpe_main_widget;
129 QList<QCopRec> qcopq; 129 QList<QCopRec> qcopq;
130 130
131 void enqueueQCop( const QCString &ch, const QCString &msg, 131 void enqueueQCop( const QCString &ch, const QCString &msg,
132 const QByteArray &data ) 132 const QByteArray &data )
133 { 133 {
134 qcopq.append( new QCopRec( ch, msg, data ) ); 134 qcopq.append( new QCopRec( ch, msg, data ) );
135 } 135 }
136 void sendQCopQ() 136 void sendQCopQ()
137 { 137 {
138 QCopRec * r; 138 QCopRec * r;
139#ifndef QT_NO_COP 139#ifndef QT_NO_COP
140 140
141 for ( QListIterator<QCopRec> it( qcopq ); ( r = it.current() ); ++it ) 141 for ( QListIterator<QCopRec> it( qcopq ); ( r = it.current() ); ++it )
142 QCopChannel::sendLocally( r->channel, r->message, r->data ); 142 QCopChannel::sendLocally( r->channel, r->message, r->data );
143#endif 143#endif
144 144
145 qcopq.clear(); 145 qcopq.clear();
146 } 146 }
147 static void show_mx(QWidget* mw, bool nomaximize) 147 static void show_mx(QWidget* mw, bool nomaximize)
148 { 148 {
149 if ( mw->layout() && mw->inherits("QDialog") ) { 149 if ( mw->layout() && mw->inherits("QDialog") ) {
150 QPEApplication::showDialog((QDialog*)mw, nomaximize); 150 QPEApplication::showDialog((QDialog*)mw, nomaximize);
151 } 151 }
152 else { 152 else {
153#ifdef Q_WS_QWS 153#ifdef Q_WS_QWS
154 if ( !nomaximize ) 154 if ( !nomaximize )
155 mw->showMaximized(); 155 mw->showMaximized();
156 else 156 else
157#endif 157#endif
158 158
159 mw->show(); 159 mw->show();
160 } 160 }
161 } 161 }
162 static bool setWidgetCaptionFromAppName( QWidget* /*mw*/, const QString& /*appName*/, const QString& /*appsPath*/ ) 162 static bool setWidgetCaptionFromAppName( QWidget* /*mw*/, const QString& /*appName*/, const QString& /*appsPath*/ )
163 { 163 {
164 /* 164 /*
165 // This works but disable it for now until it is safe to apply 165 // This works but disable it for now until it is safe to apply
166 // What is does is scan the .desktop files of all the apps for 166 // What is does is scan the .desktop files of all the apps for
167 // the applnk that has the corresponding argv[0] as this program 167 // the applnk that has the corresponding argv[0] as this program
168 // then it uses the name stored in the .desktop file as the caption 168 // then it uses the name stored in the .desktop file as the caption
169 // for the main widget. This saves duplicating translations for 169 // for the main widget. This saves duplicating translations for
170 // the app name in the program and in the .desktop files. 170 // the app name in the program and in the .desktop files.
171 171
172 AppLnkSet apps( appsPath ); 172 AppLnkSet apps( appsPath );
173 173
174 QList<AppLnk> appsList = apps.children(); 174 QList<AppLnk> appsList = apps.children();
175 for ( QListIterator<AppLnk> it(appsList); it.current(); ++it ) { 175 for ( QListIterator<AppLnk> it(appsList); it.current(); ++it ) {
176 if ( (*it)->exec() == appName ) { 176 if ( (*it)->exec() == appName ) {
177 mw->setCaption( (*it)->name() ); 177 mw->setCaption( (*it)->name() );
178 return TRUE; 178 return TRUE;
179 } 179 }
180 } 180 }
181 */ 181 */
182 return FALSE; 182 return FALSE;
183 } 183 }
184 184
185 185
186 void show(QWidget* mw, bool nomax) 186 void show(QWidget* mw, bool nomax)
187 { 187 {
188 setWidgetCaptionFromAppName( mw, appName, QPEApplication::qpeDir() + "apps" ); 188 setWidgetCaptionFromAppName( mw, appName, QPEApplication::qpeDir() + "apps" );
189 nomaximize = nomax; 189 nomaximize = nomax;
190 qpe_main_widget = mw; 190 qpe_main_widget = mw;
191#ifndef QT_NO_COP 191#ifndef QT_NO_COP
192 192
193 sendQCopQ(); 193 sendQCopQ();
194#endif 194#endif
195 195
196 if ( preloaded ) { 196 if ( preloaded ) {
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" )
710 && activePopupWidget() ->parentWidget() 710 && activePopupWidget() ->parentWidget()
711 && activePopupWidget() ->parentWidget() ->inherits( "QComboBox" ) ) 711 && activePopupWidget() ->parentWidget() ->inherits( "QComboBox" ) )
712 key = Qt::Key_Return; 712 key = Qt::Key_Return;
713 713
714 if ( activePopupWidget() && activePopupWidget() ->inherits( "QPopupMenu" ) ) 714 if ( activePopupWidget() && activePopupWidget() ->inherits( "QPopupMenu" ) )
715 key = Qt::Key_Return; 715 key = Qt::Key_Return;
716 716
717#ifdef QWS 717#ifdef QWS
718 718
719 ke->simpleData.keycode = key; 719 ke->simpleData.keycode = key;
720#endif 720#endif
721} 721}
722 722
723class HackWidget : public QWidget 723class HackWidget : public QWidget
724{ 724{
725public: 725public:
726 bool needsOk() 726 bool needsOk()
727 { 727 {
728 return ( getWState() & WState_Reserved1 ); 728 return ( getWState() & WState_Reserved1 );
729 } 729 }
730}; 730};
731 731
732/*! 732/*!
733 \internal 733 \internal
734*/ 734*/
735 735
736#ifdef QWS 736#ifdef QWS
737bool QPEApplication::qwsEventFilter( QWSEvent * e ) 737bool QPEApplication::qwsEventFilter( QWSEvent * e )
738{ 738{
739 if ( !d->notbusysent && e->type == QWSEvent::Focus ) { 739 if ( !d->notbusysent && e->type == QWSEvent::Focus ) {
740 if ( qApp->type() != QApplication::GuiServer ) { 740 if ( qApp->type() != QApplication::GuiServer ) {
741 QCopEnvelope e( "QPE/System", "notBusy(QString)" ); 741 QCopEnvelope e( "QPE/System", "notBusy(QString)" );
742 e << d->appName; 742 e << d->appName;
743 } 743 }
744 d->notbusysent = TRUE; 744 d->notbusysent = TRUE;
745 } 745 }
746 if ( type() == GuiServer ) { 746 if ( type() == GuiServer ) {
747 switch ( e->type ) { 747 switch ( e->type ) {
748 case QWSEvent::Mouse: 748 case QWSEvent::Mouse:
749 if ( e->asMouse() ->simpleData.state && !QWidget::find( e->window() ) ) 749 if ( e->asMouse() ->simpleData.state && !QWidget::find( e->window() ) )
750 emit clientMoused(); 750 emit clientMoused();
751 break; 751 break;
752 default: 752 default:
753 break; 753 break;
754 } 754 }
755 } 755 }
756 if ( e->type == QWSEvent::Key ) { 756 if ( e->type == QWSEvent::Key ) {
757 QWSKeyEvent *ke = ( QWSKeyEvent * ) e; 757 QWSKeyEvent *ke = ( QWSKeyEvent * ) e;
758 if ( ke->simpleData.keycode == Qt::Key_F33 ) { 758 if ( ke->simpleData.keycode == Qt::Key_F33 ) {
759 // Use special "OK" key to press "OK" on top level widgets 759 // Use special "OK" key to press "OK" on top level widgets
760 QWidget * active = activeWindow(); 760 QWidget * active = activeWindow();
761 QWidget *popup = 0; 761 QWidget *popup = 0;
762 if ( active && active->isPopup() ) { 762 if ( active && active->isPopup() ) {
763 popup = active; 763 popup = active;
764 active = active->parentWidget(); 764 active = active->parentWidget();
765 } 765 }
766 if ( active && ( int ) active->winId() == ke->simpleData.window && 766 if ( active && ( int ) active->winId() == ke->simpleData.window &&
767 !active->testWFlags( WStyle_Customize | WType_Popup | WType_Desktop ) ) { 767 !active->testWFlags( WStyle_Customize | WType_Popup | WType_Desktop ) ) {
768 if ( ke->simpleData.is_press ) { 768 if ( ke->simpleData.is_press ) {
769 if ( popup ) 769 if ( popup )
770 popup->close(); 770 popup->close();
771 if ( active->inherits( "QDialog" ) ) { 771 if ( active->inherits( "QDialog" ) ) {
772 HackDialog * d = ( HackDialog * ) active; 772 HackDialog * d = ( HackDialog * ) active;
773 d->acceptIt(); 773 d->acceptIt();
774 return TRUE; 774 return TRUE;
775 } 775 }
776 else if ( ( ( HackWidget * ) active ) ->needsOk() ) { 776 else if ( ( ( HackWidget * ) active ) ->needsOk() ) {
777 QSignal s; 777 QSignal s;
778 s.connect( active, SLOT( accept() ) ); 778 s.connect( active, SLOT( accept() ) );
779 s.activate(); 779 s.activate();
780 } 780 }
781 else { 781 else {
782 // do the same as with the select key: Map to the default action of the widget: 782 // do the same as with the select key: Map to the default action of the widget:
783 mapToDefaultAction( ke, Qt::Key_Return ); 783 mapToDefaultAction( ke, Qt::Key_Return );
784 } 784 }
785 } 785 }
786 } 786 }
787 } 787 }
788 else if ( ke->simpleData.keycode == Qt::Key_F30 ) { 788 else if ( ke->simpleData.keycode == Qt::Key_F30 ) {
789 // Use special "select" key to do whatever default action a widget has 789 // Use special "select" key to do whatever default action a widget has
790 mapToDefaultAction( ke, Qt::Key_Space ); 790 mapToDefaultAction( ke, Qt::Key_Space );
791 } 791 }
792 else if ( ke->simpleData.keycode == Qt::Key_Escape && 792 else if ( ke->simpleData.keycode == Qt::Key_Escape &&
793 ke->simpleData.is_press ) { 793 ke->simpleData.is_press ) {
794 // Escape key closes app if focus on toplevel 794 // Escape key closes app if focus on toplevel
795 QWidget * active = activeWindow(); 795 QWidget * active = activeWindow();
796 if ( active && active->testWFlags( WType_TopLevel ) && 796 if ( active && active->testWFlags( WType_TopLevel ) &&
797 ( int ) active->winId() == ke->simpleData.window && 797 ( int ) active->winId() == ke->simpleData.window &&
798 !active->testWFlags( WStyle_Dialog | WStyle_Customize | WType_Popup | WType_Desktop ) ) { 798 !active->testWFlags( WStyle_Dialog | WStyle_Customize | WType_Popup | WType_Desktop ) ) {
799 if ( active->inherits( "QDialog" ) ) { 799 if ( active->inherits( "QDialog" ) ) {
800 HackDialog * d = ( HackDialog * ) active; 800 HackDialog * d = ( HackDialog * ) active;
801 d->rejectIt(); 801 d->rejectIt();
802 return TRUE; 802 return TRUE;
803 } 803 }
804 else if ( strcmp( argv() [ 0 ], "embeddedkonsole" ) != 0 ) { 804 else if ( strcmp( argv() [ 0 ], "embeddedkonsole" ) != 0 ) {
805 active->close(); 805 active->close();
806 } 806 }
807 } 807 }
808 } 808 }
809 else if ( ke->simpleData.keycode >= Qt::Key_F1 && ke->simpleData.keycode <= Qt::Key_F29 ) { 809 else if ( ke->simpleData.keycode >= Qt::Key_F1 && ke->simpleData.keycode <= Qt::Key_F29 ) {
810 // this should be if ( ODevice::inst ( )-> buttonForKeycode ( ... )) 810 // this should be if ( ODevice::inst ( )-> buttonForKeycode ( ... ))
811 // but we cannot access libopie function within libqpe :( 811 // but we cannot access libopie function within libqpe :(
812 812
813 QWidget * active = activeWindow ( ); 813 QWidget * active = activeWindow ( );
814 if ( active && ((int) active-> winId ( ) == ke-> simpleData.window )) { 814 if ( active && ((int) active-> winId ( ) == ke-> simpleData.window )) {
815 if ( d-> kbgrabbed ) { // we grabbed the keyboard 815 if ( d-> kbgrabbed ) { // we grabbed the keyboard
816 QChar ch ( ke-> simpleData.unicode ); 816 QChar ch ( ke-> simpleData.unicode );
817 QKeyEvent qke ( ke-> simpleData. is_press ? QEvent::KeyPress : QEvent::KeyRelease, 817 QKeyEvent qke ( ke-> simpleData. is_press ? QEvent::KeyPress : QEvent::KeyRelease,
818 ke-> simpleData.keycode, 818 ke-> simpleData.keycode,
819 ch. latin1 ( ), 819 ch. latin1 ( ),
820 ke-> simpleData.modifiers, 820 ke-> simpleData.modifiers,
821 QString ( ch ), 821 QString ( ch ),
822 ke-> simpleData.is_auto_repeat, 1 ); 822 ke-> simpleData.is_auto_repeat, 1 );
823 823
824 QObject *which = QWidget::keyboardGrabber ( ); 824 QObject *which = QWidget::keyboardGrabber ( );
825 if ( !which ) 825 if ( !which )
826 which = QApplication::focusWidget ( ); 826 which = QApplication::focusWidget ( );
827 if ( !which ) 827 if ( !which )
828 which = QApplication::activeWindow ( ); 828 which = QApplication::activeWindow ( );
829 if ( !which ) 829 if ( !which )
830 which = qApp; 830 which = qApp;
831 831
832 QApplication::sendEvent ( which, &qke ); 832 QApplication::sendEvent ( which, &qke );
833 } 833 }
834 else { // we didn't grab the keyboard, so send the event to the launcher 834 else { // we didn't grab the keyboard, so send the event to the launcher
835 QCopEnvelope e ( "QPE/Launcher", "deviceButton(int,int,int)" ); 835 QCopEnvelope e ( "QPE/Launcher", "deviceButton(int,int,int)" );
836 e << int( ke-> simpleData.keycode ) << int( ke-> simpleData. is_press ) << int( ke-> simpleData.is_auto_repeat ); 836 e << int( ke-> simpleData.keycode ) << int( ke-> simpleData. is_press ) << int( ke-> simpleData.is_auto_repeat );
837 } 837 }
838 } 838 }
839 return true; 839 return true;
840 } 840 }
841 } 841 }
842 if ( e->type == QWSEvent::Focus ) { 842 if ( e->type == QWSEvent::Focus ) {
843 QWSFocusEvent * fe = ( QWSFocusEvent* ) e; 843 QWSFocusEvent * fe = ( QWSFocusEvent* ) e;
844 if ( !fe->simpleData.get_focus ) { 844 if ( !fe->simpleData.get_focus ) {
845 QWidget * active = activeWindow(); 845 QWidget * active = activeWindow();
846 while ( active && active->isPopup() ) { 846 while ( active && active->isPopup() ) {
847 active->close(); 847 active->close();
848 active = activeWindow(); 848 active = activeWindow();
849 } 849 }
850 } 850 }
851 else { 851 else {
852 // make sure our modal widget is ALWAYS on top 852 // make sure our modal widget is ALWAYS on top
853 QWidget *topm = activeModalWidget(); 853 QWidget *topm = activeModalWidget();
854 if ( topm ) { 854 if ( topm ) {
855 topm->raise(); 855 topm->raise();
856 } 856 }
857 } 857 }
858 if ( fe->simpleData.get_focus && inputMethodDict ) { 858 if ( fe->simpleData.get_focus && inputMethodDict ) {
859 InputMethodHint m = inputMethodHint( QWidget::find( e->window() ) ); 859 InputMethodHint m = inputMethodHint( QWidget::find( e->window() ) );
860 if ( m == AlwaysOff ) 860 if ( m == AlwaysOff )
861 Global::hideInputMethod(); 861 Global::hideInputMethod();
862 if ( m == AlwaysOn ) 862 if ( m == AlwaysOn )
863 Global::showInputMethod(); 863 Global::showInputMethod();
864 } 864 }
865 } 865 }
866 return QApplication::qwsEventFilter( e ); 866 return QApplication::qwsEventFilter( e );
867} 867}
868#endif 868#endif
869 869
870/*! 870/*!
871 Destroys the QPEApplication. 871 Destroys the QPEApplication.
872*/ 872*/
873QPEApplication::~QPEApplication() 873QPEApplication::~QPEApplication()
874{ 874{
875 ungrabKeyboard(); 875 ungrabKeyboard();
876#if defined(Q_WS_QWS) && !defined(QT_NO_COP) 876#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
877 // Need to delete QCopChannels early, since the display will 877 // Need to delete QCopChannels early, since the display will
878 // be gone by the time we get to ~QObject(). 878 // be gone by the time we get to ~QObject().
879 delete sysChannel; 879 delete sysChannel;
880 delete pidChannel; 880 delete pidChannel;
881#endif 881#endif
882 882
883 delete d; 883 delete d;
884} 884}
885 885
886/*! 886/*!
887 Returns <tt>$OPIEDIR/</tt>. 887 Returns <tt>$OPIEDIR/</tt>.
888*/ 888*/
889QString QPEApplication::qpeDir() 889QString QPEApplication::qpeDir()
890{ 890{
891 const char * base = getenv( "OPIEDIR" ); 891 const char * base = getenv( "OPIEDIR" );
892 if ( base ) 892 if ( base )
893 return QString( base ) + "/"; 893 return QString( base ) + "/";
894 894
895 return QString( "../" ); 895 return QString( "../" );
896} 896}
897 897
898/*! 898/*!
899 Returns the user's current Document directory. There is a trailing "/". 899 Returns the user's current Document directory. There is a trailing "/".
900 .. well, it does now,, and there's no trailing '/' 900 .. well, it does now,, and there's no trailing '/'
901*/ 901*/
902QString QPEApplication::documentDir() 902QString QPEApplication::documentDir()
903{ 903{
904 const char* base = getenv( "HOME"); 904 const char* base = getenv( "HOME");
905 if ( base ) 905 if ( base )
906 return QString( base ) + "/Documents"; 906 return QString( base ) + "/Documents";
907 907
908 return QString( "../Documents" ); 908 return QString( "../Documents" );
909} 909}
910 910
911static int deforient = -1; 911static int deforient = -1;
912 912
913/*! 913/*!
914 \internal 914 \internal
915*/ 915*/
916int QPEApplication::defaultRotation() 916int QPEApplication::defaultRotation()
917{ 917{
918 if ( deforient < 0 ) { 918 if ( deforient < 0 ) {
919 QString d = getenv( "QWS_DISPLAY" ); 919 QString d = getenv( "QWS_DISPLAY" );
920 if ( d.contains( "Rot90" ) ) { 920 if ( d.contains( "Rot90" ) ) {
921 deforient = 90; 921 deforient = 90;
922 } 922 }
923 else if ( d.contains( "Rot180" ) ) { 923 else if ( d.contains( "Rot180" ) ) {
924 deforient = 180; 924 deforient = 180;
925 } 925 }
926 else if ( d.contains( "Rot270" ) ) { 926 else if ( d.contains( "Rot270" ) ) {
927 deforient = 270; 927 deforient = 270;
928 } 928 }
929 else { 929 else {
930 deforient = 0; 930 deforient = 0;
931 } 931 }
932 } 932 }
933 return deforient; 933 return deforient;
934} 934}
935 935
936/*! 936/*!
937 \internal 937 \internal
938*/ 938*/
939void QPEApplication::setDefaultRotation( int r ) 939void QPEApplication::setDefaultRotation( int r )
940{ 940{
941 if ( qApp->type() == GuiServer ) { 941 if ( qApp->type() == GuiServer ) {
942 deforient = r; 942 deforient = r;
943 setenv( "QWS_DISPLAY", QString( "Transformed:Rot%1:0" ).arg( r ).latin1(), 1 ); 943 setenv( "QWS_DISPLAY", QString( "Transformed:Rot%1:0" ).arg( r ).latin1(), 1 );
944 Config config("qpe"); 944 Config config("qpe");
945 config.setGroup( "Rotation" ); 945 config.setGroup( "Rotation" );
946 config.writeEntry( "Rot", r ); 946 config.writeEntry( "Rot", r );
947 } 947 }
948 else { 948 else {
949#ifndef QT_NO_COP 949#ifndef QT_NO_COP
950 { QCopEnvelope e( "QPE/System", "setDefaultRotation(int)" ); 950 { QCopEnvelope e( "QPE/System", "setDefaultRotation(int)" );
951 e << r; 951 e << r;
952 } 952 }
953#endif 953#endif
954 954
955 } 955 }
956} 956}
957 957
958 958
959/*! 959/*!
960 \internal 960 \internal
961*/ 961*/
962void QPEApplication::applyStyle() 962void QPEApplication::applyStyle()
963{ 963{
964 Config config( "qpe" ); 964 Config config( "qpe" );
965 config.setGroup( "Appearance" ); 965 config.setGroup( "Appearance" );
966 966
967 // don't block ourselves ... 967 // don't block ourselves ...
968 Opie::force_appearance = 0; 968 Opie::force_appearance = 0;
969 969
970 static QString appname = Opie::binaryName ( ); 970 static QString appname = Opie::binaryName ( );
971 971
972 QStringList ex = config. readListEntry ( "NoStyle", ';' ); 972 QStringList ex = config. readListEntry ( "NoStyle", ';' );
973 int nostyle = 0; 973 int nostyle = 0;
974 for ( QStringList::Iterator it = ex. begin ( ); it != ex. end ( ); ++it ) { 974 for ( QStringList::Iterator it = ex. begin ( ); it != ex. end ( ); ++it ) {
975 if ( QRegExp (( *it ). mid ( 1 ), false, true ). find ( appname, 0 ) >= 0 ) { 975 if ( QRegExp (( *it ). mid ( 1 ), false, true ). find ( appname, 0 ) >= 0 ) {
976 nostyle = ( *it ). left ( 1 ). toInt ( 0, 32 ); 976 nostyle = ( *it ). left ( 1 ). toInt ( 0, 32 );
977 break; 977 break;
978 } 978 }
979 } 979 }
980 980
981 // Widget style 981 // Widget style
982 QString style = config.readEntry( "Style", "Light" ); 982 QString style = config.readEntry( "Style", "Light" );
983 983
984 // don't set a custom style 984 // don't set a custom style
985 if ( nostyle & Opie::Force_Style ) 985 if ( nostyle & Opie::Force_Style )
986 style = "Light"; 986 style = "Light";
987 987
988 internalSetStyle ( style ); 988 internalSetStyle ( style );
989 989
990 // Colors 990 // Colors
991 QColor bgcolor( config.readEntry( "Background", "#E5E1D5" ) ); 991 QColor bgcolor( config.readEntry( "Background", "#E5E1D5" ) );
992 QColor btncolor( config.readEntry( "Button", "#D6CDBB" ) ); 992 QColor btncolor( config.readEntry( "Button", "#D6CDBB" ) );
993 QPalette pal( btncolor, bgcolor ); 993 QPalette pal( btncolor, bgcolor );
994 QString color = config.readEntry( "Highlight", "#800000" ); 994 QString color = config.readEntry( "Highlight", "#800000" );
995 pal.setColor( QColorGroup::Highlight, QColor( color ) ); 995 pal.setColor( QColorGroup::Highlight, QColor( color ) );
996 color = config.readEntry( "HighlightedText", "#FFFFFF" ); 996 color = config.readEntry( "HighlightedText", "#FFFFFF" );
997 pal.setColor( QColorGroup::HighlightedText, QColor( color ) ); 997 pal.setColor( QColorGroup::HighlightedText, QColor( color ) );
998 color = config.readEntry( "Text", "#000000" ); 998 color = config.readEntry( "Text", "#000000" );
999 pal.setColor( QColorGroup::Text, QColor( color ) ); 999 pal.setColor( QColorGroup::Text, QColor( color ) );
1000 color = config.readEntry( "ButtonText", "#000000" ); 1000 color = config.readEntry( "ButtonText", "#000000" );
1001 pal.setColor( QPalette::Active, QColorGroup::ButtonText, QColor( color ) ); 1001 pal.setColor( QPalette::Active, QColorGroup::ButtonText, QColor( color ) );
1002 color = config.readEntry( "Base", "#FFFFFF" ); 1002 color = config.readEntry( "Base", "#FFFFFF" );
1003 pal.setColor( QColorGroup::Base, QColor( color ) ); 1003 pal.setColor( QColorGroup::Base, QColor( color ) );
1004 1004
1005 pal.setColor( QPalette::Disabled, QColorGroup::Text, 1005 pal.setColor( QPalette::Disabled, QColorGroup::Text,
1006 pal.color( QPalette::Active, QColorGroup::Background ).dark() ); 1006 pal.color( QPalette::Active, QColorGroup::Background ).dark() );
1007 1007
1008 setPalette( pal, TRUE ); 1008 setPalette( pal, TRUE );
1009 1009
1010 // Window Decoration 1010 // Window Decoration
1011 QString dec = config.readEntry( "Decoration", "Qtopia" ); 1011 QString dec = config.readEntry( "Decoration", "Qtopia" );
1012 1012
1013 // don't set a custom deco 1013 // don't set a custom deco
1014 if ( nostyle & Opie::Force_Decoration ) 1014 if ( nostyle & Opie::Force_Decoration )
1015 dec = ""; 1015 dec = "";
1016 1016
1017 //qDebug ( "Setting Deco: %s -- old %s (%d)", dec.latin1(), d-> decorationName.latin1(), nostyle); 1017 //qDebug ( "Setting Deco: %s -- old %s (%d)", dec.latin1(), d-> decorationName.latin1(), nostyle);
1018 1018
1019 if ( dec != d->decorationName ) { 1019 if ( dec != d->decorationName ) {
1020 qwsSetDecoration( new QPEDecoration( dec ) ); 1020 qwsSetDecoration( new QPEDecoration( dec ) );
1021 d->decorationName = dec; 1021 d->decorationName = dec;
1022 } 1022 }
1023 1023
1024 // Font 1024 // Font
1025 QString ff = config.readEntry( "FontFamily", font().family() ); 1025 QString ff = config.readEntry( "FontFamily", font().family() );
1026 int fs = config.readNumEntry( "FontSize", font().pointSize() ); 1026 int fs = config.readNumEntry( "FontSize", font().pointSize() );
1027 1027
1028 // don't set a custom font 1028 // don't set a custom font
1029 if ( nostyle & Opie::Force_Font ) { 1029 if ( nostyle & Opie::Force_Font ) {
1030 ff = "Helvetica"; 1030 ff = "Helvetica";
1031 fs = 10; 1031 fs = 10;
1032 } 1032 }
1033 1033
1034 setFont ( QFont ( ff, fs ), true ); 1034 setFont ( QFont ( ff, fs ), true );
1035 1035
1036 // revert to global blocking policy ... 1036 // revert to global blocking policy ...
1037 Opie::force_appearance = config. readBoolEntry ( "ForceStyle", false ) ? Opie::Force_All : Opie::Force_None; 1037 Opie::force_appearance = config. readBoolEntry ( "ForceStyle", false ) ? Opie::Force_All : Opie::Force_None;
1038 Opie::force_appearance &= ~nostyle; 1038 Opie::force_appearance &= ~nostyle;
1039} 1039}
1040 1040
1041void QPEApplication::systemMessage( const QCString& msg, const QByteArray& data ) 1041void QPEApplication::systemMessage( const QCString& msg, const QByteArray& data )
1042{ 1042{
1043#ifdef Q_WS_QWS 1043#ifdef Q_WS_QWS
1044 QDataStream stream( data, IO_ReadOnly ); 1044 QDataStream stream( data, IO_ReadOnly );
1045 if ( msg == "applyStyle()" ) { 1045 if ( msg == "applyStyle()" ) {
1046 applyStyle(); 1046 applyStyle();
1047 } 1047 }
1048 else if ( msg == "toggleApplicationMenu()" ) { 1048 else if ( msg == "toggleApplicationMenu()" ) {
1049 QWidget *active = activeWindow ( ); 1049 QWidget *active = activeWindow ( );
1050 1050
1051 if ( active ) { 1051 if ( active ) {
1052 QPEMenuToolFocusManager *man = QPEMenuToolFocusManager::manager ( ); 1052 QPEMenuToolFocusManager *man = QPEMenuToolFocusManager::manager ( );
1053 bool oldactive = man-> isActive ( ); 1053 bool oldactive = man-> isActive ( );
1054 1054
1055 man-> setActive( !man-> isActive() ); 1055 man-> setActive( !man-> isActive() );
1056 1056
1057 if ( !oldactive && !man-> isActive ( )) { // no menubar to toggle -> try O-Menu 1057 if ( !oldactive && !man-> isActive ( )) { // no menubar to toggle -> try O-Menu
1058 QCopEnvelope e ( "QPE/TaskBar", "toggleStartMenu()" ); 1058 QCopEnvelope e ( "QPE/TaskBar", "toggleStartMenu()" );
1059 } 1059 }
1060 } 1060 }
1061 } 1061 }
1062 else if ( msg == "setDefaultRotation(int)" ) { 1062 else if ( msg == "setDefaultRotation(int)" ) {
1063 if ( type() == GuiServer ) { 1063 if ( type() == GuiServer ) {
1064 int r; 1064 int r;
1065 stream >> r; 1065 stream >> r;
1066 setDefaultRotation( r ); 1066 setDefaultRotation( r );
1067 } 1067 }
1068 } 1068 }
1069 else if ( msg == "setCurrentRotation(int)" ) { 1069 else if ( msg == "setCurrentRotation(int)" ) {
1070 int r; 1070 int r;
1071 stream >> r; 1071 stream >> r;
1072 setCurrentRotation( r ); 1072 setCurrentRotation( r );
1073 } 1073 }
1074 else if ( msg == "shutdown()" ) { 1074 else if ( msg == "shutdown()" ) {
1075 if ( type() == GuiServer ) 1075 if ( type() == GuiServer )
1076 shutdown(); 1076 shutdown();
1077 } 1077 }
1078 else if ( msg == "quit()" ) { 1078 else if ( msg == "quit()" ) {
1079 if ( type() != GuiServer ) 1079 if ( type() != GuiServer )
1080 tryQuit(); 1080 tryQuit();
1081 } 1081 }
1082 else if ( msg == "forceQuit()" ) { 1082 else if ( msg == "forceQuit()" ) {
1083 if ( type() != GuiServer ) 1083 if ( type() != GuiServer )
1084 quit(); 1084 quit();
1085 } 1085 }
1086 else if ( msg == "restart()" ) { 1086 else if ( msg == "restart()" ) {
1087 if ( type() == GuiServer ) 1087 if ( type() == GuiServer )
1088 restart(); 1088 restart();
1089 } 1089 }
1090 else if ( msg == "language(QString)" ) { 1090 else if ( msg == "language(QString)" ) {
1091 if ( type() == GuiServer ) { 1091 if ( type() == GuiServer ) {
1092 QString l; 1092 QString l;
1093 stream >> l; 1093 stream >> l;
1094 QString cl = getenv( "LANG" ); 1094 QString cl = getenv( "LANG" );
1095 if ( cl != l ) { 1095 if ( cl != l ) {
1096 if ( l.isNull() ) 1096 if ( l.isNull() )
1097 unsetenv( "LANG" ); 1097 unsetenv( "LANG" );
1098 else 1098 else
1099 setenv( "LANG", l.latin1(), 1 ); 1099 setenv( "LANG", l.latin1(), 1 );
1100 restart(); 1100 restart();
1101 } 1101 }
1102 } 1102 }
1103 } 1103 }
1104 else if ( msg == "timeChange(QString)" ) { 1104 else if ( msg == "timeChange(QString)" ) {
1105 QString t; 1105 QString t;
1106 stream >> t; 1106 stream >> t;
1107 if ( t.isNull() ) 1107 if ( t.isNull() )
1108 unsetenv( "TZ" ); 1108 unsetenv( "TZ" );
1109 else 1109 else
1110 setenv( "TZ", t.latin1(), 1 ); 1110 setenv( "TZ", t.latin1(), 1 );
1111 // emit the signal so everyone else knows... 1111 // emit the signal so everyone else knows...
1112 emit timeChanged(); 1112 emit timeChanged();
1113 } 1113 }
1114 else if ( msg == "execute(QString)" ) { 1114 else if ( msg == "execute(QString)" ) {
1115 if ( type() == GuiServer ) { 1115 if ( type() == GuiServer ) {
1116 QString t; 1116 QString t;
1117 stream >> t; 1117 stream >> t;
1118 Global::execute( t ); 1118 Global::execute( t );
1119 } 1119 }
1120 } 1120 }
1121 else if ( msg == "execute(QString,QString)" ) { 1121 else if ( msg == "execute(QString,QString)" ) {
1122 if ( type() == GuiServer ) { 1122 if ( type() == GuiServer ) {
1123 QString t, d; 1123 QString t, d;
1124 stream >> t >> d; 1124 stream >> t >> d;
1125 Global::execute( t, d ); 1125 Global::execute( t, d );
1126 } 1126 }
1127 } 1127 }
1128 else if ( msg == "addAlarm(QDateTime,QCString,QCString,int)" ) { 1128 else if ( msg == "addAlarm(QDateTime,QCString,QCString,int)" ) {
1129 if ( type() == GuiServer ) { 1129 if ( type() == GuiServer ) {
1130 QDateTime when; 1130 QDateTime when;
1131 QCString channel, message; 1131 QCString channel, message;
1132 int data; 1132 int data;
1133 stream >> when >> channel >> message >> data; 1133 stream >> when >> channel >> message >> data;
1134 AlarmServer::addAlarm( when, channel, message, data ); 1134 AlarmServer::addAlarm( when, channel, message, data );
1135 } 1135 }
1136 } 1136 }
1137 else if ( msg == "deleteAlarm(QDateTime,QCString,QCString,int)" ) { 1137 else if ( msg == "deleteAlarm(QDateTime,QCString,QCString,int)" ) {
1138 if ( type() == GuiServer ) { 1138 if ( type() == GuiServer ) {
1139 QDateTime when; 1139 QDateTime when;
1140 QCString channel, message; 1140 QCString channel, message;
1141 int data; 1141 int data;
1142 stream >> when >> channel >> message >> data; 1142 stream >> when >> channel >> message >> data;
1143 AlarmServer::deleteAlarm( when, channel, message, data ); 1143 AlarmServer::deleteAlarm( when, channel, message, data );
1144 } 1144 }
1145 } 1145 }
1146 else if ( msg == "clockChange(bool)" ) { 1146 else if ( msg == "clockChange(bool)" ) {
1147 int tmp; 1147 int tmp;
1148 stream >> tmp; 1148 stream >> tmp;
1149 emit clockChanged( tmp ); 1149 emit clockChanged( tmp );
1150 } 1150 }
1151 else if ( msg == "weekChange(bool)" ) { 1151 else if ( msg == "weekChange(bool)" ) {
1152 int tmp; 1152 int tmp;
1153 stream >> tmp; 1153 stream >> tmp;
1154 emit weekChanged( tmp ); 1154 emit weekChanged( tmp );
1155 } 1155 }
1156 else if ( msg == "setDateFormat(DateFormat)" ) { 1156 else if ( msg == "setDateFormat(DateFormat)" ) {
1157 DateFormat tmp; 1157 DateFormat tmp;
1158 stream >> tmp; 1158 stream >> tmp;
1159 emit dateFormatChanged( tmp ); 1159 emit dateFormatChanged( tmp );
1160 } 1160 }
1161 else if ( msg == "setVolume(int,int)" ) { 1161 else if ( msg == "setVolume(int,int)" ) {
1162 int t, v; 1162 int t, v;
1163 stream >> t >> v; 1163 stream >> t >> v;
1164 setVolume( t, v ); 1164 setVolume( t, v );
1165 emit volumeChanged( muted ); 1165 emit volumeChanged( muted );
1166 } 1166 }
1167 else if ( msg == "volumeChange(bool)" ) { 1167 else if ( msg == "volumeChange(bool)" ) {
1168 stream >> muted; 1168 stream >> muted;
1169 setVolume(); 1169 setVolume();
1170 emit volumeChanged( muted ); 1170 emit volumeChanged( muted );
1171 } 1171 }
1172 else if ( msg == "setMic(int,int)" ) { // Added: 2002-02-08 by Jeremy Cowgar <jc@cowgar.com> 1172 else if ( msg == "setMic(int,int)" ) { // Added: 2002-02-08 by Jeremy Cowgar <jc@cowgar.com>
1173 int t, v; 1173 int t, v;
1174 stream >> t >> v; 1174 stream >> t >> v;
1175 setMic( t, v ); 1175 setMic( t, v );
1176 emit micChanged( micMuted ); 1176 emit micChanged( micMuted );
1177 } 1177 }
1178 else if ( msg == "micChange(bool)" ) { // Added: 2002-02-08 by Jeremy Cowgar <jc@cowgar.com> 1178 else if ( msg == "micChange(bool)" ) { // Added: 2002-02-08 by Jeremy Cowgar <jc@cowgar.com>
1179 stream >> micMuted; 1179 stream >> micMuted;
1180 setMic(); 1180 setMic();
1181 emit micChanged( micMuted ); 1181 emit micChanged( micMuted );
1182 } 1182 }
1183 else if ( msg == "setBass(int,int)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org> 1183 else if ( msg == "setBass(int,int)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org>
1184 int t, v; 1184 int t, v;
1185 stream >> t >> v; 1185 stream >> t >> v;
1186 setBass( t, v ); 1186 setBass( t, v );
1187 } 1187 }
1188 else if ( msg == "bassChange(bool)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org> 1188 else if ( msg == "bassChange(bool)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org>
1189 setBass(); 1189 setBass();
1190 } 1190 }
1191 else if ( msg == "setTreble(int,int)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org> 1191 else if ( msg == "setTreble(int,int)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org>
1192 int t, v; 1192 int t, v;
1193 stream >> t >> v; 1193 stream >> t >> v;
1194 setTreble( t, v ); 1194 setTreble( t, v );
1195 } 1195 }
1196 else if ( msg == "trebleChange(bool)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org> 1196 else if ( msg == "trebleChange(bool)" ) { // Added: 2002-12-13 by Maximilian Reiss <harlekin@handhelds.org>
1197 setTreble(); 1197 setTreble();
1198 } 1198 }
1199 1199
1200 1200
1201 1201
1202#endif 1202#endif
1203} 1203}
1204 1204
1205/*! 1205/*!
1206 \internal 1206 \internal
1207*/ 1207*/
1208bool QPEApplication::raiseAppropriateWindow() 1208bool QPEApplication::raiseAppropriateWindow()
1209{ 1209{
1210 bool r = FALSE; 1210 bool r = FALSE;
1211 // ########## raise()ing main window should raise and set active 1211 // ########## raise()ing main window should raise and set active
1212 // ########## it and then all childen. This belongs in Qt/Embedded 1212 // ########## it and then all childen. This belongs in Qt/Embedded
1213 QWidget *top = d->qpe_main_widget; 1213 QWidget *top = d->qpe_main_widget;
1214 if ( !top ) 1214 if ( !top )
1215 top = mainWidget(); 1215 top = mainWidget();
1216 if ( top && d->keep_running ) { 1216 if ( top && d->keep_running ) {
1217 if ( top->isVisible() ) 1217 if ( top->isVisible() )
1218 r = TRUE; 1218 r = TRUE;
1219 else if (d->preloaded) { 1219 else if (d->preloaded) {
1220 // We are preloaded and not visible.. pretend we just started.. 1220 // We are preloaded and not visible.. pretend we just started..
1221 QCopEnvelope e("QPE/System", "fastAppShowing(QString)"); 1221 QCopEnvelope e("QPE/System", "fastAppShowing(QString)");
1222 e << d->appName; 1222 e << d->appName;
1223 } 1223 }
1224 1224
1225 d->show_mx(top, d->nomaximize); 1225 d->show_mx(top, d->nomaximize);
1226 top->raise(); 1226 top->raise();
1227 top->setActiveWindow(); 1227 top->setActiveWindow();
1228 } 1228 }
1229 QWidget *topm = activeModalWidget(); 1229 QWidget *topm = activeModalWidget();
1230 if ( topm && topm != top ) { 1230 if ( topm && topm != top ) {
1231 topm->show(); 1231 topm->show();
1232 topm->raise(); 1232 topm->raise();
1233 topm->setActiveWindow(); 1233 topm->setActiveWindow();
1234 // If we haven't already handled the fastAppShowing message 1234 // If we haven't already handled the fastAppShowing message
1235 if (!top && d->preloaded) { 1235 if (!top && d->preloaded) {
1236 QCopEnvelope e("QPE/System", "fastAppShowing(QString)"); 1236 QCopEnvelope e("QPE/System", "fastAppShowing(QString)");
1237 e << d->appName; 1237 e << d->appName;
1238 } 1238 }
1239 r = FALSE; 1239 r = FALSE;
1240 } 1240 }
1241 return r; 1241 return r;
1242} 1242}
1243 1243
1244void QPEApplication::pidMessage( const QCString& msg, const QByteArray& data) 1244void QPEApplication::pidMessage( const QCString& msg, const QByteArray& data)
1245{ 1245{
1246#ifdef Q_WS_QWS 1246#ifdef Q_WS_QWS
1247 1247
1248 if ( msg == "quit()" ) { 1248 if ( msg == "quit()" ) {
1249 tryQuit(); 1249 tryQuit();
1250 } 1250 }
1251 else if ( msg == "quitIfInvisible()" ) { 1251 else if ( msg == "quitIfInvisible()" ) {
1252 if ( d->qpe_main_widget && !d->qpe_main_widget->isVisible() ) 1252 if ( d->qpe_main_widget && !d->qpe_main_widget->isVisible() )
1253 quit(); 1253 quit();
1254 } 1254 }
1255 else if ( msg == "close()" ) { 1255 else if ( msg == "close()" ) {
1256 hideOrQuit(); 1256 hideOrQuit();
1257 } 1257 }
1258 else if ( msg == "disablePreload()" ) { 1258 else if ( msg == "disablePreload()" ) {
1259 d->preloaded = FALSE; 1259 d->preloaded = FALSE;
1260 d->keep_running = TRUE; 1260 d->keep_running = TRUE;
1261 /* so that quit will quit */ 1261 /* so that quit will quit */
1262 } 1262 }
1263 else if ( msg == "enablePreload()" ) { 1263 else if ( msg == "enablePreload()" ) {
1264 if (d->qpe_main_widget) 1264 if (d->qpe_main_widget)
1265 d->preloaded = TRUE; 1265 d->preloaded = TRUE;
1266 d->keep_running = TRUE; 1266 d->keep_running = TRUE;
1267 /* so next quit won't quit */ 1267 /* so next quit won't quit */
1268 } 1268 }
1269 else if ( msg == "raise()" ) { 1269 else if ( msg == "raise()" ) {
1270 d->keep_running = TRUE; 1270 d->keep_running = TRUE;
1271 d->notbusysent = FALSE; 1271 d->notbusysent = FALSE;
1272 raiseAppropriateWindow(); 1272 raiseAppropriateWindow();
1273 // Tell the system we're still chugging along... 1273 // Tell the system we're still chugging along...
1274 QCopEnvelope e("QPE/System", "appRaised(QString)"); 1274 QCopEnvelope e("QPE/System", "appRaised(QString)");
1275 e << d->appName; 1275 e << d->appName;
1276 } 1276 }
1277 else if ( msg == "flush()" ) { 1277 else if ( msg == "flush()" ) {
1278 emit flush(); 1278 emit flush();
1279 // we need to tell the desktop 1279 // we need to tell the desktop
1280 QCopEnvelope e( "QPE/Desktop", "flushDone(QString)" ); 1280 QCopEnvelope e( "QPE/Desktop", "flushDone(QString)" );
1281 e << d->appName; 1281 e << d->appName;
1282 } 1282 }
1283 else if ( msg == "reload()" ) { 1283 else if ( msg == "reload()" ) {
1284 emit reload(); 1284 emit reload();
1285 } 1285 }
1286 else if ( msg == "setDocument(QString)" ) { 1286 else if ( msg == "setDocument(QString)" ) {
1287 d->keep_running = TRUE; 1287 d->keep_running = TRUE;
1288 QDataStream stream( data, IO_ReadOnly ); 1288 QDataStream stream( data, IO_ReadOnly );
1289 QString doc; 1289 QString doc;
1290 stream >> doc; 1290 stream >> doc;
1291 QWidget *mw = mainWidget(); 1291 QWidget *mw = mainWidget();
1292 if ( !mw ) 1292 if ( !mw )
1293 mw = d->qpe_main_widget; 1293 mw = d->qpe_main_widget;
1294 if ( mw ) 1294 if ( mw )
1295 Global::setDocument( mw, doc ); 1295 Global::setDocument( mw, doc );
1296 } 1296 }
1297 else if ( msg == "nextView()" ) { 1297 else if ( msg == "nextView()" ) {
1298 qDebug("got nextView()"); 1298 qDebug("got nextView()");
1299 /* 1299 /*
1300 if ( raiseAppropriateWindow() ) 1300 if ( raiseAppropriateWindow() )
1301 */ 1301 */
1302 emit appMessage( msg, data); 1302 emit appMessage( msg, data);
1303 } 1303 }
1304 else { 1304 else {
1305 emit appMessage( msg, data); 1305 emit appMessage( msg, data);
1306 } 1306 }
1307 1307
1308#endif 1308#endif
1309} 1309}
1310 1310
1311 1311
1312/*! 1312/*!
1313 Sets widget \a mw as the mainWidget() and shows it. For small windows, 1313 Sets widget \a mw as the mainWidget() and shows it. For small windows,
1314 consider passing TRUE for \a nomaximize rather than the default FALSE. 1314 consider passing TRUE for \a nomaximize rather than the default FALSE.
1315 1315
1316 \sa showMainDocumentWidget() 1316 \sa showMainDocumentWidget()
1317*/ 1317*/
1318void QPEApplication::showMainWidget( QWidget* mw, bool nomaximize ) 1318void QPEApplication::showMainWidget( QWidget* mw, bool nomaximize )
1319{ 1319{
1320 d->show(mw, nomaximize ); 1320 d->show(mw, nomaximize );
1321} 1321}
1322 1322
1323/*! 1323/*!
1324 Sets widget \a mw as the mainWidget() and shows it. For small windows, 1324 Sets widget \a mw as the mainWidget() and shows it. For small windows,
1325 consider passing TRUE for \a nomaximize rather than the default FALSE. 1325 consider passing TRUE for \a nomaximize rather than the default FALSE.
1326 1326
1327 This calls designates the application as 1327 This calls designates the application as
1328 a \link docwidget.html document-oriented\endlink application. 1328 a \link docwidget.html document-oriented\endlink application.
1329 1329
1330 The \a mw widget \e must have this slot: setDocument(const QString&). 1330 The \a mw widget \e must have this slot: setDocument(const QString&).
1331 1331
1332 \sa showMainWidget() 1332 \sa showMainWidget()
1333*/ 1333*/
1334void QPEApplication::showMainDocumentWidget( QWidget* mw, bool nomaximize ) 1334void QPEApplication::showMainDocumentWidget( QWidget* mw, bool nomaximize )
1335{ 1335{
1336 if ( mw && argc() == 2 ) 1336 if ( mw && argc() == 2 )
1337 Global::setDocument( mw, QString::fromUtf8(argv()[1]) ); 1337 Global::setDocument( mw, QString::fromUtf8(argv()[1]) );
1338 1338
1339 d->show(mw, nomaximize ); 1339 d->show(mw, nomaximize );
1340} 1340}
1341 1341
1342 1342
1343/*! 1343/*!
1344 If an application is started via a \link qcop.html QCop\endlink 1344 If an application is started via a \link qcop.html QCop\endlink
1345 message, the application will process the \link qcop.html 1345 message, the application will process the \link qcop.html
1346 QCop\endlink message and then quit. If the application calls this 1346 QCop\endlink message and then quit. If the application calls this
1347 function while processing a \link qcop.html QCop\endlink message, 1347 function while processing a \link qcop.html QCop\endlink message,
1348 after processing its outstanding \link qcop.html QCop\endlink 1348 after processing its outstanding \link qcop.html QCop\endlink
1349 messages the application will start 'properly' and show itself. 1349 messages the application will start 'properly' and show itself.
1350 1350
1351 \sa keepRunning() 1351 \sa keepRunning()
1352*/ 1352*/
1353void QPEApplication::setKeepRunning() 1353void QPEApplication::setKeepRunning()
1354{ 1354{
1355 if ( qApp && qApp->inherits( "QPEApplication" ) ) { 1355 if ( qApp && qApp->inherits( "QPEApplication" ) ) {
1356 QPEApplication * qpeApp = ( QPEApplication* ) qApp; 1356 QPEApplication * qpeApp = ( QPEApplication* ) qApp;
1357 qpeApp->d->keep_running = TRUE; 1357 qpeApp->d->keep_running = TRUE;
1358 } 1358 }
1359} 1359}
1360 1360
1361/*! 1361/*!
1362 Returns TRUE if the application will quit after processing the 1362 Returns TRUE if the application will quit after processing the
1363 current list of qcop messages; otherwise returns FALSE. 1363 current list of qcop messages; otherwise returns FALSE.
1364 1364
1365 \sa setKeepRunning() 1365 \sa setKeepRunning()
1366*/ 1366*/
1367bool QPEApplication::keepRunning() const 1367bool QPEApplication::keepRunning() const
1368{ 1368{
1369 return d->keep_running; 1369 return d->keep_running;
1370} 1370}
1371 1371
1372/*! 1372/*!
1373 \internal 1373 \internal
1374*/ 1374*/
1375void QPEApplication::internalSetStyle( const QString &style ) 1375void QPEApplication::internalSetStyle( const QString &style )
1376{ 1376{
1377#if QT_VERSION >= 300 1377#if QT_VERSION >= 300
1378 if ( style == "QPE" ) { 1378 if ( style == "QPE" ) {
1379 setStyle( new QPEStyle ); 1379 setStyle( new QPEStyle );
1380 } 1380 }
1381 else { 1381 else {
1382 QStyle *s = QStyleFactory::create( style ); 1382 QStyle *s = QStyleFactory::create( style );
1383 if ( s ) 1383 if ( s )
1384 setStyle( s ); 1384 setStyle( s );
1385 } 1385 }
1386#else 1386#else
1387 if ( style == "Windows" ) { 1387 if ( style == "Windows" ) {
1388 setStyle( new QWindowsStyle ); 1388 setStyle( new QWindowsStyle );
1389 } 1389 }
1390 else if ( style == "QPE" ) { 1390 else if ( style == "QPE" ) {
1391 setStyle( new QPEStyle ); 1391 setStyle( new QPEStyle );
1392 } 1392 }
1393 else if ( style == "Light" ) { 1393 else if ( style == "Light" ) {
1394 setStyle( new LightStyle ); 1394 setStyle( new LightStyle );
1395 } 1395 }
1396#ifndef QT_NO_STYLE_PLATINUM 1396#ifndef QT_NO_STYLE_PLATINUM
1397 else if ( style == "Platinum" ) { 1397 else if ( style == "Platinum" ) {
1398 setStyle( new QPlatinumStyle ); 1398 setStyle( new QPlatinumStyle );
1399 } 1399 }
1400#endif 1400#endif
1401#ifndef QT_NO_STYLE_MOTIF 1401#ifndef QT_NO_STYLE_MOTIF
1402 else if ( style == "Motif" ) { 1402 else if ( style == "Motif" ) {
1403 setStyle( new QMotifStyle ); 1403 setStyle( new QMotifStyle );
1404 } 1404 }
1405#endif 1405#endif
1406#ifndef QT_NO_STYLE_MOTIFPLUS 1406#ifndef QT_NO_STYLE_MOTIFPLUS
1407 else if ( style == "MotifPlus" ) { 1407 else if ( style == "MotifPlus" ) {
1408 setStyle( new QMotifPlusStyle ); 1408 setStyle( new QMotifPlusStyle );
1409 } 1409 }
1410#endif 1410#endif
1411 1411
1412 else { 1412 else {
1413 QStyle *sty = 0; 1413 QStyle *sty = 0;
1414 QString path = QPEApplication::qpeDir ( ) + "/plugins/styles/"; 1414 QString path = QPEApplication::qpeDir ( ) + "/plugins/styles/";
1415 1415
1416 if ( style. find ( ".so" ) > 0 ) 1416 if ( style. find ( ".so" ) > 0 )
1417 path += style; 1417 path += style;
1418 else 1418 else
1419 path = path + "lib" + style. lower ( ) + ".so"; // compatibility 1419 path = path + "lib" + style. lower ( ) + ".so"; // compatibility
1420 1420
1421 static QLibrary *lastlib = 0; 1421 static QLibrary *lastlib = 0;
1422 static StyleInterface *lastiface = 0; 1422 static StyleInterface *lastiface = 0;
1423 1423
1424 QLibrary *lib = new QLibrary ( path ); 1424 QLibrary *lib = new QLibrary ( path );
1425 StyleInterface *iface = 0; 1425 StyleInterface *iface = 0;
1426 1426
1427 if (( lib-> queryInterface ( IID_Style, ( QUnknownInterface ** ) &iface ) == QS_OK ) && iface ) 1427 if (( lib-> queryInterface ( IID_Style, ( QUnknownInterface ** ) &iface ) == QS_OK ) && iface )
1428 sty = iface-> style ( ); 1428 sty = iface-> style ( );
1429 1429
1430 if ( sty ) { 1430 if ( sty ) {
1431 setStyle ( sty ); 1431 setStyle ( sty );
1432 1432
1433 if ( lastiface ) 1433 if ( lastiface )
1434 lastiface-> release ( ); 1434 lastiface-> release ( );
1435 lastiface = iface; 1435 lastiface = iface;
1436 1436
1437 if ( lastlib ) { 1437 if ( lastlib ) {
1438 lastlib-> unload ( ); 1438 lastlib-> unload ( );
1439 delete lastlib; 1439 delete lastlib;
1440 } 1440 }
1441 lastlib = lib; 1441 lastlib = lib;
1442 } 1442 }
1443 else { 1443 else {
1444 if ( iface ) 1444 if ( iface )
1445 iface-> release ( ); 1445 iface-> release ( );
1446 delete lib; 1446 delete lib;
1447 1447
1448 setStyle ( new LightStyle ( )); 1448 setStyle ( new LightStyle ( ));
1449 } 1449 }
1450 } 1450 }
1451#endif 1451#endif
1452} 1452}
1453 1453
1454/*! 1454/*!
1455 \internal 1455 \internal
1456*/ 1456*/
1457void QPEApplication::prepareForTermination( bool willrestart ) 1457void QPEApplication::prepareForTermination( bool willrestart )
1458{ 1458{
1459 if ( willrestart ) { 1459 if ( willrestart ) {
1460 // Draw a big wait icon, the image can be altered in later revisions 1460 // Draw a big wait icon, the image can be altered in later revisions
1461 // QWidget *d = QApplication::desktop(); 1461 // QWidget *d = QApplication::desktop();
1462 QImage img = Resource::loadImage( "launcher/new_wait" ); 1462 QImage img = Resource::loadImage( "launcher/new_wait" );
1463 QPixmap pix; 1463 QPixmap pix;
1464 pix.convertFromImage( img.smoothScale( 1 * img.width(), 1 * img.height() ) ); 1464 pix.convertFromImage( img.smoothScale( 1 * img.width(), 1 * img.height() ) );
1465 QLabel *lblWait = new QLabel( 0, "wait hack!", QWidget::WStyle_Customize | 1465 QLabel *lblWait = new QLabel( 0, "wait hack!", QWidget::WStyle_Customize |
1466 QWidget::WStyle_NoBorder | QWidget::WStyle_Tool ); 1466 QWidget::WStyle_NoBorder | QWidget::WStyle_Tool );
1467 lblWait->setPixmap( pix ); 1467 lblWait->setPixmap( pix );
1468 lblWait->setAlignment( QWidget::AlignCenter ); 1468 lblWait->setAlignment( QWidget::AlignCenter );
1469 lblWait->show(); 1469 lblWait->show();
1470 lblWait->showMaximized(); 1470 lblWait->showMaximized();
1471 } 1471 }
1472#ifndef SINGLE_APP 1472#ifndef SINGLE_APP
1473 { QCopEnvelope envelope( "QPE/System", "forceQuit()" ); 1473 { QCopEnvelope envelope( "QPE/System", "forceQuit()" );
1474 } 1474 }
1475 processEvents(); // ensure the message goes out. 1475 processEvents(); // ensure the message goes out.
1476 sleep( 1 ); // You have 1 second to comply. 1476 sleep( 1 ); // You have 1 second to comply.
1477#endif 1477#endif
1478} 1478}
1479 1479
1480/*! 1480/*!
1481 \internal 1481 \internal
1482*/ 1482*/
1483void QPEApplication::shutdown() 1483void QPEApplication::shutdown()
1484{ 1484{
1485 // Implement in server's QPEApplication subclass 1485 // Implement in server's QPEApplication subclass
1486} 1486}
1487 1487
1488/*! 1488/*!
1489 \internal 1489 \internal
1490*/ 1490*/
1491void QPEApplication::restart() 1491void QPEApplication::restart()
1492{ 1492{
1493 // Implement in server's QPEApplication subclass 1493 // Implement in server's QPEApplication subclass
1494} 1494}
1495 1495
1496static QPtrDict<void>* stylusDict = 0; 1496static QPtrDict<void>* stylusDict = 0;
1497static void createDict() 1497static void createDict()
1498{ 1498{
1499 if ( !stylusDict ) 1499 if ( !stylusDict )
1500 stylusDict = new QPtrDict<void>; 1500 stylusDict = new QPtrDict<void>;
1501} 1501}
1502 1502
1503/*! 1503/*!
1504 Returns the current StylusMode for widget \a w. 1504 Returns the current StylusMode for widget \a w.
1505 1505
1506 \sa setStylusOperation() StylusMode 1506 \sa setStylusOperation() StylusMode
1507*/ 1507*/
1508QPEApplication::StylusMode QPEApplication::stylusOperation( QWidget* w ) 1508QPEApplication::StylusMode QPEApplication::stylusOperation( QWidget* w )
1509{ 1509{
1510 if ( stylusDict ) 1510 if ( stylusDict )
1511 return ( StylusMode ) ( int ) stylusDict->find( w ); 1511 return ( StylusMode ) ( int ) stylusDict->find( w );
1512 return LeftOnly; 1512 return LeftOnly;
1513} 1513}
1514 1514
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