summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--library/alarmserver.cpp9
-rw-r--r--library/applnk.cpp1
-rw-r--r--library/tzselect.cpp1
3 files changed, 6 insertions, 5 deletions
diff --git a/library/alarmserver.cpp b/library/alarmserver.cpp
index 48ab9c1..ba7b015 100644
--- a/library/alarmserver.cpp
+++ b/library/alarmserver.cpp
@@ -1,507 +1,506 @@
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 <qdir.h> 21#include "alarmserver.h"
22
23 22
23#include <qpe/global.h>
24#include <qpe/qpeapplication.h> 24#include <qpe/qpeapplication.h>
25
26#include <qpe/qcopenvelope_qws.h> 25#include <qpe/qcopenvelope_qws.h>
27#include "alarmserver.h"
28#include <qpe/timeconversion.h> 26#include <qpe/timeconversion.h>
29 27
28#include <qdir.h>
29
30#include <sys/types.h> 30#include <sys/types.h>
31#include <sys/stat.h> 31#include <sys/stat.h>
32
33#include <stdlib.h> 32#include <stdlib.h>
34#include <unistd.h> 33#include <unistd.h>
35 34
36 35
37#undef USE_ATD // not used anymore -- we run opie-alarm on suspend/resume 36#undef USE_ATD // not used anymore -- we run opie-alarm on suspend/resume
38 37
39 38
40struct timerEventItem 39struct timerEventItem
41{ 40{
42 time_t UTCtime; 41 time_t UTCtime;
43 QCString channel, message; 42 QCString channel, message;
44 int data; 43 int data;
45 bool operator==( const timerEventItem &right ) const 44 bool operator==( const timerEventItem &right ) const
46 { 45 {
47 return ( UTCtime == right.UTCtime 46 return ( UTCtime == right.UTCtime
48 && channel == right.channel 47 && channel == right.channel
49 && message == right.message 48 && message == right.message
50 && data == right.data ); 49 && data == right.data );
51 } 50 }
52}; 51};
53 52
54class TimerReceiverObject : public QObject 53class TimerReceiverObject : public QObject
55{ 54{
56public: 55public:
57 TimerReceiverObject() 56 TimerReceiverObject()
58 { } 57 { }
59 ~TimerReceiverObject() 58 ~TimerReceiverObject()
60 { } 59 { }
61 void resetTimer(); 60 void resetTimer();
62 void setTimerEventItem(); 61 void setTimerEventItem();
63 void deleteTimer(); 62 void deleteTimer();
64protected: 63protected:
65 void timerEvent( QTimerEvent *te ); 64 void timerEvent( QTimerEvent *te );
66 65
67#ifdef USE_ATD 66#ifdef USE_ATD
68private: 67private:
69 QString atfilename; 68 QString atfilename;
70#endif 69#endif
71}; 70};
72 71
73TimerReceiverObject *timerEventReceiver = NULL; 72TimerReceiverObject *timerEventReceiver = NULL;
74QList<timerEventItem> timerEventList; 73QList<timerEventItem> timerEventList;
75timerEventItem *nearestTimerEvent = NULL; 74timerEventItem *nearestTimerEvent = NULL;
76 75
77 76
78// set the timer to go off on the next event in the list 77// set the timer to go off on the next event in the list
79void setNearestTimerEvent() 78void setNearestTimerEvent()
80{ 79{
81 nearestTimerEvent = NULL; 80 nearestTimerEvent = NULL;
82 QListIterator<timerEventItem> it( timerEventList ); 81 QListIterator<timerEventItem> it( timerEventList );
83 if ( *it ) 82 if ( *it )
84 nearestTimerEvent = *it; 83 nearestTimerEvent = *it;
85 for ( ; *it; ++it ) 84 for ( ; *it; ++it )
86 if ( (*it)->UTCtime < nearestTimerEvent->UTCtime ) 85 if ( (*it)->UTCtime < nearestTimerEvent->UTCtime )
87 nearestTimerEvent = *it; 86 nearestTimerEvent = *it;
88 if (nearestTimerEvent) 87 if (nearestTimerEvent)
89 timerEventReceiver->resetTimer(); 88 timerEventReceiver->resetTimer();
90 else 89 else
91 timerEventReceiver->deleteTimer(); 90 timerEventReceiver->deleteTimer();
92} 91}
93 92
94 93
95//store current state to file 94//store current state to file
96//Simple implementation. Should run on a timer. 95//Simple implementation. Should run on a timer.
97 96
98static void saveState() 97static void saveState()
99{ 98{
100 QString savefilename = Global::applicationFileName( "AlarmServer", "saveFile" ); 99 QString savefilename = Global::applicationFileName( "AlarmServer", "saveFile" );
101 if ( timerEventList.isEmpty() ) { 100 if ( timerEventList.isEmpty() ) {
102 unlink( savefilename ); 101 unlink( savefilename );
103 return ; 102 return ;
104 } 103 }
105 104
106 QFile savefile(savefilename + ".new"); 105 QFile savefile(savefilename + ".new");
107 if ( savefile.open(IO_WriteOnly) ) { 106 if ( savefile.open(IO_WriteOnly) ) {
108 QDataStream ds( &savefile ); 107 QDataStream ds( &savefile );
109 108
110 //save 109 //save
111 110
112 QListIterator<timerEventItem> it( timerEventList ); 111 QListIterator<timerEventItem> it( timerEventList );
113 for ( ; *it; ++it ) { 112 for ( ; *it; ++it ) {
114 ds << it.current()->UTCtime; 113 ds << it.current()->UTCtime;
115 ds << it.current()->channel; 114 ds << it.current()->channel;
116 ds << it.current()->message; 115 ds << it.current()->message;
117 ds << it.current()->data; 116 ds << it.current()->data;
118 } 117 }
119 118
120 119
121 savefile.close(); 120 savefile.close();
122 unlink( savefilename ); 121 unlink( savefilename );
123 QDir d; 122 QDir d;
124 d.rename(savefilename + ".new", savefilename); 123 d.rename(savefilename + ".new", savefilename);
125 124
126 } 125 }
127} 126}
128 127
129/*! 128/*!
130 Sets up the alarm server. Restoring to previous state (session management). 129 Sets up the alarm server. Restoring to previous state (session management).
131 */ 130 */
132void AlarmServer::initialize() 131void AlarmServer::initialize()
133{ 132{
134 //read autosave file and put events in timerEventList 133 //read autosave file and put events in timerEventList
135 134
136 QString savefilename = Global::applicationFileName( "AlarmServer", "saveFile" ); 135 QString savefilename = Global::applicationFileName( "AlarmServer", "saveFile" );
137 136
138 QFile savefile(savefilename); 137 QFile savefile(savefilename);
139 if ( savefile.open(IO_ReadOnly) ) { 138 if ( savefile.open(IO_ReadOnly) ) {
140 QDataStream ds( &savefile ); 139 QDataStream ds( &savefile );
141 while ( !ds.atEnd() ) { 140 while ( !ds.atEnd() ) {
142 timerEventItem *newTimerEventItem = new timerEventItem; 141 timerEventItem *newTimerEventItem = new timerEventItem;
143 ds >> newTimerEventItem->UTCtime; 142 ds >> newTimerEventItem->UTCtime;
144 ds >> newTimerEventItem->channel; 143 ds >> newTimerEventItem->channel;
145 ds >> newTimerEventItem->message; 144 ds >> newTimerEventItem->message;
146 ds >> newTimerEventItem->data; 145 ds >> newTimerEventItem->data;
147 timerEventList.append( newTimerEventItem ); 146 timerEventList.append( newTimerEventItem );
148 } 147 }
149 savefile.close(); 148 savefile.close();
150 if (!timerEventReceiver) 149 if (!timerEventReceiver)
151 timerEventReceiver = new TimerReceiverObject; 150 timerEventReceiver = new TimerReceiverObject;
152 setNearestTimerEvent(); 151 setNearestTimerEvent();
153 } 152 }
154} 153}
155 154
156 155
157#ifdef USE_ATD 156#ifdef USE_ATD
158 157
159static const char* atdir = "/var/spool/at/"; 158static const char* atdir = "/var/spool/at/";
160 159
161static bool triggerAtd( bool writeHWClock = FALSE ) 160static bool triggerAtd( bool writeHWClock = FALSE )
162{ 161{
163 QFile trigger(QString(atdir) + "trigger"); 162 QFile trigger(QString(atdir) + "trigger");
164 if ( trigger.open(IO_WriteOnly | IO_Raw) ) { 163 if ( trigger.open(IO_WriteOnly | IO_Raw) ) {
165 if ( trigger.writeBlock("\n", 2) != 2 ) { 164 if ( trigger.writeBlock("\n", 2) != 2 ) {
166 QMessageBox::critical( 0, QObject::tr( "Out of Space" ), 165 QMessageBox::critical( 0, QObject::tr( "Out of Space" ),
167 QObject::tr( "Unable to schedule alarm.\nFree some memory and try again." ) ); 166 QObject::tr( "Unable to schedule alarm.\nFree some memory and try again." ) );
168 trigger.close(); 167 trigger.close();
169 QFile::remove 168 QFile::remove
170 ( trigger.name() ); 169 ( trigger.name() );
171 return FALSE; 170 return FALSE;
172 } 171 }
173 return TRUE; 172 return TRUE;
174 } 173 }
175 return FALSE; 174 return FALSE;
176} 175}
177 176
178#else 177#else
179 178
180static bool writeResumeAt ( time_t wakeup ) 179static bool writeResumeAt ( time_t wakeup )
181{ 180{
182 FILE *fp = ::fopen ( "/var/run/resumeat", "w" ); 181 FILE *fp = ::fopen ( "/var/run/resumeat", "w" );
183 182
184 if ( fp ) { 183 if ( fp ) {
185 ::fprintf ( fp, "%d\n", (int) wakeup ); 184 ::fprintf ( fp, "%d\n", (int) wakeup );
186 ::fclose ( fp ); 185 ::fclose ( fp );
187 } 186 }
188 else 187 else
189 qWarning ( "Failed to write wakeup time to /var/run/resumeat" ); 188 qWarning ( "Failed to write wakeup time to /var/run/resumeat" );
190 189
191 return ( fp ); 190 return ( fp );
192} 191}
193 192
194#endif 193#endif
195 194
196void TimerReceiverObject::deleteTimer() 195void TimerReceiverObject::deleteTimer()
197{ 196{
198#ifdef USE_ATD 197#ifdef USE_ATD
199 if ( !atfilename.isEmpty() ) { 198 if ( !atfilename.isEmpty() ) {
200 unlink( atfilename ); 199 unlink( atfilename );
201 atfilename = QString::null; 200 atfilename = QString::null;
202 triggerAtd( FALSE ); 201 triggerAtd( FALSE );
203 } 202 }
204#else 203#else
205 writeResumeAt ( 0 ); 204 writeResumeAt ( 0 );
206#endif 205#endif
207} 206}
208 207
209void TimerReceiverObject::resetTimer() 208void TimerReceiverObject::resetTimer()
210{ 209{
211 const int maxsecs = 2147000; 210 const int maxsecs = 2147000;
212 QDateTime nearest = TimeConversion::fromUTC(nearestTimerEvent->UTCtime); 211 QDateTime nearest = TimeConversion::fromUTC(nearestTimerEvent->UTCtime);
213 QDateTime now = QDateTime::currentDateTime(); 212 QDateTime now = QDateTime::currentDateTime();
214 if ( nearest < now ) 213 if ( nearest < now )
215 nearest = now; 214 nearest = now;
216 int secs = TimeConversion::secsTo( now, nearest ); 215 int secs = TimeConversion::secsTo( now, nearest );
217 if ( secs > maxsecs ) { 216 if ( secs > maxsecs ) {
218 // too far for millisecond timing 217 // too far for millisecond timing
219 secs = maxsecs; 218 secs = maxsecs;
220 } 219 }
221 220
222 // System timer (needed so that we wake from deep sleep), 221 // System timer (needed so that we wake from deep sleep),
223 // from the Epoch in seconds. 222 // from the Epoch in seconds.
224 // 223 //
225 int at_secs = TimeConversion::toUTC(nearest); 224 int at_secs = TimeConversion::toUTC(nearest);
226 // qDebug("reset timer to %d seconds from Epoch",at_secs); 225 // qDebug("reset timer to %d seconds from Epoch",at_secs);
227 226
228#ifdef USE_ATD 227#ifdef USE_ATD
229 228
230 QString fn = atdir + QString::number(at_secs) + "." 229 QString fn = atdir + QString::number(at_secs) + "."
231 + QString::number(getpid()); 230 + QString::number(getpid());
232 if ( fn != atfilename ) { 231 if ( fn != atfilename ) {
233 QFile atfile(fn + ".new"); 232 QFile atfile(fn + ".new");
234 if ( atfile.open(IO_WriteOnly | IO_Raw) ) { 233 if ( atfile.open(IO_WriteOnly | IO_Raw) ) {
235 int total_written; 234 int total_written;
236 235
237 // just wake up and delete the at file 236 // just wake up and delete the at file
238 QString cmd = "#!/bin/sh\nrm " + fn; 237 QString cmd = "#!/bin/sh\nrm " + fn;
239 total_written = atfile.writeBlock(cmd.latin1(), cmd.length()); 238 total_written = atfile.writeBlock(cmd.latin1(), cmd.length());
240 if ( total_written != int(cmd.length()) ) { 239 if ( total_written != int(cmd.length()) ) {
241 QMessageBox::critical( 0, tr("Out of Space"), 240 QMessageBox::critical( 0, tr("Out of Space"),
242 tr("Unable to schedule alarm.\n" 241 tr("Unable to schedule alarm.\n"
243 "Please free up space and try again") ); 242 "Please free up space and try again") );
244 atfile.close(); 243 atfile.close();
245 QFile::remove 244 QFile::remove
246 ( atfile.name() ); 245 ( atfile.name() );
247 return ; 246 return ;
248 } 247 }
249 atfile.close(); 248 atfile.close();
250 unlink( atfilename ); 249 unlink( atfilename );
251 QDir d; 250 QDir d;
252 d.rename(fn + ".new", fn); 251 d.rename(fn + ".new", fn);
253 chmod(fn.latin1(), 0755); 252 chmod(fn.latin1(), 0755);
254 atfilename = fn; 253 atfilename = fn;
255 triggerAtd( FALSE ); 254 triggerAtd( FALSE );
256 } 255 }
257 else { 256 else {
258 qWarning("Cannot open atd file %s", fn.latin1()); 257 qWarning("Cannot open atd file %s", fn.latin1());
259 } 258 }
260 } 259 }
261#else 260#else
262 writeResumeAt ( at_secs ); 261 writeResumeAt ( at_secs );
263 262
264#endif 263#endif
265 264
266 // Qt timers (does the actual alarm) 265 // Qt timers (does the actual alarm)
267 // from now in milliseconds 266 // from now in milliseconds
268 // 267 //
269 qDebug("AlarmServer waiting %d seconds", secs); 268 qDebug("AlarmServer waiting %d seconds", secs);
270 startTimer( 1000 * secs + 500 ); 269 startTimer( 1000 * secs + 500 );
271} 270}
272 271
273void TimerReceiverObject::timerEvent( QTimerEvent * ) 272void TimerReceiverObject::timerEvent( QTimerEvent * )
274{ 273{
275 bool needSave = FALSE; 274 bool needSave = FALSE;
276 killTimers(); 275 killTimers();
277 if (nearestTimerEvent) { 276 if (nearestTimerEvent) {
278 if ( nearestTimerEvent->UTCtime 277 if ( nearestTimerEvent->UTCtime
279 <= TimeConversion::toUTC(QDateTime::currentDateTime()) ) { 278 <= TimeConversion::toUTC(QDateTime::currentDateTime()) ) {
280#ifndef QT_NO_COP 279#ifndef QT_NO_COP
281 QCopEnvelope e( nearestTimerEvent->channel, 280 QCopEnvelope e( nearestTimerEvent->channel,
282 nearestTimerEvent->message ); 281 nearestTimerEvent->message );
283 e << TimeConversion::fromUTC( nearestTimerEvent->UTCtime ) 282 e << TimeConversion::fromUTC( nearestTimerEvent->UTCtime )
284 << nearestTimerEvent->data; 283 << nearestTimerEvent->data;
285#endif 284#endif
286 285
287 timerEventList.remove( nearestTimerEvent ); 286 timerEventList.remove( nearestTimerEvent );
288 needSave = TRUE; 287 needSave = TRUE;
289 } 288 }
290 setNearestTimerEvent(); 289 setNearestTimerEvent();
291 } 290 }
292 else { 291 else {
293 resetTimer(); 292 resetTimer();
294 } 293 }
295 if ( needSave ) 294 if ( needSave )
296 saveState(); 295 saveState();
297} 296}
298 297
299/*! 298/*!
300 \class AlarmServer alarmserver.h 299 \class AlarmServer alarmserver.h
301 \brief The AlarmServer class allows alarms to be scheduled and unscheduled. 300 \brief The AlarmServer class allows alarms to be scheduled and unscheduled.
302 301
303 Applications can schedule alarms with addAlarm() and can 302 Applications can schedule alarms with addAlarm() and can
304 unschedule alarms with deleteAlarm(). When the time for an alarm 303 unschedule alarms with deleteAlarm(). When the time for an alarm
305 to go off is reached the specified \link qcop.html QCop\endlink 304 to go off is reached the specified \link qcop.html QCop\endlink
306 message is sent on the specified channel (optionally with 305 message is sent on the specified channel (optionally with
307 additional data). 306 additional data).
308 307
309 Scheduling an alarm using this class is important (rather just using 308 Scheduling an alarm using this class is important (rather just using
310 a QTimer) since the machine may be asleep and needs to get woken up using 309 a QTimer) since the machine may be asleep and needs to get woken up using
311 the Linux kernel which implements this at the kernel level to minimize 310 the Linux kernel which implements this at the kernel level to minimize
312 battery usage while asleep. 311 battery usage while asleep.
313 312
314 A small example on how to use AlarmServer. 313 A small example on how to use AlarmServer.
315 314
316 First we need to connect a slot the AppMessage QCOP call. appMessage 315 First we need to connect a slot the AppMessage QCOP call. appMessage
317 will be emitted if QPE/Application/appname gets called. 316 will be emitted if QPE/Application/appname gets called.
318 317
319 \code 318 \code
320 TestApp::TestApp(QWidget *parent, const char* name, WFlags fl ) 319 TestApp::TestApp(QWidget *parent, const char* name, WFlags fl )
321 : QMainWindow(parent,name,fl){ 320 : QMainWindow(parent,name,fl){
322 connect(qApp,SIGNAL(appMessage(const QCString&,const QByteArray&)), 321 connect(qApp,SIGNAL(appMessage(const QCString&,const QByteArray&)),
323 this,SLOT(slotAppMessage(const QCString&,const QByteArray&))); 322 this,SLOT(slotAppMessage(const QCString&,const QByteArray&)));
324 } 323 }
325 \endcode 324 \endcode
326 325
327 To add / delete an alarm, you can use the static method AlarmServer::addAlarm and 326 To add / delete an alarm, you can use the static method AlarmServer::addAlarm and
328 AlarmServer::deleteAlarm. Note that an old (expired) alarm will automatically be deleted 327 AlarmServer::deleteAlarm. Note that an old (expired) alarm will automatically be deleted
329 from the alarmserver list, but a change in timing will have the effect, that both 328 from the alarmserver list, but a change in timing will have the effect, that both
330 alarms will be emitted. So if you change an Alarm be sure to delete the old one! 329 alarms will be emitted. So if you change an Alarm be sure to delete the old one!
331 @see addAlarm 330 @see addAlarm
332 331
333 \code 332 \code
334 QDateTime oldDt = oldAlarmDateTime(); 333 QDateTime oldDt = oldAlarmDateTime();
335 QPEApplication::execDialog(ourDlg); 334 QPEApplication::execDialog(ourDlg);
336 QDateTime newDt = ourDlg->dateTime(); 335 QDateTime newDt = ourDlg->dateTime();
337 if(newDt == oldDt ) return; 336 if(newDt == oldDt ) return;
338 @slash* code is missing for unsetting an alarm *@slash 337 @slash* code is missing for unsetting an alarm *@slash
339 338
340 AlarmServer::deleteAlarm(oldDt,"QPE/Application/appname","checkAlarm(QDateTime,int)",0); 339 AlarmServer::deleteAlarm(oldDt,"QPE/Application/appname","checkAlarm(QDateTime,int)",0);
341 AlarmServer::addAlarm( newDt,"QPE/AlarmServer/appname","checkAlarm(QDateTime,int)",0); 340 AlarmServer::addAlarm( newDt,"QPE/AlarmServer/appname","checkAlarm(QDateTime,int)",0);
342 341
343 \endcode 342 \endcode
344 343
345 Now once the Alarm is emitted you need to check the appMessage and then do what you want. 344 Now once the Alarm is emitted you need to check the appMessage and then do what you want.
346 \code 345 \code
347 void TestApp::slotAppMessage(const QCString& str, const QByteArray& ar ){ 346 void TestApp::slotAppMessage(const QCString& str, const QByteArray& ar ){
348 QDataStream stream(ar,IO_ReadOnly); 347 QDataStream stream(ar,IO_ReadOnly);
349 if(str == "checkAlarm(QDateTime,int)" ){ 348 if(str == "checkAlarm(QDateTime,int)" ){
350 QDateTime dt; 349 QDateTime dt;
351 int a; 350 int a;
352 stream >> dt >> a; 351 stream >> dt >> a;
353 // fire up alarm 352 // fire up alarm
354 } 353 }
355 } 354 }
356 \endcode 355 \endcode
357 356
358 \ingroup qtopiaemb 357 \ingroup qtopiaemb
359 \sa QCopEnvelope 358 \sa QCopEnvelope
360 @see QPEApplication::appMessage(const QCString&,const QByteArray&) 359 @see QPEApplication::appMessage(const QCString&,const QByteArray&)
361 @see OPimMainWindow 360 @see OPimMainWindow
362 @see ODevice::alarmSound() 361 @see ODevice::alarmSound()
363 @see Sound::soundAlarm() 362 @see Sound::soundAlarm()
364*/ 363*/
365 364
366/*! 365/*!
367 Schedules an alarm to go off at (or soon after) time \a when. When 366 Schedules an alarm to go off at (or soon after) time \a when. When
368 the alarm goes off, the \link qcop.html QCop\endlink \a message will 367 the alarm goes off, the \link qcop.html QCop\endlink \a message will
369 be sent to \a channel, with \a data as a parameter. 368 be sent to \a channel, with \a data as a parameter.
370 369
371 If this function is called with exactly the same data as a previous 370 If this function is called with exactly the same data as a previous
372 call the subsequent call is ignored, so there is only ever one alarm 371 call the subsequent call is ignored, so there is only ever one alarm
373 with a given set of parameters. 372 with a given set of parameters.
374 373
375 Once an alarm is emitted. The \a channel with a \a message will be emitted 374 Once an alarm is emitted. The \a channel with a \a message will be emitted
376 and data will be send. 375 and data will be send.
377 The QDateTime and int are the two parameters included in the QCOP message. 376 The QDateTime and int are the two parameters included in the QCOP message.
378 You can specify channel, message and the integer parameter. QDateTime will be 377 You can specify channel, message and the integer parameter. QDateTime will be
379 the datetime of the QCop call. 378 the datetime of the QCop call.
380 379
381 @param when The QDateTime of the alarm 380 @param when The QDateTime of the alarm
382 @param channel The channel which gets called once the alarm is emitted 381 @param channel The channel which gets called once the alarm is emitted
383 @param message The message to be send to the channel 382 @param message The message to be send to the channel
384 @param data Additional data as integer 383 @param data Additional data as integer
385 384
386 @see QCopChannel 385 @see QCopChannel
387 \sa deleteAlarm() 386 \sa deleteAlarm()
388*/ 387*/
389void AlarmServer::addAlarm ( QDateTime when, const QCString& channel, 388void AlarmServer::addAlarm ( QDateTime when, const QCString& channel,
390 const QCString& message, int data) 389 const QCString& message, int data)
391{ 390{
392 if ( qApp->type() == QApplication::GuiServer ) { 391 if ( qApp->type() == QApplication::GuiServer ) {
393 bool needSave = FALSE; 392 bool needSave = FALSE;
394 // Here we are the server so either it has been directly called from 393 // Here we are the server so either it has been directly called from
395 // within the server or it has been sent to us from a client via QCop 394 // within the server or it has been sent to us from a client via QCop
396 if (!timerEventReceiver) 395 if (!timerEventReceiver)
397 timerEventReceiver = new TimerReceiverObject; 396 timerEventReceiver = new TimerReceiverObject;
398 397
399 timerEventItem *newTimerEventItem = new timerEventItem; 398 timerEventItem *newTimerEventItem = new timerEventItem;
400 newTimerEventItem->UTCtime = TimeConversion::toUTC( when ); 399 newTimerEventItem->UTCtime = TimeConversion::toUTC( when );
401 newTimerEventItem->channel = channel; 400 newTimerEventItem->channel = channel;
402 newTimerEventItem->message = message; 401 newTimerEventItem->message = message;
403 newTimerEventItem->data = data; 402 newTimerEventItem->data = data;
404 // explore the case of already having the event in here... 403 // explore the case of already having the event in here...
405 QListIterator<timerEventItem> it( timerEventList ); 404 QListIterator<timerEventItem> it( timerEventList );
406 for ( ; *it; ++it ) 405 for ( ; *it; ++it )
407 if ( *(*it) == *newTimerEventItem ) 406 if ( *(*it) == *newTimerEventItem )
408 return ; 407 return ;
409 // if we made it here, it is okay to add the item... 408 // if we made it here, it is okay to add the item...
410 timerEventList.append( newTimerEventItem ); 409 timerEventList.append( newTimerEventItem );
411 needSave = TRUE; 410 needSave = TRUE;
412 // quicker than using setNearestTimerEvent() 411 // quicker than using setNearestTimerEvent()
413 if ( nearestTimerEvent ) { 412 if ( nearestTimerEvent ) {
414 if (newTimerEventItem->UTCtime < nearestTimerEvent->UTCtime) { 413 if (newTimerEventItem->UTCtime < nearestTimerEvent->UTCtime) {
415 nearestTimerEvent = newTimerEventItem; 414 nearestTimerEvent = newTimerEventItem;
416 timerEventReceiver->killTimers(); 415 timerEventReceiver->killTimers();
417 timerEventReceiver->resetTimer(); 416 timerEventReceiver->resetTimer();
418 } 417 }
419 } 418 }
420 else { 419 else {
421 nearestTimerEvent = newTimerEventItem; 420 nearestTimerEvent = newTimerEventItem;
422 timerEventReceiver->resetTimer(); 421 timerEventReceiver->resetTimer();
423 } 422 }
424 if ( needSave ) 423 if ( needSave )
425 saveState(); 424 saveState();
426 } 425 }
427 else { 426 else {
428#ifndef QT_NO_COP 427#ifndef QT_NO_COP
429 QCopEnvelope e( "QPE/System", "addAlarm(QDateTime,QCString,QCString,int)" ); 428 QCopEnvelope e( "QPE/System", "addAlarm(QDateTime,QCString,QCString,int)" );
430 e << when << channel << message << data; 429 e << when << channel << message << data;
431#endif 430#endif
432 431
433 } 432 }
434} 433}
435 434
436/*! 435/*!
437 Deletes previously scheduled alarms which match \a when, \a channel, 436 Deletes previously scheduled alarms which match \a when, \a channel,
438 \a message, and \a data. 437 \a message, and \a data.
439 438
440 Passing null values for \a when, \a channel, or for the \link 439 Passing null values for \a when, \a channel, or for the \link
441 qcop.html QCop\endlink \a message, acts as a wildcard meaning "any". 440 qcop.html QCop\endlink \a message, acts as a wildcard meaning "any".
442 Similarly, passing -1 for \a data indicates "any". 441 Similarly, passing -1 for \a data indicates "any".
443 442
444 If there is no matching alarm, nothing happens. 443 If there is no matching alarm, nothing happens.
445 444
446 \sa addAlarm() 445 \sa addAlarm()
447 446
448*/ 447*/
449void AlarmServer::deleteAlarm (QDateTime when, const QCString& channel, const QCString& message, int data) 448void AlarmServer::deleteAlarm (QDateTime when, const QCString& channel, const QCString& message, int data)
450{ 449{
451 if ( qApp->type() == QApplication::GuiServer) { 450 if ( qApp->type() == QApplication::GuiServer) {
452 bool needSave = FALSE; 451 bool needSave = FALSE;
453 if ( timerEventReceiver != NULL ) { 452 if ( timerEventReceiver != NULL ) {
454 timerEventReceiver->killTimers(); 453 timerEventReceiver->killTimers();
455 454
456 // iterate over the list of events 455 // iterate over the list of events
457 QListIterator<timerEventItem> it( timerEventList ); 456 QListIterator<timerEventItem> it( timerEventList );
458 time_t deleteTime = TimeConversion::toUTC( when ); 457 time_t deleteTime = TimeConversion::toUTC( when );
459 for ( ; *it; ++it ) { 458 for ( ; *it; ++it ) {
460 // if its a match, delete it 459 // if its a match, delete it
461 if ( ( (*it)->UTCtime == deleteTime || when.isNull() ) 460 if ( ( (*it)->UTCtime == deleteTime || when.isNull() )
462 && ( channel.isNull() || (*it)->channel == channel ) 461 && ( channel.isNull() || (*it)->channel == channel )
463 && ( message.isNull() || (*it)->message == message ) 462 && ( message.isNull() || (*it)->message == message )
464 && ( data == -1 || (*it)->data == data ) ) { 463 && ( data == -1 || (*it)->data == data ) ) {
465 // if it's first, then we need to update the timer 464 // if it's first, then we need to update the timer
466 if ( (*it) == nearestTimerEvent ) { 465 if ( (*it) == nearestTimerEvent ) {
467 timerEventList.remove(*it); 466 timerEventList.remove(*it);
468 setNearestTimerEvent(); 467 setNearestTimerEvent();
469 } 468 }
470 else { 469 else {
471 timerEventList.remove(*it); 470 timerEventList.remove(*it);
472 } 471 }
473 needSave = TRUE; 472 needSave = TRUE;
474 } 473 }
475 } 474 }
476 if ( nearestTimerEvent ) 475 if ( nearestTimerEvent )
477 timerEventReceiver->resetTimer(); 476 timerEventReceiver->resetTimer();
478 } 477 }
479 if ( needSave ) 478 if ( needSave )
480 saveState(); 479 saveState();
481 } 480 }
482 else { 481 else {
483#ifndef QT_NO_COP 482#ifndef QT_NO_COP
484 QCopEnvelope e( "QPE/System", "deleteAlarm(QDateTime,QCString,QCString,int)" ); 483 QCopEnvelope e( "QPE/System", "deleteAlarm(QDateTime,QCString,QCString,int)" );
485 e << when << channel << message << data; 484 e << when << channel << message << data;
486#endif 485#endif
487 486
488 } 487 }
489} 488}
490 489
491/*! 490/*!
492 The implementation depends on the mode of AlarmServer. If the AlarmServer 491 The implementation depends on the mode of AlarmServer. If the AlarmServer
493 uses atd the current system time will be written to the hardware clock. 492 uses atd the current system time will be written to the hardware clock.
494 If the AlarmServer relies on opie-alarm the time will be written once the 493 If the AlarmServer relies on opie-alarm the time will be written once the
495 device gets suspended. opie-alarm is used by the Zaurus, iPAQs and SIMpad 494 device gets suspended. opie-alarm is used by the Zaurus, iPAQs and SIMpad
496*/ 495*/
497void Global::writeHWClock() 496void Global::writeHWClock()
498{ 497{
499#ifdef USE_ATD 498#ifdef USE_ATD
500 if ( !triggerAtd( TRUE ) ) { 499 if ( !triggerAtd( TRUE ) ) {
501 // atd not running? set it ourselves 500 // atd not running? set it ourselves
502 system("/sbin/hwclock --systohc"); // ##### UTC? 501 system("/sbin/hwclock --systohc"); // ##### UTC?
503 } 502 }
504#else 503#else
505 // hwclock is written on suspend 504 // hwclock is written on suspend
506#endif 505#endif
507} 506}
diff --git a/library/applnk.cpp b/library/applnk.cpp
index e9d519e..1c1a227 100644
--- a/library/applnk.cpp
+++ b/library/applnk.cpp
@@ -1,1496 +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/global.h>
30#include <qpe/qcopenvelope_qws.h> 31#include <qpe/qcopenvelope_qws.h>
31#include <qpe/mimetype.h> 32#include <qpe/mimetype.h>
32#include <qpe/config.h> 33#include <qpe/config.h>
33#include <qpe/storage.h> 34#include <qpe/storage.h>
34#include <qpe/resource.h> 35#include <qpe/resource.h>
35 36
36#include <qdir.h> 37#include <qdir.h>
37 38
38 39
39#include <stdlib.h> 40#include <stdlib.h>
40 41
41int AppLnk::lastId = 5000; 42int AppLnk::lastId = 5000;
42 43
43static int smallSize = 14; 44static int smallSize = 14;
44static int bigSize = 32; 45static int bigSize = 32;
45 46
46static QString safeFileName(const QString& n) 47static QString safeFileName(const QString& n)
47{ 48{
48 QString safename=n; 49 QString safename=n;
49 safename.replace(QRegExp("[^0-9A-Za-z.]"),"_"); 50 safename.replace(QRegExp("[^0-9A-Za-z.]"),"_");
50 safename.replace(QRegExp("^[^A-Za-z]*"),""); 51 safename.replace(QRegExp("^[^A-Za-z]*"),"");
51 if ( safename.isEmpty() ) 52 if ( safename.isEmpty() )
52 safename = "_"; 53 safename = "_";
53 return safename; 54 return safename;
54} 55}
55 56
56static bool prepareDirectories(const QString& lf) 57static bool prepareDirectories(const QString& lf)
57{ 58{
58 if ( !QFile::exists(lf) ) { 59 if ( !QFile::exists(lf) ) {
59 // May need to create directories 60 // May need to create directories
60 QFileInfo fi(lf); 61 QFileInfo fi(lf);
61 if ( system(("mkdir -p "+fi.dirPath(TRUE))) ) 62 if ( system(("mkdir -p "+fi.dirPath(TRUE))) )
62 return FALSE; 63 return FALSE;
63 } 64 }
64 return TRUE; 65 return TRUE;
65} 66}
66 67
67class AppLnkPrivate 68class AppLnkPrivate
68{ 69{
69public: 70public:
70 /* the size of the Pixmap */ 71 /* the size of the Pixmap */
71 enum Size {Normal = 0, Big }; 72 enum Size {Normal = 0, Big };
72 AppLnkPrivate() { 73 AppLnkPrivate() {
73 /* we want one normal and one big item */ 74 /* we want one normal and one big item */
74 75
75 QPixmap pix; 76 QPixmap pix;
76 mPixmaps.insert(0, pix ); 77 mPixmaps.insert(0, pix );
77 mPixmaps.insert(1, pix); 78 mPixmaps.insert(1, pix);
78 } 79 }
79 80
80 QStringList mCatList; // always correct 81 QStringList mCatList; // always correct
81 QArray<int> mCat; // cached value; correct if not empty 82 QArray<int> mCat; // cached value; correct if not empty
82 QMap<int, QPixmap> mPixmaps; 83 QMap<int, QPixmap> mPixmaps;
83 84
84 void updateCatListFromArray() 85 void updateCatListFromArray()
85 { 86 {
86 Categories cat( 0 ); 87 Categories cat( 0 );
87 cat.load( categoryFileName() ); 88 cat.load( categoryFileName() );
88 // we need to update the names for the mCat... to mCatList 89 // we need to update the names for the mCat... to mCatList
89 mCatList.clear(); 90 mCatList.clear();
90 for (uint i = 0; i < mCat.count(); i++ ) 91 for (uint i = 0; i < mCat.count(); i++ )
91 mCatList << cat.label("Document View", mCat[i] ); 92 mCatList << cat.label("Document View", mCat[i] );
92 93
93 } 94 }
94 95
95 void setCatArrayDirty() 96 void setCatArrayDirty()
96 { 97 {
97 mCat.resize(0); 98 mCat.resize(0);
98 } 99 }
99 100
100 void ensureCatArray() 101 void ensureCatArray()
101 { 102 {
102 if ( mCat.count() > 0 || mCatList.count()==0 ) 103 if ( mCat.count() > 0 || mCatList.count()==0 )
103 return; 104 return;
104 105
105 Categories cat( 0 ); 106 Categories cat( 0 );
106 cat.load( categoryFileName() ); 107 cat.load( categoryFileName() );
107 mCat.resize( mCatList.count() ); 108 mCat.resize( mCatList.count() );
108 int i; 109 int i;
109 QStringList::ConstIterator it; 110 QStringList::ConstIterator it;
110 for ( i = 0, it = mCatList.begin(); it != mCatList.end(); 111 for ( i = 0, it = mCatList.begin(); it != mCatList.end();
111 ++it, i++ ) { 112 ++it, i++ ) {
112 113
113 bool number; 114 bool number;
114 int id = (*it).toInt( &number ); 115 int id = (*it).toInt( &number );
115 if ( !number ) { 116 if ( !number ) {
116 id = cat.id( "Document View", *it ); 117 id = cat.id( "Document View", *it );
117 if ( id == 0 ) 118 if ( id == 0 )
118 id = cat.addCategory( "Document View", *it ); 119 id = cat.addCategory( "Document View", *it );
119 } 120 }
120 mCat[i] = id; 121 mCat[i] = id;
121 } 122 }
122 } 123 }
123}; 124};
124 125
125/*! 126/*!
126 \class AppLnk applnk.h 127 \class AppLnk applnk.h
127 \brief The AppLnk class represents an application available on the system. 128 \brief The AppLnk class represents an application available on the system.
128 129
129 Every Qtopia application \e app has a corresponding \e app.desktop 130 Every Qtopia application \e app has a corresponding \e app.desktop
130 file. When one of these files is read its data is stored as an 131 file. When one of these files is read its data is stored as an
131 AppLnk object. 132 AppLnk object.
132 133
133 The AppLnk class introduces some Qtopia-specific concepts, and 134 The AppLnk class introduces some Qtopia-specific concepts, and
134 provides a variety of functions, as described in the following 135 provides a variety of functions, as described in the following
135 sections. 136 sections.
136 \tableofcontents 137 \tableofcontents
137 138
138 \target Types 139 \target Types
139 \section1 Types 140 \section1 Types
140 141
141 Every AppLnk object has a \e type. For applications, games and 142 Every AppLnk object has a \e type. For applications, games and
142 settings the type is \c Application; for documents the 143 settings the type is \c Application; for documents the
143 type is the document's MIME type. 144 type is the document's MIME type.
144 145
145 \target files-and-links 146 \target files-and-links
146 \section1 Files and Links 147 \section1 Files and Links
147 148
148 When you create an AppLnk (or more likely, a \link doclnk.html 149 When you create an AppLnk (or more likely, a \link doclnk.html
149 DocLnk\endlink), you don't deal directly with filenames in the 150 DocLnk\endlink), you don't deal directly with filenames in the
150 filesystem. Instead you do this: 151 filesystem. Instead you do this:
151 \code 152 \code
152 DocLnk d; 153 DocLnk d;
153 d.setType("text/plain"); 154 d.setType("text/plain");
154 d.setName("My Nicely Named Document / Whatever"); // Yes, "/" is legal. 155 d.setName("My Nicely Named Document / Whatever"); // Yes, "/" is legal.
155 \endcode 156 \endcode
156 At this point, the file() and linkFile() are unknown. Normally 157 At this point, the file() and linkFile() are unknown. Normally
157 this is uninteresting, and the names become automatically known, 158 this is uninteresting, and the names become automatically known,
158 and more importantly, becomes reserved, when you ask what they are: 159 and more importantly, becomes reserved, when you ask what they are:
159 160
160 \code 161 \code
161 QString fn = d.file(); 162 QString fn = d.file();
162 \endcode 163 \endcode
163 This invents a filename, and creates the file on disk (an empty 164 This invents a filename, and creates the file on disk (an empty
164 reservation file) to prevent the name being used by another 165 reservation file) to prevent the name being used by another
165 application. 166 application.
166 167
167 In some circumstances, you don't want to create the file if it 168 In some circumstances, you don't want to create the file if it
168 doesn't already exist (e.g. in the Document tab, some of the \link 169 doesn't already exist (e.g. in the Document tab, some of the \link
169 doclnk.html DocLnk\endlink objects represented by icons are 170 doclnk.html DocLnk\endlink objects represented by icons are
170 DocLnk's created just for that view - they don't have 171 DocLnk's created just for that view - they don't have
171 corresponding \c .desktop files. To avoid littering empty 172 corresponding \c .desktop files. To avoid littering empty
172 reservation files around, we check in a few places to see whether 173 reservation files around, we check in a few places to see whether
173 the file really needs to exist). 174 the file really needs to exist).
174 175
175 \section1 Functionality 176 \section1 Functionality
176 177
177 AppLnk objects are created by calling the constructor with the 178 AppLnk objects are created by calling the constructor with the
178 name of a \e .desktop file. The object can be checked for validity 179 name of a \e .desktop file. The object can be checked for validity
179 using isValid(). 180 using isValid().
180 181
181 The following functions are used to set or retrieve information 182 The following functions are used to set or retrieve information
182 about the application: 183 about the application:
183 \table 184 \table
184 \header \i Get Function \i Set Function \i Short Description 185 \header \i Get Function \i Set Function \i Short Description
185 \row \i \l name() \i \l setName() \i application's name 186 \row \i \l name() \i \l setName() \i application's name
186 \row \i \l pixmap() \i \e none \i application's icon 187 \row \i \l pixmap() \i \e none \i application's icon
187 \row \i \l bigPixmap() \i \e none \i application's large icon 188 \row \i \l bigPixmap() \i \e none \i application's large icon
188 \row \i \e none \i setIcon() \i sets the icon's filename 189 \row \i \e none \i setIcon() \i sets the icon's filename
189 \row \i \l type() \i \l setType() \i see \link #Types Types\endlink above 190 \row \i \l type() \i \l setType() \i see \link #Types Types\endlink above
190 \row \i \l rotation() \i \e none \i 0, 90, 180 or 270 degrees 191 \row \i \l rotation() \i \e none \i 0, 90, 180 or 270 degrees
191 \row \i \l comment() \i \l setComment() \i text for the Details dialog 192 \row \i \l comment() \i \l setComment() \i text for the Details dialog
192 \row \i \l exec() \i \l setExec() \i executable's filename 193 \row \i \l exec() \i \l setExec() \i executable's filename
193 \row \i \l file() \i \e none \i document's filename 194 \row \i \l file() \i \e none \i document's filename
194 \row \i \l linkFile() \i \l setLinkFile() \i \e .desktop filename 195 \row \i \l linkFile() \i \l setLinkFile() \i \e .desktop filename
195 \row \i \l mimeTypes() \i \e none \i the mime types the application can view or edit 196 \row \i \l mimeTypes() \i \e none \i the mime types the application can view or edit
196 \row \i \l categories() \i \l setCategories() \i \e{see the function descriptions} 197 \row \i \l categories() \i \l setCategories() \i \e{see the function descriptions}
197 \row \i \l fileKnown() \i \e none \i see \link 198 \row \i \l fileKnown() \i \e none \i see \link
198#files-and-links Files and Links\endlink above 199#files-and-links Files and Links\endlink above
199 \row \i \l linkFileKnown() \i \e none \i see \link 200 \row \i \l linkFileKnown() \i \e none \i see \link
200#files-and-links Files and Links\endlink above 201#files-and-links Files and Links\endlink above
201 \row \i \l property() \i \l setProperty() \i any AppLnk property 202 \row \i \l property() \i \l setProperty() \i any AppLnk property
202 can be retrieved or set (if writeable) using these 203 can be retrieved or set (if writeable) using these
203 \endtable 204 \endtable
204 205
205 To save an AppLnk to disk use writeLink(). To execute the 206 To save an AppLnk to disk use writeLink(). To execute the
206 application that the AppLnk object refers to, use execute(). 207 application that the AppLnk object refers to, use execute().
207 208
208 AppLnk's can be deleted from disk using removeLinkFile(). To 209 AppLnk's can be deleted from disk using removeLinkFile(). To
209 remove both the link and the application's executable use 210 remove both the link and the application's executable use
210 removeFiles(). 211 removeFiles().
211 212
212 Icon sizes can be globally changed (but only for AppLnk objects 213 Icon sizes can be globally changed (but only for AppLnk objects
213 created after the calls) with setSmallIconSize() and 214 created after the calls) with setSmallIconSize() and
214 setBigIconSize(). 215 setBigIconSize().
215 216
216 \ingroup qtopiaemb 217 \ingroup qtopiaemb
217*/ 218*/
218 219
219/*! 220/*!
220 Sets the size used for small icons to \a small pixels. 221 Sets the size used for small icons to \a small pixels.
221 Only affects AppLnk objects created after the call. 222 Only affects AppLnk objects created after the call.
222 223
223 \sa smallIconSize() setIcon() 224 \sa smallIconSize() setIcon()
224*/ 225*/
225void AppLnk::setSmallIconSize(int small) 226void AppLnk::setSmallIconSize(int small)
226{ 227{
227 smallSize = small; 228 smallSize = small;
228} 229}
229 230
230/*! 231/*!
231 Returns the size used for small icons. 232 Returns the size used for small icons.
232 233
233 \sa setSmallIconSize() setIcon() 234 \sa setSmallIconSize() setIcon()
234*/ 235*/
235int AppLnk::smallIconSize() 236int AppLnk::smallIconSize()
236{ 237{
237 return smallSize; 238 return smallSize;
238} 239}
239 240
240 241
241/*! 242/*!
242 Sets the size used for large icons to \a big pixels. 243 Sets the size used for large icons to \a big pixels.
243 Only affects AppLnk objects created after the call. 244 Only affects AppLnk objects created after the call.
244 245
245 \sa bigIconSize() setIcon() 246 \sa bigIconSize() setIcon()
246*/ 247*/
247void AppLnk::setBigIconSize(int big) 248void AppLnk::setBigIconSize(int big)
248{ 249{
249 bigSize = big; 250 bigSize = big;
250} 251}
251 252
252/*! 253/*!
253 Returns the size used for large icons. 254 Returns the size used for large icons.
254 255
255 \sa setBigIconSize() setIcon() 256 \sa setBigIconSize() setIcon()
256*/ 257*/
257int AppLnk::bigIconSize() 258int AppLnk::bigIconSize()
258{ 259{
259 return bigSize; 260 return bigSize;
260} 261}
261 262
262 263
263/*! 264/*!
264 \fn QString AppLnk::name() const 265 \fn QString AppLnk::name() const
265 266
266 Returns the Name property. This is the user-visible name for the 267 Returns the Name property. This is the user-visible name for the
267 document or application, not the filename. 268 document or application, not the filename.
268 269
269 See \link #files-and-links Files and Links\endlink. 270 See \link #files-and-links Files and Links\endlink.
270 271
271 \sa setName() 272 \sa setName()
272*/ 273*/
273/*! 274/*!
274 \fn QString AppLnk::exec() const 275 \fn QString AppLnk::exec() const
275 276
276 Returns the Exec property. This is the name of the executable 277 Returns the Exec property. This is the name of the executable
277 program associated with the AppLnk. 278 program associated with the AppLnk.
278 279
279 \sa setExec() 280 \sa setExec()
280*/ 281*/
281/*! 282/*!
282 \fn QString AppLnk::rotation() const 283 \fn QString AppLnk::rotation() const
283 284
284 Returns the Rotation property. The value is 0, 90, 180 or 270 285 Returns the Rotation property. The value is 0, 90, 180 or 270
285 degrees. 286 degrees.
286*/ 287*/
287/*! 288/*!
288 \fn QString AppLnk::comment() const 289 \fn QString AppLnk::comment() const
289 290
290 Returns the Comment property. 291 Returns the Comment property.
291 292
292 \sa setComment() 293 \sa setComment()
293*/ 294*/
294/*! 295/*!
295 \fn QStringList AppLnk::mimeTypes() const 296 \fn QStringList AppLnk::mimeTypes() const
296 297
297 Returns the MimeTypes property. This is the list of MIME types 298 Returns the MimeTypes property. This is the list of MIME types
298 that the application can view or edit. 299 that the application can view or edit.
299*/ 300*/
300/*! 301/*!
301 \fn const QArray<int>& AppLnk::categories() const 302 \fn const QArray<int>& AppLnk::categories() const
302 303
303 Returns the Categories property. 304 Returns the Categories property.
304 305
305 See the CategoryWidget for more details. 306 See the CategoryWidget for more details.
306 307
307 \sa setCategories() 308 \sa setCategories()
308*/ 309*/
309 310
310const QArray<int>& AppLnk::categories() const 311const QArray<int>& AppLnk::categories() const
311{ 312{
312 d->ensureCatArray(); 313 d->ensureCatArray();
313 return d->mCat; 314 return d->mCat;
314} 315}
315 316
316/*! 317/*!
317 \fn int AppLnk::id() const 318 \fn int AppLnk::id() const
318 319
319 Returns the id of the AppLnk. If the AppLnk is not in an AppLnkSet, 320 Returns the id of the AppLnk. If the AppLnk is not in an AppLnkSet,
320 this value is 0, otherwise it is a value that is unique for the 321 this value is 0, otherwise it is a value that is unique for the
321 duration of the current process. 322 duration of the current process.
322 323
323 \sa AppLnkSet::find() 324 \sa AppLnkSet::find()
324*/ 325*/
325 326
326/*! 327/*!
327 \fn bool AppLnk::isValid() const 328 \fn bool AppLnk::isValid() const
328 329
329 Returns TRUE if this AppLnk is valid; otherwise returns FALSE. 330 Returns TRUE if this AppLnk is valid; otherwise returns FALSE.
330*/ 331*/
331/*! 332/*!
332 \fn bool AppLnk::fileKnown() const 333 \fn bool AppLnk::fileKnown() const
333 334
334 If the with the AppLnk associated file is not equal to QString::null 335 If the with the AppLnk associated file is not equal to QString::null
335*/ 336*/
336/*! 337/*!
337 \fn bool AppLnk::linkFileKnown()const 338 \fn bool AppLnk::linkFileKnown()const
338 339
339 The filename of the AppLnk 340 The filename of the AppLnk
340 341
341*/ 342*/
342/*! 343/*!
343 \fn void AppLnk::setRotation( const QString& ) 344 \fn void AppLnk::setRotation( const QString& )
344 345
345 The default rotation of the associated application. This 346 The default rotation of the associated application. This
346 function is included inline for binary compatible issues 347 function is included inline for binary compatible issues
347*/ 348*/
348/*! 349/*!
349 Creates an invalid AppLnk. 350 Creates an invalid AppLnk.
350 351
351 \sa isValid() 352 \sa isValid()
352*/ 353*/
353AppLnk::AppLnk() 354AppLnk::AppLnk()
354{ 355{
355 mId = 0; 356 mId = 0;
356 d = new AppLnkPrivate(); 357 d = new AppLnkPrivate();
357} 358}
358 359
359/*! 360/*!
360 Loads \a file (e.g. \e app.desktop) as an AppLnk. 361 Loads \a file (e.g. \e app.desktop) as an AppLnk.
361 362
362 \sa writeLink() 363 \sa writeLink()
363*/ 364*/
364AppLnk::AppLnk( const QString &file ) 365AppLnk::AppLnk( const QString &file )
365{ 366{
366 QStringList sl; 367 QStringList sl;
367 d = new AppLnkPrivate(); 368 d = new AppLnkPrivate();
368 if ( !file.isNull() ) { 369 if ( !file.isNull() ) {
369 Config config( file, Config::File ); 370 Config config( file, Config::File );
370 371
371 if ( config.isValid() ) { 372 if ( config.isValid() ) {
372 config.setGroup( "Desktop Entry" ); 373 config.setGroup( "Desktop Entry" );
373 374
374 mName = config.readEntry( "Name", file ); 375 mName = config.readEntry( "Name", file );
375 mExec = config.readEntry( "Exec" ); 376 mExec = config.readEntry( "Exec" );
376 mType = config.readEntry( "Type", QString::null ); 377 mType = config.readEntry( "Type", QString::null );
377 mIconFile = config.readEntry( "Icon", QString::null ); 378 mIconFile = config.readEntry( "Icon", QString::null );
378 mRotation = config.readEntry( "Rotation", "" ); 379 mRotation = config.readEntry( "Rotation", "" );
379 mComment = config.readEntry( "Comment", QString::null ); 380 mComment = config.readEntry( "Comment", QString::null );
380 // MIME types are case-insensitive. 381 // MIME types are case-insensitive.
381 mMimeTypes = config.readListEntry( "MimeType", ';' ); 382 mMimeTypes = config.readListEntry( "MimeType", ';' );
382 for (QStringList::Iterator it=mMimeTypes.begin(); it!=mMimeTypes.end(); ++it) 383 for (QStringList::Iterator it=mMimeTypes.begin(); it!=mMimeTypes.end(); ++it)
383 *it = (*it).lower(); 384 *it = (*it).lower();
384 mMimeTypeIcons = config.readListEntry( "MimeTypeIcons", ';' ); 385 mMimeTypeIcons = config.readListEntry( "MimeTypeIcons", ';' );
385 mLinkFile = file; 386 mLinkFile = file;
386 mFile = config.readEntry("File", QString::null); 387 mFile = config.readEntry("File", QString::null);
387 if ( !mExec. isEmpty ( )) { 388 if ( !mExec. isEmpty ( )) {
388 mFile = QString::null; 389 mFile = QString::null;
389 } 390 }
390 else if ( mFile[0] != '/' ) { 391 else if ( mFile[0] != '/' ) {
391 int slash = file.findRev('/'); 392 int slash = file.findRev('/');
392 if ( slash >= 0 ) { 393 if ( slash >= 0 ) {
393 mFile = file.left(slash) + '/' + mFile; 394 mFile = file.left(slash) + '/' + mFile;
394 } 395 }
395 } 396 }
396 d->mCatList = config.readListEntry("Categories", ';'); 397 d->mCatList = config.readListEntry("Categories", ';');
397 if ( d->mCatList[0].toInt() < -1 ) { 398 if ( d->mCatList[0].toInt() < -1 ) {
398 // numeric cats in file! convert to text 399 // numeric cats in file! convert to text
399 Categories cat( 0 ); 400 Categories cat( 0 );
400 cat.load( categoryFileName() ); 401 cat.load( categoryFileName() );
401 d->mCat.resize( d->mCatList.count() ); 402 d->mCat.resize( d->mCatList.count() );
402 int i; 403 int i;
403 QStringList::ConstIterator it; 404 QStringList::ConstIterator it;
404 for ( i = 0, it = d->mCatList.begin(); it != d->mCatList.end(); 405 for ( i = 0, it = d->mCatList.begin(); it != d->mCatList.end();
405 ++it, i++ ) { 406 ++it, i++ ) {
406 bool number; 407 bool number;
407 int id = (*it).toInt( &number ); 408 int id = (*it).toInt( &number );
408 if ( !number ) { 409 if ( !number ) {
409 // convert from text 410 // convert from text
410 id = cat.id( "Document View", *it ); 411 id = cat.id( "Document View", *it );
411 if ( id == 0 ) 412 if ( id == 0 )
412 id = cat.addCategory( "Document View", *it ); 413 id = cat.addCategory( "Document View", *it );
413 } 414 }
414 d->mCat[i] = id; 415 d->mCat[i] = id;
415 } 416 }
416 d->updateCatListFromArray(); 417 d->updateCatListFromArray();
417 } 418 }
418 } 419 }
419 } 420 }
420 mId = 0; 421 mId = 0;
421} 422}
422 423
423AppLnk& AppLnk::operator=(const AppLnk &copy) 424AppLnk& AppLnk::operator=(const AppLnk &copy)
424{ 425{
425 if ( this == &copy ) return *this; 426 if ( this == &copy ) return *this;
426 if ( mId ) 427 if ( mId )
427 qWarning("Deleting AppLnk that is in an AppLnkSet"); 428 qWarning("Deleting AppLnk that is in an AppLnkSet");
428 if ( d ) 429 if ( d )
429 delete d; 430 delete d;
430 431
431 432
432 mName = copy.mName; 433 mName = copy.mName;
433 434
434 /* remove for Qtopia 3.0 -zecke */ 435 /* remove for Qtopia 3.0 -zecke */
435 mPixmap = copy.mPixmap; 436 mPixmap = copy.mPixmap;
436 mBigPixmap = copy.mBigPixmap; 437 mBigPixmap = copy.mBigPixmap;
437 438
438 mExec = copy.mExec; 439 mExec = copy.mExec;
439 mType = copy.mType; 440 mType = copy.mType;
440 mRotation = copy.mRotation; 441 mRotation = copy.mRotation;
441 mComment = copy.mComment; 442 mComment = copy.mComment;
442 mFile = copy.mFile; 443 mFile = copy.mFile;
443 mLinkFile = copy.mLinkFile; 444 mLinkFile = copy.mLinkFile;
444 mIconFile = copy.mIconFile; 445 mIconFile = copy.mIconFile;
445 mMimeTypes = copy.mMimeTypes; 446 mMimeTypes = copy.mMimeTypes;
446 mMimeTypeIcons = copy.mMimeTypeIcons; 447 mMimeTypeIcons = copy.mMimeTypeIcons;
447 mId = 0; 448 mId = 0;
448 d = new AppLnkPrivate(); 449 d = new AppLnkPrivate();
449 d->mCat = copy.d->mCat; 450 d->mCat = copy.d->mCat;
450 d->mCatList = copy.d->mCatList; 451 d->mCatList = copy.d->mCatList;
451 d->mPixmaps = copy.d->mPixmaps; 452 d->mPixmaps = copy.d->mPixmaps;
452 453
453 return *this; 454 return *this;
454} 455}
455/*! 456/*!
456 protected internally to share code 457 protected internally to share code
457 should I document that at all? 458 should I document that at all?
458 I don't know the TT style for that 459 I don't know the TT style for that
459*/ 460*/
460const QPixmap& AppLnk::pixmap( int pos, int size ) const { 461const QPixmap& AppLnk::pixmap( int pos, int size ) const {
461 if ( d->mPixmaps[pos].isNull() ) { 462 if ( d->mPixmaps[pos].isNull() ) {
462 AppLnk* that = (AppLnk*)this; 463 AppLnk* that = (AppLnk*)this;
463 if ( mIconFile.isEmpty() ) { 464 if ( mIconFile.isEmpty() ) {
464 MimeType mt(type()); 465 MimeType mt(type());
465 that->d->mPixmaps[pos] = pos ? mt.bigPixmap() : mt.pixmap(); 466 that->d->mPixmaps[pos] = pos ? mt.bigPixmap() : mt.pixmap();
466 if ( that->d->mPixmaps[pos].isNull() ) 467 if ( that->d->mPixmaps[pos].isNull() )
467 that->d->mPixmaps[pos].convertFromImage( 468 that->d->mPixmaps[pos].convertFromImage(
468 Resource::loadImage("UnknownDocument") 469 Resource::loadImage("UnknownDocument")
469 .smoothScale( size, size ) ); 470 .smoothScale( size, size ) );
470 return that->d->mPixmaps[pos]; 471 return that->d->mPixmaps[pos];
471 } 472 }
472 QImage unscaledIcon = Resource::loadImage( that->mIconFile ); 473 QImage unscaledIcon = Resource::loadImage( that->mIconFile );
473 if ( unscaledIcon.isNull() ) { 474 if ( unscaledIcon.isNull() ) {
474 // qDebug( "Cannot find icon: %s", that->mIconFile.latin1() ); 475 // qDebug( "Cannot find icon: %s", that->mIconFile.latin1() );
475 that->d->mPixmaps[pos].convertFromImage( 476 that->d->mPixmaps[pos].convertFromImage(
476 Resource::loadImage("UnknownDocument") 477 Resource::loadImage("UnknownDocument")
477 .smoothScale( size, size ) ); 478 .smoothScale( size, size ) );
478 } else { 479 } else {
479 that->d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) ); 480 that->d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
480 that->d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) ); 481 that->d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
481 } 482 }
482 return that->d->mPixmaps[pos]; 483 return that->d->mPixmaps[pos];
483 } 484 }
484 return d->mPixmaps[pos]; 485 return d->mPixmaps[pos];
485} 486}
486 487
487/*! 488/*!
488 Returns a small pixmap associated with the application. 489 Returns a small pixmap associated with the application.
489 490
490 \sa bigPixmap() setIcon() 491 \sa bigPixmap() setIcon()
491*/ 492*/
492const QPixmap& AppLnk::pixmap() const 493const QPixmap& AppLnk::pixmap() const
493{ 494{
494 if ( d->mPixmaps[0].isNull() ) { 495 if ( d->mPixmaps[0].isNull() ) {
495 return pixmap(AppLnkPrivate::Normal, smallSize ); 496 return pixmap(AppLnkPrivate::Normal, smallSize );
496 } 497 }
497 return d->mPixmaps[0]; 498 return d->mPixmaps[0];
498} 499}
499 500
500/*! 501/*!
501 Returns a large pixmap associated with the application. 502 Returns a large pixmap associated with the application.
502 503
503 \sa pixmap() setIcon() 504 \sa pixmap() setIcon()
504*/ 505*/
505const QPixmap& AppLnk::bigPixmap() const 506const QPixmap& AppLnk::bigPixmap() const
506{ 507{
507 if ( d->mPixmaps[1].isNull() ) { 508 if ( d->mPixmaps[1].isNull() ) {
508 return pixmap( AppLnkPrivate::Big, bigSize ); 509 return pixmap( AppLnkPrivate::Big, bigSize );
509 } 510 }
510 return d->mPixmaps[1]; 511 return d->mPixmaps[1];
511} 512}
512 513
513/*! 514/*!
514 Returns the type of the AppLnk. For applications, games and 515 Returns the type of the AppLnk. For applications, games and
515 settings the type is \c Application; for documents the type is the 516 settings the type is \c Application; for documents the type is the
516 document's MIME type. 517 document's MIME type.
517*/ 518*/
518QString AppLnk::type() const 519QString AppLnk::type() const
519{ 520{
520 if ( mType.isNull() ) { 521 if ( mType.isNull() ) {
521 AppLnk* that = (AppLnk*)this; 522 AppLnk* that = (AppLnk*)this;
522 QString f = file(); 523 QString f = file();
523 if ( !f.isNull() ) { 524 if ( !f.isNull() ) {
524 MimeType mt(f); 525 MimeType mt(f);
525 that->mType = mt.id(); 526 that->mType = mt.id();
526 return that->mType; 527 return that->mType;
527 } 528 }
528 } 529 }
529 return mType; 530 return mType;
530} 531}
531 532
532/*! 533/*!
533 Returns the file associated with the AppLnk. 534 Returns the file associated with the AppLnk.
534 535
535 \sa exec() name() 536 \sa exec() name()
536*/ 537*/
537QString AppLnk::file() const 538QString AppLnk::file() const
538{ 539{
539 if ( mExec.isEmpty ( ) && mFile.isNull() ) { 540 if ( mExec.isEmpty ( ) && mFile.isNull() ) {
540 AppLnk* that = (AppLnk*)this; 541 AppLnk* that = (AppLnk*)this;
541 QString ext = MimeType(mType).extension(); 542 QString ext = MimeType(mType).extension();
542 if ( !ext.isEmpty() ) 543 if ( !ext.isEmpty() )
543 ext = "." + ext; 544 ext = "." + ext;
544 if ( !mLinkFile.isEmpty() ) { 545 if ( !mLinkFile.isEmpty() ) {
545 that->mFile = 546 that->mFile =
546 mLinkFile.right(8)==".desktop" // 8 = strlen(".desktop") 547 mLinkFile.right(8)==".desktop" // 8 = strlen(".desktop")
547 ? mLinkFile.left(mLinkFile.length()-8) : mLinkFile; 548 ? mLinkFile.left(mLinkFile.length()-8) : mLinkFile;
548 qDebug("mFile now == %s", mFile.latin1()); 549 qDebug("mFile now == %s", mFile.latin1());
549 } else if ( mType.contains('/') ) { 550 } else if ( mType.contains('/') ) {
550 that->mFile = 551 that->mFile =
551 QString(getenv("HOME"))+"/Documents/"+mType+"/"+safeFileName(that->mName); 552 QString(getenv("HOME"))+"/Documents/"+mType+"/"+safeFileName(that->mName);
552 /* 553 /*
553 * A file with the same name or a .desktop file already exists 554 * A file with the same name or a .desktop file already exists
554 */ 555 */
555 if ( QFile::exists(that->mFile+ext) || QFile::exists(that->mFile+".desktop") ) { 556 if ( QFile::exists(that->mFile+ext) || QFile::exists(that->mFile+".desktop") ) {
556 int n=1; 557 int n=1;
557 QString nn; 558 QString nn;
558 while (QFile::exists((nn=(that->mFile+"_"+QString::number(n)))+ext) 559 while (QFile::exists((nn=(that->mFile+"_"+QString::number(n)))+ext)
559 || QFile::exists(nn+".desktop")) 560 || QFile::exists(nn+".desktop"))
560 n++; 561 n++;
561 that->mFile = nn; 562 that->mFile = nn;
562 } 563 }
563 that->mLinkFile = that->mFile+".desktop"; 564 that->mLinkFile = that->mFile+".desktop";
564 that->mFile += ext; 565 that->mFile += ext;
565 } 566 }
566 prepareDirectories(that->mFile); 567 prepareDirectories(that->mFile);
567 if ( !that->mFile.isEmpty() ) { 568 if ( !that->mFile.isEmpty() ) {
568 QFile f(that->mFile); 569 QFile f(that->mFile);
569 if ( !f.open(IO_WriteOnly) ) 570 if ( !f.open(IO_WriteOnly) )
570 that->mFile = QString::null; 571 that->mFile = QString::null;
571 return that->mFile; 572 return that->mFile;
572 } 573 }
573 } 574 }
574 return mFile; 575 return mFile;
575} 576}
576 577
577/*! 578/*!
578 Returns the desktop file corresponding to this AppLnk. 579 Returns the desktop file corresponding to this AppLnk.
579 580
580 \sa file() exec() name() 581 \sa file() exec() name()
581*/ 582*/
582QString AppLnk::linkFile() const 583QString AppLnk::linkFile() const
583{ 584{
584 if ( mLinkFile.isNull() ) { 585 if ( mLinkFile.isNull() ) {
585 AppLnk* that = (AppLnk*)this; 586 AppLnk* that = (AppLnk*)this;
586 if ( type().contains('/') ) { 587 if ( type().contains('/') ) {
587 StorageInfo storage; 588 StorageInfo storage;
588 const FileSystem *fs = storage.fileSystemOf( that->mFile ); 589 const FileSystem *fs = storage.fileSystemOf( that->mFile );
589 /* tmpfs + and ramfs are available too but not removable 590 /* tmpfs + and ramfs are available too but not removable
590 * either we fix storage or add this 591 * either we fix storage or add this
591 */ 592 */
592 if ( fs && ( fs->isRemovable() || fs->disk() == "/dev/mtdblock6" || fs->disk() == "tmpfs") ) { 593 if ( fs && ( fs->isRemovable() || fs->disk() == "/dev/mtdblock6" || fs->disk() == "tmpfs") ) {
593 that->mLinkFile = fs->path(); 594 that->mLinkFile = fs->path();
594 } else 595 } else
595 that->mLinkFile = getenv( "HOME" ); 596 that->mLinkFile = getenv( "HOME" );
596 that->mLinkFile += "/Documents/"+type()+"/"+safeFileName(that->mName); 597 that->mLinkFile += "/Documents/"+type()+"/"+safeFileName(that->mName);
597 598
598 /* the desktop file exists make sure we don't point to the same file */ 599 /* the desktop file exists make sure we don't point to the same file */
599 if ( QFile::exists(that->mLinkFile+".desktop") ) { 600 if ( QFile::exists(that->mLinkFile+".desktop") ) {
600 AppLnk lnk( that->mLinkFile + ".desktop" ); 601 AppLnk lnk( that->mLinkFile + ".desktop" );
601 602
602 /* the linked is different */ 603 /* the linked is different */
603 if(that->file() != lnk.file() ) { 604 if(that->file() != lnk.file() ) {
604 int n = 1; 605 int n = 1;
605 QString nn; 606 QString nn;
606 while (QFile::exists((nn=that->mLinkFile+"_"+QString::number(n))+".desktop")) { 607 while (QFile::exists((nn=that->mLinkFile+"_"+QString::number(n))+".desktop")) {
607 n++; 608 n++;
608 /* just to be sure */ 609 /* just to be sure */
609 AppLnk lnk(nn ); 610 AppLnk lnk(nn );
610 if (lnk.file() == that->file() ) 611 if (lnk.file() == that->file() )
611 break; 612 break;
612 } 613 }
613 that->mLinkFile = nn; 614 that->mLinkFile = nn;
614 } 615 }
615 } 616 }
616 that->mLinkFile += ".desktop"; 617 that->mLinkFile += ".desktop";
617 storeLink(); 618 storeLink();
618 } 619 }
619 return that->mLinkFile; 620 return that->mLinkFile;
620 } 621 }
621 return mLinkFile; 622 return mLinkFile;
622} 623}
623 624
624/*! 625/*!
625 Copies \a copy. 626 Copies \a copy.
626*/ 627*/
627AppLnk::AppLnk( const AppLnk &copy ) 628AppLnk::AppLnk( const AppLnk &copy )
628{ 629{
629 mName = copy.mName; 630 mName = copy.mName;
630 mPixmap = copy.mPixmap; 631 mPixmap = copy.mPixmap;
631 mBigPixmap = copy.mBigPixmap; 632 mBigPixmap = copy.mBigPixmap;
632 mExec = copy.mExec; 633 mExec = copy.mExec;
633 mType = copy.mType; 634 mType = copy.mType;
634 mRotation = copy.mRotation; 635 mRotation = copy.mRotation;
635 mComment = copy.mComment; 636 mComment = copy.mComment;
636 mFile = copy.mFile; 637 mFile = copy.mFile;
637 mLinkFile = copy.mLinkFile; 638 mLinkFile = copy.mLinkFile;
638 mIconFile = copy.mIconFile; 639 mIconFile = copy.mIconFile;
639 mMimeTypes = copy.mMimeTypes; 640 mMimeTypes = copy.mMimeTypes;
640 mMimeTypeIcons = copy.mMimeTypeIcons; 641 mMimeTypeIcons = copy.mMimeTypeIcons;
641 mId = 0; 642 mId = 0;
642 d = new AppLnkPrivate(); 643 d = new AppLnkPrivate();
643 d->mCat = copy.d->mCat; 644 d->mCat = copy.d->mCat;
644 d->mCatList = copy.d->mCatList; 645 d->mCatList = copy.d->mCatList;
645 d->mPixmaps = copy.d->mPixmaps; 646 d->mPixmaps = copy.d->mPixmaps;
646} 647}
647 648
648/*! 649/*!
649 Destroys the AppLnk. Note that if the AppLnk is currently a member 650 Destroys the AppLnk. Note that if the AppLnk is currently a member
650 of an AppLnkSet, this will produce a run-time warning. 651 of an AppLnkSet, this will produce a run-time warning.
651 652
652 \sa AppLnkSet::add() AppLnkSet::remove() 653 \sa AppLnkSet::add() AppLnkSet::remove()
653*/ 654*/
654AppLnk::~AppLnk() 655AppLnk::~AppLnk()
655{ 656{
656 if ( mId ) 657 if ( mId )
657 qWarning("Deleting AppLnk that is in an AppLnkSet"); 658 qWarning("Deleting AppLnk that is in an AppLnkSet");
658 if ( d ) 659 if ( d )
659 delete d; 660 delete d;
660} 661}
661 662
662/*! 663/*!
663 \overload 664 \overload
664 Executes the application associated with this AppLnk. 665 Executes the application associated with this AppLnk.
665 666
666 \sa exec() 667 \sa exec()
667*/ 668*/
668void AppLnk::execute() const 669void AppLnk::execute() const
669{ 670{
670 execute( QStringList::split( ' ', property( "Arguments" ) ) ); 671 execute( QStringList::split( ' ', property( "Arguments" ) ) );
671} 672}
672 673
673/*! 674/*!
674 Executes the application associated with this AppLnk, with 675 Executes the application associated with this AppLnk, with
675 \a args as arguments. 676 \a args as arguments.
676 677
677 \sa exec() 678 \sa exec()
678*/ 679*/
679void AppLnk::execute(const QStringList& args) const 680void AppLnk::execute(const QStringList& args) const
680{ 681{
681#ifdef Q_WS_QWS 682#ifdef Q_WS_QWS
682 if ( !mRotation.isEmpty() ) { 683 if ( !mRotation.isEmpty() ) {
683 // ######## this will only work in the server 684 // ######## this will only work in the server
684 int rot = QPEApplication::defaultRotation(); 685 int rot = QPEApplication::defaultRotation();
685 rot = (rot+mRotation.toInt())%360; 686 rot = (rot+mRotation.toInt())%360;
686 QCString old = getenv("QWS_DISPLAY"); 687 QCString old = getenv("QWS_DISPLAY");
687 setenv("QWS_DISPLAY", QString("Transformed:Rot%1:0").arg(rot), 1); 688 setenv("QWS_DISPLAY", QString("Transformed:Rot%1:0").arg(rot), 1);
688 invoke(args); 689 invoke(args);
689 setenv("QWS_DISPLAY", old.data(), 1); 690 setenv("QWS_DISPLAY", old.data(), 1);
690 } else 691 } else
691#endif 692#endif
692 invoke(args); 693 invoke(args);
693} 694}
694 695
695/*! 696/*!
696 Invokes the application associated with this AppLnk, with 697 Invokes the application associated with this AppLnk, with
697 \a args as arguments. Rotation is not taken into account by 698 \a args as arguments. Rotation is not taken into account by
698 this function, so you should not call it directly. 699 this function, so you should not call it directly.
699 700
700 \sa execute() 701 \sa execute()
701*/ 702*/
702void AppLnk::invoke(const QStringList& args) const 703void AppLnk::invoke(const QStringList& args) const
703{ 704{
704 if ( property( "Arguments" ).isEmpty() ) 705 if ( property( "Arguments" ).isEmpty() )
705 Global::execute( exec(), args[0] ); 706 Global::execute( exec(), args[0] );
706 else 707 else
707 Global::execute( exec(), args.join( " " ) ); 708 Global::execute( exec(), args.join( " " ) );
708} 709}
709 710
710/*! 711/*!
711 Sets the Exec property to \a exec. 712 Sets the Exec property to \a exec.
712 713
713 \sa exec() name() 714 \sa exec() name()
714*/ 715*/
715void AppLnk::setExec( const QString& exec ) 716void AppLnk::setExec( const QString& exec )
716{ 717{
717 mExec = exec; 718 mExec = exec;
718} 719}
719 720
720#if 0 // this was inlined for better BC 721#if 0 // this was inlined for better BC
721/*! 722/*!
722 Sets the Rotation property to \a rot. 723 Sets the Rotation property to \a rot.
723 724
724 \sa rotation() 725 \sa rotation()
725*/ 726*/
726void AppLnk::setRotation ( const QString &rot ) 727void AppLnk::setRotation ( const QString &rot )
727{ 728{
728 mRotation = rot; 729 mRotation = rot;
729} 730}
730#endif 731#endif
731 732
732/*! 733/*!
733 Sets the Name property to \a docname. 734 Sets the Name property to \a docname.
734 735
735 \sa name() 736 \sa name()
736*/ 737*/
737void AppLnk::setName( const QString& docname ) 738void AppLnk::setName( const QString& docname )
738{ 739{
739 mName = docname; 740 mName = docname;
740} 741}
741 742
742/*! 743/*!
743 Sets the File property to \a filename. 744 Sets the File property to \a filename.
744 745
745 \sa file() name() 746 \sa file() name()
746*/ 747*/
747void AppLnk::setFile( const QString& filename ) 748void AppLnk::setFile( const QString& filename )
748{ 749{
749 mFile = filename; 750 mFile = filename;
750} 751}
751 752
752/*! 753/*!
753 Sets the LinkFile property to \a filename. 754 Sets the LinkFile property to \a filename.
754 755
755 \sa linkFile() 756 \sa linkFile()
756*/ 757*/
757void AppLnk::setLinkFile( const QString& filename ) 758void AppLnk::setLinkFile( const QString& filename )
758{ 759{
759 mLinkFile = filename; 760 mLinkFile = filename;
760} 761}
761 762
762/*! 763/*!
763 Sets the Comment property to \a comment. 764 Sets the Comment property to \a comment.
764 765
765 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
766 user uses the 'press-and-hold' gesture. 767 user uses the 'press-and-hold' gesture.
767 768
768 \sa comment() 769 \sa comment()
769*/ 770*/
770void AppLnk::setComment( const QString& comment ) 771void AppLnk::setComment( const QString& comment )
771{ 772{
772 mComment = comment; 773 mComment = comment;
773} 774}
774 775
775/*! 776/*!
776 Sets the Type property to \a type. 777 Sets the Type property to \a type.
777 778
778 For applications, games and settings the type should be \c 779 For applications, games and settings the type should be \c
779 Application; for documents the type should be the document's MIME 780 Application; for documents the type should be the document's MIME
780 type. 781 type.
781 782
782 \sa type() 783 \sa type()
783*/ 784*/
784void AppLnk::setType( const QString& type ) 785void AppLnk::setType( const QString& type )
785{ 786{
786 mType = type; 787 mType = type;
787} 788}
788 789
789/*! 790/*!
790 \fn QString AppLnk::icon() const 791 \fn QString AppLnk::icon() const
791 792
792 Returns the Icon property. 793 Returns the Icon property.
793 794
794 \sa setIcon() 795 \sa setIcon()
795*/ 796*/
796 797
797/*! 798/*!
798 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
799 which the pixmap() and bigPixmap() are obtained. 800 which the pixmap() and bigPixmap() are obtained.
800 801
801 \sa icon() setSmallIconSize() setBigIconSize() 802 \sa icon() setSmallIconSize() setBigIconSize()
802*/ 803*/
803void AppLnk::setIcon( const QString& iconname ) 804void AppLnk::setIcon( const QString& iconname )
804{ 805{
805 mIconFile = iconname; 806 mIconFile = iconname;
806 QImage unscaledIcon = Resource::loadImage( mIconFile ); 807 QImage unscaledIcon = Resource::loadImage( mIconFile );
807 d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) ); 808 d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
808 d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) ); 809 d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
809} 810}
810 811
811/*! 812/*!
812 Sets the Categories property to \a c. 813 Sets the Categories property to \a c.
813 814
814 See the CategoryWidget for more details. 815 See the CategoryWidget for more details.
815 816
816 \sa categories() 817 \sa categories()
817*/ 818*/
818void AppLnk::setCategories( const QArray<int>& c ) 819void AppLnk::setCategories( const QArray<int>& c )
819{ 820{
820 d->mCat = c; 821 d->mCat = c;
821 d->updateCatListFromArray(); 822 d->updateCatListFromArray();
822} 823}
823 824
824/*! 825/*!
825 \fn QStringList AppLnk::mimeTypeIcons() const 826 \fn QStringList AppLnk::mimeTypeIcons() const
826 827
827 Returns the MimeTypeIcons property of the AppLnk. 828 Returns the MimeTypeIcons property of the AppLnk.
828*/ 829*/
829 830
830/*! 831/*!
831 Attempts to ensure that the link file for this AppLnk exists, 832 Attempts to ensure that the link file for this AppLnk exists,
832 including creating any required directories. Returns TRUE if 833 including creating any required directories. Returns TRUE if
833 successful; otherwise returns FALSE. 834 successful; otherwise returns FALSE.
834 835
835 You should not need to use this function. 836 You should not need to use this function.
836*/ 837*/
837bool AppLnk::ensureLinkExists() const 838bool AppLnk::ensureLinkExists() const
838{ 839{
839 QString lf = linkFile(); 840 QString lf = linkFile();
840 return prepareDirectories(lf); 841 return prepareDirectories(lf);
841} 842}
842 843
843/*! 844/*!
844 Commits the AppLnk to disk. Returns TRUE if the operation succeeded; 845 Commits the AppLnk to disk. Returns TRUE if the operation succeeded;
845 otherwise returns FALSE. 846 otherwise returns FALSE.
846 847
847 In addition, the "linkChanged(QString)" message is sent to the 848 In addition, the "linkChanged(QString)" message is sent to the
848 "QPE/System" \link qcop.html QCop\endlink channel. 849 "QPE/System" \link qcop.html QCop\endlink channel.
849*/ 850*/
850bool AppLnk::writeLink() const 851bool AppLnk::writeLink() const
851{ 852{
852 // Only re-writes settable parts 853 // Only re-writes settable parts
853 QString lf = linkFile(); 854 QString lf = linkFile();
854 if ( !ensureLinkExists() ) 855 if ( !ensureLinkExists() )
855 return FALSE; 856 return FALSE;
856 storeLink(); 857 storeLink();
857 return TRUE; 858 return TRUE;
858} 859}
859 860
860/*! 861/*!
861 \internal 862 \internal
862*/ 863*/
863void AppLnk::storeLink() const 864void AppLnk::storeLink() const
864{ 865{
865 Config config( mLinkFile, Config::File ); 866 Config config( mLinkFile, Config::File );
866 config.setGroup("Desktop Entry"); 867 config.setGroup("Desktop Entry");
867 config.writeEntry("Name",mName); 868 config.writeEntry("Name",mName);
868 if ( !mIconFile.isNull() ) config.writeEntry("Icon",mIconFile); 869 if ( !mIconFile.isNull() ) config.writeEntry("Icon",mIconFile);
869 config.writeEntry("Type",type()); 870 config.writeEntry("Type",type());
870 if(!rotation().isEmpty()) 871 if(!rotation().isEmpty())
871 config.writeEntry("Rotation",rotation()); 872 config.writeEntry("Rotation",rotation());
872 else 873 else
873 config.removeEntry("Rotation"); 874 config.removeEntry("Rotation");
874 if ( !mComment.isNull() ) config.writeEntry("Comment",mComment); 875 if ( !mComment.isNull() ) config.writeEntry("Comment",mComment);
875 QString f = file(); 876 QString f = file();
876 int i = 0; 877 int i = 0;
877 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] )
878 i++; 879 i++;
879 while ( i && f[i] != '/' ) 880 while ( i && f[i] != '/' )
880 i--; 881 i--;
881 // simple case where in the same directory 882 // simple case where in the same directory
882 if ( mLinkFile.find( '/', i + 1 ) < 0 ) 883 if ( mLinkFile.find( '/', i + 1 ) < 0 )
883 f = f.mid(i+1); 884 f = f.mid(i+1);
884 // ### could do relative ie ../../otherDocs/file.doc 885 // ### could do relative ie ../../otherDocs/file.doc
885 config.writeEntry("File",f); 886 config.writeEntry("File",f);
886 config.writeEntry( "Categories", d->mCatList, ';' ); 887 config.writeEntry( "Categories", d->mCatList, ';' );
887 888
888#ifndef QT_NO_COP 889#ifndef QT_NO_COP
889 QCopEnvelope e("QPE/System", "linkChanged(QString)"); 890 QCopEnvelope e("QPE/System", "linkChanged(QString)");
890 e << mLinkFile; 891 e << mLinkFile;
891#endif 892#endif
892} 893}
893 894
894/*! 895/*!
895 Sets the property named \a key to \a value. 896 Sets the property named \a key to \a value.
896 897
897 \sa property() 898 \sa property()
898*/ 899*/
899void AppLnk::setProperty(const QString& key, const QString& value) 900void AppLnk::setProperty(const QString& key, const QString& value)
900{ 901{
901 if ( ensureLinkExists() ) { 902 if ( ensureLinkExists() ) {
902 Config cfg(linkFile(), Config::File); 903 Config cfg(linkFile(), Config::File);
903 cfg.writeEntry(key,value); 904 cfg.writeEntry(key,value);
904 } 905 }
905} 906}
906 907
907/*! 908/*!
908 Returns the property named \a key. 909 Returns the property named \a key.
909 910
910 \sa setProperty() 911 \sa setProperty()
911*/ 912*/
912QString AppLnk::property(const QString& key) const 913QString AppLnk::property(const QString& key) const
913{ 914{
914 QString lf = linkFile(); 915 QString lf = linkFile();
915 if ( !QFile::exists(lf) ) 916 if ( !QFile::exists(lf) )
916 return QString::null; 917 return QString::null;
917 Config cfg(lf, Config::File); 918 Config cfg(lf, Config::File);
918 return cfg.readEntry(key); 919 return cfg.readEntry(key);
919} 920}
920 921
921bool AppLnk::isPreloaded() const { 922bool AppLnk::isPreloaded() const {
922 // Preload information is stored in the Launcher config in v1.5. 923 // Preload information is stored in the Launcher config in v1.5.
923 Config cfg("Launcher"); 924 Config cfg("Launcher");
924 cfg.setGroup("Preload"); 925 cfg.setGroup("Preload");
925 QStringList apps = cfg.readListEntry("Apps",','); 926 QStringList apps = cfg.readListEntry("Apps",',');
926 if (apps.contains(exec())) 927 if (apps.contains(exec()))
927 return true; 928 return true;
928 return false; 929 return false;
929} 930}
930 931
931void AppLnk::setPreloaded(bool yesNo) { 932void AppLnk::setPreloaded(bool yesNo) {
932 // Preload information is stored in the Launcher config in v1.5. 933 // Preload information is stored in the Launcher config in v1.5.
933 Config cfg("Launcher"); 934 Config cfg("Launcher");
934 cfg.setGroup("Preload"); 935 cfg.setGroup("Preload");
935 QStringList apps = cfg.readListEntry("Apps", ','); 936 QStringList apps = cfg.readListEntry("Apps", ',');
936 if (apps.contains(exec()) && !yesNo) 937 if (apps.contains(exec()) && !yesNo)
937 apps.remove(exec()); 938 apps.remove(exec());
938 else if (yesNo && !apps.contains(exec())) 939 else if (yesNo && !apps.contains(exec()))
939 apps.append(exec()); 940 apps.append(exec());
940 cfg.writeEntry("Apps", apps, ','); 941 cfg.writeEntry("Apps", apps, ',');
941} 942}
942 943
943 944
944/*! 945/*!
945 Deletes both the linkFile() and the file() associated with this AppLnk. 946 Deletes both the linkFile() and the file() associated with this AppLnk.
946 947
947 \sa removeLinkFile() 948 \sa removeLinkFile()
948*/ 949*/
949void AppLnk::removeFiles() 950void AppLnk::removeFiles()
950{ 951{
951 bool valid = isValid(); 952 bool valid = isValid();
952 if ( !valid || !linkFileKnown() || QFile::remove(linkFile()) ) { 953 if ( !valid || !linkFileKnown() || QFile::remove(linkFile()) ) {
953 if ( QFile::remove(file()) ) { 954 if ( QFile::remove(file()) ) {
954#ifndef QT_NO_COP 955#ifndef QT_NO_COP
955 QCopEnvelope e("QPE/System", "linkChanged(QString)"); 956 QCopEnvelope e("QPE/System", "linkChanged(QString)");
956 if ( linkFileKnown() ) 957 if ( linkFileKnown() )
957 e << linkFile(); 958 e << linkFile();
958 else 959 else
959 e << file(); 960 e << file();
960#endif 961#endif
961 } else if ( valid ) { 962 } else if ( valid ) {
962 // restore link 963 // restore link
963 writeLink(); 964 writeLink();
964 } 965 }
965 } 966 }
966} 967}
967 968
968/*! 969/*!
969 Deletes the linkFile(), leaving any file() untouched. 970 Deletes the linkFile(), leaving any file() untouched.
970 971
971 \sa removeFiles() 972 \sa removeFiles()
972*/ 973*/
973void AppLnk::removeLinkFile() 974void AppLnk::removeLinkFile()
974{ 975{
975 if ( isValid() && linkFileKnown() && QFile::remove(linkFile()) ) { 976 if ( isValid() && linkFileKnown() && QFile::remove(linkFile()) ) {
976#ifndef QT_NO_COP 977#ifndef QT_NO_COP
977 QCopEnvelope e("QPE/System", "linkChanged(QString)"); 978 QCopEnvelope e("QPE/System", "linkChanged(QString)");
978 e << linkFile(); 979 e << linkFile();
979#endif 980#endif
980 } 981 }
981} 982}
982 983
983class AppLnkSetPrivate { 984class AppLnkSetPrivate {
984public: 985public:
985 AppLnkSetPrivate() 986 AppLnkSetPrivate()
986 { 987 {
987 typPix.setAutoDelete(TRUE); 988 typPix.setAutoDelete(TRUE);
988 typPixBig.setAutoDelete(TRUE); 989 typPixBig.setAutoDelete(TRUE);
989 typName.setAutoDelete(TRUE); 990 typName.setAutoDelete(TRUE);
990 } 991 }
991 992
992 QDict<QPixmap> typPix; 993 QDict<QPixmap> typPix;
993 QDict<QPixmap> typPixBig; 994 QDict<QPixmap> typPixBig;
994 QDict<QString> typName; 995 QDict<QString> typName;
995}; 996};
996 997
997/*! 998/*!
998 \class AppLnkSet applnk.h 999 \class AppLnkSet applnk.h
999 \brief The AppLnkSet class is a set of AppLnk objects. 1000 \brief The AppLnkSet class is a set of AppLnk objects.
1000*/ 1001*/
1001 1002
1002/*! 1003/*!
1003 \fn QStringList AppLnkSet::types() const 1004 \fn QStringList AppLnkSet::types() const
1004 1005
1005 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.
1006 1007
1007 For applications, games and settings the type is \c Application; 1008 For applications, games and settings the type is \c Application;
1008 for documents the type is the document's MIME type. 1009 for documents the type is the document's MIME type.
1009 1010
1010 \sa AppLnk::type(), typeName(), typePixmap(), typeBigPixmap() 1011 \sa AppLnk::type(), typeName(), typePixmap(), typeBigPixmap()
1011*/ 1012*/
1012 1013
1013/*! 1014/*!
1014 \fn const QList<AppLnk>& AppLnkSet::children() const 1015 \fn const QList<AppLnk>& AppLnkSet::children() const
1015 1016
1016 Returns the members of the set. 1017 Returns the members of the set.
1017*/ 1018*/
1018 1019
1019/*! 1020/*!
1020 Constructs an empty AppLnkSet. 1021 Constructs an empty AppLnkSet.
1021*/ 1022*/
1022AppLnkSet::AppLnkSet() : 1023AppLnkSet::AppLnkSet() :
1023 d(new AppLnkSetPrivate) 1024 d(new AppLnkSetPrivate)
1024{ 1025{
1025} 1026}
1026 1027
1027/*! 1028/*!
1028 Constructs an AppLnkSet that contains AppLnk objects representing 1029 Constructs an AppLnkSet that contains AppLnk objects representing
1029 all the files in the given \a directory (and any subdirectories 1030 all the files in the given \a directory (and any subdirectories
1030 recursively). 1031 recursively).
1031 1032
1032 \omit 1033 \omit
1033 The directories may contain ".directory" files which override 1034 The directories may contain ".directory" files which override
1034 any AppLnk::type() values for AppLnk objects found in the directory. 1035 any AppLnk::type() values for AppLnk objects found in the directory.
1035 This allows simple localization of application types. 1036 This allows simple localization of application types.
1036 \endomit 1037 \endomit
1037*/ 1038*/
1038AppLnkSet::AppLnkSet( const QString &directory ) : 1039AppLnkSet::AppLnkSet( const QString &directory ) :
1039 d(new AppLnkSetPrivate) 1040 d(new AppLnkSetPrivate)
1040{ 1041{
1041 QDir dir( directory ); 1042 QDir dir( directory );
1042 mFile = directory; 1043 mFile = directory;
1043 findChildren(directory,QString::null,QString::null); 1044 findChildren(directory,QString::null,QString::null);
1044} 1045}
1045 1046
1046/*! 1047/*!
1047 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
1048 the caller becomes responsible for deleting the AppLnk objects. 1049 the caller becomes responsible for deleting the AppLnk objects.
1049*/ 1050*/
1050void AppLnkSet::detachChildren() 1051void AppLnkSet::detachChildren()
1051{ 1052{
1052 QListIterator<AppLnk> it( mApps ); 1053 QListIterator<AppLnk> it( mApps );
1053 for ( ; it.current(); ) { 1054 for ( ; it.current(); ) {
1054 AppLnk* a = *it; 1055 AppLnk* a = *it;
1055 ++it; 1056 ++it;
1056 a->mId = 0; 1057 a->mId = 0;
1057 } 1058 }
1058 mApps.clear(); 1059 mApps.clear();
1059} 1060}
1060 1061
1061/*! 1062/*!
1062 Destroys the set, deleting all the AppLnk objects it contains. 1063 Destroys the set, deleting all the AppLnk objects it contains.
1063 1064
1064 \sa detachChildren() 1065 \sa detachChildren()
1065*/ 1066*/
1066AppLnkSet::~AppLnkSet() 1067AppLnkSet::~AppLnkSet()
1067{ 1068{
1068 QListIterator<AppLnk> it( mApps ); 1069 QListIterator<AppLnk> it( mApps );
1069 for ( ; it.current(); ) { 1070 for ( ; it.current(); ) {
1070 AppLnk* a = *it; 1071 AppLnk* a = *it;
1071 ++it; 1072 ++it;
1072 a->mId = 0; 1073 a->mId = 0;
1073 delete a; 1074 delete a;
1074 } 1075 }
1075 delete d; 1076 delete d;
1076} 1077}
1077 1078
1078void 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)
1079{ 1080{
1080 depth++; 1081 depth++;
1081 if ( depth > 10 ) 1082 if ( depth > 10 )
1082 return; 1083 return;
1083 1084
1084 QDir dir( dr ); 1085 QDir dir( dr );
1085 QString typNameLocal = typName; 1086 QString typNameLocal = typName;
1086 1087
1087 if ( dir.exists( ".directory" ) ) { 1088 if ( dir.exists( ".directory" ) ) {
1088 Config config( dr + "/.directory", Config::File ); 1089 Config config( dr + "/.directory", Config::File );
1089 config.setGroup( "Desktop Entry" ); 1090 config.setGroup( "Desktop Entry" );
1090 typNameLocal = config.readEntry( "Name", typNameLocal ); 1091 typNameLocal = config.readEntry( "Name", typNameLocal );
1091 if ( !typ.isEmpty() ) { 1092 if ( !typ.isEmpty() ) {
1092 QString iconFile = config.readEntry( "Icon", "AppsIcon" ); 1093 QString iconFile = config.readEntry( "Icon", "AppsIcon" );
1093 QImage unscaledIcon = Resource::loadImage( iconFile ); 1094 QImage unscaledIcon = Resource::loadImage( iconFile );
1094 QPixmap pm, bpm; 1095 QPixmap pm, bpm;
1095 pm.convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) ); 1096 pm.convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
1096 bpm.convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) ); 1097 bpm.convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
1097 d->typPix.insert(typ, new QPixmap(pm)); 1098 d->typPix.insert(typ, new QPixmap(pm));
1098 d->typPixBig.insert(typ, new QPixmap(bpm)); 1099 d->typPixBig.insert(typ, new QPixmap(bpm));
1099 d->typName.insert(typ, new QString(typNameLocal)); 1100 d->typName.insert(typ, new QString(typNameLocal));
1100 } 1101 }
1101 } 1102 }
1102 1103
1103 const QFileInfoList *list = dir.entryInfoList(); 1104 const QFileInfoList *list = dir.entryInfoList();
1104 if ( list ) { 1105 if ( list ) {
1105 QFileInfo* fi; 1106 QFileInfo* fi;
1106 bool cadded=FALSE; 1107 bool cadded=FALSE;
1107 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) { 1108 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) {
1108 QString bn = fi->fileName(); 1109 QString bn = fi->fileName();
1109// qDebug("findChildren "+bn); 1110// qDebug("findChildren "+bn);
1110 if ( bn[0] != '.' && bn != "CVS" ) { 1111 if ( bn[0] != '.' && bn != "CVS" ) {
1111 if ( fi->isDir() ) { 1112 if ( fi->isDir() ) {
1112 QString c = typ.isNull() ? bn : typ+"/"+bn; 1113 QString c = typ.isNull() ? bn : typ+"/"+bn;
1113 QString d = typNameLocal.isNull() ? bn : typNameLocal+"/"+bn; 1114 QString d = typNameLocal.isNull() ? bn : typNameLocal+"/"+bn;
1114 findChildren(fi->filePath(), c, d, depth ); 1115 findChildren(fi->filePath(), c, d, depth );
1115 } else { 1116 } else {
1116 if ( fi->extension(FALSE) == "desktop" ) { 1117 if ( fi->extension(FALSE) == "desktop" ) {
1117 AppLnk* app = new AppLnk( fi->filePath() ); 1118 AppLnk* app = new AppLnk( fi->filePath() );
1118#ifdef QT_NO_QWS_MULTIPROCESS 1119#ifdef QT_NO_QWS_MULTIPROCESS
1119 if ( !Global::isBuiltinCommand( app->exec() ) ) 1120 if ( !Global::isBuiltinCommand( app->exec() ) )
1120 delete app; 1121 delete app;
1121 else 1122 else
1122#endif 1123#endif
1123 { 1124 {
1124 if ( !typ.isEmpty() ) { 1125 if ( !typ.isEmpty() ) {
1125 if ( !cadded ) { 1126 if ( !cadded ) {
1126 typs.append(typ); 1127 typs.append(typ);
1127 cadded = TRUE; 1128 cadded = TRUE;
1128 } 1129 }
1129 app->setType(typ); 1130 app->setType(typ);
1130 } 1131 }
1131 add(app); 1132 add(app);
1132 } 1133 }
1133 } 1134 }
1134 } 1135 }
1135 } 1136 }
1136 } 1137 }
1137 } 1138 }
1138} 1139}
1139 1140
1140/*! 1141/*!
1141 Adds AppLnk \a f to the set. The set takes responsibility for 1142 Adds AppLnk \a f to the set. The set takes responsibility for
1142 deleting \a f. 1143 deleting \a f.
1143 1144
1144 \sa remove() 1145 \sa remove()
1145*/ 1146*/
1146void AppLnkSet::add( AppLnk *f ) 1147void AppLnkSet::add( AppLnk *f )
1147{ 1148{
1148 if ( f->mId == 0 ) { 1149 if ( f->mId == 0 ) {
1149 AppLnk::lastId++; 1150 AppLnk::lastId++;
1150 f->mId = AppLnk::lastId; 1151 f->mId = AppLnk::lastId;
1151 mApps.append( f ); 1152 mApps.append( f );
1152 } else { 1153 } else {
1153 qWarning("Attempt to add an AppLnk twice"); 1154 qWarning("Attempt to add an AppLnk twice");
1154 } 1155 }
1155} 1156}
1156 1157
1157/*! 1158/*!
1158 Removes AppLnk \a f to the set. The caller becomes responsible for 1159 Removes AppLnk \a f to the set. The caller becomes responsible for
1159 deleting \a f. Returns TRUE if \a f was in the set; otherwise 1160 deleting \a f. Returns TRUE if \a f was in the set; otherwise
1160 returns FALSE. 1161 returns FALSE.
1161 1162
1162 \sa add() 1163 \sa add()
1163*/ 1164*/
1164bool AppLnkSet::remove( AppLnk *f ) 1165bool AppLnkSet::remove( AppLnk *f )
1165{ 1166{
1166 if ( mApps.remove( f ) ) { 1167 if ( mApps.remove( f ) ) {
1167 f->mId = 0; 1168 f->mId = 0;
1168 return TRUE; 1169 return TRUE;
1169 } 1170 }
1170 return FALSE; 1171 return FALSE;
1171} 1172}
1172 1173
1173 1174
1174/*! 1175/*!
1175 Returns the localized name for type \a t. 1176 Returns the localized name for type \a t.
1176 1177
1177 For applications, games and settings the type is \c Application; 1178 For applications, games and settings the type is \c Application;
1178 for documents the type is the document's MIME type. 1179 for documents the type is the document's MIME type.
1179*/ 1180*/
1180QString AppLnkSet::typeName( const QString& t ) const 1181QString AppLnkSet::typeName( const QString& t ) const
1181{ 1182{
1182 QString *st = d->typName.find(t); 1183 QString *st = d->typName.find(t);
1183 return st ? *st : QString::null; 1184 return st ? *st : QString::null;
1184} 1185}
1185 1186
1186/*! 1187/*!
1187 Returns the small pixmap associated with type \a t. 1188 Returns the small pixmap associated with type \a t.
1188 1189
1189 For applications, games and settings the type is \c Application; 1190 For applications, games and settings the type is \c Application;
1190 for documents the type is the document's MIME type. 1191 for documents the type is the document's MIME type.
1191*/ 1192*/
1192QPixmap AppLnkSet::typePixmap( const QString& t ) const 1193QPixmap AppLnkSet::typePixmap( const QString& t ) const
1193{ 1194{
1194 QPixmap *pm = d->typPix.find(t); 1195 QPixmap *pm = d->typPix.find(t);
1195 return pm ? *pm : QPixmap(); 1196 return pm ? *pm : QPixmap();
1196} 1197}
1197 1198
1198/*! 1199/*!
1199 Returns the large pixmap associated with type \a t. 1200 Returns the large pixmap associated with type \a t.
1200 1201
1201 For applications, games and settings the type is \c Application; 1202 For applications, games and settings the type is \c Application;
1202 for documents the type is the document's MIME type. 1203 for documents the type is the document's MIME type.
1203*/ 1204*/
1204QPixmap AppLnkSet::typeBigPixmap( const QString& t ) const 1205QPixmap AppLnkSet::typeBigPixmap( const QString& t ) const
1205{ 1206{
1206 QPixmap *pm = d->typPixBig.find(t); 1207 QPixmap *pm = d->typPixBig.find(t);
1207 return pm ? *pm : QPixmap(); 1208 return pm ? *pm : QPixmap();
1208} 1209}
1209 1210
1210/*! 1211/*!
1211 Returns the AppLnk with the given \a id. 1212 Returns the AppLnk with the given \a id.
1212*/ 1213*/
1213const AppLnk *AppLnkSet::find( int id ) const 1214const AppLnk *AppLnkSet::find( int id ) const
1214{ 1215{
1215 QListIterator<AppLnk> it( children() ); 1216 QListIterator<AppLnk> it( children() );
1216 1217
1217 for ( ; it.current(); ++it ) { 1218 for ( ; it.current(); ++it ) {
1218 const AppLnk *app = it.current(); 1219 const AppLnk *app = it.current();
1219 if ( app->id() == id ) 1220 if ( app->id() == id )
1220 return app; 1221 return app;
1221 } 1222 }
1222 1223
1223 return 0; 1224 return 0;
1224} 1225}
1225 1226
1226/*! 1227/*!
1227 Returns the AppLnk with the given \a exec attribute. 1228 Returns the AppLnk with the given \a exec attribute.
1228*/ 1229*/
1229const AppLnk *AppLnkSet::findExec( const QString& exec ) const 1230const AppLnk *AppLnkSet::findExec( const QString& exec ) const
1230{ 1231{
1231 QListIterator<AppLnk> it( children() ); 1232 QListIterator<AppLnk> it( children() );
1232 1233
1233 for ( ; it.current(); ++it ) { 1234 for ( ; it.current(); ++it ) {
1234 const AppLnk *app = it.current(); 1235 const AppLnk *app = it.current();
1235 if ( app->exec() == exec ) 1236 if ( app->exec() == exec )
1236 return app; 1237 return app;
1237 } 1238 }
1238 1239
1239 return 0; 1240 return 0;
1240} 1241}
1241 1242
1242/*! 1243/*!
1243 \class DocLnkSet applnk.h 1244 \class DocLnkSet applnk.h
1244 \brief The DocLnkSet class is a set of DocLnk objects. 1245 \brief The DocLnkSet class is a set of DocLnk objects.
1245*/ 1246*/
1246 1247
1247/*! 1248/*!
1248 \fn const QList<DocLnk>& DocLnkSet::children() const 1249 \fn const QList<DocLnk>& DocLnkSet::children() const
1249 1250
1250 Returns the members of the set. 1251 Returns the members of the set.
1251*/ 1252*/
1252 1253
1253/*! 1254/*!
1254 Constructs an empty DocLnkSet. 1255 Constructs an empty DocLnkSet.
1255 1256
1256 \sa appendFrom() 1257 \sa appendFrom()
1257*/ 1258*/
1258DocLnkSet::DocLnkSet() 1259DocLnkSet::DocLnkSet()
1259{ 1260{
1260} 1261}
1261 1262
1262/*! 1263/*!
1263 Constructs a DocLnkSet that contains DocLnk objects representing all 1264 Constructs a DocLnkSet that contains DocLnk objects representing all
1264 the files in the \a directory (and any subdirectories, recursively). 1265 the files in the \a directory (and any subdirectories, recursively).
1265 1266
1266 If \a mimefilter is not null, 1267 If \a mimefilter is not null,
1267 only documents with a MIME type matching \a mimefilter are selected. 1268 only documents with a MIME type matching \a mimefilter are selected.
1268 The value may contain multiple wild-card patterns separated by ";", 1269 The value may contain multiple wild-card patterns separated by ";",
1269 such as \c{*o/mpeg;audio/x-wav}. 1270 such as \c{*o/mpeg;audio/x-wav}.
1270 1271
1271 See also \link applnk.html#files-and-links Files and Links\endlink. 1272 See also \link applnk.html#files-and-links Files and Links\endlink.
1272 1273
1273*/ 1274*/
1274DocLnkSet::DocLnkSet( const QString &directory, const QString& mimefilter ) : 1275DocLnkSet::DocLnkSet( const QString &directory, const QString& mimefilter ) :
1275 AppLnkSet() 1276 AppLnkSet()
1276{ 1277{
1277 QDir dir( directory ); 1278 QDir dir( directory );
1278 mFile = dir.dirName(); 1279 mFile = dir.dirName();
1279 QDict<void> reference(1021); 1280 QDict<void> reference(1021);
1280 1281
1281 QStringList subFilter = QStringList::split(";", mimefilter); 1282 QStringList subFilter = QStringList::split(";", mimefilter);
1282 QValueList<QRegExp> mimeFilters; 1283 QValueList<QRegExp> mimeFilters;
1283 for( QStringList::Iterator it = subFilter.begin(); it != subFilter.end(); ++ it ) 1284 for( QStringList::Iterator it = subFilter.begin(); it != subFilter.end(); ++ it )
1284 mimeFilters.append( QRegExp(*it, FALSE, TRUE) ); 1285 mimeFilters.append( QRegExp(*it, FALSE, TRUE) );
1285 1286
1286 findChildren(directory, mimeFilters, reference); 1287 findChildren(directory, mimeFilters, reference);
1287 1288
1288 const QList<DocLnk> &list = children(); 1289 const QList<DocLnk> &list = children();
1289 for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) { 1290 for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) {
1290 reference.remove( (*it)->file() ); 1291 reference.remove( (*it)->file() );
1291 } 1292 }
1292 for ( QDictIterator<void> dit(reference); dit.current(); ++dit ) { 1293 for ( QDictIterator<void> dit(reference); dit.current(); ++dit ) {
1293 if ( dit.current() == (void*)2 ) { 1294 if ( dit.current() == (void*)2 ) {
1294 // Unreferenced, make an unwritten link 1295 // Unreferenced, make an unwritten link
1295 DocLnk* dl = new DocLnk; 1296 DocLnk* dl = new DocLnk;
1296 QFileInfo fi( dit.currentKey() ); 1297 QFileInfo fi( dit.currentKey() );
1297 dl->setFile(fi.filePath()); 1298 dl->setFile(fi.filePath());
1298 dl->setName(fi.baseName()); 1299 dl->setName(fi.baseName());
1299 // #### default to current path? 1300 // #### default to current path?
1300 // dl->setCategories( ... ); 1301 // dl->setCategories( ... );
1301 bool match = mimefilter.isNull(); 1302 bool match = mimefilter.isNull();
1302 if ( !match ) 1303 if ( !match )
1303 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 )
1304 if ( (*it).match(dl->type()) >= 0 ) 1305 if ( (*it).match(dl->type()) >= 0 )
1305 match = TRUE; 1306 match = TRUE;
1306 if ( match /* && dl->type() != "application/octet-stream" */ 1307 if ( match /* && dl->type() != "application/octet-stream" */
1307 && !!dl->exec() ) 1308 && !!dl->exec() )
1308 add(dl); 1309 add(dl);
1309 else 1310 else
1310 delete dl; 1311 delete dl;
1311 } 1312 }
1312 } 1313 }
1313} 1314}
1314 1315
1315// other becomes empty 1316// other becomes empty
1316/*! 1317/*!
1317 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
1318 empty. 1319 empty.
1319*/ 1320*/
1320void DocLnkSet::appendFrom( DocLnkSet& other ) 1321void DocLnkSet::appendFrom( DocLnkSet& other )
1321{ 1322{
1322 if ( &other == this ) 1323 if ( &other == this )
1323 return; 1324 return;
1324 QListIterator<AppLnk> it( other.mApps ); 1325 QListIterator<AppLnk> it( other.mApps );
1325 for ( ; it.current(); ) { 1326 for ( ; it.current(); ) {
1326 mApps.append(*it); 1327 mApps.append(*it);
1327 ++it; 1328 ++it;
1328 } 1329 }
1329 other.mApps.clear(); 1330 other.mApps.clear();
1330} 1331}
1331 1332
1332void 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)
1333{ 1334{
1334 depth++; 1335 depth++;
1335 if ( depth > 10 ) 1336 if ( depth > 10 )
1336 return; 1337 return;
1337 1338
1338 QDir dir( dr ); 1339 QDir dir( dr );
1339 1340
1340 /* Opie got a different approach 1341 /* Opie got a different approach
1341 * I guess it's geek vs. consumer 1342 * I guess it's geek vs. consumer
1342 * in this case to be discussed 1343 * in this case to be discussed
1343 */ 1344 */
1344 if ( dir.exists( ".Qtopia-ignore" ) ) 1345 if ( dir.exists( ".Qtopia-ignore" ) )
1345 return; 1346 return;
1346 1347
1347 const QFileInfoList *list = dir.entryInfoList(); 1348 const QFileInfoList *list = dir.entryInfoList();
1348 if ( list ) { 1349 if ( list ) {
1349 QFileInfo* fi; 1350 QFileInfo* fi;
1350 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) { 1351 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) {
1351 QString bn = fi->fileName(); 1352 QString bn = fi->fileName();
1352 if ( bn[0] != '.' ) { 1353 if ( bn[0] != '.' ) {
1353 if ( fi->isDir() ) { 1354 if ( fi->isDir() ) {
1354 if ( bn != "CVS" && bn != "Qtopia" && bn != "QtPalmtop" ) 1355 if ( bn != "CVS" && bn != "Qtopia" && bn != "QtPalmtop" )
1355 findChildren(fi->filePath(), mimeFilters, reference, depth); 1356 findChildren(fi->filePath(), mimeFilters, reference, depth);
1356 } else { 1357 } else {
1357 if ( fi->extension(FALSE) == "desktop" ) { 1358 if ( fi->extension(FALSE) == "desktop" ) {
1358 DocLnk* dl = new DocLnk( fi->filePath() ); 1359 DocLnk* dl = new DocLnk( fi->filePath() );
1359 QFileInfo fi2(dl->file()); 1360 QFileInfo fi2(dl->file());
1360 bool match = FALSE; 1361 bool match = FALSE;
1361 if ( !fi2.exists() ) { 1362 if ( !fi2.exists() ) {
1362 dir.remove( dl->file() ); 1363 dir.remove( dl->file() );
1363 } 1364 }
1364 if ( mimeFilters.count() == 0 ) { 1365 if ( mimeFilters.count() == 0 ) {
1365 add( dl ); 1366 add( dl );
1366 match = TRUE; 1367 match = TRUE;
1367 } else { 1368 } else {
1368 for( QValueList<QRegExp>::ConstIterator it = mimeFilters.begin(); it != mimeFilters.end(); ++ it ) { 1369 for( QValueList<QRegExp>::ConstIterator it = mimeFilters.begin(); it != mimeFilters.end(); ++ it ) {
1369 if ( (*it).match(dl->type()) >= 0 ) { 1370 if ( (*it).match(dl->type()) >= 0 ) {
1370 add(dl); 1371 add(dl);
1371 match = TRUE; 1372 match = TRUE;
1372 } 1373 }
1373 } 1374 }
1374 } 1375 }
1375 if ( !match ) 1376 if ( !match )
1376 delete dl; 1377 delete dl;
1377 } else { 1378 } else {
1378 if ( !reference.find(fi->fileName()) ) 1379 if ( !reference.find(fi->fileName()) )
1379 reference.insert(fi->filePath(), (void*)2); 1380 reference.insert(fi->filePath(), (void*)2);
1380 } 1381 }
1381 } 1382 }
1382 } 1383 }
1383 } 1384 }
1384 } 1385 }
1385} 1386}
1386 1387
1387/*! 1388/*!
1388 \class DocLnk applnk.h 1389 \class DocLnk applnk.h
1389 \brief The DocLnk class represents loaded document references. 1390 \brief The DocLnk class represents loaded document references.
1390*/ 1391*/
1391 1392
1392/*! 1393/*!
1393 \fn DocLnk::DocLnk( const DocLnk &o ) 1394 \fn DocLnk::DocLnk( const DocLnk &o )
1394 1395
1395 Copies \a o. 1396 Copies \a o.
1396*/ 1397*/
1397 1398
1398/*! 1399/*!
1399 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
1400 \a file for other files. 1401 \a file for other files.
1401*/ 1402*/
1402DocLnk::DocLnk( const QString &file ) : 1403DocLnk::DocLnk( const QString &file ) :
1403 AppLnk(file) 1404 AppLnk(file)
1404{ 1405{
1405 init(file); 1406 init(file);
1406} 1407}
1407 1408
1408/*! 1409/*!
1409 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
1410 \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
1411 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
1412 is read as a normal file. 1413 is read as a normal file.
1413*/ 1414*/
1414DocLnk::DocLnk( const QString &file, bool may_be_desktopfile ) : 1415DocLnk::DocLnk( const QString &file, bool may_be_desktopfile ) :
1415 AppLnk(may_be_desktopfile ? file : QString::null) 1416 AppLnk(may_be_desktopfile ? file : QString::null)
1416{ 1417{
1417 init(file); 1418 init(file);
1418} 1419}
1419 1420
1420void DocLnk::init(const QString &file) 1421void DocLnk::init(const QString &file)
1421{ 1422{
1422 if ( isValid() ) { 1423 if ( isValid() ) {
1423#ifndef FORCED_DIR_STRUCTURE_WAY 1424#ifndef FORCED_DIR_STRUCTURE_WAY
1424 if ( mType.isNull() ) 1425 if ( mType.isNull() )
1425 // try to infer it 1426 // try to infer it
1426#endif 1427#endif
1427 { 1428 {
1428 int s0 = file.findRev('/'); 1429 int s0 = file.findRev('/');
1429 if ( s0 > 0 ) { 1430 if ( s0 > 0 ) {
1430 int s1 = file.findRev('/',s0-1); 1431 int s1 = file.findRev('/',s0-1);
1431 if ( s1 > 0 ) { 1432 if ( s1 > 0 ) {
1432 int s2 = file.findRev('/',s1-1); 1433 int s2 = file.findRev('/',s1-1);
1433 if ( s2 > 0 ) { 1434 if ( s2 > 0 ) {
1434 mType = file.mid(s2+1,s0-s2-1); 1435 mType = file.mid(s2+1,s0-s2-1);
1435 } 1436 }
1436 } 1437 }
1437 } 1438 }
1438 } 1439 }
1439 } else if ( QFile::exists(file) ) { 1440 } else if ( QFile::exists(file) ) {
1440 QString n = file; 1441 QString n = file;
1441 n.replace(QRegExp(".*/"),""); 1442 n.replace(QRegExp(".*/"),"");
1442 n.replace(QRegExp("\\..*"),""); 1443 n.replace(QRegExp("\\..*"),"");
1443 setName( n ); 1444 setName( n );
1444 setFile( file ); 1445 setFile( file );
1445 } 1446 }
1446 MimeType mt(mType); 1447 MimeType mt(mType);
1447 if( mt.application() ) 1448 if( mt.application() )
1448 mExec = mt.application()->exec(); 1449 mExec = mt.application()->exec();
1449} 1450}
1450 1451
1451/*! 1452/*!
1452 Constructs an invalid DocLnk. 1453 Constructs an invalid DocLnk.
1453*/ 1454*/
1454DocLnk::DocLnk() 1455DocLnk::DocLnk()
1455{ 1456{
1456} 1457}
1457 1458
1458/*! 1459/*!
1459 Destroys the DocLnk. Just like AppLnk objects, a run-time error 1460 Destroys the DocLnk. Just like AppLnk objects, a run-time error
1460 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).
1461*/ 1462*/
1462DocLnk::~DocLnk() 1463DocLnk::~DocLnk()
1463{ 1464{
1464} 1465}
1465 1466
1466/*! 1467/*!
1467 \reimp 1468 \reimp
1468*/ 1469*/
1469QString DocLnk::exec() const 1470QString DocLnk::exec() const
1470{ 1471{
1471 MimeType mt(type()); 1472 MimeType mt(type());
1472 const AppLnk* app = mt.application(); 1473 const AppLnk* app = mt.application();
1473 if ( app ) 1474 if ( app )
1474 return app->exec(); 1475 return app->exec();
1475 else 1476 else
1476 return QString::null; 1477 return QString::null;
1477} 1478}
1478 1479
1479/*! 1480/*!
1480 \reimp 1481 \reimp
1481*/ 1482*/
1482void DocLnk::invoke(const QStringList& args) const 1483void DocLnk::invoke(const QStringList& args) const
1483{ 1484{
1484 MimeType mt(type()); 1485 MimeType mt(type());
1485 const AppLnk* app = mt.application(); 1486 const AppLnk* app = mt.application();
1486 if ( app ) { 1487 if ( app ) {
1487 QStringList a = args; 1488 QStringList a = args;
1488 if ( linkFileKnown() && QFile::exists( linkFile() ) ) 1489 if ( linkFileKnown() && QFile::exists( linkFile() ) )
1489 a.append(linkFile()); 1490 a.append(linkFile());
1490 else 1491 else
1491 a.append(file()); 1492 a.append(file());
1492 app->execute(a); 1493 app->execute(a);
1493 } 1494 }
1494} 1495}
1495 1496
1496 1497
diff --git a/library/tzselect.cpp b/library/tzselect.cpp
index 848dfb7..8dd427f 100644
--- a/library/tzselect.cpp
+++ b/library/tzselect.cpp
@@ -1,302 +1,303 @@
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_TZSELECT_INC_LOCAL 21#define QTOPIA_INTERNAL_TZSELECT_INC_LOCAL
22 22
23#include "tzselect.h" 23#include "tzselect.h"
24#include "resource.h" 24#include "resource.h"
25#include "config.h" 25#include "config.h"
26#include <qtoolbutton.h> 26#include <qtoolbutton.h>
27#include <qfile.h> 27#include <qfile.h>
28#include <stdlib.h> 28#include <stdlib.h>
29 29
30#include <qcopchannel_qws.h> 30#include <qcopchannel_qws.h>
31#include <qpe/global.h>
31#include <qpe/qpeapplication.h> 32#include <qpe/qpeapplication.h>
32#include <qmessagebox.h> 33#include <qmessagebox.h>
33 34
34/*! 35/*!
35 \class TimeZoneSelector 36 \class TimeZoneSelector
36 37
37 \brief The TimeZoneSelector widget allows users to configure their time zone information. 38 \brief The TimeZoneSelector widget allows users to configure their time zone information.
38 39
39 \ingroup qtopiaemb 40 \ingroup qtopiaemb
40*/ 41*/
41 42
42class TimeZoneSelectorPrivate 43class TimeZoneSelectorPrivate
43{ 44{
44public: 45public:
45 TimeZoneSelectorPrivate() : includeLocal(FALSE) {} 46 TimeZoneSelectorPrivate() : includeLocal(FALSE) {}
46 bool includeLocal; 47 bool includeLocal;
47}; 48};
48 49
49TZCombo::TZCombo( QWidget *p, const char* n ) 50TZCombo::TZCombo( QWidget *p, const char* n )
50 : QComboBox( p, n ) 51 : QComboBox( p, n )
51{ 52{
52 updateZones(); 53 updateZones();
53 // check to see if TZ is set, if it is set the current item to that 54 // check to see if TZ is set, if it is set the current item to that
54 QString tz = getenv("TZ"); 55 QString tz = getenv("TZ");
55 if (parent()->inherits("TimeZoneSelector")) { 56 if (parent()->inherits("TimeZoneSelector")) {
56 if ( ((TimeZoneSelector *)parent())->localIncluded() ) { 57 if ( ((TimeZoneSelector *)parent())->localIncluded() ) {
57 // overide to the 'local' type. 58 // overide to the 'local' type.
58 tz = "None"; 59 tz = "None";
59 } 60 }
60 } 61 }
61 if ( !tz.isNull() ) { 62 if ( !tz.isNull() ) {
62 int n = 0, 63 int n = 0,
63 index = 0; 64 index = 0;
64 for ( QStringList::Iterator it=identifiers.begin(); 65 for ( QStringList::Iterator it=identifiers.begin();
65 it!=identifiers.end(); ++it) { 66 it!=identifiers.end(); ++it) {
66 if ( *it == tz ) 67 if ( *it == tz )
67 index = n; 68 index = n;
68 n++; 69 n++;
69 } 70 }
70 setCurrentItem(index); 71 setCurrentItem(index);
71 } else { 72 } else {
72 setCurrentItem(0); 73 setCurrentItem(0);
73 } 74 }
74 75
75 76
76 77
77 // listen on QPE/System 78 // listen on QPE/System
78#if !defined(QT_NO_COP) 79#if !defined(QT_NO_COP)
79 QCopChannel *channel = new QCopChannel( "QPE/System", this ); 80 QCopChannel *channel = new QCopChannel( "QPE/System", this );
80 connect( channel, SIGNAL(received(const QCString&,const QByteArray&)), 81 connect( channel, SIGNAL(received(const QCString&,const QByteArray&)),
81 this, SLOT(handleSystemChannel(const QCString&,const QByteArray&)) ); 82 this, SLOT(handleSystemChannel(const QCString&,const QByteArray&)) );
82#endif 83#endif
83 84
84 85
85} 86}
86 87
87TZCombo::~TZCombo() 88TZCombo::~TZCombo()
88{ 89{
89} 90}
90 91
91void TZCombo::updateZones() 92void TZCombo::updateZones()
92{ 93{
93 QString cur = currentText(); 94 QString cur = currentText();
94 clear(); 95 clear();
95 identifiers.clear(); 96 identifiers.clear();
96 int curix=0; 97 int curix=0;
97 QString tz = getenv("TZ"); 98 QString tz = getenv("TZ");
98 bool tzFound = FALSE; 99 bool tzFound = FALSE;
99 Config cfg("CityTime"); 100 Config cfg("CityTime");
100 cfg.setGroup("TimeZones"); 101 cfg.setGroup("TimeZones");
101 int listIndex = 0; 102 int listIndex = 0;
102 if (parent()->inherits("TimeZoneSelector")) { 103 if (parent()->inherits("TimeZoneSelector")) {
103 if ( ((TimeZoneSelector *)parent())->localIncluded() ) { 104 if ( ((TimeZoneSelector *)parent())->localIncluded() ) {
104 // overide to the 'local' type. 105 // overide to the 'local' type.
105 identifiers.append( "None" ); 106 identifiers.append( "None" );
106 insertItem( tr("None") ); 107 insertItem( tr("None") );
107 if ( cur == tr("None")) 108 if ( cur == tr("None"))
108 curix = 0; 109 curix = 0;
109 listIndex++; 110 listIndex++;
110 } 111 }
111 } 112 }
112 int cfgIndex = 0; 113 int cfgIndex = 0;
113 while (1) { 114 while (1) {
114 QString zn = cfg.readEntry("Zone"+QString::number(cfgIndex), QString::null); 115 QString zn = cfg.readEntry("Zone"+QString::number(cfgIndex), QString::null);
115 if ( zn.isNull() ) 116 if ( zn.isNull() )
116 break; 117 break;
117 if ( zn == tz ) 118 if ( zn == tz )
118 tzFound = TRUE; 119 tzFound = TRUE;
119 QString nm = cfg.readEntry("ZoneName"+QString::number(cfgIndex)); 120 QString nm = cfg.readEntry("ZoneName"+QString::number(cfgIndex));
120 identifiers.append(zn); 121 identifiers.append(zn);
121 insertItem(nm); 122 insertItem(nm);
122 if ( nm == cur ) 123 if ( nm == cur )
123 curix = listIndex; 124 curix = listIndex;
124 ++cfgIndex; 125 ++cfgIndex;
125 ++listIndex; 126 ++listIndex;
126 } 127 }
127 if ( !listIndex ) { 128 if ( !listIndex ) {
128 QStringList list = timezoneDefaults(); 129 QStringList list = timezoneDefaults();
129 for ( QStringList::Iterator it = list.begin(); it!=list.end(); ++it ) { 130 for ( QStringList::Iterator it = list.begin(); it!=list.end(); ++it ) {
130 QString zn = *it; 131 QString zn = *it;
131 QString nm = *++it; 132 QString nm = *++it;
132 if ( zn == tz ) 133 if ( zn == tz )
133 tzFound = TRUE; 134 tzFound = TRUE;
134 if ( nm == cur ) 135 if ( nm == cur )
135 curix = listIndex; 136 curix = listIndex;
136 identifiers.append(zn); 137 identifiers.append(zn);
137 insertItem(nm); 138 insertItem(nm);
138 ++listIndex; 139 ++listIndex;
139 } 140 }
140 } 141 }
141 for (QStringList::Iterator it=extras.begin(); it!=extras.end(); ++it) { 142 for (QStringList::Iterator it=extras.begin(); it!=extras.end(); ++it) {
142 insertItem(*it); 143 insertItem(*it);
143 identifiers.append(*it); 144 identifiers.append(*it);
144 if ( *it == cur ) 145 if ( *it == cur )
145 curix = listIndex; 146 curix = listIndex;
146 ++listIndex; 147 ++listIndex;
147 } 148 }
148 if ( !tzFound && !tz.isEmpty()) { 149 if ( !tzFound && !tz.isEmpty()) {
149 int i = tz.find( '/' ); 150 int i = tz.find( '/' );
150 QString nm = tz.mid( i+1 ).replace(QRegExp("_"), " "); 151 QString nm = tz.mid( i+1 ).replace(QRegExp("_"), " ");
151 identifiers.append(tz); 152 identifiers.append(tz);
152 insertItem(nm); 153 insertItem(nm);
153 if ( nm == cur ) 154 if ( nm == cur )
154 curix = listIndex; 155 curix = listIndex;
155 ++listIndex; 156 ++listIndex;
156 } 157 }
157 setCurrentItem(curix); 158 setCurrentItem(curix);
158} 159}
159 160
160 161
161void TZCombo::keyPressEvent( QKeyEvent *e ) 162void TZCombo::keyPressEvent( QKeyEvent *e )
162{ 163{
163 // ### should popup() in Qt 3.0 (it's virtual there) 164 // ### should popup() in Qt 3.0 (it's virtual there)
164// updateZones(); 165// updateZones();
165 QComboBox::keyPressEvent(e); 166 QComboBox::keyPressEvent(e);
166} 167}
167 168
168void TZCombo::mousePressEvent(QMouseEvent*e) 169void TZCombo::mousePressEvent(QMouseEvent*e)
169{ 170{
170 // ### should popup() in Qt 3.0 (it's virtual there) 171 // ### should popup() in Qt 3.0 (it's virtual there)
171// updateZones(); 172// updateZones();
172 QComboBox::mousePressEvent(e); 173 QComboBox::mousePressEvent(e);
173} 174}
174 175
175QString TZCombo::currZone() const 176QString TZCombo::currZone() const
176{ 177{
177 return identifiers[currentItem()]; 178 return identifiers[currentItem()];
178} 179}
179 180
180void TZCombo::setCurrZone( const QString& id ) 181void TZCombo::setCurrZone( const QString& id )
181{ 182{
182 for (int i=0; i< count(); i++) { 183 for (int i=0; i< count(); i++) {
183 if ( identifiers[i] == id ) { 184 if ( identifiers[i] == id ) {
184 setCurrentItem(i); 185 setCurrentItem(i);
185 return; 186 return;
186} 187}
187 } 188 }
188 insertItem(id); 189 insertItem(id);
189 setCurrentItem( count() - 1); 190 setCurrentItem( count() - 1);
190 identifiers.append(id); 191 identifiers.append(id);
191 extras.append(id); 192 extras.append(id);
192} 193}
193 194
194 195
195 196
196void TZCombo::handleSystemChannel(const QCString&msg, const QByteArray&) 197void TZCombo::handleSystemChannel(const QCString&msg, const QByteArray&)
197{ 198{
198 if ( msg == "timeZoneListChange()" ) { 199 if ( msg == "timeZoneListChange()" ) {
199 updateZones(); 200 updateZones();
200 } 201 }
201} 202}
202 203
203/*! 204/*!
204 Creates a new TimeZoneSelector with parent \a p and name \a n. The combobox will be 205 Creates a new TimeZoneSelector with parent \a p and name \a n. The combobox will be
205 populated with the available timezones. 206 populated with the available timezones.
206*/ 207*/
207 208
208TimeZoneSelector::TimeZoneSelector(QWidget* p, const char* n) : 209TimeZoneSelector::TimeZoneSelector(QWidget* p, const char* n) :
209 QHBox(p,n) 210 QHBox(p,n)
210{ 211{
211 d = new TimeZoneSelectorPrivate(); 212 d = new TimeZoneSelectorPrivate();
212 // build the combobox before we do any updates... 213 // build the combobox before we do any updates...
213 cmbTz = new TZCombo( this, "timezone combo" ); 214 cmbTz = new TZCombo( this, "timezone combo" );
214 215
215 cmdTz = new QToolButton( this, "timezone button" ); 216 cmdTz = new QToolButton( this, "timezone button" );
216 cmdTz->setIconSet( Resource::loadIconSet( "citytime_icon" ) ); 217 cmdTz->setIconSet( Resource::loadIconSet( "citytime_icon" ) );
217 cmdTz->setMaximumSize( cmdTz->sizeHint() ); 218 cmdTz->setMaximumSize( cmdTz->sizeHint() );
218 219
219 // set up a connection to catch a newly selected item and throw our 220 // set up a connection to catch a newly selected item and throw our
220 // signal 221 // signal
221 QObject::connect( cmbTz, SIGNAL( activated(int) ), 222 QObject::connect( cmbTz, SIGNAL( activated(int) ),
222 this, SLOT( slotTzActive(int) ) ); 223 this, SLOT( slotTzActive(int) ) );
223 QObject::connect( cmdTz, SIGNAL( clicked() ), 224 QObject::connect( cmdTz, SIGNAL( clicked() ),
224 this, SLOT( slotExecute() ) ); 225 this, SLOT( slotExecute() ) );
225} 226}
226 227
227/*! 228/*!
228 Destroys a TimeZoneSelector. 229 Destroys a TimeZoneSelector.
229*/ 230*/
230TimeZoneSelector::~TimeZoneSelector() 231TimeZoneSelector::~TimeZoneSelector()
231{ 232{
232} 233}
233 234
234void TimeZoneSelector::setLocalIncluded(bool b) 235void TimeZoneSelector::setLocalIncluded(bool b)
235{ 236{
236 d->includeLocal = b; 237 d->includeLocal = b;
237 cmbTz->updateZones(); 238 cmbTz->updateZones();
238} 239}
239 240
240bool TimeZoneSelector::localIncluded() const 241bool TimeZoneSelector::localIncluded() const
241{ 242{
242 return d->includeLocal; 243 return d->includeLocal;
243} 244}
244 245
245/*! 246/*!
246 Returns the currently selected timezone as a string in location format, e.g. 247 Returns the currently selected timezone as a string in location format, e.g.
247 \code Australia/Brisbane \endcode 248 \code Australia/Brisbane \endcode
248*/ 249*/
249QString TimeZoneSelector::currentZone() const 250QString TimeZoneSelector::currentZone() const
250{ 251{
251 return cmbTz->currZone(); 252 return cmbTz->currZone();
252} 253}
253 254
254/*! 255/*!
255 Sets the current timezone to \a id. 256 Sets the current timezone to \a id.
256*/ 257*/
257void TimeZoneSelector::setCurrentZone( const QString& id ) 258void TimeZoneSelector::setCurrentZone( const QString& id )
258{ 259{
259 cmbTz->setCurrZone( id ); 260 cmbTz->setCurrZone( id );
260} 261}
261/*! \fn void TimeZoneSelector::signalNewTz( const QString& id ) 262/*! \fn void TimeZoneSelector::signalNewTz( const QString& id )
262 This signal is emitted when a timezone has been selected by the user. The id 263 This signal is emitted when a timezone has been selected by the user. The id
263 is a \l QString in location format, eg \code Australia/Brisbane \endcode 264 is a \l QString in location format, eg \code Australia/Brisbane \endcode
264*/ 265*/
265 266
266 267
267void TimeZoneSelector::slotTzActive( int ) 268void TimeZoneSelector::slotTzActive( int )
268{ 269{
269 emit signalNewTz( cmbTz->currZone() ); 270 emit signalNewTz( cmbTz->currZone() );
270} 271}
271 272
272void TimeZoneSelector::slotExecute( void ) 273void TimeZoneSelector::slotExecute( void )
273{ 274{
274 // execute the world time application... 275 // execute the world time application...
275 if (QFile::exists(QPEApplication::qpeDir()+"bin/citytime")) 276 if (QFile::exists(QPEApplication::qpeDir()+"bin/citytime"))
276 Global::execute( "citytime" ); 277 Global::execute( "citytime" );
277 else 278 else
278 QMessageBox::warning(this,tr("citytime executable not found"), 279 QMessageBox::warning(this,tr("citytime executable not found"),
279 tr("In order to choose the time zones,\nplease install citytime.")); 280 tr("In order to choose the time zones,\nplease install citytime."));
280} 281}
281 282
282QStringList timezoneDefaults( void ) 283QStringList timezoneDefaults( void )
283{ 284{
284 QStringList tzs; 285 QStringList tzs;
285 // load up the list just like the file format (citytime.cpp) 286 // load up the list just like the file format (citytime.cpp)
286 tzs.append( "America/New_York" ); 287 tzs.append( "America/New_York" );
287 tzs.append( "New York" ); 288 tzs.append( "New York" );
288 tzs.append( "America/Los_Angeles" ); 289 tzs.append( "America/Los_Angeles" );
289 tzs.append( "Los Angeles" ); 290 tzs.append( "Los Angeles" );
290 tzs.append( "Australia/Brisbane" ); 291 tzs.append( "Australia/Brisbane" );
291 tzs.append( "Brisbane" ); 292 tzs.append( "Brisbane" );
292 tzs.append( "Europe/Berlin" ); 293 tzs.append( "Europe/Berlin" );
293 tzs.append( "Berlin" ); 294 tzs.append( "Berlin" );
294 tzs.append( "Asia/Tokyo" ); 295 tzs.append( "Asia/Tokyo" );
295 tzs.append( "Tokyo" ); 296 tzs.append( "Tokyo" );
296 tzs.append( "America/Denver" ); 297 tzs.append( "America/Denver" );
297 tzs.append( "Denver" ); 298 tzs.append( "Denver" );
298 299
299 return tzs; 300 return tzs;
300} 301}
301 302
302 303