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