summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--library/applnk.cpp83
1 files changed, 56 insertions, 27 deletions
diff --git a/library/applnk.cpp b/library/applnk.cpp
index 2af6cf4..5185b5f 100644
--- a/library/applnk.cpp
+++ b/library/applnk.cpp
@@ -1,1093 +1,1122 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#define QTOPIA_INTERNAL_MIMEEXT
22
21#include "applnk.h" 23#include "applnk.h"
22 24
23#include <qpe/qpeapplication.h> 25#include <qpe/qpeapplication.h>
24#include <qpe/categories.h> 26#include <qpe/categories.h>
25#include <qpe/categoryselect.h> 27#include <qpe/categoryselect.h>
26#include <qpe/qcopenvelope_qws.h> 28#include <qpe/qcopenvelope_qws.h>
27#include <qpe/global.h> 29#include <qpe/global.h>
28#include <qpe/mimetype.h> 30#include <qpe/mimetype.h>
29#include <qpe/config.h> 31#include <qpe/config.h>
30#include <qpe/storage.h> 32#include <qpe/storage.h>
31#include <qpe/resource.h> 33#include <qpe/resource.h>
32 34
33#include <qdict.h> 35#include <qdict.h>
34#include <qdir.h> 36#include <qdir.h>
35#include <qregexp.h> 37#include <qregexp.h>
36 38
37#ifdef Q_WS_QWS 39#ifdef Q_WS_QWS
38#include <qgfx_qws.h> 40#include <qgfx_qws.h>
39#endif 41#endif
40 42
41#include <stdlib.h> 43#include <stdlib.h>
42 44
43int AppLnk::lastId = 5000; 45int AppLnk::lastId = 5000;
44 46
45static int smallSize = 14; 47static int smallSize = 14;
46static int bigSize = 32; 48static int bigSize = 32;
47 49
48static QString safeFileName(const QString& n) 50static QString safeFileName(const QString& n)
49{ 51{
50 QString safename=n; 52 QString safename=n;
51 safename.replace(QRegExp("[^0-9A-Za-z.]"),"_"); 53 safename.replace(QRegExp("[^0-9A-Za-z.]"),"_"); // Njaard says this is broken
52 safename.replace(QRegExp("^[^A-Za-z]*"),""); 54 safename.replace(QRegExp("^[^A-Za-z]*"),"");
53 if ( safename.isEmpty() ) 55 if ( safename.isEmpty() )
54 safename = "_"; 56 safename = "_";
55 return safename; 57 return safename;
56} 58}
57 59
60static bool prepareDirectories(const QString& lf)
61{
62 if ( !QFile::exists(lf) ) {
63 // May need to create directories
64 QFileInfo fi(lf);
65 if ( system(("mkdir -p "+fi.dirPath(TRUE))) )
66 return FALSE;
67 }
68 return TRUE;
69}
58 70
59class AppLnkPrivate 71class AppLnkPrivate
60{ 72{
61public: 73public:
62 QArray<int> mCat; 74 QArray<int> mCat;
63}; 75};
64 76
65/*! 77/*!
66 \class AppLnk applnk.h 78 \class AppLnk applnk.h
67 \brief The AppLnk class represents an application available on the system. 79 \brief The AppLnk class represents an application available on the system.
68 80
69 Information about applications are stored in Qtopia as ".desktop" files. 81 Information about applications are stored in Qtopia as ".desktop" files.
70 When read, these files are stored as AppLnk objects. 82 When read, these files are stored as AppLnk objects.
71*/ 83*/
72 84
73/*! 85/*!
74 Sets the size used for small icons to \a small pixels. 86 Sets the size used for small icons to \a small pixels.
75 Only affects AppLnk objects created after the call. 87 Only affects AppLnk objects created after the call.
76*/ 88*/
77void AppLnk::setSmallIconSize(int small) 89void AppLnk::setSmallIconSize(int small)
78{ 90{
79 smallSize = small; 91 smallSize = small;
80} 92}
81 93
82/*! 94/*!
83 Returns the size used for small icons. 95 Returns the size used for small icons.
84*/ 96*/
85int AppLnk::smallIconSize() 97int AppLnk::smallIconSize()
86{ 98{
87 return smallSize; 99 return smallSize;
88} 100}
89 101
90 102
91/*! 103/*!
92 Sets the size used for large icons to \a big pixels. 104 Sets the size used for large icons to \a big pixels.
93 Only affects AppLnk objects created after the call. 105 Only affects AppLnk objects created after the call.
94*/ 106*/
95void AppLnk::setBigIconSize(int big) 107void AppLnk::setBigIconSize(int big)
96{ 108{
97 bigSize = big; 109 bigSize = big;
98} 110}
99 111
100/*! 112/*!
101 Returns the size used for large icons. 113 Returns the size used for large icons.
102*/ 114*/
103int AppLnk::bigIconSize() 115int AppLnk::bigIconSize()
104{ 116{
105 return bigSize; 117 return bigSize;
106} 118}
107 119
108 120
109/*! 121/*!
110 \fn QString AppLnk::name() const 122 \fn QString AppLnk::name() const
111 123
112 Returns the Name property. 124 Returns the Name property.
113*/ 125*/
114/*! 126/*!
115 \fn QString AppLnk::exec() const 127 \fn QString AppLnk::exec() const
116 128
117 Returns the Exec property. This is the executable program associated 129 Returns the Exec property. This is the executable program associated
118 with the AppLnk. 130 with the AppLnk.
119*/ 131*/
120/*! 132/*!
121 \fn QString AppLnk::rotation() const 133 \fn QString AppLnk::rotation() const
122 134
123 Returns the Rotation property. 135 Returns the Rotation property.
124*/ 136*/
125/*! 137/*!
126 \fn QString AppLnk::comment() const 138 \fn QString AppLnk::comment() const
127 139
128 Returns the Comment property. 140 Returns the Comment property.
129*/ 141*/
130/*! 142/*!
131 \fn QStringList AppLnk::mimeTypes() const 143 \fn QStringList AppLnk::mimeTypes() const
132 144
133 Returns the MimeTypes property. This is the list of MIME types 145 Returns the MimeTypes property. This is the list of MIME types
134 that the application can view or edit. 146 that the application can view or edit.
135*/ 147*/
136/*! 148/*!
137 \fn const QArray<int>& AppLnk::categories() const 149 \fn const QArray<int>& AppLnk::categories() const
138 150
139 Returns the Categories property. 151 Returns the Categories property.
140*/ 152*/
141 153
142const QArray<int>& AppLnk::categories() const 154const QArray<int>& AppLnk::categories() const
143{ 155{
144 return d->mCat; 156 return d->mCat;
145} 157}
146 158
147/*! 159/*!
148 \fn int AppLnk::id() const 160 \fn int AppLnk::id() const
149 161
150 Returns the id of the AppLnk. If the AppLnk is not in an AppLnkSet, 162 Returns the id of the AppLnk. If the AppLnk is not in an AppLnkSet,
151 this value is 0, otherwise it is a value that is unique for the 163 this value is 0, otherwise it is a value that is unique for the
152 duration of the current process. 164 duration of the current process.
153*/ 165*/
154 166
155/*! 167/*!
156 \fn bool AppLnk::isValid() const 168 \fn bool AppLnk::isValid() const
157 169
158 Returns whether this AppLnk is valid. 170 Returns whether this AppLnk is valid.
159*/ 171*/
160 172
161/*! 173/*!
162 Creates an invalid AppLnk. 174 Creates an invalid AppLnk.
163 175
164 \sa isValid() 176 \sa isValid()
165*/ 177*/
166AppLnk::AppLnk() 178AppLnk::AppLnk()
167{ 179{
168 mId = 0; 180 mId = 0;
169 d = new AppLnkPrivate(); 181 d = new AppLnkPrivate();
170} 182}
171 183
172/*! 184/*!
173 Loads \a file as an AppLnk. 185 Loads \a file as an AppLnk.
174*/ 186*/
175AppLnk::AppLnk( const QString &file ) 187AppLnk::AppLnk( const QString &file )
176{ 188{
177 QStringList sl; 189 QStringList sl;
178 d = new AppLnkPrivate(); 190 d = new AppLnkPrivate();
179 if ( !file.isNull() ) { 191 if ( !file.isNull() ) {
180 Config config( file, Config::File ); 192 Config config( file, Config::File );
181 193
182 if ( config.isValid() ) { 194 if ( config.isValid() ) {
183 config.setGroup( "Desktop Entry" ); 195 config.setGroup( "Desktop Entry" );
184 196
185 mName = config.readEntry( "Name", file ); 197 mName = config.readEntry( "Name", file );
186 mExec = config.readEntry( "Exec" ); 198 mExec = config.readEntry( "Exec" );
187 mType = config.readEntry( "Type", QString::null ); 199 mType = config.readEntry( "Type", QString::null );
188 mIconFile = config.readEntry( "Icon", QString::null ); 200 mIconFile = config.readEntry( "Icon", QString::null );
189 mRotation = config.readEntry( "Rotation", "" ); 201 mRotation = config.readEntry( "Rotation", "" );
190 mComment = config.readEntry( "Comment", QString::null ); 202 mComment = config.readEntry( "Comment", QString::null );
191 mMimeTypes = config.readListEntry( "MimeType", ';' ); 203 mMimeTypes = config.readListEntry( "MimeType", ';' );
192 mMimeTypeIcons = config.readListEntry( "MimeTypeIcons", ';' ); 204 mMimeTypeIcons = config.readListEntry( "MimeTypeIcons", ';' );
193 mLinkFile = file; 205 mLinkFile = file;
194 mFile = config.readEntry("File", QString::null); 206 mFile = config.readEntry("File", QString::null);
195 sl = config.readListEntry("Categories", ';'); 207 sl = config.readListEntry("Categories", ';');
196 } 208 }
197 } 209 }
198 // let's try our darndest to create categories... 210 // let's try our darndest to create categories...
199 Categories cat( 0 ); 211 Categories cat( 0 );
200 cat.load( categoryFileName() ); 212 cat.load( categoryFileName() );
201 d->mCat.resize( sl.count() ); 213 d->mCat.resize( sl.count() );
202 int i; 214 int i;
203 QStringList::Iterator it; 215 QStringList::Iterator it;
204 for ( i = 0, it = sl.begin(); it != sl.end(); 216 for ( i = 0, it = sl.begin(); it != sl.end();
205 ++it, i++ ) { 217 ++it, i++ ) {
206 218
207 bool number; 219 bool number;
208 int id = (*it).toInt( &number ); 220 int id = (*it).toInt( &number );
209 if ( !number ) { 221 if ( !number ) {
210 // convert from old school... 222 // convert from old school...
211 id = cat.id( "Document Viewer", *it ); 223 id = cat.id( "Document Viewer", *it );
212 if ( id == 0 ) 224 if ( id == 0 )
213 id = cat.addCategory( "Document Viewer", *it ); 225 id = cat.addCategory( "Document Viewer", *it );
214 } 226 }
215 d->mCat[i] = id; 227 d->mCat[i] = id;
216 } 228 }
217 mId = 0; 229 mId = 0;
218} 230}
219 231
220/*! 232/*!
221 Returns a small pixmap associated with the application. 233 Returns a small pixmap associated with the application.
222*/ 234*/
223const QPixmap& AppLnk::pixmap() const 235const QPixmap& AppLnk::pixmap() const
224{ 236{
225 if ( mPixmap.isNull() ) { 237 if ( mPixmap.isNull() ) {
226 AppLnk* that = (AppLnk*)this; 238 AppLnk* that = (AppLnk*)this;
227 if ( mIconFile.isEmpty() ) { 239 if ( mIconFile.isEmpty() ) {
228 MimeType mt(type()); 240 MimeType mt(type());
229 that->mPixmap = mt.pixmap(); 241 that->mPixmap = mt.pixmap();
230 if ( that->mPixmap.isNull() ) 242 if ( that->mPixmap.isNull() )
231 that->mPixmap = Resource::loadPixmap("UnknownDocument-14"); 243 that->mPixmap = Resource::loadPixmap("UnknownDocument-14");
232 return that->mPixmap; 244 return that->mPixmap;
233 } 245 }
234 QImage unscaledIcon = Resource::loadImage( that->mIconFile ); 246 QImage unscaledIcon = Resource::loadImage( that->mIconFile );
235 that->mPixmap.convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) ); 247 that->mPixmap.convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
236 that->mBigPixmap.convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) ); 248 that->mBigPixmap.convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
237 return that->mPixmap; 249 return that->mPixmap;
238 } 250 }
239 return mPixmap; 251 return mPixmap;
240} 252}
241 253
242/*! 254/*!
243 Returns a large pixmap associated with the application. 255 Returns a large pixmap associated with the application.
244*/ 256*/
245const QPixmap& AppLnk::bigPixmap() const 257const QPixmap& AppLnk::bigPixmap() const
246{ 258{
247 if ( mBigPixmap.isNull() ) { 259 if ( mBigPixmap.isNull() ) {
248 AppLnk* that = (AppLnk*)this; 260 AppLnk* that = (AppLnk*)this;
249 if ( mIconFile.isEmpty() ) { 261 if ( mIconFile.isEmpty() ) {
250 MimeType mt(type()); 262 MimeType mt(type());
251 that->mBigPixmap = mt.bigPixmap(); 263 that->mBigPixmap = mt.bigPixmap();
252 if ( that->mBigPixmap.isNull() ) 264 if ( that->mBigPixmap.isNull() )
253 that->mBigPixmap = Resource::loadPixmap("UnknownDocument"); 265 that->mBigPixmap = Resource::loadPixmap("UnknownDocument");
254 return that->mBigPixmap; 266 return that->mBigPixmap;
255 } 267 }
256 QImage unscaledIcon = Resource::loadImage( that->mIconFile ); 268 QImage unscaledIcon = Resource::loadImage( that->mIconFile );
257 that->mPixmap.convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) ); 269 that->mPixmap.convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
258 that->mBigPixmap.convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) ); 270 that->mBigPixmap.convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
259 return that->mBigPixmap; 271 return that->mBigPixmap;
260 } 272 }
261 return mBigPixmap; 273 return mBigPixmap;
262} 274}
263 275
264/*! 276/*!
265 Returns the type of the application. 277 Returns the type of the application.
266*/ 278*/
267QString AppLnk::type() const 279QString AppLnk::type() const
268{ 280{
269 if ( mType.isNull() ) { 281 if ( mType.isNull() ) {
270 AppLnk* that = (AppLnk*)this; 282 AppLnk* that = (AppLnk*)this;
271 MimeType mt(file()); 283 MimeType mt(file());
272 that->mType = mt.id(); 284 that->mType = mt.id();
273 return that->mType; 285 return that->mType;
274 } 286 }
275 return mType; 287 return mType;
276} 288}
277 289
278/*! 290/*!
279 Returns the file associated with the AppLnk. 291 Returns the file associated with the AppLnk.
280 292
281 \sa exec() 293 \sa exec()
282*/ 294*/
283QString AppLnk::file() const 295QString AppLnk::file() const
284{ 296{
285 if ( mFile.isNull() ) { 297 if ( mFile.isNull() ) {
286 AppLnk* that = (AppLnk*)this; 298 AppLnk* that = (AppLnk*)this; // copy?
299 QString ext = MimeType(mType).extension();
300 if ( !ext.isEmpty() )
301 ext = "." + ext;
287 if ( !mLinkFile.isEmpty() ) { 302 if ( !mLinkFile.isEmpty() ) {
288 that->mFile = 303 that->mFile =
289 mLinkFile.right(8)==".desktop" // 8 = strlen(".desktop") 304 mLinkFile.right(8)==".desktop" // 8 = strlen(".desktop")
290 ? mLinkFile.left(mLinkFile.length()-8) : mLinkFile; 305 ? mLinkFile.left(mLinkFile.length()-8) : mLinkFile;
291 } else if ( mType.contains('/') ) { 306 } else if ( mType.contains('/') ) {
292 that->mFile = 307 that->mFile =
293 QString(getenv("HOME"))+"/Documents/"+mType+"/"+safeFileName(that->mName); 308 QString(getenv("HOME"))+"/Documents/"+mType+"/"+safeFileName(that->mName);
294 if ( QFile::exists(that->mFile) || QFile::exists(that->mFile+".desktop") ) { 309 if ( QFile::exists(that->mFile+ext) || QFile::exists(that->mFile+".desktop") ) { // a .desktop with the same name exists
295 int n=1; 310 int n=1;
311 qWarning("AppLnk::file() n=1 %s", that->mFile.latin1() );
296 QString nn; 312 QString nn;
297 while (QFile::exists((nn=(that->mFile+"_"+QString::number(n)))) 313 while (QFile::exists((nn=(that->mFile+"_"+QString::number(n)))+ext)
298 || QFile::exists(nn+".desktop")) 314 || QFile::exists(nn+".desktop"))
299 n++; 315 n++;
300 that->mFile = nn; 316 that->mFile = nn;
317 qWarning("AppLnl::file() now mFile is %s", that->mFile.latin1() );
301 } 318 }
302 that->mLinkFile = that->mFile+".desktop"; 319 that->mLinkFile = that->mFile+".desktop";
320 that->mFile += ext;
303 } 321 }
322 prepareDirectories(that->mFile);
323 QFile f(that->mFile);
324 if ( !f.open(IO_WriteOnly) )
325 that->mFile = QString::null;
304 return that->mFile; 326 return that->mFile;
305 } 327 }
306 return mFile; 328 return mFile;
307} 329}
308 330
309/*! 331/*!
310 Returns the desktop file coresponding to this AppLnk. 332 Returns the desktop file coresponding to this AppLnk.
311 333
312 \sa file(), exec() 334 \sa file(), exec()
313*/ 335*/
314QString AppLnk::linkFile() const 336QString AppLnk::linkFile() const
315{ 337{
316 if ( mLinkFile.isNull() ) { 338 if ( mLinkFile.isNull() ) {
317 AppLnk* that = (AppLnk*)this; 339 AppLnk* that = (AppLnk*)this;
318 if ( type().contains('/') ) { 340 if ( type().contains('/') ) {
319 StorageInfo storage; 341 StorageInfo storage;
320 const FileSystem *fs = storage.fileSystemOf( that->mFile ); 342 const FileSystem *fs = storage.fileSystemOf( that->mFile );
321 // qDebug("creating lnkFile for %s", mFile.latin1() );
322 // if ( fs )
323 // qDebug("fs is %s", fs->path().latin1() );
324 if ( fs && fs->isRemovable() ) { 343 if ( fs && fs->isRemovable() ) {
325 // qDebug("isRemovable");
326 that->mLinkFile = fs->path(); 344 that->mLinkFile = fs->path();
327 } else 345 } else
328 that->mLinkFile = getenv( "HOME" ); 346 that->mLinkFile = getenv( "HOME" );
329 that->mLinkFile += "/Documents/"+type()+"/"+safeFileName(that->mName); 347 that->mLinkFile += "/Documents/"+type()+"/"+safeFileName(that->mName);
330 if ( QFile::exists(that->mLinkFile+".desktop") ) { 348 if ( QFile::exists(that->mLinkFile+".desktop") ) { // ok the file exists lets check if we point to the same file
331 int n=1; 349 int n=1;
332 QString nn; 350 QString nn;
333 while (QFile::exists((nn=that->mLinkFile+"_"+QString::number(n))+".desktop")) 351 AppLnk lnk( that->mLinkFile+".desktop" );
352 if(that->file() != lnk.file() ){
353 qWarning("AppLnk::linkFile exists %s", that->mLinkFile.latin1() );
354 while (QFile::exists((nn=that->mLinkFile+"_"+QString::number(n))+".desktop")){
334 n++; 355 n++;
335 that->mLinkFile = nn; 356 AppLnk lnk(nn ); // just to be sure
357 if(lnk.file() ==that->file() ){
358 break;
359 }
360 }
361 that->mLinkFile = nn;
362 }
336 } 363 }
337 that->mLinkFile += ".desktop"; 364 that->mLinkFile += ".desktop";
338 // qDebug("file is %s", mLinkFile.latin1() ); 365 qWarning("AppLnk::linkFile is %s", that->mLinkFile.latin1() );
366 storeLink();
339 } 367 }
340 return that->mLinkFile; 368 return that->mLinkFile;
341 } 369 }
342 return mLinkFile; 370 return mLinkFile;
343} 371}
344 372
345/*! 373/*!
346 Copies \a copy. 374 Copies \a copy.
347*/ 375*/
348AppLnk::AppLnk( const AppLnk &copy ) 376AppLnk::AppLnk( const AppLnk &copy )
349{ 377{
350 mName = copy.mName; 378 mName = copy.mName;
351 mPixmap = copy.mPixmap; 379 mPixmap = copy.mPixmap;
352 mBigPixmap = copy.mBigPixmap; 380 mBigPixmap = copy.mBigPixmap;
353 mExec = copy.mExec; 381 mExec = copy.mExec;
354 mType = copy.mType; 382 mType = copy.mType;
355 mRotation = copy.mRotation; 383 mRotation = copy.mRotation;
356 mComment = copy.mComment; 384 mComment = copy.mComment;
357 mFile = copy.mFile; 385 mFile = copy.mFile;
358 mLinkFile = copy.mLinkFile; 386 mLinkFile = copy.mLinkFile;
359 mIconFile = copy.mIconFile; 387 mIconFile = copy.mIconFile;
360 mMimeTypes = copy.mMimeTypes; 388 mMimeTypes = copy.mMimeTypes;
361 mMimeTypeIcons = copy.mMimeTypeIcons; 389 mMimeTypeIcons = copy.mMimeTypeIcons;
362 mId = 0; 390 mId = 0;
363 d = new AppLnkPrivate(); 391 d = new AppLnkPrivate();
364 d->mCat = copy.d->mCat; 392 d->mCat = copy.d->mCat;
365} 393}
366 394
367/*! 395/*!
368 Destroys the AppLnk. Note that if the AppLnk is current a member of 396 Destroys the AppLnk. Note that if the AppLnk is current a member of
369 an AppLnkSet, this will produce a run-time warning. 397 an AppLnkSet, this will produce a run-time warning.
370 398
371 \sa AppLnkSet::add(), AppLnkSet::remove() 399 \sa AppLnkSet::add(), AppLnkSet::remove()
372*/ 400*/
373AppLnk::~AppLnk() 401AppLnk::~AppLnk()
374{ 402{
375 if ( mId ) 403 if ( mId )
376 qWarning("Deleting AppLnk that is in an AppLnkSet"); 404 qWarning("Deleting AppLnk that is in an AppLnkSet");
377 if ( d ) 405 if ( d )
378 delete d; 406 delete d;
379} 407}
380 408
381/*! 409/*!
382 Executes the application associated with this AppLnk. 410 Executes the application associated with this AppLnk.
383*/ 411*/
384void AppLnk::execute() const 412void AppLnk::execute() const
385{ 413{
386 execute(QStringList()); 414 execute(QStringList());
387} 415}
388 416
389/*! 417/*!
390 Executes the application associated with this AppLnk, with 418 Executes the application associated with this AppLnk, with
391 \a args as arguments. 419 \a args as arguments.
392*/ 420*/
393void AppLnk::execute(const QStringList& args) const 421void AppLnk::execute(const QStringList& args) const
394{ 422{
395#ifdef Q_WS_QWS 423#ifdef Q_WS_QWS
396 if ( !mRotation.isEmpty() ) { 424 if ( !mRotation.isEmpty() ) {
397 // ######## this will only work in the server 425 // ######## this will only work in the server
398 int rot = QPEApplication::defaultRotation(); 426 int rot = QPEApplication::defaultRotation();
399 rot = (rot+mRotation.toInt())%360; 427 rot = (rot+mRotation.toInt())%360;
400 QCString old = getenv("QWS_DISPLAY"); 428 QCString old = getenv("QWS_DISPLAY");
401 setenv("QWS_DISPLAY", QString("Transformed:Rot%1:0").arg(rot), 1); 429 setenv("QWS_DISPLAY", QString("Transformed:Rot%1:0").arg(rot), 1);
402 invoke(args); 430 invoke(args);
403 setenv("QWS_DISPLAY", old.data(), 1); 431 setenv("QWS_DISPLAY", old.data(), 1);
404 } else 432 } else
405#endif 433#endif
406 invoke(args); 434 invoke(args);
407} 435}
408 436
409/*! 437/*!
410 Invokes the application associated with this AppLnk, with 438 Invokes the application associated with this AppLnk, with
411 \a args as arguments. Rotation is not taken into account by 439 \a args as arguments. Rotation is not taken into account by
412 this function, you should not call it directly. 440 this function, you should not call it directly.
413 441
414 \sa execute() 442 \sa execute()
415*/ 443*/
416void AppLnk::invoke(const QStringList& args) const 444void AppLnk::invoke(const QStringList& args) const
417{ 445{
418 Global::execute( exec(), args[0] ); 446 Global::execute( exec(), args[0] );
419} 447}
420 448
421/*! 449/*!
422 Sets the Exec property to \a exec. 450 Sets the Exec property to \a exec.
423 451
424 \sa exec() 452 \sa exec()
425*/ 453*/
426void AppLnk::setExec( const QString& exec ) 454void AppLnk::setExec( const QString& exec )
427{ 455{
428 mExec = exec; 456 mExec = exec;
429} 457}
430 458
431/*! 459/*!
432 Sets the Name property to \a docname. 460 Sets the Name property to \a docname.
433 461
434 \sa name() 462 \sa name()
435*/ 463*/
436void AppLnk::setName( const QString& docname ) 464void AppLnk::setName( const QString& docname )
437{ 465{
438 mName = docname; 466 mName = docname;
439} 467}
440 468
441/*! 469/*!
442 Sets the File property to \a filename. 470 Sets the File property to \a filename.
443 471
444 \sa file() 472 \sa file()
445*/ 473*/
446void AppLnk::setFile( const QString& filename ) 474void AppLnk::setFile( const QString& filename )
447{ 475{
448 mFile = filename; 476 mFile = filename;
449} 477}
450 478
451/*! 479/*!
452 Sets the LinkFile property to \a filename. 480 Sets the LinkFile property to \a filename.
453 481
454 \sa linkFile() 482 \sa linkFile()
455*/ 483*/
456void AppLnk::setLinkFile( const QString& filename ) 484void AppLnk::setLinkFile( const QString& filename )
457{ 485{
458 mLinkFile = filename; 486 mLinkFile = filename;
459} 487}
460 488
461/*! 489/*!
462 Sets the Comment property to \a comment. 490 Sets the Comment property to \a comment.
463 491
464 \sa comment() 492 \sa comment()
465*/ 493*/
466void AppLnk::setComment( const QString& comment ) 494void AppLnk::setComment( const QString& comment )
467{ 495{
468 mComment = comment; 496 mComment = comment;
469} 497}
470 498
471/*! 499/*!
472 Sets the Type property to \a type. 500 Sets the Type property to \a type.
473 501
474 \sa type() 502 \sa type()
475*/ 503*/
476void AppLnk::setType( const QString& type ) 504void AppLnk::setType( const QString& type )
477{ 505{
478 mType = type; 506 mType = type;
479} 507}
480 508
481/*! 509/*!
482 Sets the Icon property to \a iconname. 510 Sets the Icon property to \a iconname.
483 511
484 \sa pixmap(), bigPixmap() 512 \sa pixmap(), bigPixmap()
485*/ 513*/
486void AppLnk::setIcon( const QString& iconname ) 514void AppLnk::setIcon( const QString& iconname )
487{ 515{
488 mIconFile = iconname; 516 mIconFile = iconname;
489 QImage unscaledIcon = Resource::loadImage( mIconFile ); 517 QImage unscaledIcon = Resource::loadImage( mIconFile );
490 mPixmap.convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) ); 518 mPixmap.convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
491 mBigPixmap.convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) ); 519 mBigPixmap.convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
492} 520}
493 521
494/*! 522/*!
495 Sets the Categories property to \a c. 523 Sets the Categories property to \a c.
496 524
497 \sa categories() 525 \sa categories()
498*/ 526*/
499void AppLnk::setCategories( const QArray<int>& c ) 527void AppLnk::setCategories( const QArray<int>& c )
500{ 528{
501 d->mCat = c; 529 d->mCat = c;
502} 530}
503 531
504/*! 532/*!
505 \fn QStringList AppLnk::mimeTypeIcons() const 533 \fn QStringList AppLnk::mimeTypeIcons() const
506 534
507 Returns the MimeTypeIcons property of the AppLnk. 535 Returns the MimeTypeIcons property of the AppLnk.
508*/ 536*/
509 537
510/*! 538/*!
511 Attempts to ensure that the link file for this AppLnk exists, including 539 Attempts to ensure that the link file for this AppLnk exists, including
512 creating any required directories. Returns TRUE if successful. 540 creating any required directories. Returns TRUE if successful.
513*/ 541*/
514bool AppLnk::ensureLinkExists() const 542bool AppLnk::ensureLinkExists() const
515{ 543{
516 QString lf = linkFile(); 544 QString lf = linkFile();
517 if ( !QFile::exists(lf) ) { 545 return prepareDirectories(lf);
518 // May need to create directories
519 QFileInfo fi(lf);
520 if ( system(("mkdir -p "+fi.dirPath(TRUE))) )
521 return FALSE;
522 }
523 return TRUE;
524} 546}
525 547
526/*! 548/*!
527 Commits the AppLnk to disk. Returns whether the operation succeeded. 549 Commits the AppLnk to disk. Returns whether the operation succeeded.
528 550
529 The "linkChanged(QString)" message is sent to the 551 The "linkChanged(QString)" message is sent to the
530 "QPE/System" QCop channel as a result. 552 "QPE/System" QCop channel as a result.
531*/ 553*/
532bool AppLnk::writeLink() const 554bool AppLnk::writeLink() const
533{ 555{
534 // Only re-writes settable parts 556 // Only re-writes settable parts
535 QString lf = linkFile(); 557 QString lf = linkFile();
536 if ( !ensureLinkExists() ) 558 if ( !ensureLinkExists() )
537 return FALSE; 559 return FALSE;
538 Config config( lf, Config::File ); 560 storeLink();
561 return TRUE;
562}
563
564void AppLnk::storeLink() const
565{
566 Config config( mLinkFile, Config::File );
539 config.setGroup("Desktop Entry"); 567 config.setGroup("Desktop Entry");
540 config.writeEntry("Name",mName); 568 config.writeEntry("Name",mName);
541 if ( !mIconFile.isNull() ) config.writeEntry("Icon",mIconFile); 569 if ( !mIconFile.isNull() ) config.writeEntry("Icon",mIconFile);
542 config.writeEntry("Type",type()); 570 config.writeEntry("Type",type());
543 if ( !mComment.isNull() ) config.writeEntry("Comment",mComment); 571 if ( !mComment.isNull() ) config.writeEntry("Comment",mComment);
544 config.writeEntry("File",file()); 572 config.writeEntry("File",file());
545 // write out the id... 573 // write out the id...
546 int i; 574 int i;
547 QStringList sl; 575 QStringList sl;
548 for ( i = 0; i < int(d->mCat.count()); i++ ) { 576 for ( i = 0; i < int(d->mCat.count()); i++ ) {
549 sl.append( QString::number( d->mCat[i] ) ); 577 sl.append( QString::number( d->mCat[i] ) );
550 } 578 }
551 config.writeEntry( "Categories", sl, ';' ); 579 config.writeEntry( "Categories", sl, ';' );
552 580
553 QCopEnvelope e("QPE/System", "linkChanged(QString)"); 581 QCopEnvelope e("QPE/System", "linkChanged(QString)");
554 e << lf; 582 e << mLinkFile;
555
556 return TRUE;
557} 583}
558 584
559/*! 585/*!
560 Sets the property named \a key to \a value. 586 Sets the property named \a key to \a value.
561*/ 587*/
562void AppLnk::setProperty(const QString& key, const QString& value) 588void AppLnk::setProperty(const QString& key, const QString& value)
563{ 589{
564 if ( ensureLinkExists() ) { 590 if ( ensureLinkExists() ) {
565 Config cfg(linkFile(), Config::File); 591 Config cfg(linkFile(), Config::File);
566 cfg.writeEntry(key,value); 592 cfg.writeEntry(key,value);
567 } 593 }
568} 594}
569 595
570/*! 596/*!
571 Returns the property named \a key. 597 Returns the property named \a key.
572*/ 598*/
573QString AppLnk::property(const QString& key) const 599QString AppLnk::property(const QString& key) const
574{ 600{
575 QString lf = linkFile(); 601 QString lf = linkFile();
576 if ( !QFile::exists(lf) ) 602 if ( !QFile::exists(lf) )
577 return QString::null; 603 return QString::null;
578 Config cfg(lf, Config::File); 604 Config cfg(lf, Config::File);
579 return cfg.readEntry(key); 605 return cfg.readEntry(key);
580} 606}
581 607
582 608
583/*! 609/*!
584 Deletes both the linkFile() and file() associated with this AppLnk. 610 Deletes both the linkFile() and file() associated with this AppLnk.
585*/ 611*/
586void AppLnk::removeFiles() 612void AppLnk::removeFiles()
587{ 613{
588 bool valid = isValid(); 614 bool valid = isValid();
589 if ( !valid || QFile::remove(linkFile()) ) { 615 if ( !valid || !linkFileKnown() || QFile::remove(linkFile()) ) {
590 if ( QFile::remove(file()) ) { 616 if ( QFile::remove(file()) ) {
591 QCopEnvelope e("QPE/System", "linkChanged(QString)"); 617 QCopEnvelope e("QPE/System", "linkChanged(QString)");
592 e << linkFile(); 618 if ( linkFileKnown() )
619 e << linkFile();
620 else
621 e << file();
593 } else if ( valid ) { 622 } else if ( valid ) {
594 // restore link 623 // restore link
595 writeLink(); 624 writeLink();
596 } 625 }
597 } 626 }
598} 627}
599 628
600/*! 629/*!
601 Delete the linkFile(), leaving any file() untouched. 630 Delete the linkFile(), leaving any file() untouched.
602*/ 631*/
603void AppLnk::removeLinkFile() 632void AppLnk::removeLinkFile()
604{ 633{
605 if ( isValid() && QFile::remove(linkFile()) ) { 634 if ( isValid() && linkFileKnown() && QFile::remove(linkFile()) ) {
606 QCopEnvelope e("QPE/System", "linkChanged(QString)"); 635 QCopEnvelope e("QPE/System", "linkChanged(QString)");
607 e << linkFile(); 636 e << linkFile();
608 } 637 }
609} 638}
610 639
611class AppLnkSetPrivate { 640class AppLnkSetPrivate {
612public: 641public:
613 AppLnkSetPrivate() 642 AppLnkSetPrivate()
614 { 643 {
615 typPix.setAutoDelete(TRUE); 644 typPix.setAutoDelete(TRUE);
616 typPixBig.setAutoDelete(TRUE); 645 typPixBig.setAutoDelete(TRUE);
617 typName.setAutoDelete(TRUE); 646 typName.setAutoDelete(TRUE);
618 } 647 }
619 648
620 QDict<QPixmap> typPix; 649 QDict<QPixmap> typPix;
621 QDict<QPixmap> typPixBig; 650 QDict<QPixmap> typPixBig;
622 QDict<QString> typName; 651 QDict<QString> typName;
623}; 652};
624 653
625/*! 654/*!
626 \class AppLnkSet applnk.h 655 \class AppLnkSet applnk.h
627 \brief The AppLnkSet class is a set of AppLnk objects. 656 \brief The AppLnkSet class is a set of AppLnk objects.
628*/ 657*/
629 658
630/*! 659/*!
631 \fn QStringList AppLnkSet::types() const 660 \fn QStringList AppLnkSet::types() const
632 661
633 Returns the list of types in the set. 662 Returns the list of types in the set.
634 663
635 \sa AppLnk::type(), typeName(), typePixmap(), typeBigPixmap() 664 \sa AppLnk::type(), typeName(), typePixmap(), typeBigPixmap()
636*/ 665*/
637 666
638/*! 667/*!
639 \fn const QList<AppLnk>& AppLnkSet::children() const 668 \fn const QList<AppLnk>& AppLnkSet::children() const
640 669
641 Returns the members of the set. 670 Returns the members of the set.
642*/ 671*/
643 672
644/*! 673/*!
645 Constructs an empty AppLnkSet. 674 Constructs an empty AppLnkSet.
646*/ 675*/
647AppLnkSet::AppLnkSet() : 676AppLnkSet::AppLnkSet() :
648 d(new AppLnkSetPrivate) 677 d(new AppLnkSetPrivate)
649{ 678{
650} 679}
651 680
652/*! 681/*!
653 Constructs an AppLnkSet that contains AppLnk objects representing 682 Constructs an AppLnkSet that contains AppLnk objects representing
654 all the files in a \a directory (recursively). 683 all the files in a \a directory (recursively).
655 684
656 The directories may contain ".directory" files which overrides 685 The directories may contain ".directory" files which overrides
657 any AppLnk::type() value of AppLnk objects found in the directory. 686 any AppLnk::type() value of AppLnk objects found in the directory.
658 This allows simple localization of application types. 687 This allows simple localization of application types.
659*/ 688*/
660AppLnkSet::AppLnkSet( const QString &directory ) : 689AppLnkSet::AppLnkSet( const QString &directory ) :
661 d(new AppLnkSetPrivate) 690 d(new AppLnkSetPrivate)
662{ 691{
663 QDir dir( directory ); 692 QDir dir( directory );
664 mFile = directory; 693 mFile = directory;
665 findChildren(directory,QString::null,QString::null); 694 findChildren(directory,QString::null,QString::null);
666} 695}
667 696
668/*! 697/*!
669 Detaches all AppLnk objects from the set. The set become empty 698 Detaches all AppLnk objects from the set. The set become empty
670 and the call becomes responsible for deleting the AppLnk objects. 699 and the call becomes responsible for deleting the AppLnk objects.
671*/ 700*/
672void AppLnkSet::detachChildren() 701void AppLnkSet::detachChildren()
673{ 702{
674 QListIterator<AppLnk> it( mApps ); 703 QListIterator<AppLnk> it( mApps );
675 for ( ; it.current(); ) { 704 for ( ; it.current(); ) {
676 AppLnk* a = *it; 705 AppLnk* a = *it;
677 ++it; 706 ++it;
678 a->mId = 0; 707 a->mId = 0;
679 } 708 }
680 mApps.clear(); 709 mApps.clear();
681} 710}
682 711
683/*! 712/*!
684 Destroys the set, deleting all AppLnk objects it contains. 713 Destroys the set, deleting all AppLnk objects it contains.
685 714
686 \sa detachChildren() 715 \sa detachChildren()
687*/ 716*/
688AppLnkSet::~AppLnkSet() 717AppLnkSet::~AppLnkSet()
689{ 718{
690 QListIterator<AppLnk> it( mApps ); 719 QListIterator<AppLnk> it( mApps );
691 for ( ; it.current(); ) { 720 for ( ; it.current(); ) {
692 AppLnk* a = *it; 721 AppLnk* a = *it;
693 ++it; 722 ++it;
694 a->mId = 0; 723 a->mId = 0;
695 delete a; 724 delete a;
696 } 725 }
697 delete d; 726 delete d;
698} 727}
699 728
700void AppLnkSet::findChildren(const QString &dr, const QString& typ, const QString& typName, int depth) 729void AppLnkSet::findChildren(const QString &dr, const QString& typ, const QString& typName, int depth)
701{ 730{
702 depth++; 731 depth++;
703 if ( depth > 10 ) 732 if ( depth > 10 )
704 return; 733 return;
705 734
706 QDir dir( dr ); 735 QDir dir( dr );
707 QString typNameLocal = typName; 736 QString typNameLocal = typName;
708 737
709 if ( dir.exists( ".directory" ) ) { 738 if ( dir.exists( ".directory" ) ) {
710 Config config( dr + "/.directory", Config::File ); 739 Config config( dr + "/.directory", Config::File );
711 config.setGroup( "Desktop Entry" ); 740 config.setGroup( "Desktop Entry" );
712 typNameLocal = config.readEntry( "Name", typNameLocal ); 741 typNameLocal = config.readEntry( "Name", typNameLocal );
713 if ( !typ.isEmpty() ) { 742 if ( !typ.isEmpty() ) {
714 QString iconFile = config.readEntry( "Icon", "AppsIcon" ); 743 QString iconFile = config.readEntry( "Icon", "AppsIcon" );
715 QImage unscaledIcon = Resource::loadImage( iconFile ); 744 QImage unscaledIcon = Resource::loadImage( iconFile );
716 QPixmap pm, bpm; 745 QPixmap pm, bpm;
717 pm.convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) ); 746 pm.convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
718 bpm.convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) ); 747 bpm.convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
719 d->typPix.insert(typ, new QPixmap(pm)); 748 d->typPix.insert(typ, new QPixmap(pm));
720 d->typPixBig.insert(typ, new QPixmap(bpm)); 749 d->typPixBig.insert(typ, new QPixmap(bpm));
721 d->typName.insert(typ, new QString(typNameLocal)); 750 d->typName.insert(typ, new QString(typNameLocal));
722 } 751 }
723 } 752 }
724 753
725 const QFileInfoList *list = dir.entryInfoList(); 754 const QFileInfoList *list = dir.entryInfoList();
726 if ( list ) { 755 if ( list ) {
727 QFileInfo* fi; 756 QFileInfo* fi;
728 bool cadded=FALSE; 757 bool cadded=FALSE;
729 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) { 758 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) {
730 QString bn = fi->fileName(); 759 QString bn = fi->fileName();
731 if ( bn[0] != '.' && bn != "CVS" ) { 760 if ( bn[0] != '.' && bn != "CVS" ) {
732 if ( fi->isDir() ) { 761 if ( fi->isDir() ) {
733 QString c = typ.isNull() ? bn : typ+"/"+bn; 762 QString c = typ.isNull() ? bn : typ+"/"+bn;
734 QString d = typNameLocal.isNull() ? bn : typNameLocal+"/"+bn; 763 QString d = typNameLocal.isNull() ? bn : typNameLocal+"/"+bn;
735 findChildren(fi->filePath(), c, d, depth ); 764 findChildren(fi->filePath(), c, d, depth );
736 } else { 765 } else {
737 if ( fi->extension(FALSE) == "desktop" ) { 766 if ( fi->extension(FALSE) == "desktop" ) {
738 AppLnk* app = new AppLnk( fi->filePath() ); 767 AppLnk* app = new AppLnk( fi->filePath() );
739#ifdef QT_NO_QWS_MULTIPROCESS 768#ifdef QT_NO_QWS_MULTIPROCESS
740 if ( !Global::isBuiltinCommand( app->exec() ) ) 769 if ( !Global::isBuiltinCommand( app->exec() ) )
741 delete app; 770 delete app;
742 else 771 else
743#endif 772#endif
744 { 773 {
745 if ( !typ.isEmpty() ) { 774 if ( !typ.isEmpty() ) {
746 if ( !cadded ) { 775 if ( !cadded ) {
747 typs.append(typ); 776 typs.append(typ);
748 cadded = TRUE; 777 cadded = TRUE;
749 } 778 }
750 app->setType(typ); 779 app->setType(typ);
751 } 780 }
752 add(app); 781 add(app);
753 } 782 }
754 } 783 }
755 } 784 }
756 } 785 }
757 } 786 }
758 } 787 }
759} 788}
760 789
761/*! 790/*!
762 Adds \a f to the set. The set takes over responsibility for deleting \a f. 791 Adds \a f to the set. The set takes over responsibility for deleting \a f.
763 792
764 \sa remove() 793 \sa remove()
765*/ 794*/
766void AppLnkSet::add( AppLnk *f ) 795void AppLnkSet::add( AppLnk *f )
767{ 796{
768 if ( f->mId == 0 ) { 797 if ( f->mId == 0 ) {
769 AppLnk::lastId++; 798 AppLnk::lastId++;
770 f->mId = AppLnk::lastId; 799 f->mId = AppLnk::lastId;
771 mApps.append( f ); 800 mApps.append( f );
772 } else { 801 } else {
773 qWarning("Attempt to add an AppLnk twice"); 802 qWarning("Attempt to add an AppLnk twice");
774 } 803 }
775} 804}
776 805
777/*! 806/*!
778 Removes \a f to the set, returning whether \a f was in the set. 807 Removes \a f to the set, returning whether \a f was in the set.
779 The caller becomes responsible for deleting \a f. 808 The caller becomes responsible for deleting \a f.
780 809
781 \sa add() 810 \sa add()
782*/ 811*/
783bool AppLnkSet::remove( AppLnk *f ) 812bool AppLnkSet::remove( AppLnk *f )
784{ 813{
785 if ( mApps.remove( f ) ) { 814 if ( mApps.remove( f ) ) {
786 f->mId = 0; 815 f->mId = 0;
787 return TRUE; 816 return TRUE;
788 } 817 }
789 return FALSE; 818 return FALSE;
790} 819}
791 820
792/*! 821/*!
793 Returns the localized name for type \a t. 822 Returns the localized name for type \a t.
794*/ 823*/
795QString AppLnkSet::typeName( const QString& t ) const 824QString AppLnkSet::typeName( const QString& t ) const
796{ 825{
797 QString *st = d->typName.find(t); 826 QString *st = d->typName.find(t);
798 return st ? *st : QString::null; 827 return st ? *st : QString::null;
799} 828}
800 829
801/*! 830/*!
802 Returns the small pixmap associated with type \a t. 831 Returns the small pixmap associated with type \a t.
803*/ 832*/
804QPixmap AppLnkSet::typePixmap( const QString& t ) const 833QPixmap AppLnkSet::typePixmap( const QString& t ) const
805{ 834{
806 QPixmap *pm = d->typPix.find(t); 835 QPixmap *pm = d->typPix.find(t);
807 return pm ? *pm : QPixmap(); 836 return pm ? *pm : QPixmap();
808} 837}
809 838
810/*! 839/*!
811 Returns the large pixmap associated with type \a t. 840 Returns the large pixmap associated with type \a t.
812*/ 841*/
813QPixmap AppLnkSet::typeBigPixmap( const QString& t ) const 842QPixmap AppLnkSet::typeBigPixmap( const QString& t ) const
814{ 843{
815 QPixmap *pm = d->typPixBig.find(t); 844 QPixmap *pm = d->typPixBig.find(t);
816 return pm ? *pm : QPixmap(); 845 return pm ? *pm : QPixmap();
817} 846}
818 847
819/*! 848/*!
820 Returns the AppLnk with the given \a id. 849 Returns the AppLnk with the given \a id.
821*/ 850*/
822const AppLnk *AppLnkSet::find( int id ) const 851const AppLnk *AppLnkSet::find( int id ) const
823{ 852{
824 QListIterator<AppLnk> it( children() ); 853 QListIterator<AppLnk> it( children() );
825 854
826 for ( ; it.current(); ++it ) { 855 for ( ; it.current(); ++it ) {
827 const AppLnk *app = it.current(); 856 const AppLnk *app = it.current();
828 if ( app->id() == id ) 857 if ( app->id() == id )
829 return app; 858 return app;
830 } 859 }
831 860
832 return 0; 861 return 0;
833} 862}
834 863
835/*! 864/*!
836 Returns the AppLnk with the given \a exec attribute. 865 Returns the AppLnk with the given \a exec attribute.
837*/ 866*/
838const AppLnk *AppLnkSet::findExec( const QString& exec ) const 867const AppLnk *AppLnkSet::findExec( const QString& exec ) const
839{ 868{
840 QListIterator<AppLnk> it( children() ); 869 QListIterator<AppLnk> it( children() );
841 870
842 for ( ; it.current(); ++it ) { 871 for ( ; it.current(); ++it ) {
843 const AppLnk *app = it.current(); 872 const AppLnk *app = it.current();
844 if ( app->exec() == exec ) 873 if ( app->exec() == exec )
845 return app; 874 return app;
846 } 875 }
847 876
848 return 0; 877 return 0;
849} 878}
850 879
851/*! 880/*!
852 \class DocLnkSet applnk.h 881 \class DocLnkSet applnk.h
853 \brief The DocLnkSet class is a set of DocLnk objects. 882 \brief The DocLnkSet class is a set of DocLnk objects.
854*/ 883*/
855 884
856/*! 885/*!
857 \fn const QList<DocLnk>& DocLnkSet::children() const 886 \fn const QList<DocLnk>& DocLnkSet::children() const
858 887
859 Returns the members of the set. 888 Returns the members of the set.
860*/ 889*/
861 890
862/*! 891/*!
863 Constructs an empty DocLnkSet. 892 Constructs an empty DocLnkSet.
864 893
865 \sa appendFrom() 894 \sa appendFrom()
866*/ 895*/
867DocLnkSet::DocLnkSet() 896DocLnkSet::DocLnkSet()
868{ 897{
869} 898}
870 899
871/*! 900/*!
872 Constructs an DocLnkSet that contains DocLnk objects representing 901 Constructs an DocLnkSet that contains DocLnk objects representing
873 all the files in a \a directory (recursively). 902 all the files in a \a directory (recursively).
874 903
875 If \a mimefilter is not null, 904 If \a mimefilter is not null,
876 only documents with a MIME type matching \a mimefilter are selected. 905 only documents with a MIME type matching \a mimefilter are selected.
877 The value may contain multiple wild-card patterns separated by ";", 906 The value may contain multiple wild-card patterns separated by ";",
878 such as "*o/mpeg;audio/x-wav". 907 such as "*o/mpeg;audio/x-wav".
879*/ 908*/
880DocLnkSet::DocLnkSet( const QString &directory, const QString& mimefilter ) : 909DocLnkSet::DocLnkSet( const QString &directory, const QString& mimefilter ) :
881 AppLnkSet() 910 AppLnkSet()
882{ 911{
883 QDir dir( directory ); 912 QDir dir( directory );
884 mFile = dir.dirName(); 913 mFile = dir.dirName();
885 QDict<void> reference; 914 QDict<void> reference;
886 915
887 QStringList subFilter = QStringList::split(";", mimefilter); 916 QStringList subFilter = QStringList::split(";", mimefilter);
888 QValueList<QRegExp> mimeFilters; 917 QValueList<QRegExp> mimeFilters;
889 for( QStringList::Iterator it = subFilter.begin(); it != subFilter.end(); ++ it ) 918 for( QStringList::Iterator it = subFilter.begin(); it != subFilter.end(); ++ it )
890 mimeFilters.append( QRegExp(*it, FALSE, TRUE) ); 919 mimeFilters.append( QRegExp(*it, FALSE, TRUE) );
891 920
892 findChildren(directory, mimeFilters, reference); 921 findChildren(directory, mimeFilters, reference);
893 922
894 const QList<DocLnk> &list = children(); 923 const QList<DocLnk> &list = children();
895 for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) { 924 for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) {
896 reference.remove( (*it)->file() ); 925 reference.remove( (*it)->file() );
897 } 926 }
898 927
899 for ( QDictIterator<void> dit(reference); dit.current(); ++dit ) { 928 for ( QDictIterator<void> dit(reference); dit.current(); ++dit ) {
900 if ( dit.current() == (void*)2 ) { 929 if ( dit.current() == (void*)2 ) {
901 // Unreferenced, make an unwritten link 930 // Unreferenced, make an unwritten link
902 DocLnk* dl = new DocLnk; 931 DocLnk* dl = new DocLnk;
903 QFileInfo fi( dit.currentKey() ); 932 QFileInfo fi( dit.currentKey() );
904 dl->setFile(fi.filePath()); 933 dl->setFile(fi.filePath());
905 dl->setName(fi.baseName()); 934 dl->setName(fi.baseName());
906 // #### default to current path? 935 // #### default to current path?
907 // dl->setCategories( ... ); 936 // dl->setCategories( ... );
908 bool match = mimefilter.isNull(); 937 bool match = mimefilter.isNull();
909 if ( !match ) 938 if ( !match )
910 for( QValueList<QRegExp>::Iterator it = mimeFilters.begin(); it != mimeFilters.end() && !match; ++ it ) 939 for( QValueList<QRegExp>::Iterator it = mimeFilters.begin(); it != mimeFilters.end() && !match; ++ it )
911 if ( (*it).match(dl->type()) >= 0 ) 940 if ( (*it).match(dl->type()) >= 0 )
912 match = TRUE; 941 match = TRUE;
913 if ( match /* && dl->type() != "application/octet-stream" */ 942 if ( match /* && dl->type() != "application/octet-stream" */
914 && !!dl->exec() ) 943 && !!dl->exec() )
915 add(dl); 944 add(dl);
916 else 945 else
917 delete dl; 946 delete dl;
918 } 947 }
919 } 948 }
920} 949}
921 950
922// other becomes empty 951// other becomes empty
923/*! 952/*!
924 Transfers all DocLnk objects from \a other to this set. \a other becomes 953 Transfers all DocLnk objects from \a other to this set. \a other becomes
925 empty. 954 empty.
926*/ 955*/
927void DocLnkSet::appendFrom( DocLnkSet& other ) 956void DocLnkSet::appendFrom( DocLnkSet& other )
928{ 957{
929 if ( &other == this ) 958 if ( &other == this )
930 return; 959 return;
931 QListIterator<AppLnk> it( other.mApps ); 960 QListIterator<AppLnk> it( other.mApps );
932 for ( ; it.current(); ) { 961 for ( ; it.current(); ) {
933 mApps.append(*it); 962 mApps.append(*it);
934 ++it; 963 ++it;
935 } 964 }
936 other.mApps.clear(); 965 other.mApps.clear();
937} 966}
938 967
939void DocLnkSet::findChildren(const QString &dr, const QValueList<QRegExp> &mimeFilters, QDict<void> &reference, int depth) 968void DocLnkSet::findChildren(const QString &dr, const QValueList<QRegExp> &mimeFilters, QDict<void> &reference, int depth)
940{ 969{
941 depth++; 970 depth++;
942 if ( depth > 10 ) 971 if ( depth > 10 )
943 return; 972 return;
944 973
945 QDir dir( dr ); 974 QDir dir( dr );
946 975
947 const QFileInfoList *list = dir.entryInfoList(); 976 const QFileInfoList *list = dir.entryInfoList();
948 if ( list ) { 977 if ( list ) {
949 QFileInfo* fi; 978 QFileInfo* fi;
950 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) { 979 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) {
951 QString bn = fi->fileName(); 980 QString bn = fi->fileName();
952 if ( bn[0] != '.' && bn != "CVS" ) { 981 if ( bn[0] != '.' && bn != "CVS" ) {
953 if ( fi->isDir() ) { 982 if ( fi->isDir() ) {
954 findChildren(fi->filePath(), mimeFilters, reference, depth); 983 findChildren(fi->filePath(), mimeFilters, reference, depth);
955 } else { 984 } else {
956 if ( fi->extension(FALSE) == "desktop" ) { 985 if ( fi->extension(FALSE) == "desktop" ) {
957 DocLnk* dl = new DocLnk( fi->filePath() ); 986 DocLnk* dl = new DocLnk( fi->filePath() );
958 QFileInfo fi2(dl->file()); 987 QFileInfo fi2(dl->file());
959 bool match = FALSE; 988 bool match = FALSE;
960 if ( !fi2.exists() ) { 989 if ( !fi2.exists() ) {
961 dir.remove( dl->file() ); 990 dir.remove( dl->file() );
962 } 991 }
963 if ( mimeFilters.count() == 0 ) { 992 if ( mimeFilters.count() == 0 ) {
964 add( dl ); 993 add( dl );
965 match = TRUE; 994 match = TRUE;
966 } else { 995 } else {
967 for( QValueList<QRegExp>::ConstIterator it = mimeFilters.begin(); it != mimeFilters.end(); ++ it ) { 996 for( QValueList<QRegExp>::ConstIterator it = mimeFilters.begin(); it != mimeFilters.end(); ++ it ) {
968 if ( (*it).match(dl->type()) >= 0 ) { 997 if ( (*it).match(dl->type()) >= 0 ) {
969 add(dl); 998 add(dl);
970 match = TRUE; 999 match = TRUE;
971 } 1000 }
972 } 1001 }
973 } 1002 }
974 if ( !match ) 1003 if ( !match )
975 delete dl; 1004 delete dl;
976 } else { 1005 } else {
977 if ( !reference.find(fi->fileName()) ) 1006 if ( !reference.find(fi->fileName()) )
978 reference.insert(fi->filePath(), (void*)2); 1007 reference.insert(fi->filePath(), (void*)2);
979 } 1008 }
980 } 1009 }
981 } 1010 }
982 } 1011 }
983 } 1012 }
984} 1013}
985 1014
986/*! 1015/*!
987 \class DocLnk applnk.h 1016 \class DocLnk applnk.h
988 \brief The DocLnk class represents loaded document references. 1017 \brief The DocLnk class represents loaded document references.
989*/ 1018*/
990 1019
991/*! 1020/*!
992 \fn DocLnk::DocLnk( const DocLnk &o ) 1021 \fn DocLnk::DocLnk( const DocLnk &o )
993 1022
994 Copies \a o. 1023 Copies \a o.
995*/ 1024*/
996 1025
997/*! 1026/*!
998 Constructs a DocLnk from a valid .desktop \a file or a new .desktop 1027 Constructs a DocLnk from a valid .desktop \a file or a new .desktop
999 \a file for other files. 1028 \a file for other files.
1000*/ 1029*/
1001DocLnk::DocLnk( const QString &file ) : 1030DocLnk::DocLnk( const QString &file ) :
1002 AppLnk(file) 1031 AppLnk(file)
1003{ 1032{
1004 init(file); 1033 init(file);
1005} 1034}
1006 1035
1007/*! 1036/*!
1008 Constructs a DocLnk from a valid .desktop \a file or a new .desktop 1037 Constructs a DocLnk from a valid .desktop \a file or a new .desktop
1009 \a file for other files. If \a may_be_desktopfile is TRUE, then \a file 1038 \a file for other files. If \a may_be_desktopfile is TRUE, then \a file
1010 is first attempted to be read as a .desktop file. 1039 is first attempted to be read as a .desktop file.
1011*/ 1040*/
1012DocLnk::DocLnk( const QString &file, bool may_be_desktopfile ) : 1041DocLnk::DocLnk( const QString &file, bool may_be_desktopfile ) :
1013 AppLnk(may_be_desktopfile ? file : QString::null) 1042 AppLnk(may_be_desktopfile ? file : QString::null)
1014{ 1043{
1015 init(file); 1044 init(file);
1016} 1045}
1017 1046
1018void DocLnk::init(const QString &file) 1047void DocLnk::init(const QString &file)
1019{ 1048{
1020 if ( isValid() ) { 1049 if ( isValid() ) {
1021#ifndef FORCED_DIR_STRUCTURE_WAY 1050#ifndef FORCED_DIR_STRUCTURE_WAY
1022 if ( mType.isNull() ) 1051 if ( mType.isNull() )
1023 // try to infer it 1052 // try to infer it
1024#endif 1053#endif
1025 { 1054 {
1026 int s0 = file.findRev('/'); 1055 int s0 = file.findRev('/');
1027 if ( s0 > 0 ) { 1056 if ( s0 > 0 ) {
1028 int s1 = file.findRev('/',s0-1); 1057 int s1 = file.findRev('/',s0-1);
1029 if ( s1 > 0 ) { 1058 if ( s1 > 0 ) {
1030 int s2 = file.findRev('/',s1-1); 1059 int s2 = file.findRev('/',s1-1);
1031 if ( s2 > 0 ) { 1060 if ( s2 > 0 ) {
1032 mType = file.mid(s2+1,s0-s2-1); 1061 mType = file.mid(s2+1,s0-s2-1);
1033 } 1062 }
1034 } 1063 }
1035 } 1064 }
1036 } 1065 }
1037 } else if ( QFile::exists(file) ) { 1066 } else if ( QFile::exists(file) ) {
1038 QString n = file; 1067 QString n = file;
1039 n.replace(QRegExp("\\..*"),""); 1068 n.replace(QRegExp("\\..*"),"");
1040 n.replace(QRegExp(".*/"),""); 1069 n.replace(QRegExp(".*/"),"");
1041 setName( n ); 1070 setName( n );
1042 setFile( file ); 1071 setFile( file );
1043 } 1072 }
1044 MimeType mt(mType); 1073 MimeType mt(mType);
1045 if( mt.application() ) 1074 if( mt.application() )
1046 mExec = mt.application()->exec(); 1075 mExec = mt.application()->exec();
1047} 1076}
1048 1077
1049/*! 1078/*!
1050 Constructs an invalid DocLnk. 1079 Constructs an invalid DocLnk.
1051*/ 1080*/
1052DocLnk::DocLnk() 1081DocLnk::DocLnk()
1053{ 1082{
1054} 1083}
1055 1084
1056/*! 1085/*!
1057 Destroys the DocLnk. As with AppLnk objects, a run-time error 1086 Destroys the DocLnk. As with AppLnk objects, a run-time error
1058 occurs if the DocLnk is a member of a DocLnkSet (or AppLnkSet). 1087 occurs if the DocLnk is a member of a DocLnkSet (or AppLnkSet).
1059*/ 1088*/
1060DocLnk::~DocLnk() 1089DocLnk::~DocLnk()
1061{ 1090{
1062} 1091}
1063 1092
1064/*! 1093/*!
1065 \reimp 1094 \reimp
1066*/ 1095*/
1067QString DocLnk::exec() const 1096QString DocLnk::exec() const
1068{ 1097{
1069 MimeType mt(type()); 1098 MimeType mt(type());
1070 const AppLnk* app = mt.application(); 1099 const AppLnk* app = mt.application();
1071 if ( app ) 1100 if ( app )
1072 return app->exec(); 1101 return app->exec();
1073 else 1102 else
1074 return QString::null; 1103 return QString::null;
1075} 1104}
1076 1105
1077/*! 1106/*!
1078 \reimp 1107 \reimp
1079*/ 1108*/
1080void DocLnk::invoke(const QStringList& args) const 1109void DocLnk::invoke(const QStringList& args) const
1081{ 1110{
1082 MimeType mt(type()); 1111 MimeType mt(type());
1083 const AppLnk* app = mt.application(); 1112 const AppLnk* app = mt.application();
1084 if ( app ) { 1113 if ( app ) {
1085 QStringList a = args; 1114 QStringList a = args;
1086 if ( QFile::exists( linkFile() ) ) 1115 if ( linkFileKnown() && QFile::exists( linkFile() ) )
1087 a.append(linkFile()); 1116 a.append(linkFile());
1088 else 1117 else
1089 a.append(file()); 1118 a.append(file());
1090 app->execute(a); 1119 app->execute(a);
1091 } 1120 }
1092} 1121}
1093 1122