summaryrefslogtreecommitdiff
path: root/library/applnk.cpp
authorwimpie <wimpie>2005-01-09 02:59:13 (UTC)
committer wimpie <wimpie>2005-01-09 02:59:13 (UTC)
commit987bc9a2c5b39ddd4dc2a665cea65688bfd2179e (patch) (unidiff)
tree815fc6d12162f1a5eccc4b1ae0da61dea3811bdf /library/applnk.cpp
parente54346d28b19d3ac671802a25e8c03f346693291 (diff)
downloadopie-987bc9a2c5b39ddd4dc2a665cea65688bfd2179e.zip
opie-987bc9a2c5b39ddd4dc2a665cea65688bfd2179e.tar.gz
opie-987bc9a2c5b39ddd4dc2a665cea65688bfd2179e.tar.bz2
applnk : lazy loading of mime type icons (load only when needed)
resource.cpp : print warning when requested image cannot be found and print the name of that image too
Diffstat (limited to 'library/applnk.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/applnk.cpp130
1 files changed, 81 insertions, 49 deletions
diff --git a/library/applnk.cpp b/library/applnk.cpp
index 1c1a227..80f2c62 100644
--- a/library/applnk.cpp
+++ b/library/applnk.cpp
@@ -1,1497 +1,1529 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of the Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#define QTOPIA_INTERNAL_MIMEEXT 21#define QTOPIA_INTERNAL_MIMEEXT
22#define QTOPIA_INTERNAL_PRELOADACCESS 22#define QTOPIA_INTERNAL_PRELOADACCESS
23#define QTOPIA_INTERNAL_APPLNKASSIGN 23#define QTOPIA_INTERNAL_APPLNKASSIGN
24 24
25#include "applnk.h" 25#include "applnk.h"
26 26
27#include <qpe/qpeapplication.h> 27#include <qpe/qpeapplication.h>
28#include <qpe/categories.h> 28#include <qpe/categories.h>
29#include <qpe/categoryselect.h> 29#include <qpe/categoryselect.h>
30#include <qpe/global.h> 30#include <qpe/global.h>
31#include <qpe/qcopenvelope_qws.h> 31#include <qpe/qcopenvelope_qws.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 <qdir.h> 37#include <qdir.h>
38 38
39 39
40#include <stdlib.h> 40#include <stdlib.h>
41 41
42int AppLnk::lastId = 5000; 42int AppLnk::lastId = 5000;
43 43
44static int smallSize = 14; 44static int smallSize = 14;
45static int bigSize = 32; 45static int bigSize = 32;
46 46
47static QString safeFileName(const QString& n) 47static QString safeFileName(const QString& n)
48{ 48{
49 QString safename=n; 49 QString safename=n;
50 safename.replace(QRegExp("[^0-9A-Za-z.]"),"_"); 50 safename.replace(QRegExp("[^0-9A-Za-z.]"),"_");
51 safename.replace(QRegExp("^[^A-Za-z]*"),""); 51 safename.replace(QRegExp("^[^A-Za-z]*"),"");
52 if ( safename.isEmpty() ) 52 if ( safename.isEmpty() )
53 safename = "_"; 53 safename = "_";
54 return safename; 54 return safename;
55} 55}
56 56
57static bool prepareDirectories(const QString& lf) 57static bool prepareDirectories(const QString& lf)
58{ 58{
59 if ( !QFile::exists(lf) ) { 59 if ( !QFile::exists(lf) ) {
60 // May need to create directories 60 // May need to create directories
61 QFileInfo fi(lf); 61 QFileInfo fi(lf);
62 if ( system(("mkdir -p "+fi.dirPath(TRUE))) ) 62 if ( system(("mkdir -p "+fi.dirPath(TRUE))) )
63 return FALSE; 63 return FALSE;
64 } 64 }
65 return TRUE; 65 return TRUE;
66} 66}
67 67
68class AppLnkPrivate 68class AppLnkPrivate
69{ 69{
70public: 70public:
71 /* the size of the Pixmap */ 71 /* the size of the Pixmap */
72 enum Size {Normal = 0, Big }; 72 enum Size {Normal = 0, Big };
73 AppLnkPrivate() { 73 AppLnkPrivate() {
74 /* we want one normal and one big item */ 74 /* we want one normal and one big item */
75 75
76 QPixmap pix; 76 QPixmap pix;
77 mPixmaps.insert(0, pix ); 77 mPixmaps.insert(0, pix );
78 mPixmaps.insert(1, pix); 78 mPixmaps.insert(1, pix);
79 } 79 }
80 80
81 QStringList mCatList; // always correct 81 QStringList mCatList; // always correct
82 QArray<int> mCat; // cached value; correct if not empty 82 QArray<int> mCat; // cached value; correct if not empty
83 QMap<int, QPixmap> mPixmaps; 83 QMap<int, QPixmap> mPixmaps;
84 84
85 void updateCatListFromArray() 85 void updateCatListFromArray()
86 { 86 {
87 Categories cat( 0 ); 87 Categories cat( 0 );
88 cat.load( categoryFileName() ); 88 cat.load( categoryFileName() );
89 // we need to update the names for the mCat... to mCatList 89 // we need to update the names for the mCat... to mCatList
90 mCatList.clear(); 90 mCatList.clear();
91 for (uint i = 0; i < mCat.count(); i++ ) 91 for (uint i = 0; i < mCat.count(); i++ )
92 mCatList << cat.label("Document View", mCat[i] ); 92 mCatList << cat.label("Document View", mCat[i] );
93 93
94 } 94 }
95 95
96 void setCatArrayDirty() 96 void setCatArrayDirty()
97 { 97 {
98 mCat.resize(0); 98 mCat.resize(0);
99 } 99 }
100 100
101 void ensureCatArray() 101 void ensureCatArray()
102 { 102 {
103 if ( mCat.count() > 0 || mCatList.count()==0 ) 103 if ( mCat.count() > 0 || mCatList.count()==0 )
104 return; 104 return;
105 105
106 Categories cat( 0 ); 106 Categories cat( 0 );
107 cat.load( categoryFileName() ); 107 cat.load( categoryFileName() );
108 mCat.resize( mCatList.count() ); 108 mCat.resize( mCatList.count() );
109 int i; 109 int i;
110 QStringList::ConstIterator it; 110 QStringList::ConstIterator it;
111 for ( i = 0, it = mCatList.begin(); it != mCatList.end(); 111 for ( i = 0, it = mCatList.begin(); it != mCatList.end();
112 ++it, i++ ) { 112 ++it, i++ ) {
113 113
114 bool number; 114 bool number;
115 int id = (*it).toInt( &number ); 115 int id = (*it).toInt( &number );
116 if ( !number ) { 116 if ( !number ) {
117 id = cat.id( "Document View", *it ); 117 id = cat.id( "Document View", *it );
118 if ( id == 0 ) 118 if ( id == 0 )
119 id = cat.addCategory( "Document View", *it ); 119 id = cat.addCategory( "Document View", *it );
120 } 120 }
121 mCat[i] = id; 121 mCat[i] = id;
122 } 122 }
123 } 123 }
124}; 124};
125 125
126/*! 126/*!
127 \class AppLnk applnk.h 127 \class AppLnk applnk.h
128 \brief The AppLnk class represents an application available on the system. 128 \brief The AppLnk class represents an application available on the system.
129 129
130 Every Qtopia application \e app has a corresponding \e app.desktop 130 Every Qtopia application \e app has a corresponding \e app.desktop
131 file. When one of these files is read its data is stored as an 131 file. When one of these files is read its data is stored as an
132 AppLnk object. 132 AppLnk object.
133 133
134 The AppLnk class introduces some Qtopia-specific concepts, and 134 The AppLnk class introduces some Qtopia-specific concepts, and
135 provides a variety of functions, as described in the following 135 provides a variety of functions, as described in the following
136 sections. 136 sections.
137 \tableofcontents 137 \tableofcontents
138 138
139 \target Types 139 \target Types
140 \section1 Types 140 \section1 Types
141 141
142 Every AppLnk object has a \e type. For applications, games and 142 Every AppLnk object has a \e type. For applications, games and
143 settings the type is \c Application; for documents the 143 settings the type is \c Application; for documents the
144 type is the document's MIME type. 144 type is the document's MIME type.
145 145
146 \target files-and-links 146 \target files-and-links
147 \section1 Files and Links 147 \section1 Files and Links
148 148
149 When you create an AppLnk (or more likely, a \link doclnk.html 149 When you create an AppLnk (or more likely, a \link doclnk.html
150 DocLnk\endlink), you don't deal directly with filenames in the 150 DocLnk\endlink), you don't deal directly with filenames in the
151 filesystem. Instead you do this: 151 filesystem. Instead you do this:
152 \code 152 \code
153 DocLnk d; 153 DocLnk d;
154 d.setType("text/plain"); 154 d.setType("text/plain");
155 d.setName("My Nicely Named Document / Whatever"); // Yes, "/" is legal. 155 d.setName("My Nicely Named Document / Whatever"); // Yes, "/" is legal.
156 \endcode 156 \endcode
157 At this point, the file() and linkFile() are unknown. Normally 157 At this point, the file() and linkFile() are unknown. Normally
158 this is uninteresting, and the names become automatically known, 158 this is uninteresting, and the names become automatically known,
159 and more importantly, becomes reserved, when you ask what they are: 159 and more importantly, becomes reserved, when you ask what they are:
160 160
161 \code 161 \code
162 QString fn = d.file(); 162 QString fn = d.file();
163 \endcode 163 \endcode
164 This invents a filename, and creates the file on disk (an empty 164 This invents a filename, and creates the file on disk (an empty
165 reservation file) to prevent the name being used by another 165 reservation file) to prevent the name being used by another
166 application. 166 application.
167 167
168 In some circumstances, you don't want to create the file if it 168 In some circumstances, you don't want to create the file if it
169 doesn't already exist (e.g. in the Document tab, some of the \link 169 doesn't already exist (e.g. in the Document tab, some of the \link
170 doclnk.html DocLnk\endlink objects represented by icons are 170 doclnk.html DocLnk\endlink objects represented by icons are
171 DocLnk's created just for that view - they don't have 171 DocLnk's created just for that view - they don't have
172 corresponding \c .desktop files. To avoid littering empty 172 corresponding \c .desktop files. To avoid littering empty
173 reservation files around, we check in a few places to see whether 173 reservation files around, we check in a few places to see whether
174 the file really needs to exist). 174 the file really needs to exist).
175 175
176 \section1 Functionality 176 \section1 Functionality
177 177
178 AppLnk objects are created by calling the constructor with the 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 179 name of a \e .desktop file. The object can be checked for validity
180 using isValid(). 180 using isValid().
181 181
182 The following functions are used to set or retrieve information 182 The following functions are used to set or retrieve information
183 about the application: 183 about the application:
184 \table 184 \table
185 \header \i Get Function \i Set Function \i Short Description 185 \header \i Get Function \i Set Function \i Short Description
186 \row \i \l name() \i \l setName() \i application's name 186 \row \i \l name() \i \l setName() \i application's name
187 \row \i \l pixmap() \i \e none \i application's icon 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 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 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 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 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 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 193 \row \i \l exec() \i \l setExec() \i executable's filename
194 \row \i \l file() \i \e none \i document'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 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 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} 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 198 \row \i \l fileKnown() \i \e none \i see \link
199#files-and-links Files and Links\endlink above 199#files-and-links Files and Links\endlink above
200 \row \i \l linkFileKnown() \i \e none \i see \link 200 \row \i \l linkFileKnown() \i \e none \i see \link
201#files-and-links Files and Links\endlink above 201#files-and-links Files and Links\endlink above
202 \row \i \l property() \i \l setProperty() \i any AppLnk property 202 \row \i \l property() \i \l setProperty() \i any AppLnk property
203 can be retrieved or set (if writeable) using these 203 can be retrieved or set (if writeable) using these
204 \endtable 204 \endtable
205 205
206 To save an AppLnk to disk use writeLink(). To execute the 206 To save an AppLnk to disk use writeLink(). To execute the
207 application that the AppLnk object refers to, use execute(). 207 application that the AppLnk object refers to, use execute().
208 208
209 AppLnk's can be deleted from disk using removeLinkFile(). To 209 AppLnk's can be deleted from disk using removeLinkFile(). To
210 remove both the link and the application's executable use 210 remove both the link and the application's executable use
211 removeFiles(). 211 removeFiles().
212 212
213 Icon sizes can be globally changed (but only for AppLnk objects 213 Icon sizes can be globally changed (but only for AppLnk objects
214 created after the calls) with setSmallIconSize() and 214 created after the calls) with setSmallIconSize() and
215 setBigIconSize(). 215 setBigIconSize().
216 216
217 \ingroup qtopiaemb 217 \ingroup qtopiaemb
218*/ 218*/
219 219
220/*! 220/*!
221 Sets the size used for small icons to \a small pixels. 221 Sets the size used for small icons to \a small pixels.
222 Only affects AppLnk objects created after the call. 222 Only affects AppLnk objects created after the call.
223 223
224 \sa smallIconSize() setIcon() 224 \sa smallIconSize() setIcon()
225*/ 225*/
226void AppLnk::setSmallIconSize(int small) 226void AppLnk::setSmallIconSize(int small)
227{ 227{
228 smallSize = small; 228 smallSize = small;
229} 229}
230 230
231/*! 231/*!
232 Returns the size used for small icons. 232 Returns the size used for small icons.
233 233
234 \sa setSmallIconSize() setIcon() 234 \sa setSmallIconSize() setIcon()
235*/ 235*/
236int AppLnk::smallIconSize() 236int AppLnk::smallIconSize()
237{ 237{
238 return smallSize; 238 return smallSize;
239} 239}
240 240
241 241
242/*! 242/*!
243 Sets the size used for large icons to \a big pixels. 243 Sets the size used for large icons to \a big pixels.
244 Only affects AppLnk objects created after the call. 244 Only affects AppLnk objects created after the call.
245 245
246 \sa bigIconSize() setIcon() 246 \sa bigIconSize() setIcon()
247*/ 247*/
248void AppLnk::setBigIconSize(int big) 248void AppLnk::setBigIconSize(int big)
249{ 249{
250 bigSize = big; 250 bigSize = big;
251} 251}
252 252
253/*! 253/*!
254 Returns the size used for large icons. 254 Returns the size used for large icons.
255 255
256 \sa setBigIconSize() setIcon() 256 \sa setBigIconSize() setIcon()
257*/ 257*/
258int AppLnk::bigIconSize() 258int AppLnk::bigIconSize()
259{ 259{
260 return bigSize; 260 return bigSize;
261} 261}
262 262
263 263
264/*! 264/*!
265 \fn QString AppLnk::name() const 265 \fn QString AppLnk::name() const
266 266
267 Returns the Name property. This is the user-visible name for the 267 Returns the Name property. This is the user-visible name for the
268 document or application, not the filename. 268 document or application, not the filename.
269 269
270 See \link #files-and-links Files and Links\endlink. 270 See \link #files-and-links Files and Links\endlink.
271 271
272 \sa setName() 272 \sa setName()
273*/ 273*/
274/*! 274/*!
275 \fn QString AppLnk::exec() const 275 \fn QString AppLnk::exec() const
276 276
277 Returns the Exec property. This is the name of the executable 277 Returns the Exec property. This is the name of the executable
278 program associated with the AppLnk. 278 program associated with the AppLnk.
279 279
280 \sa setExec() 280 \sa setExec()
281*/ 281*/
282/*! 282/*!
283 \fn QString AppLnk::rotation() const 283 \fn QString AppLnk::rotation() const
284 284
285 Returns the Rotation property. The value is 0, 90, 180 or 270 285 Returns the Rotation property. The value is 0, 90, 180 or 270
286 degrees. 286 degrees.
287*/ 287*/
288/*! 288/*!
289 \fn QString AppLnk::comment() const 289 \fn QString AppLnk::comment() const
290 290
291 Returns the Comment property. 291 Returns the Comment property.
292 292
293 \sa setComment() 293 \sa setComment()
294*/ 294*/
295/*! 295/*!
296 \fn QStringList AppLnk::mimeTypes() const 296 \fn QStringList AppLnk::mimeTypes() const
297 297
298 Returns the MimeTypes property. This is the list of MIME types 298 Returns the MimeTypes property. This is the list of MIME types
299 that the application can view or edit. 299 that the application can view or edit.
300*/ 300*/
301/*! 301/*!
302 \fn const QArray<int>& AppLnk::categories() const 302 \fn const QArray<int>& AppLnk::categories() const
303 303
304 Returns the Categories property. 304 Returns the Categories property.
305 305
306 See the CategoryWidget for more details. 306 See the CategoryWidget for more details.
307 307
308 \sa setCategories() 308 \sa setCategories()
309*/ 309*/
310 310
311const QArray<int>& AppLnk::categories() const 311const QArray<int>& AppLnk::categories() const
312{ 312{
313 d->ensureCatArray(); 313 d->ensureCatArray();
314 return d->mCat; 314 return d->mCat;
315} 315}
316 316
317/*! 317/*!
318 \fn int AppLnk::id() const 318 \fn int AppLnk::id() const
319 319
320 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,
321 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
322 duration of the current process. 322 duration of the current process.
323 323
324 \sa AppLnkSet::find() 324 \sa AppLnkSet::find()
325*/ 325*/
326 326
327/*! 327/*!
328 \fn bool AppLnk::isValid() const 328 \fn bool AppLnk::isValid() const
329 329
330 Returns TRUE if this AppLnk is valid; otherwise returns FALSE. 330 Returns TRUE if this AppLnk is valid; otherwise returns FALSE.
331*/ 331*/
332/*! 332/*!
333 \fn bool AppLnk::fileKnown() const 333 \fn bool AppLnk::fileKnown() const
334 334
335 If the with the AppLnk associated file is not equal to QString::null 335 If the with the AppLnk associated file is not equal to QString::null
336*/ 336*/
337/*! 337/*!
338 \fn bool AppLnk::linkFileKnown()const 338 \fn bool AppLnk::linkFileKnown()const
339 339
340 The filename of the AppLnk 340 The filename of the AppLnk
341 341
342*/ 342*/
343/*! 343/*!
344 \fn void AppLnk::setRotation( const QString& ) 344 \fn void AppLnk::setRotation( const QString& )
345 345
346 The default rotation of the associated application. This 346 The default rotation of the associated application. This
347 function is included inline for binary compatible issues 347 function is included inline for binary compatible issues
348*/ 348*/
349/*! 349/*!
350 Creates an invalid AppLnk. 350 Creates an invalid AppLnk.
351 351
352 \sa isValid() 352 \sa isValid()
353*/ 353*/
354AppLnk::AppLnk() 354AppLnk::AppLnk()
355{ 355{
356 mId = 0; 356 mId = 0;
357 d = new AppLnkPrivate(); 357 d = new AppLnkPrivate();
358} 358}
359 359
360/*! 360/*!
361 Loads \a file (e.g. \e app.desktop) as an AppLnk. 361 Loads \a file (e.g. \e app.desktop) as an AppLnk.
362 362
363 \sa writeLink() 363 \sa writeLink()
364*/ 364*/
365AppLnk::AppLnk( const QString &file ) 365AppLnk::AppLnk( const QString &file )
366{ 366{
367 QStringList sl; 367 QStringList sl;
368 d = new AppLnkPrivate(); 368 d = new AppLnkPrivate();
369 if ( !file.isNull() ) { 369 if ( !file.isNull() ) {
370 Config config( file, Config::File ); 370 Config config( file, Config::File );
371 371
372 if ( config.isValid() ) { 372 if ( config.isValid() ) {
373 config.setGroup( "Desktop Entry" ); 373 config.setGroup( "Desktop Entry" );
374 374
375 mName = config.readEntry( "Name", file ); 375 mName = config.readEntry( "Name", file );
376 mExec = config.readEntry( "Exec" ); 376 mExec = config.readEntry( "Exec" );
377 mType = config.readEntry( "Type", QString::null ); 377 mType = config.readEntry( "Type", QString::null );
378 mIconFile = config.readEntry( "Icon", QString::null ); 378 mIconFile = config.readEntry( "Icon", QString::null );
379 mRotation = config.readEntry( "Rotation", "" ); 379 mRotation = config.readEntry( "Rotation", "" );
380 mComment = config.readEntry( "Comment", QString::null ); 380 mComment = config.readEntry( "Comment", QString::null );
381 // MIME types are case-insensitive. 381 // MIME types are case-insensitive.
382 mMimeTypes = config.readListEntry( "MimeType", ';' ); 382 mMimeTypes = config.readListEntry( "MimeType", ';' );
383 for (QStringList::Iterator it=mMimeTypes.begin(); it!=mMimeTypes.end(); ++it) 383 for (QStringList::Iterator it=mMimeTypes.begin(); it!=mMimeTypes.end(); ++it)
384 *it = (*it).lower(); 384 *it = (*it).lower();
385 mMimeTypeIcons = config.readListEntry( "MimeTypeIcons", ';' ); 385 mMimeTypeIcons = config.readListEntry( "MimeTypeIcons", ';' );
386 mLinkFile = file; 386 mLinkFile = file;
387 mFile = config.readEntry("File", QString::null); 387 mFile = config.readEntry("File", QString::null);
388 if ( !mExec. isEmpty ( )) { 388 if ( !mExec. isEmpty ( )) {
389 mFile = QString::null; 389 mFile = QString::null;
390 } 390 }
391 else if ( mFile[0] != '/' ) { 391 else if ( mFile[0] != '/' ) {
392 int slash = file.findRev('/'); 392 int slash = file.findRev('/');
393 if ( slash >= 0 ) { 393 if ( slash >= 0 ) {
394 mFile = file.left(slash) + '/' + mFile; 394 mFile = file.left(slash) + '/' + mFile;
395 } 395 }
396 } 396 }
397 d->mCatList = config.readListEntry("Categories", ';'); 397 d->mCatList = config.readListEntry("Categories", ';');
398 if ( d->mCatList[0].toInt() < -1 ) { 398 if ( d->mCatList[0].toInt() < -1 ) {
399 // numeric cats in file! convert to text 399 // numeric cats in file! convert to text
400 Categories cat( 0 ); 400 Categories cat( 0 );
401 cat.load( categoryFileName() ); 401 cat.load( categoryFileName() );
402 d->mCat.resize( d->mCatList.count() ); 402 d->mCat.resize( d->mCatList.count() );
403 int i; 403 int i;
404 QStringList::ConstIterator it; 404 QStringList::ConstIterator it;
405 for ( i = 0, it = d->mCatList.begin(); it != d->mCatList.end(); 405 for ( i = 0, it = d->mCatList.begin(); it != d->mCatList.end();
406 ++it, i++ ) { 406 ++it, i++ ) {
407 bool number; 407 bool number;
408 int id = (*it).toInt( &number ); 408 int id = (*it).toInt( &number );
409 if ( !number ) { 409 if ( !number ) {
410 // convert from text 410 // convert from text
411 id = cat.id( "Document View", *it ); 411 id = cat.id( "Document View", *it );
412 if ( id == 0 ) 412 if ( id == 0 )
413 id = cat.addCategory( "Document View", *it ); 413 id = cat.addCategory( "Document View", *it );
414 } 414 }
415 d->mCat[i] = id; 415 d->mCat[i] = id;
416 } 416 }
417 d->updateCatListFromArray(); 417 d->updateCatListFromArray();
418 } 418 }
419 } 419 }
420 } 420 }
421 mId = 0; 421 mId = 0;
422} 422}
423 423
424AppLnk& AppLnk::operator=(const AppLnk &copy) 424AppLnk& AppLnk::operator=(const AppLnk &copy)
425{ 425{
426 if ( this == &copy ) return *this; 426 if ( this == &copy ) return *this;
427 if ( mId ) 427 if ( mId )
428 qWarning("Deleting AppLnk that is in an AppLnkSet"); 428 qWarning("Deleting AppLnk that is in an AppLnkSet");
429 if ( d ) 429 if ( d )
430 delete d; 430 delete d;
431 431
432 432
433 mName = copy.mName; 433 mName = copy.mName;
434 434
435 /* remove for Qtopia 3.0 -zecke */ 435 /* remove for Qtopia 3.0 -zecke */
436 mPixmap = copy.mPixmap; 436 mPixmap = copy.mPixmap;
437 mBigPixmap = copy.mBigPixmap; 437 mBigPixmap = copy.mBigPixmap;
438 438
439 mExec = copy.mExec; 439 mExec = copy.mExec;
440 mType = copy.mType; 440 mType = copy.mType;
441 mRotation = copy.mRotation; 441 mRotation = copy.mRotation;
442 mComment = copy.mComment; 442 mComment = copy.mComment;
443 mFile = copy.mFile; 443 mFile = copy.mFile;
444 mLinkFile = copy.mLinkFile; 444 mLinkFile = copy.mLinkFile;
445 mIconFile = copy.mIconFile; 445 mIconFile = copy.mIconFile;
446 mMimeTypes = copy.mMimeTypes; 446 mMimeTypes = copy.mMimeTypes;
447 mMimeTypeIcons = copy.mMimeTypeIcons; 447 mMimeTypeIcons = copy.mMimeTypeIcons;
448 mId = 0; 448 mId = 0;
449 d = new AppLnkPrivate(); 449 d = new AppLnkPrivate();
450 d->mCat = copy.d->mCat; 450 d->mCat = copy.d->mCat;
451 d->mCatList = copy.d->mCatList; 451 d->mCatList = copy.d->mCatList;
452 d->mPixmaps = copy.d->mPixmaps; 452 d->mPixmaps = copy.d->mPixmaps;
453 453
454 return *this; 454 return *this;
455} 455}
456/*! 456/*!
457 protected internally to share code 457 protected internally to share code
458 should I document that at all? 458 should I document that at all?
459 I don't know the TT style for that 459 I don't know the TT style for that
460*/ 460*/
461const QPixmap& AppLnk::pixmap( int pos, int size ) const { 461const QPixmap& AppLnk::pixmap( int pos, int size ) const {
462 if ( d->mPixmaps[pos].isNull() ) { 462 if ( d->mPixmaps[pos].isNull() ) {
463 AppLnk* that = (AppLnk*)this; 463 AppLnk* that = (AppLnk*)this;
464 if ( mIconFile.isEmpty() ) { 464 if ( mIconFile.isEmpty() ) {
465 MimeType mt(type()); 465 MimeType mt(type());
466 that->d->mPixmaps[pos] = pos ? mt.bigPixmap() : mt.pixmap(); 466 that->d->mPixmaps[pos] = pos ? mt.bigPixmap() : mt.pixmap();
467 if ( that->d->mPixmaps[pos].isNull() ) 467 if ( that->d->mPixmaps[pos].isNull() )
468 that->d->mPixmaps[pos].convertFromImage( 468 that->d->mPixmaps[pos].convertFromImage(
469 Resource::loadImage("UnknownDocument") 469 Resource::loadImage("UnknownDocument")
470 .smoothScale( size, size ) ); 470 .smoothScale( size, size ) );
471 return that->d->mPixmaps[pos]; 471 return that->d->mPixmaps[pos];
472 } 472 }
473 QImage unscaledIcon = Resource::loadImage( that->mIconFile ); 473 QImage unscaledIcon = Resource::loadImage( that->mIconFile );
474 if ( unscaledIcon.isNull() ) { 474 if ( unscaledIcon.isNull() ) {
475 // qDebug( "Cannot find icon: %s", that->mIconFile.latin1() ); 475 // qDebug( "Cannot find icon: %s", that->mIconFile.latin1() );
476 that->d->mPixmaps[pos].convertFromImage( 476 that->d->mPixmaps[pos].convertFromImage(
477 Resource::loadImage("UnknownDocument") 477 Resource::loadImage("UnknownDocument")
478 .smoothScale( size, size ) ); 478 .smoothScale( size, size ) );
479 } else { 479 } else {
480 that->d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) ); 480 that->d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
481 that->d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) ); 481 that->d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
482 } 482 }
483 return that->d->mPixmaps[pos]; 483 return that->d->mPixmaps[pos];
484 } 484 }
485 return d->mPixmaps[pos]; 485 return d->mPixmaps[pos];
486} 486}
487 487
488/*! 488/*!
489 Returns a small pixmap associated with the application. 489 Returns a small pixmap associated with the application.
490 490
491 \sa bigPixmap() setIcon() 491 \sa bigPixmap() setIcon()
492*/ 492*/
493const QPixmap& AppLnk::pixmap() const 493const QPixmap& AppLnk::pixmap() const
494{ 494{
495 if ( d->mPixmaps[0].isNull() ) { 495 if ( d->mPixmaps[0].isNull() ) {
496 return pixmap(AppLnkPrivate::Normal, smallSize ); 496 return pixmap(AppLnkPrivate::Normal, smallSize );
497 } 497 }
498 return d->mPixmaps[0]; 498 return d->mPixmaps[0];
499} 499}
500 500
501/*! 501/*!
502 Returns a large pixmap associated with the application. 502 Returns a large pixmap associated with the application.
503 503
504 \sa pixmap() setIcon() 504 \sa pixmap() setIcon()
505*/ 505*/
506const QPixmap& AppLnk::bigPixmap() const 506const QPixmap& AppLnk::bigPixmap() const
507{ 507{
508 if ( d->mPixmaps[1].isNull() ) { 508 if ( d->mPixmaps[1].isNull() ) {
509 return pixmap( AppLnkPrivate::Big, bigSize ); 509 return pixmap( AppLnkPrivate::Big, bigSize );
510 } 510 }
511 return d->mPixmaps[1]; 511 return d->mPixmaps[1];
512} 512}
513 513
514/*! 514/*!
515 Returns the type of the AppLnk. For applications, games and 515 Returns the type of the AppLnk. For applications, games and
516 settings the type is \c Application; for documents the type is the 516 settings the type is \c Application; for documents the type is the
517 document's MIME type. 517 document's MIME type.
518*/ 518*/
519QString AppLnk::type() const 519QString AppLnk::type() const
520{ 520{
521 if ( mType.isNull() ) { 521 if ( mType.isNull() ) {
522 AppLnk* that = (AppLnk*)this; 522 AppLnk* that = (AppLnk*)this;
523 QString f = file(); 523 QString f = file();
524 if ( !f.isNull() ) { 524 if ( !f.isNull() ) {
525 MimeType mt(f); 525 MimeType mt(f);
526 that->mType = mt.id(); 526 that->mType = mt.id();
527 return that->mType; 527 return that->mType;
528 } 528 }
529 } 529 }
530 return mType; 530 return mType;
531} 531}
532 532
533/*! 533/*!
534 Returns the file associated with the AppLnk. 534 Returns the file associated with the AppLnk.
535 535
536 \sa exec() name() 536 \sa exec() name()
537*/ 537*/
538QString AppLnk::file() const 538QString AppLnk::file() const
539{ 539{
540 if ( mExec.isEmpty ( ) && mFile.isNull() ) { 540 if ( mExec.isEmpty ( ) && mFile.isNull() ) {
541 AppLnk* that = (AppLnk*)this; 541 AppLnk* that = (AppLnk*)this;
542 QString ext = MimeType(mType).extension(); 542 QString ext = MimeType(mType).extension();
543 if ( !ext.isEmpty() ) 543 if ( !ext.isEmpty() )
544 ext = "." + ext; 544 ext = "." + ext;
545 if ( !mLinkFile.isEmpty() ) { 545 if ( !mLinkFile.isEmpty() ) {
546 that->mFile = 546 that->mFile =
547 mLinkFile.right(8)==".desktop" // 8 = strlen(".desktop") 547 mLinkFile.right(8)==".desktop" // 8 = strlen(".desktop")
548 ? mLinkFile.left(mLinkFile.length()-8) : mLinkFile; 548 ? mLinkFile.left(mLinkFile.length()-8) : mLinkFile;
549 qDebug("mFile now == %s", mFile.latin1()); 549 qDebug("mFile now == %s", mFile.latin1());
550 } else if ( mType.contains('/') ) { 550 } else if ( mType.contains('/') ) {
551 that->mFile = 551 that->mFile =
552 QString(getenv("HOME"))+"/Documents/"+mType+"/"+safeFileName(that->mName); 552 QString(getenv("HOME"))+"/Documents/"+mType+"/"+safeFileName(that->mName);
553 /* 553 /*
554 * A file with the same name or a .desktop file already exists 554 * A file with the same name or a .desktop file already exists
555 */ 555 */
556 if ( QFile::exists(that->mFile+ext) || QFile::exists(that->mFile+".desktop") ) { 556 if ( QFile::exists(that->mFile+ext) || QFile::exists(that->mFile+".desktop") ) {
557 int n=1; 557 int n=1;
558 QString nn; 558 QString nn;
559 while (QFile::exists((nn=(that->mFile+"_"+QString::number(n)))+ext) 559 while (QFile::exists((nn=(that->mFile+"_"+QString::number(n)))+ext)
560 || QFile::exists(nn+".desktop")) 560 || QFile::exists(nn+".desktop"))
561 n++; 561 n++;
562 that->mFile = nn; 562 that->mFile = nn;
563 } 563 }
564 that->mLinkFile = that->mFile+".desktop"; 564 that->mLinkFile = that->mFile+".desktop";
565 that->mFile += ext; 565 that->mFile += ext;
566 } 566 }
567 prepareDirectories(that->mFile); 567 prepareDirectories(that->mFile);
568 if ( !that->mFile.isEmpty() ) { 568 if ( !that->mFile.isEmpty() ) {
569 QFile f(that->mFile); 569 QFile f(that->mFile);
570 if ( !f.open(IO_WriteOnly) ) 570 if ( !f.open(IO_WriteOnly) )
571 that->mFile = QString::null; 571 that->mFile = QString::null;
572 return that->mFile; 572 return that->mFile;
573 } 573 }
574 } 574 }
575 return mFile; 575 return mFile;
576} 576}
577 577
578/*! 578/*!
579 Returns the desktop file corresponding to this AppLnk. 579 Returns the desktop file corresponding to this AppLnk.
580 580
581 \sa file() exec() name() 581 \sa file() exec() name()
582*/ 582*/
583QString AppLnk::linkFile() const 583QString AppLnk::linkFile() const
584{ 584{
585 if ( mLinkFile.isNull() ) { 585 if ( mLinkFile.isNull() ) {
586 AppLnk* that = (AppLnk*)this; 586 AppLnk* that = (AppLnk*)this;
587 if ( type().contains('/') ) { 587 if ( type().contains('/') ) {
588 StorageInfo storage; 588 StorageInfo storage;
589 const FileSystem *fs = storage.fileSystemOf( that->mFile ); 589 const FileSystem *fs = storage.fileSystemOf( that->mFile );
590 /* tmpfs + and ramfs are available too but not removable 590 /* tmpfs + and ramfs are available too but not removable
591 * either we fix storage or add this 591 * either we fix storage or add this
592 */ 592 */
593 if ( fs && ( fs->isRemovable() || fs->disk() == "/dev/mtdblock6" || fs->disk() == "tmpfs") ) { 593 if ( fs && ( fs->isRemovable() || fs->disk() == "/dev/mtdblock6" || fs->disk() == "tmpfs") ) {
594 that->mLinkFile = fs->path(); 594 that->mLinkFile = fs->path();
595 } else 595 } else
596 that->mLinkFile = getenv( "HOME" ); 596 that->mLinkFile = getenv( "HOME" );
597 that->mLinkFile += "/Documents/"+type()+"/"+safeFileName(that->mName); 597 that->mLinkFile += "/Documents/"+type()+"/"+safeFileName(that->mName);
598 598
599 /* the desktop file exists make sure we don't point to the same file */ 599 /* the desktop file exists make sure we don't point to the same file */
600 if ( QFile::exists(that->mLinkFile+".desktop") ) { 600 if ( QFile::exists(that->mLinkFile+".desktop") ) {
601 AppLnk lnk( that->mLinkFile + ".desktop" ); 601 AppLnk lnk( that->mLinkFile + ".desktop" );
602 602
603 /* the linked is different */ 603 /* the linked is different */
604 if(that->file() != lnk.file() ) { 604 if(that->file() != lnk.file() ) {
605 int n = 1; 605 int n = 1;
606 QString nn; 606 QString nn;
607 while (QFile::exists((nn=that->mLinkFile+"_"+QString::number(n))+".desktop")) { 607 while (QFile::exists((nn=that->mLinkFile+"_"+QString::number(n))+".desktop")) {
608 n++; 608 n++;
609 /* just to be sure */ 609 /* just to be sure */
610 AppLnk lnk(nn ); 610 AppLnk lnk(nn );
611 if (lnk.file() == that->file() ) 611 if (lnk.file() == that->file() )
612 break; 612 break;
613 } 613 }
614 that->mLinkFile = nn; 614 that->mLinkFile = nn;
615 } 615 }
616 } 616 }
617 that->mLinkFile += ".desktop"; 617 that->mLinkFile += ".desktop";
618 storeLink(); 618 storeLink();
619 } 619 }
620 return that->mLinkFile; 620 return that->mLinkFile;
621 } 621 }
622 return mLinkFile; 622 return mLinkFile;
623} 623}
624 624
625/*! 625/*!
626 Copies \a copy. 626 Copies \a copy.
627*/ 627*/
628AppLnk::AppLnk( const AppLnk &copy ) 628AppLnk::AppLnk( const AppLnk &copy )
629{ 629{
630 mName = copy.mName; 630 mName = copy.mName;
631 mPixmap = copy.mPixmap; 631 mPixmap = copy.mPixmap;
632 mBigPixmap = copy.mBigPixmap; 632 mBigPixmap = copy.mBigPixmap;
633 mExec = copy.mExec; 633 mExec = copy.mExec;
634 mType = copy.mType; 634 mType = copy.mType;
635 mRotation = copy.mRotation; 635 mRotation = copy.mRotation;
636 mComment = copy.mComment; 636 mComment = copy.mComment;
637 mFile = copy.mFile; 637 mFile = copy.mFile;
638 mLinkFile = copy.mLinkFile; 638 mLinkFile = copy.mLinkFile;
639 mIconFile = copy.mIconFile; 639 mIconFile = copy.mIconFile;
640 mMimeTypes = copy.mMimeTypes; 640 mMimeTypes = copy.mMimeTypes;
641 mMimeTypeIcons = copy.mMimeTypeIcons; 641 mMimeTypeIcons = copy.mMimeTypeIcons;
642 mId = 0; 642 mId = 0;
643 d = new AppLnkPrivate(); 643 d = new AppLnkPrivate();
644 d->mCat = copy.d->mCat; 644 d->mCat = copy.d->mCat;
645 d->mCatList = copy.d->mCatList; 645 d->mCatList = copy.d->mCatList;
646 d->mPixmaps = copy.d->mPixmaps; 646 d->mPixmaps = copy.d->mPixmaps;
647} 647}
648 648
649/*! 649/*!
650 Destroys the AppLnk. Note that if the AppLnk is currently a member 650 Destroys the AppLnk. Note that if the AppLnk is currently a member
651 of an AppLnkSet, this will produce a run-time warning. 651 of an AppLnkSet, this will produce a run-time warning.
652 652
653 \sa AppLnkSet::add() AppLnkSet::remove() 653 \sa AppLnkSet::add() AppLnkSet::remove()
654*/ 654*/
655AppLnk::~AppLnk() 655AppLnk::~AppLnk()
656{ 656{
657 if ( mId ) 657 if ( mId )
658 qWarning("Deleting AppLnk that is in an AppLnkSet"); 658 qWarning("Deleting AppLnk that is in an AppLnkSet");
659 if ( d ) 659 if ( d )
660 delete d; 660 delete d;
661} 661}
662 662
663/*! 663/*!
664 \overload 664 \overload
665 Executes the application associated with this AppLnk. 665 Executes the application associated with this AppLnk.
666 666
667 \sa exec() 667 \sa exec()
668*/ 668*/
669void AppLnk::execute() const 669void AppLnk::execute() const
670{ 670{
671 execute( QStringList::split( ' ', property( "Arguments" ) ) ); 671 execute( QStringList::split( ' ', property( "Arguments" ) ) );
672} 672}
673 673
674/*! 674/*!
675 Executes the application associated with this AppLnk, with 675 Executes the application associated with this AppLnk, with
676 \a args as arguments. 676 \a args as arguments.
677 677
678 \sa exec() 678 \sa exec()
679*/ 679*/
680void AppLnk::execute(const QStringList& args) const 680void AppLnk::execute(const QStringList& args) const
681{ 681{
682#ifdef Q_WS_QWS 682#ifdef Q_WS_QWS
683 if ( !mRotation.isEmpty() ) { 683 if ( !mRotation.isEmpty() ) {
684 // ######## this will only work in the server 684 // ######## this will only work in the server
685 int rot = QPEApplication::defaultRotation(); 685 int rot = QPEApplication::defaultRotation();
686 rot = (rot+mRotation.toInt())%360; 686 rot = (rot+mRotation.toInt())%360;
687 QCString old = getenv("QWS_DISPLAY"); 687 QCString old = getenv("QWS_DISPLAY");
688 setenv("QWS_DISPLAY", QString("Transformed:Rot%1:0").arg(rot), 1); 688 setenv("QWS_DISPLAY", QString("Transformed:Rot%1:0").arg(rot), 1);
689 invoke(args); 689 invoke(args);
690 setenv("QWS_DISPLAY", old.data(), 1); 690 setenv("QWS_DISPLAY", old.data(), 1);
691 } else 691 } else
692#endif 692#endif
693 invoke(args); 693 invoke(args);
694} 694}
695 695
696/*! 696/*!
697 Invokes the application associated with this AppLnk, with 697 Invokes the application associated with this AppLnk, with
698 \a args as arguments. Rotation is not taken into account by 698 \a args as arguments. Rotation is not taken into account by
699 this function, so you should not call it directly. 699 this function, so you should not call it directly.
700 700
701 \sa execute() 701 \sa execute()
702*/ 702*/
703void AppLnk::invoke(const QStringList& args) const 703void AppLnk::invoke(const QStringList& args) const
704{ 704{
705 if ( property( "Arguments" ).isEmpty() ) 705 if ( property( "Arguments" ).isEmpty() )
706 Global::execute( exec(), args[0] ); 706 Global::execute( exec(), args[0] );
707 else 707 else
708 Global::execute( exec(), args.join( " " ) ); 708 Global::execute( exec(), args.join( " " ) );
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 AppLnkImagePrivate {
985public :
986 AppLnkImagePrivate( const QString & ImageName ) {
987 IconName = ImageName;
988 Small = 0;
989 Big = 0;
990 }
991 ~AppLnkImagePrivate( ) {
992 if ( Small ) delete Small;
993 if ( Big ) delete Big;
994 }
995
996 inline QPixmap * small( void ) {
997 if( ! Small ) {
998 QImage unscaledIcon = Resource::loadImage( IconName );
999 // works as long as smallSize remains static
1000 Small = new QPixmap();
1001 Small->convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
1002 }
1003 return Small;
1004 }
1005
1006 inline QPixmap * big( void ) {
1007 if( ! Big ) {
1008 QImage unscaledIcon = Resource::loadImage( IconName );
1009 // works as long as bigSize remains static
1010 Big = new QPixmap();
1011 Big->convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
1012 }
1013 return Big;
1014 }
1015
1016 QString IconName;
1017 QPixmap * Small;
1018 QPixmap * Big;
1019};
1020
984class AppLnkSetPrivate { 1021class AppLnkSetPrivate {
985public: 1022public:
986 AppLnkSetPrivate() 1023 AppLnkSetPrivate()
987 { 1024 {
988 typPix.setAutoDelete(TRUE); 1025 typPix.setAutoDelete(TRUE);
989 typPixBig.setAutoDelete(TRUE); 1026 typName.setAutoDelete(TRUE);
990 typName.setAutoDelete(TRUE);
991 } 1027 }
992 1028
993 QDict<QPixmap> typPix; 1029 QDict<AppLnkImagePrivate> typPix;
994 QDict<QPixmap> typPixBig;
995 QDict<QString> typName; 1030 QDict<QString> typName;
996}; 1031};
997 1032
998/*! 1033/*!
999 \class AppLnkSet applnk.h 1034 \class AppLnkSet applnk.h
1000 \brief The AppLnkSet class is a set of AppLnk objects. 1035 \brief The AppLnkSet class is a set of AppLnk objects.
1001*/ 1036*/
1002 1037
1003/*! 1038/*!
1004 \fn QStringList AppLnkSet::types() const 1039 \fn QStringList AppLnkSet::types() const
1005 1040
1006 Returns the list of \link applnk.html#Types types\endlink in the set. 1041 Returns the list of \link applnk.html#Types types\endlink in the set.
1007 1042
1008 For applications, games and settings the type is \c Application; 1043 For applications, games and settings the type is \c Application;
1009 for documents the type is the document's MIME type. 1044 for documents the type is the document's MIME type.
1010 1045
1011 \sa AppLnk::type(), typeName(), typePixmap(), typeBigPixmap() 1046 \sa AppLnk::type(), typeName(), typePixmap(), typeBigPixmap()
1012*/ 1047*/
1013 1048
1014/*! 1049/*!
1015 \fn const QList<AppLnk>& AppLnkSet::children() const 1050 \fn const QList<AppLnk>& AppLnkSet::children() const
1016 1051
1017 Returns the members of the set. 1052 Returns the members of the set.
1018*/ 1053*/
1019 1054
1020/*! 1055/*!
1021 Constructs an empty AppLnkSet. 1056 Constructs an empty AppLnkSet.
1022*/ 1057*/
1023AppLnkSet::AppLnkSet() : 1058AppLnkSet::AppLnkSet() :
1024 d(new AppLnkSetPrivate) 1059 d(new AppLnkSetPrivate)
1025{ 1060{
1026} 1061}
1027 1062
1028/*! 1063/*!
1029 Constructs an AppLnkSet that contains AppLnk objects representing 1064 Constructs an AppLnkSet that contains AppLnk objects representing
1030 all the files in the given \a directory (and any subdirectories 1065 all the files in the given \a directory (and any subdirectories
1031 recursively). 1066 recursively).
1032 1067
1033 \omit 1068 \omit
1034 The directories may contain ".directory" files which override 1069 The directories may contain ".directory" files which override
1035 any AppLnk::type() values for AppLnk objects found in the directory. 1070 any AppLnk::type() values for AppLnk objects found in the directory.
1036 This allows simple localization of application types. 1071 This allows simple localization of application types.
1037 \endomit 1072 \endomit
1038*/ 1073*/
1039AppLnkSet::AppLnkSet( const QString &directory ) : 1074AppLnkSet::AppLnkSet( const QString &directory ) :
1040 d(new AppLnkSetPrivate) 1075 d(new AppLnkSetPrivate)
1041{ 1076{
1042 QDir dir( directory ); 1077 QDir dir( directory );
1043 mFile = directory; 1078 mFile = directory;
1044 findChildren(directory,QString::null,QString::null); 1079 findChildren(directory,QString::null,QString::null);
1045} 1080}
1046 1081
1047/*! 1082/*!
1048 Detaches all AppLnk objects from the set. The set become empty and 1083 Detaches all AppLnk objects from the set. The set become empty and
1049 the caller becomes responsible for deleting the AppLnk objects. 1084 the caller becomes responsible for deleting the AppLnk objects.
1050*/ 1085*/
1051void AppLnkSet::detachChildren() 1086void AppLnkSet::detachChildren()
1052{ 1087{
1053 QListIterator<AppLnk> it( mApps ); 1088 QListIterator<AppLnk> it( mApps );
1054 for ( ; it.current(); ) { 1089 for ( ; it.current(); ) {
1055 AppLnk* a = *it; 1090 AppLnk* a = *it;
1056 ++it; 1091 ++it;
1057 a->mId = 0; 1092 a->mId = 0;
1058 } 1093 }
1059 mApps.clear(); 1094 mApps.clear();
1060} 1095}
1061 1096
1062/*! 1097/*!
1063 Destroys the set, deleting all the AppLnk objects it contains. 1098 Destroys the set, deleting all the AppLnk objects it contains.
1064 1099
1065 \sa detachChildren() 1100 \sa detachChildren()
1066*/ 1101*/
1067AppLnkSet::~AppLnkSet() 1102AppLnkSet::~AppLnkSet()
1068{ 1103{
1069 QListIterator<AppLnk> it( mApps ); 1104 QListIterator<AppLnk> it( mApps );
1070 for ( ; it.current(); ) { 1105 for ( ; it.current(); ) {
1071 AppLnk* a = *it; 1106 AppLnk* a = *it;
1072 ++it; 1107 ++it;
1073 a->mId = 0; 1108 a->mId = 0;
1074 delete a; 1109 delete a;
1075 } 1110 }
1076 delete d; 1111 delete d;
1077} 1112}
1078 1113
1079void AppLnkSet::findChildren(const QString &dr, const QString& typ, const QString& typName, int depth) 1114void AppLnkSet::findChildren(const QString &dr, const QString& typ, const QString& typName, int depth)
1080{ 1115{
1081 depth++; 1116 depth++;
1082 if ( depth > 10 ) 1117 if ( depth > 10 )
1083 return; 1118 return;
1084 1119
1085 QDir dir( dr ); 1120 QDir dir( dr );
1086 QString typNameLocal = typName; 1121 QString typNameLocal = typName;
1087 1122
1088 if ( dir.exists( ".directory" ) ) { 1123 if ( dir.exists( ".directory" ) ) {
1089 Config config( dr + "/.directory", Config::File ); 1124 Config config( dr + "/.directory", Config::File );
1090 config.setGroup( "Desktop Entry" ); 1125 config.setGroup( "Desktop Entry" );
1091 typNameLocal = config.readEntry( "Name", typNameLocal ); 1126 typNameLocal = config.readEntry( "Name", typNameLocal );
1092 if ( !typ.isEmpty() ) { 1127 if ( !typ.isEmpty() ) {
1093 QString iconFile = config.readEntry( "Icon", "AppsIcon" ); 1128 d->typPix.insert( typ,
1094 QImage unscaledIcon = Resource::loadImage( iconFile ); 1129 new AppLnkImagePrivate( config.readEntry( "Icon", "AppsIcon" ) )
1095 QPixmap pm, bpm; 1130 );
1096 pm.convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) ); 1131 d->typName.insert(typ, new QString(typNameLocal));
1097 bpm.convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) ); 1132
1098 d->typPix.insert(typ, new QPixmap(pm)); 1133 }
1099 d->typPixBig.insert(typ, new QPixmap(bpm));
1100 d->typName.insert(typ, new QString(typNameLocal));
1101 }
1102 } 1134 }
1103 1135
1104 const QFileInfoList *list = dir.entryInfoList(); 1136 const QFileInfoList *list = dir.entryInfoList();
1105 if ( list ) { 1137 if ( list ) {
1106 QFileInfo* fi; 1138 QFileInfo* fi;
1107 bool cadded=FALSE; 1139 bool cadded=FALSE;
1108 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) { 1140 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) {
1109 QString bn = fi->fileName(); 1141 QString bn = fi->fileName();
1110// qDebug("findChildren "+bn); 1142 // qDebug("findChildren "+bn);
1111 if ( bn[0] != '.' && bn != "CVS" ) { 1143 if ( bn[0] != '.' && bn != "CVS" ) {
1112 if ( fi->isDir() ) { 1144 if ( fi->isDir() ) {
1113 QString c = typ.isNull() ? bn : typ+"/"+bn; 1145 QString c = typ.isNull() ? bn : typ+"/"+bn;
1114 QString d = typNameLocal.isNull() ? bn : typNameLocal+"/"+bn; 1146 QString d = typNameLocal.isNull() ? bn : typNameLocal+"/"+bn;
1115 findChildren(fi->filePath(), c, d, depth ); 1147 findChildren(fi->filePath(), c, d, depth );
1116 } else { 1148 } else {
1117 if ( fi->extension(FALSE) == "desktop" ) { 1149 if ( fi->extension(FALSE) == "desktop" ) {
1118 AppLnk* app = new AppLnk( fi->filePath() ); 1150 AppLnk* app = new AppLnk( fi->filePath() );
1119#ifdef QT_NO_QWS_MULTIPROCESS 1151#ifdef QT_NO_QWS_MULTIPROCESS
1120 if ( !Global::isBuiltinCommand( app->exec() ) ) 1152 if ( !Global::isBuiltinCommand( app->exec() ) )
1121 delete app; 1153 delete app;
1122 else 1154 else
1123#endif 1155#endif
1124 { 1156 {
1125 if ( !typ.isEmpty() ) { 1157 if ( !typ.isEmpty() ) {
1126 if ( !cadded ) { 1158 if ( !cadded ) {
1127 typs.append(typ); 1159 typs.append(typ);
1128 cadded = TRUE; 1160 cadded = TRUE;
1129 } 1161 }
1130 app->setType(typ); 1162 app->setType(typ);
1163 }
1164 add(app);
1165 }
1166 }
1131 } 1167 }
1132 add(app);
1133 }
1134 } 1168 }
1135 }
1136 } 1169 }
1137 }
1138 } 1170 }
1139} 1171}
1140 1172
1141/*! 1173/*!
1142 Adds AppLnk \a f to the set. The set takes responsibility for 1174 Adds AppLnk \a f to the set. The set takes responsibility for
1143 deleting \a f. 1175 deleting \a f.
1144 1176
1145 \sa remove() 1177 \sa remove()
1146*/ 1178*/
1147void AppLnkSet::add( AppLnk *f ) 1179void AppLnkSet::add( AppLnk *f )
1148{ 1180{
1149 if ( f->mId == 0 ) { 1181 if ( f->mId == 0 ) {
1150 AppLnk::lastId++; 1182 AppLnk::lastId++;
1151 f->mId = AppLnk::lastId; 1183 f->mId = AppLnk::lastId;
1152 mApps.append( f ); 1184 mApps.append( f );
1153 } else { 1185 } else {
1154 qWarning("Attempt to add an AppLnk twice"); 1186 qWarning("Attempt to add an AppLnk twice");
1155 } 1187 }
1156} 1188}
1157 1189
1158/*! 1190/*!
1159 Removes AppLnk \a f to the set. The caller becomes responsible for 1191 Removes AppLnk \a f to the set. The caller becomes responsible for
1160 deleting \a f. Returns TRUE if \a f was in the set; otherwise 1192 deleting \a f. Returns TRUE if \a f was in the set; otherwise
1161 returns FALSE. 1193 returns FALSE.
1162 1194
1163 \sa add() 1195 \sa add()
1164*/ 1196*/
1165bool AppLnkSet::remove( AppLnk *f ) 1197bool AppLnkSet::remove( AppLnk *f )
1166{ 1198{
1167 if ( mApps.remove( f ) ) { 1199 if ( mApps.remove( f ) ) {
1168 f->mId = 0; 1200 f->mId = 0;
1169 return TRUE; 1201 return TRUE;
1170 } 1202 }
1171 return FALSE; 1203 return FALSE;
1172} 1204}
1173 1205
1174 1206
1175/*! 1207/*!
1176 Returns the localized name for type \a t. 1208 Returns the localized name for type \a t.
1177 1209
1178 For applications, games and settings the type is \c Application; 1210 For applications, games and settings the type is \c Application;
1179 for documents the type is the document's MIME type. 1211 for documents the type is the document's MIME type.
1180*/ 1212*/
1181QString AppLnkSet::typeName( const QString& t ) const 1213QString AppLnkSet::typeName( const QString& t ) const
1182{ 1214{
1183 QString *st = d->typName.find(t); 1215 QString *st = d->typName.find(t);
1184 return st ? *st : QString::null; 1216 return st ? *st : QString::null;
1185} 1217}
1186 1218
1187/*! 1219/*!
1188 Returns the small pixmap associated with type \a t. 1220 Returns the small pixmap associated with type \a t.
1189 1221
1190 For applications, games and settings the type is \c Application; 1222 For applications, games and settings the type is \c Application;
1191 for documents the type is the document's MIME type. 1223 for documents the type is the document's MIME type.
1192*/ 1224*/
1193QPixmap AppLnkSet::typePixmap( const QString& t ) const 1225QPixmap AppLnkSet::typePixmap( const QString& t ) const
1194{ 1226{
1195 QPixmap *pm = d->typPix.find(t); 1227 AppLnkImagePrivate *alip = d->typPix.find(t);
1196 return pm ? *pm : QPixmap(); 1228 return alip ? *(alip->small()) : QPixmap();
1197} 1229}
1198 1230
1199/*! 1231/*!
1200 Returns the large pixmap associated with type \a t. 1232 Returns the large pixmap associated with type \a t.
1201 1233
1202 For applications, games and settings the type is \c Application; 1234 For applications, games and settings the type is \c Application;
1203 for documents the type is the document's MIME type. 1235 for documents the type is the document's MIME type.
1204*/ 1236*/
1205QPixmap AppLnkSet::typeBigPixmap( const QString& t ) const 1237QPixmap AppLnkSet::typeBigPixmap( const QString& t ) const
1206{ 1238{
1207 QPixmap *pm = d->typPixBig.find(t); 1239 AppLnkImagePrivate *alip = d->typPix.find(t);
1208 return pm ? *pm : QPixmap(); 1240 return alip ? *(alip->big()) : QPixmap();
1209} 1241}
1210 1242
1211/*! 1243/*!
1212 Returns the AppLnk with the given \a id. 1244 Returns the AppLnk with the given \a id.
1213*/ 1245*/
1214const AppLnk *AppLnkSet::find( int id ) const 1246const AppLnk *AppLnkSet::find( int id ) const
1215{ 1247{
1216 QListIterator<AppLnk> it( children() ); 1248 QListIterator<AppLnk> it( children() );
1217 1249
1218 for ( ; it.current(); ++it ) { 1250 for ( ; it.current(); ++it ) {
1219 const AppLnk *app = it.current(); 1251 const AppLnk *app = it.current();
1220 if ( app->id() == id ) 1252 if ( app->id() == id )
1221 return app; 1253 return app;
1222 } 1254 }
1223 1255
1224 return 0; 1256 return 0;
1225} 1257}
1226 1258
1227/*! 1259/*!
1228 Returns the AppLnk with the given \a exec attribute. 1260 Returns the AppLnk with the given \a exec attribute.
1229*/ 1261*/
1230const AppLnk *AppLnkSet::findExec( const QString& exec ) const 1262const AppLnk *AppLnkSet::findExec( const QString& exec ) const
1231{ 1263{
1232 QListIterator<AppLnk> it( children() ); 1264 QListIterator<AppLnk> it( children() );
1233 1265
1234 for ( ; it.current(); ++it ) { 1266 for ( ; it.current(); ++it ) {
1235 const AppLnk *app = it.current(); 1267 const AppLnk *app = it.current();
1236 if ( app->exec() == exec ) 1268 if ( app->exec() == exec )
1237 return app; 1269 return app;
1238 } 1270 }
1239 1271
1240 return 0; 1272 return 0;
1241} 1273}
1242 1274
1243/*! 1275/*!
1244 \class DocLnkSet applnk.h 1276 \class DocLnkSet applnk.h
1245 \brief The DocLnkSet class is a set of DocLnk objects. 1277 \brief The DocLnkSet class is a set of DocLnk objects.
1246*/ 1278*/
1247 1279
1248/*! 1280/*!
1249 \fn const QList<DocLnk>& DocLnkSet::children() const 1281 \fn const QList<DocLnk>& DocLnkSet::children() const
1250 1282
1251 Returns the members of the set. 1283 Returns the members of the set.
1252*/ 1284*/
1253 1285
1254/*! 1286/*!
1255 Constructs an empty DocLnkSet. 1287 Constructs an empty DocLnkSet.
1256 1288
1257 \sa appendFrom() 1289 \sa appendFrom()
1258*/ 1290*/
1259DocLnkSet::DocLnkSet() 1291DocLnkSet::DocLnkSet()
1260{ 1292{
1261} 1293}
1262 1294
1263/*! 1295/*!
1264 Constructs a DocLnkSet that contains DocLnk objects representing all 1296 Constructs a DocLnkSet that contains DocLnk objects representing all
1265 the files in the \a directory (and any subdirectories, recursively). 1297 the files in the \a directory (and any subdirectories, recursively).
1266 1298
1267 If \a mimefilter is not null, 1299 If \a mimefilter is not null,
1268 only documents with a MIME type matching \a mimefilter are selected. 1300 only documents with a MIME type matching \a mimefilter are selected.
1269 The value may contain multiple wild-card patterns separated by ";", 1301 The value may contain multiple wild-card patterns separated by ";",
1270 such as \c{*o/mpeg;audio/x-wav}. 1302 such as \c{*o/mpeg;audio/x-wav}.
1271 1303
1272 See also \link applnk.html#files-and-links Files and Links\endlink. 1304 See also \link applnk.html#files-and-links Files and Links\endlink.
1273 1305
1274*/ 1306*/
1275DocLnkSet::DocLnkSet( const QString &directory, const QString& mimefilter ) : 1307DocLnkSet::DocLnkSet( const QString &directory, const QString& mimefilter ) :
1276 AppLnkSet() 1308 AppLnkSet()
1277{ 1309{
1278 QDir dir( directory ); 1310 QDir dir( directory );
1279 mFile = dir.dirName(); 1311 mFile = dir.dirName();
1280 QDict<void> reference(1021); 1312 QDict<void> reference(1021);
1281 1313
1282 QStringList subFilter = QStringList::split(";", mimefilter); 1314 QStringList subFilter = QStringList::split(";", mimefilter);
1283 QValueList<QRegExp> mimeFilters; 1315 QValueList<QRegExp> mimeFilters;
1284 for( QStringList::Iterator it = subFilter.begin(); it != subFilter.end(); ++ it ) 1316 for( QStringList::Iterator it = subFilter.begin(); it != subFilter.end(); ++ it )
1285 mimeFilters.append( QRegExp(*it, FALSE, TRUE) ); 1317 mimeFilters.append( QRegExp(*it, FALSE, TRUE) );
1286 1318
1287 findChildren(directory, mimeFilters, reference); 1319 findChildren(directory, mimeFilters, reference);
1288 1320
1289 const QList<DocLnk> &list = children(); 1321 const QList<DocLnk> &list = children();
1290 for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) { 1322 for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) {
1291 reference.remove( (*it)->file() ); 1323 reference.remove( (*it)->file() );
1292 } 1324 }
1293 for ( QDictIterator<void> dit(reference); dit.current(); ++dit ) { 1325 for ( QDictIterator<void> dit(reference); dit.current(); ++dit ) {
1294 if ( dit.current() == (void*)2 ) { 1326 if ( dit.current() == (void*)2 ) {
1295 // Unreferenced, make an unwritten link 1327 // Unreferenced, make an unwritten link
1296 DocLnk* dl = new DocLnk; 1328 DocLnk* dl = new DocLnk;
1297 QFileInfo fi( dit.currentKey() ); 1329 QFileInfo fi( dit.currentKey() );
1298 dl->setFile(fi.filePath()); 1330 dl->setFile(fi.filePath());
1299 dl->setName(fi.baseName()); 1331 dl->setName(fi.baseName());
1300 // #### default to current path? 1332 // #### default to current path?
1301 // dl->setCategories( ... ); 1333 // dl->setCategories( ... );
1302 bool match = mimefilter.isNull(); 1334 bool match = mimefilter.isNull();
1303 if ( !match ) 1335 if ( !match )
1304 for( QValueList<QRegExp>::Iterator it = mimeFilters.begin(); it != mimeFilters.end() && !match; ++ it ) 1336 for( QValueList<QRegExp>::Iterator it = mimeFilters.begin(); it != mimeFilters.end() && !match; ++ it )
1305 if ( (*it).match(dl->type()) >= 0 ) 1337 if ( (*it).match(dl->type()) >= 0 )
1306 match = TRUE; 1338 match = TRUE;
1307 if ( match /* && dl->type() != "application/octet-stream" */ 1339 if ( match /* && dl->type() != "application/octet-stream" */
1308 && !!dl->exec() ) 1340 && !!dl->exec() )
1309 add(dl); 1341 add(dl);
1310 else 1342 else
1311 delete dl; 1343 delete dl;
1312 } 1344 }
1313 } 1345 }
1314} 1346}
1315 1347
1316// other becomes empty 1348// other becomes empty
1317/*! 1349/*!
1318 Transfers all DocLnk objects from \a other to this set. \a other becomes 1350 Transfers all DocLnk objects from \a other to this set. \a other becomes
1319 empty. 1351 empty.
1320*/ 1352*/
1321void DocLnkSet::appendFrom( DocLnkSet& other ) 1353void DocLnkSet::appendFrom( DocLnkSet& other )
1322{ 1354{
1323 if ( &other == this ) 1355 if ( &other == this )
1324 return; 1356 return;
1325 QListIterator<AppLnk> it( other.mApps ); 1357 QListIterator<AppLnk> it( other.mApps );
1326 for ( ; it.current(); ) { 1358 for ( ; it.current(); ) {
1327 mApps.append(*it); 1359 mApps.append(*it);
1328 ++it; 1360 ++it;
1329 } 1361 }
1330 other.mApps.clear(); 1362 other.mApps.clear();
1331} 1363}
1332 1364
1333void DocLnkSet::findChildren(const QString &dr, const QValueList<QRegExp> &mimeFilters, QDict<void> &reference, int depth) 1365void DocLnkSet::findChildren(const QString &dr, const QValueList<QRegExp> &mimeFilters, QDict<void> &reference, int depth)
1334{ 1366{
1335 depth++; 1367 depth++;
1336 if ( depth > 10 ) 1368 if ( depth > 10 )
1337 return; 1369 return;
1338 1370
1339 QDir dir( dr ); 1371 QDir dir( dr );
1340 1372
1341 /* Opie got a different approach 1373 /* Opie got a different approach
1342 * I guess it's geek vs. consumer 1374 * I guess it's geek vs. consumer
1343 * in this case to be discussed 1375 * in this case to be discussed
1344 */ 1376 */
1345 if ( dir.exists( ".Qtopia-ignore" ) ) 1377 if ( dir.exists( ".Qtopia-ignore" ) )
1346 return; 1378 return;
1347 1379
1348 const QFileInfoList *list = dir.entryInfoList(); 1380 const QFileInfoList *list = dir.entryInfoList();
1349 if ( list ) { 1381 if ( list ) {
1350 QFileInfo* fi; 1382 QFileInfo* fi;
1351 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) { 1383 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) {
1352 QString bn = fi->fileName(); 1384 QString bn = fi->fileName();
1353 if ( bn[0] != '.' ) { 1385 if ( bn[0] != '.' ) {
1354 if ( fi->isDir() ) { 1386 if ( fi->isDir() ) {
1355 if ( bn != "CVS" && bn != "Qtopia" && bn != "QtPalmtop" ) 1387 if ( bn != "CVS" && bn != "Qtopia" && bn != "QtPalmtop" )
1356 findChildren(fi->filePath(), mimeFilters, reference, depth); 1388 findChildren(fi->filePath(), mimeFilters, reference, depth);
1357 } else { 1389 } else {
1358 if ( fi->extension(FALSE) == "desktop" ) { 1390 if ( fi->extension(FALSE) == "desktop" ) {
1359 DocLnk* dl = new DocLnk( fi->filePath() ); 1391 DocLnk* dl = new DocLnk( fi->filePath() );
1360 QFileInfo fi2(dl->file()); 1392 QFileInfo fi2(dl->file());
1361 bool match = FALSE; 1393 bool match = FALSE;
1362 if ( !fi2.exists() ) { 1394 if ( !fi2.exists() ) {
1363 dir.remove( dl->file() ); 1395 dir.remove( dl->file() );
1364 } 1396 }
1365 if ( mimeFilters.count() == 0 ) { 1397 if ( mimeFilters.count() == 0 ) {
1366 add( dl ); 1398 add( dl );
1367 match = TRUE; 1399 match = TRUE;
1368 } else { 1400 } else {
1369 for( QValueList<QRegExp>::ConstIterator it = mimeFilters.begin(); it != mimeFilters.end(); ++ it ) { 1401 for( QValueList<QRegExp>::ConstIterator it = mimeFilters.begin(); it != mimeFilters.end(); ++ it ) {
1370 if ( (*it).match(dl->type()) >= 0 ) { 1402 if ( (*it).match(dl->type()) >= 0 ) {
1371 add(dl); 1403 add(dl);
1372 match = TRUE; 1404 match = TRUE;
1373 } 1405 }
1374 } 1406 }
1375 } 1407 }
1376 if ( !match ) 1408 if ( !match )
1377 delete dl; 1409 delete dl;
1378 } else { 1410 } else {
1379 if ( !reference.find(fi->fileName()) ) 1411 if ( !reference.find(fi->fileName()) )
1380 reference.insert(fi->filePath(), (void*)2); 1412 reference.insert(fi->filePath(), (void*)2);
1381 } 1413 }
1382 } 1414 }
1383 } 1415 }
1384 } 1416 }
1385 } 1417 }
1386} 1418}
1387 1419
1388/*! 1420/*!
1389 \class DocLnk applnk.h 1421 \class DocLnk applnk.h
1390 \brief The DocLnk class represents loaded document references. 1422 \brief The DocLnk class represents loaded document references.
1391*/ 1423*/
1392 1424
1393/*! 1425/*!
1394 \fn DocLnk::DocLnk( const DocLnk &o ) 1426 \fn DocLnk::DocLnk( const DocLnk &o )
1395 1427
1396 Copies \a o. 1428 Copies \a o.
1397*/ 1429*/
1398 1430
1399/*! 1431/*!
1400 Constructs a DocLnk from a valid .desktop \a file or a new .desktop 1432 Constructs a DocLnk from a valid .desktop \a file or a new .desktop
1401 \a file for other files. 1433 \a file for other files.
1402*/ 1434*/
1403DocLnk::DocLnk( const QString &file ) : 1435DocLnk::DocLnk( const QString &file ) :
1404 AppLnk(file) 1436 AppLnk(file)
1405{ 1437{
1406 init(file); 1438 init(file);
1407} 1439}
1408 1440
1409/*! 1441/*!
1410 Constructs a DocLnk from a valid .desktop \a file or a new .desktop 1442 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 1443 \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 1444 attempt is made to read \a file as a .desktop file; if that fails it
1413 is read as a normal file. 1445 is read as a normal file.
1414*/ 1446*/
1415DocLnk::DocLnk( const QString &file, bool may_be_desktopfile ) : 1447DocLnk::DocLnk( const QString &file, bool may_be_desktopfile ) :
1416 AppLnk(may_be_desktopfile ? file : QString::null) 1448 AppLnk(may_be_desktopfile ? file : QString::null)
1417{ 1449{
1418 init(file); 1450 init(file);
1419} 1451}
1420 1452
1421void DocLnk::init(const QString &file) 1453void DocLnk::init(const QString &file)
1422{ 1454{
1423 if ( isValid() ) { 1455 if ( isValid() ) {
1424#ifndef FORCED_DIR_STRUCTURE_WAY 1456#ifndef FORCED_DIR_STRUCTURE_WAY
1425 if ( mType.isNull() ) 1457 if ( mType.isNull() )
1426 // try to infer it 1458 // try to infer it
1427#endif 1459#endif
1428 { 1460 {
1429 int s0 = file.findRev('/'); 1461 int s0 = file.findRev('/');
1430 if ( s0 > 0 ) { 1462 if ( s0 > 0 ) {
1431 int s1 = file.findRev('/',s0-1); 1463 int s1 = file.findRev('/',s0-1);
1432 if ( s1 > 0 ) { 1464 if ( s1 > 0 ) {
1433 int s2 = file.findRev('/',s1-1); 1465 int s2 = file.findRev('/',s1-1);
1434 if ( s2 > 0 ) { 1466 if ( s2 > 0 ) {
1435 mType = file.mid(s2+1,s0-s2-1); 1467 mType = file.mid(s2+1,s0-s2-1);
1436 } 1468 }
1437 } 1469 }
1438 } 1470 }
1439 } 1471 }
1440 } else if ( QFile::exists(file) ) { 1472 } else if ( QFile::exists(file) ) {
1441 QString n = file; 1473 QString n = file;
1442 n.replace(QRegExp(".*/"),""); 1474 n.replace(QRegExp(".*/"),"");
1443 n.replace(QRegExp("\\..*"),""); 1475 n.replace(QRegExp("\\..*"),"");
1444 setName( n ); 1476 setName( n );
1445 setFile( file ); 1477 setFile( file );
1446 } 1478 }
1447 MimeType mt(mType); 1479 MimeType mt(mType);
1448 if( mt.application() ) 1480 if( mt.application() )
1449 mExec = mt.application()->exec(); 1481 mExec = mt.application()->exec();
1450} 1482}
1451 1483
1452/*! 1484/*!
1453 Constructs an invalid DocLnk. 1485 Constructs an invalid DocLnk.
1454*/ 1486*/
1455DocLnk::DocLnk() 1487DocLnk::DocLnk()
1456{ 1488{
1457} 1489}
1458 1490
1459/*! 1491/*!
1460 Destroys the DocLnk. Just like AppLnk objects, a run-time error 1492 Destroys the DocLnk. Just like AppLnk objects, a run-time error
1461 occurs if the DocLnk is a member of a DocLnkSet (or AppLnkSet). 1493 occurs if the DocLnk is a member of a DocLnkSet (or AppLnkSet).
1462*/ 1494*/
1463DocLnk::~DocLnk() 1495DocLnk::~DocLnk()
1464{ 1496{
1465} 1497}
1466 1498
1467/*! 1499/*!
1468 \reimp 1500 \reimp
1469*/ 1501*/
1470QString DocLnk::exec() const 1502QString DocLnk::exec() const
1471{ 1503{
1472 MimeType mt(type()); 1504 MimeType mt(type());
1473 const AppLnk* app = mt.application(); 1505 const AppLnk* app = mt.application();
1474 if ( app ) 1506 if ( app )
1475 return app->exec(); 1507 return app->exec();
1476 else 1508 else
1477 return QString::null; 1509 return QString::null;
1478} 1510}
1479 1511
1480/*! 1512/*!
1481 \reimp 1513 \reimp
1482*/ 1514*/
1483void DocLnk::invoke(const QStringList& args) const 1515void DocLnk::invoke(const QStringList& args) const
1484{ 1516{
1485 MimeType mt(type()); 1517 MimeType mt(type());
1486 const AppLnk* app = mt.application(); 1518 const AppLnk* app = mt.application();
1487 if ( app ) { 1519 if ( app ) {
1488 QStringList a = args; 1520 QStringList a = args;
1489 if ( linkFileKnown() && QFile::exists( linkFile() ) ) 1521 if ( linkFileKnown() && QFile::exists( linkFile() ) )
1490 a.append(linkFile()); 1522 a.append(linkFile());
1491 else 1523 else
1492 a.append(file()); 1524 a.append(file());
1493 app->execute(a); 1525 app->execute(a);
1494 } 1526 }
1495} 1527}
1496 1528
1497 1529