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