summaryrefslogtreecommitdiff
path: root/library/applnk.cpp
Unidiff
Diffstat (limited to 'library/applnk.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/applnk.cpp16
1 files changed, 16 insertions, 0 deletions
diff --git a/library/applnk.cpp b/library/applnk.cpp
index 35822dd..00030e8 100644
--- a/library/applnk.cpp
+++ b/library/applnk.cpp
@@ -1,1481 +1,1497 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of the Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#define QTOPIA_INTERNAL_MIMEEXT 21#define QTOPIA_INTERNAL_MIMEEXT
22#define QTOPIA_INTERNAL_PRELOADACCESS 22#define QTOPIA_INTERNAL_PRELOADACCESS
23#define QTOPIA_INTERNAL_APPLNKASSIGN 23#define QTOPIA_INTERNAL_APPLNKASSIGN
24 24
25#include "applnk.h" 25#include "applnk.h"
26 26
27#include <qpe/qpeapplication.h> 27#include <qpe/qpeapplication.h>
28#include <qpe/categories.h> 28#include <qpe/categories.h>
29#include <qpe/categoryselect.h> 29#include <qpe/categoryselect.h>
30#include <qpe/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
270 Returns the Name property. This is the user-visible name for the 270 Returns the Name property. This is the user-visible name for the
271 document or application, not the filename. 271 document or application, not the filename.
272 272
273 See \link #files-and-links Files and Links\endlink. 273 See \link #files-and-links Files and Links\endlink.
274 274
275 \sa setName() 275 \sa setName()
276*/ 276*/
277/*! 277/*!
278 \fn QString AppLnk::exec() const 278 \fn QString AppLnk::exec() const
279 279
280 Returns the Exec property. This is the name of the executable 280 Returns the Exec property. This is the name of the executable
281 program associated with the AppLnk. 281 program associated with the AppLnk.
282 282
283 \sa setExec() 283 \sa setExec()
284*/ 284*/
285/*! 285/*!
286 \fn QString AppLnk::rotation() const 286 \fn QString AppLnk::rotation() const
287 287
288 Returns the Rotation property. The value is 0, 90, 180 or 270 288 Returns the Rotation property. The value is 0, 90, 180 or 270
289 degrees. 289 degrees.
290*/ 290*/
291/*! 291/*!
292 \fn QString AppLnk::comment() const 292 \fn QString AppLnk::comment() const
293 293
294 Returns the Comment property. 294 Returns the Comment property.
295 295
296 \sa setComment() 296 \sa setComment()
297*/ 297*/
298/*! 298/*!
299 \fn QStringList AppLnk::mimeTypes() const 299 \fn QStringList AppLnk::mimeTypes() const
300 300
301 Returns the MimeTypes property. This is the list of MIME types 301 Returns the MimeTypes property. This is the list of MIME types
302 that the application can view or edit. 302 that the application can view or edit.
303*/ 303*/
304/*! 304/*!
305 \fn const QArray<int>& AppLnk::categories() const 305 \fn const QArray<int>& AppLnk::categories() const
306 306
307 Returns the Categories property. 307 Returns the Categories property.
308 308
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/*!
336 \fn bool AppLnk::fileKnown() const
337
338 If the with the AppLnk associated file is not equal to QString::null
339*/
340/*!
341 \fn bool AppLnk::linkFileKnown()const
342
343 The filename of the AppLnk
335 344
345*/
346/*!
347 \fn void AppLnk::setRotation( const QString& )
348
349 The default rotation of the associated application. This
350 function is included inline for binary compatible issues
351*/
336/*! 352/*!
337 Creates an invalid AppLnk. 353 Creates an invalid AppLnk.
338 354
339 \sa isValid() 355 \sa isValid()
340*/ 356*/
341AppLnk::AppLnk() 357AppLnk::AppLnk()
342{ 358{
343 mId = 0; 359 mId = 0;
344 d = new AppLnkPrivate(); 360 d = new AppLnkPrivate();
345} 361}
346 362
347/*! 363/*!
348 Loads \a file (e.g. \e app.desktop) as an AppLnk. 364 Loads \a file (e.g. \e app.desktop) as an AppLnk.
349 365
350 \sa writeLink() 366 \sa writeLink()
351*/ 367*/
352AppLnk::AppLnk( const QString &file ) 368AppLnk::AppLnk( const QString &file )
353{ 369{
354 QStringList sl; 370 QStringList sl;
355 d = new AppLnkPrivate(); 371 d = new AppLnkPrivate();
356 if ( !file.isNull() ) { 372 if ( !file.isNull() ) {
357 Config config( file, Config::File ); 373 Config config( file, Config::File );
358 374
359 if ( config.isValid() ) { 375 if ( config.isValid() ) {
360 config.setGroup( "Desktop Entry" ); 376 config.setGroup( "Desktop Entry" );
361 377
362 mName = config.readEntry( "Name", file ); 378 mName = config.readEntry( "Name", file );
363 mExec = config.readEntry( "Exec" ); 379 mExec = config.readEntry( "Exec" );
364 mType = config.readEntry( "Type", QString::null ); 380 mType = config.readEntry( "Type", QString::null );
365 mIconFile = config.readEntry( "Icon", QString::null ); 381 mIconFile = config.readEntry( "Icon", QString::null );
366 mRotation = config.readEntry( "Rotation", "" ); 382 mRotation = config.readEntry( "Rotation", "" );
367 mComment = config.readEntry( "Comment", QString::null ); 383 mComment = config.readEntry( "Comment", QString::null );
368 // MIME types are case-insensitive. 384 // MIME types are case-insensitive.
369 mMimeTypes = config.readListEntry( "MimeType", ';' ); 385 mMimeTypes = config.readListEntry( "MimeType", ';' );
370 for (QStringList::Iterator it=mMimeTypes.begin(); it!=mMimeTypes.end(); ++it) 386 for (QStringList::Iterator it=mMimeTypes.begin(); it!=mMimeTypes.end(); ++it)
371 *it = (*it).lower(); 387 *it = (*it).lower();
372 mMimeTypeIcons = config.readListEntry( "MimeTypeIcons", ';' ); 388 mMimeTypeIcons = config.readListEntry( "MimeTypeIcons", ';' );
373 mLinkFile = file; 389 mLinkFile = file;
374 mFile = config.readEntry("File", QString::null); 390 mFile = config.readEntry("File", QString::null);
375 if ( !mExec. isEmpty ( )) { 391 if ( !mExec. isEmpty ( )) {
376 mFile = QString::null; 392 mFile = QString::null;
377 } 393 }
378 else if ( mFile[0] != '/' ) { 394 else if ( mFile[0] != '/' ) {
379 int slash = file.findRev('/'); 395 int slash = file.findRev('/');
380 if ( slash >= 0 ) { 396 if ( slash >= 0 ) {
381 mFile = file.left(slash) + '/' + mFile; 397 mFile = file.left(slash) + '/' + mFile;
382 } 398 }
383 } 399 }
384 d->mCatList = config.readListEntry("Categories", ';'); 400 d->mCatList = config.readListEntry("Categories", ';');
385 if ( d->mCatList[0].toInt() < -1 ) { 401 if ( d->mCatList[0].toInt() < -1 ) {
386 // numeric cats in file! convert to text 402 // numeric cats in file! convert to text
387 Categories cat( 0 ); 403 Categories cat( 0 );
388 cat.load( categoryFileName() ); 404 cat.load( categoryFileName() );
389 d->mCat.resize( d->mCatList.count() ); 405 d->mCat.resize( d->mCatList.count() );
390 int i; 406 int i;
391 QStringList::ConstIterator it; 407 QStringList::ConstIterator it;
392 for ( i = 0, it = d->mCatList.begin(); it != d->mCatList.end(); 408 for ( i = 0, it = d->mCatList.begin(); it != d->mCatList.end();
393 ++it, i++ ) { 409 ++it, i++ ) {
394 bool number; 410 bool number;
395 int id = (*it).toInt( &number ); 411 int id = (*it).toInt( &number );
396 if ( !number ) { 412 if ( !number ) {
397 // convert from text 413 // convert from text
398 id = cat.id( "Document View", *it ); 414 id = cat.id( "Document View", *it );
399 if ( id == 0 ) 415 if ( id == 0 )
400 id = cat.addCategory( "Document View", *it ); 416 id = cat.addCategory( "Document View", *it );
401 } 417 }
402 d->mCat[i] = id; 418 d->mCat[i] = id;
403 } 419 }
404 d->updateCatListFromArray(); 420 d->updateCatListFromArray();
405 } 421 }
406 } 422 }
407 } 423 }
408 mId = 0; 424 mId = 0;
409} 425}
410 426
411AppLnk& AppLnk::operator=(const AppLnk &copy) 427AppLnk& AppLnk::operator=(const AppLnk &copy)
412{ 428{
413 if ( this == &copy ) return *this; 429 if ( this == &copy ) return *this;
414 if ( mId ) 430 if ( mId )
415 qWarning("Deleting AppLnk that is in an AppLnkSet"); 431 qWarning("Deleting AppLnk that is in an AppLnkSet");
416 if ( d ) 432 if ( d )
417 delete d; 433 delete d;
418 434
419 435
420 mName = copy.mName; 436 mName = copy.mName;
421 437
422 /* remove for Qtopia 3.0 -zecke */ 438 /* remove for Qtopia 3.0 -zecke */
423 mPixmap = copy.mPixmap; 439 mPixmap = copy.mPixmap;
424 mBigPixmap = copy.mBigPixmap; 440 mBigPixmap = copy.mBigPixmap;
425 441
426 mExec = copy.mExec; 442 mExec = copy.mExec;
427 mType = copy.mType; 443 mType = copy.mType;
428 mRotation = copy.mRotation; 444 mRotation = copy.mRotation;
429 mComment = copy.mComment; 445 mComment = copy.mComment;
430 mFile = copy.mFile; 446 mFile = copy.mFile;
431 mLinkFile = copy.mLinkFile; 447 mLinkFile = copy.mLinkFile;
432 mIconFile = copy.mIconFile; 448 mIconFile = copy.mIconFile;
433 mMimeTypes = copy.mMimeTypes; 449 mMimeTypes = copy.mMimeTypes;
434 mMimeTypeIcons = copy.mMimeTypeIcons; 450 mMimeTypeIcons = copy.mMimeTypeIcons;
435 mId = 0; 451 mId = 0;
436 d = new AppLnkPrivate(); 452 d = new AppLnkPrivate();
437 d->mCat = copy.d->mCat; 453 d->mCat = copy.d->mCat;
438 d->mCatList = copy.d->mCatList; 454 d->mCatList = copy.d->mCatList;
439 d->mPixmaps = copy.d->mPixmaps; 455 d->mPixmaps = copy.d->mPixmaps;
440 456
441 return *this; 457 return *this;
442} 458}
443/*! 459/*!
444 protected internally to share code 460 protected internally to share code
445 should I document that at all? 461 should I document that at all?
446 I don't know the TT style for that 462 I don't know the TT style for that
447*/ 463*/
448const QPixmap& AppLnk::pixmap( int pos, int size ) const { 464const QPixmap& AppLnk::pixmap( int pos, int size ) const {
449 if ( d->mPixmaps[pos].isNull() ) { 465 if ( d->mPixmaps[pos].isNull() ) {
450 AppLnk* that = (AppLnk*)this; 466 AppLnk* that = (AppLnk*)this;
451 if ( mIconFile.isEmpty() ) { 467 if ( mIconFile.isEmpty() ) {
452 MimeType mt(type()); 468 MimeType mt(type());
453 that->d->mPixmaps[pos] = mt.pixmap(); 469 that->d->mPixmaps[pos] = mt.pixmap();
454 if ( that->d->mPixmaps[pos].isNull() ) 470 if ( that->d->mPixmaps[pos].isNull() )
455 that->d->mPixmaps[pos].convertFromImage( 471 that->d->mPixmaps[pos].convertFromImage(
456 Resource::loadImage("UnknownDocument") 472 Resource::loadImage("UnknownDocument")
457 .smoothScale( size, size ) ); 473 .smoothScale( size, size ) );
458 return that->d->mPixmaps[pos]; 474 return that->d->mPixmaps[pos];
459 } 475 }
460 QImage unscaledIcon = Resource::loadImage( that->mIconFile ); 476 QImage unscaledIcon = Resource::loadImage( that->mIconFile );
461 if ( unscaledIcon.isNull() ) { 477 if ( unscaledIcon.isNull() ) {
462 qDebug( "Cannot find icon: %s", that->mIconFile.latin1() ); 478 qDebug( "Cannot find icon: %s", that->mIconFile.latin1() );
463 that->d->mPixmaps[pos].convertFromImage( 479 that->d->mPixmaps[pos].convertFromImage(
464 Resource::loadImage("UnknownDocument") 480 Resource::loadImage("UnknownDocument")
465 .smoothScale( size, size ) ); 481 .smoothScale( size, size ) );
466 } else { 482 } else {
467 that->d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) ); 483 that->d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
468 that->d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) ); 484 that->d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
469 } 485 }
470 return that->d->mPixmaps[pos]; 486 return that->d->mPixmaps[pos];
471 } 487 }
472 return d->mPixmaps[pos]; 488 return d->mPixmaps[pos];
473} 489}
474 490
475/*! 491/*!
476 Returns a small pixmap associated with the application. 492 Returns a small pixmap associated with the application.
477 493
478 \sa bigPixmap() setIcon() 494 \sa bigPixmap() setIcon()
479*/ 495*/
480const QPixmap& AppLnk::pixmap() const 496const QPixmap& AppLnk::pixmap() const
481{ 497{
482 if ( d->mPixmaps[0].isNull() ) { 498 if ( d->mPixmaps[0].isNull() ) {
483 return pixmap(AppLnkPrivate::Normal, smallSize ); 499 return pixmap(AppLnkPrivate::Normal, smallSize );
484 } 500 }
485 return d->mPixmaps[0]; 501 return d->mPixmaps[0];
486} 502}
487 503
488/*! 504/*!
489 Returns a large pixmap associated with the application. 505 Returns a large pixmap associated with the application.
490 506
491 \sa pixmap() setIcon() 507 \sa pixmap() setIcon()
492*/ 508*/
493const QPixmap& AppLnk::bigPixmap() const 509const QPixmap& AppLnk::bigPixmap() const
494{ 510{
495 if ( d->mPixmaps[1].isNull() ) { 511 if ( d->mPixmaps[1].isNull() ) {
496 return pixmap( AppLnkPrivate::Big, bigSize ); 512 return pixmap( AppLnkPrivate::Big, bigSize );
497 } 513 }
498 return d->mPixmaps[1]; 514 return d->mPixmaps[1];
499} 515}
500 516
501/*! 517/*!
502 Returns the type of the AppLnk. For applications, games and 518 Returns the type of the AppLnk. For applications, games and
503 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
504 document's MIME type. 520 document's MIME type.
505*/ 521*/
506QString AppLnk::type() const 522QString AppLnk::type() const
507{ 523{
508 if ( mType.isNull() ) { 524 if ( mType.isNull() ) {
509 AppLnk* that = (AppLnk*)this; 525 AppLnk* that = (AppLnk*)this;
510 QString f = file(); 526 QString f = file();
511 if ( !f.isNull() ) { 527 if ( !f.isNull() ) {
512 MimeType mt(f); 528 MimeType mt(f);
513 that->mType = mt.id(); 529 that->mType = mt.id();
514 return that->mType; 530 return that->mType;
515 } 531 }
516 } 532 }
517 return mType; 533 return mType;
518} 534}
519 535
520/*! 536/*!
521 Returns the file associated with the AppLnk. 537 Returns the file associated with the AppLnk.
522 538
523 \sa exec() name() 539 \sa exec() name()
524*/ 540*/
525QString AppLnk::file() const 541QString AppLnk::file() const
526{ 542{
527 if ( mExec.isEmpty ( ) && mFile.isNull() ) { 543 if ( mExec.isEmpty ( ) && mFile.isNull() ) {
528 AppLnk* that = (AppLnk*)this; 544 AppLnk* that = (AppLnk*)this;
529 QString ext = MimeType(mType).extension(); 545 QString ext = MimeType(mType).extension();
530 if ( !ext.isEmpty() ) 546 if ( !ext.isEmpty() )
531 ext = "." + ext; 547 ext = "." + ext;
532 if ( !mLinkFile.isEmpty() ) { 548 if ( !mLinkFile.isEmpty() ) {
533 that->mFile = 549 that->mFile =
534 mLinkFile.right(8)==".desktop" // 8 = strlen(".desktop") 550 mLinkFile.right(8)==".desktop" // 8 = strlen(".desktop")
535 ? mLinkFile.left(mLinkFile.length()-8) : mLinkFile; 551 ? mLinkFile.left(mLinkFile.length()-8) : mLinkFile;
536 qDebug("mFile now == %s", mFile.latin1()); 552 qDebug("mFile now == %s", mFile.latin1());
537 } else if ( mType.contains('/') ) { 553 } else if ( mType.contains('/') ) {
538 that->mFile = 554 that->mFile =
539 QString(getenv("HOME"))+"/Documents/"+mType+"/"+safeFileName(that->mName); 555 QString(getenv("HOME"))+"/Documents/"+mType+"/"+safeFileName(that->mName);
540 /* 556 /*
541 * 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
542 */ 558 */
543 if ( QFile::exists(that->mFile+ext) || QFile::exists(that->mFile+".desktop") ) { 559 if ( QFile::exists(that->mFile+ext) || QFile::exists(that->mFile+".desktop") ) {
544 int n=1; 560 int n=1;
545 QString nn; 561 QString nn;
546 while (QFile::exists((nn=(that->mFile+"_"+QString::number(n)))+ext) 562 while (QFile::exists((nn=(that->mFile+"_"+QString::number(n)))+ext)
547 || QFile::exists(nn+".desktop")) 563 || QFile::exists(nn+".desktop"))
548 n++; 564 n++;
549 that->mFile = nn; 565 that->mFile = nn;
550 } 566 }
551 that->mLinkFile = that->mFile+".desktop"; 567 that->mLinkFile = that->mFile+".desktop";
552 that->mFile += ext; 568 that->mFile += ext;
553 } 569 }
554 prepareDirectories(that->mFile); 570 prepareDirectories(that->mFile);
555 if ( !that->mFile.isEmpty() ) { 571 if ( !that->mFile.isEmpty() ) {
556 QFile f(that->mFile); 572 QFile f(that->mFile);
557 if ( !f.open(IO_WriteOnly) ) 573 if ( !f.open(IO_WriteOnly) )
558 that->mFile = QString::null; 574 that->mFile = QString::null;
559 return that->mFile; 575 return that->mFile;
560 } 576 }
561 } 577 }
562 return mFile; 578 return mFile;
563} 579}
564 580
565/*! 581/*!
566 Returns the desktop file corresponding to this AppLnk. 582 Returns the desktop file corresponding to this AppLnk.
567 583
568 \sa file() exec() name() 584 \sa file() exec() name()
569*/ 585*/
570QString AppLnk::linkFile() const 586QString AppLnk::linkFile() const
571{ 587{
572 if ( mLinkFile.isNull() ) { 588 if ( mLinkFile.isNull() ) {
573 AppLnk* that = (AppLnk*)this; 589 AppLnk* that = (AppLnk*)this;
574 if ( type().contains('/') ) { 590 if ( type().contains('/') ) {
575 StorageInfo storage; 591 StorageInfo storage;
576 const FileSystem *fs = storage.fileSystemOf( that->mFile ); 592 const FileSystem *fs = storage.fileSystemOf( that->mFile );
577 /* tmpfs + and ramfs are available too but not removable 593 /* tmpfs + and ramfs are available too but not removable
578 * either we fix storage or add this 594 * either we fix storage or add this
579 */ 595 */
580 if ( fs && ( fs->isRemovable() || fs->disk() == "/dev/mtdblock6" || fs->disk() == "tmpfs") ) { 596 if ( fs && ( fs->isRemovable() || fs->disk() == "/dev/mtdblock6" || fs->disk() == "tmpfs") ) {
581 that->mLinkFile = fs->path(); 597 that->mLinkFile = fs->path();
582 } else 598 } else
583 that->mLinkFile = getenv( "HOME" ); 599 that->mLinkFile = getenv( "HOME" );
584 that->mLinkFile += "/Documents/"+type()+"/"+safeFileName(that->mName); 600 that->mLinkFile += "/Documents/"+type()+"/"+safeFileName(that->mName);
585 601
586 /* 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 */
587 if ( QFile::exists(that->mLinkFile+".desktop") ) { 603 if ( QFile::exists(that->mLinkFile+".desktop") ) {
588 AppLnk lnk( that->mLinkFile + ".desktop" ); 604 AppLnk lnk( that->mLinkFile + ".desktop" );
589 605
590 /* the linked is different */ 606 /* the linked is different */
591 if(that->file() != lnk.file() ) { 607 if(that->file() != lnk.file() ) {
592 int n = 1; 608 int n = 1;
593 QString nn; 609 QString nn;
594 while (QFile::exists((nn=that->mLinkFile+"_"+QString::number(n))+".desktop")) { 610 while (QFile::exists((nn=that->mLinkFile+"_"+QString::number(n))+".desktop")) {
595 n++; 611 n++;
596 /* just to be sure */ 612 /* just to be sure */
597 AppLnk lnk(nn ); 613 AppLnk lnk(nn );
598 if (lnk.file() == that->file() ) 614 if (lnk.file() == that->file() )
599 break; 615 break;
600 } 616 }
601 that->mLinkFile = nn; 617 that->mLinkFile = nn;
602 } 618 }
603 } 619 }
604 that->mLinkFile += ".desktop"; 620 that->mLinkFile += ".desktop";
605 storeLink(); 621 storeLink();
606 } 622 }
607 return that->mLinkFile; 623 return that->mLinkFile;
608 } 624 }
609 return mLinkFile; 625 return mLinkFile;
610} 626}
611 627
612/*! 628/*!
613 Copies \a copy. 629 Copies \a copy.
614*/ 630*/
615AppLnk::AppLnk( const AppLnk &copy ) 631AppLnk::AppLnk( const AppLnk &copy )
616{ 632{
617 mName = copy.mName; 633 mName = copy.mName;
618 mPixmap = copy.mPixmap; 634 mPixmap = copy.mPixmap;
619 mBigPixmap = copy.mBigPixmap; 635 mBigPixmap = copy.mBigPixmap;
620 mExec = copy.mExec; 636 mExec = copy.mExec;
621 mType = copy.mType; 637 mType = copy.mType;
622 mRotation = copy.mRotation; 638 mRotation = copy.mRotation;
623 mComment = copy.mComment; 639 mComment = copy.mComment;
624 mFile = copy.mFile; 640 mFile = copy.mFile;
625 mLinkFile = copy.mLinkFile; 641 mLinkFile = copy.mLinkFile;
626 mIconFile = copy.mIconFile; 642 mIconFile = copy.mIconFile;
627 mMimeTypes = copy.mMimeTypes; 643 mMimeTypes = copy.mMimeTypes;
628 mMimeTypeIcons = copy.mMimeTypeIcons; 644 mMimeTypeIcons = copy.mMimeTypeIcons;
629 mId = 0; 645 mId = 0;
630 d = new AppLnkPrivate(); 646 d = new AppLnkPrivate();
631 d->mCat = copy.d->mCat; 647 d->mCat = copy.d->mCat;
632 d->mCatList = copy.d->mCatList; 648 d->mCatList = copy.d->mCatList;
633 d->mPixmaps = copy.d->mPixmaps; 649 d->mPixmaps = copy.d->mPixmaps;
634} 650}
635 651
636/*! 652/*!
637 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
638 of an AppLnkSet, this will produce a run-time warning. 654 of an AppLnkSet, this will produce a run-time warning.
639 655
640 \sa AppLnkSet::add() AppLnkSet::remove() 656 \sa AppLnkSet::add() AppLnkSet::remove()
641*/ 657*/
642AppLnk::~AppLnk() 658AppLnk::~AppLnk()
643{ 659{
644 if ( mId ) 660 if ( mId )
645 qWarning("Deleting AppLnk that is in an AppLnkSet"); 661 qWarning("Deleting AppLnk that is in an AppLnkSet");
646 if ( d ) 662 if ( d )
647 delete d; 663 delete d;
648} 664}
649 665
650/*! 666/*!
651 \overload 667 \overload
652 Executes the application associated with this AppLnk. 668 Executes the application associated with this AppLnk.
653 669
654 \sa exec() 670 \sa exec()
655*/ 671*/
656void AppLnk::execute() const 672void AppLnk::execute() const
657{ 673{
658 execute(QStringList()); 674 execute(QStringList());
659} 675}
660 676
661/*! 677/*!
662 Executes the application associated with this AppLnk, with 678 Executes the application associated with this AppLnk, with
663 \a args as arguments. 679 \a args as arguments.
664 680
665 \sa exec() 681 \sa exec()
666*/ 682*/
667void AppLnk::execute(const QStringList& args) const 683void AppLnk::execute(const QStringList& args) const
668{ 684{
669#ifdef Q_WS_QWS 685#ifdef Q_WS_QWS
670 if ( !mRotation.isEmpty() ) { 686 if ( !mRotation.isEmpty() ) {
671 // ######## this will only work in the server 687 // ######## this will only work in the server
672 int rot = QPEApplication::defaultRotation(); 688 int rot = QPEApplication::defaultRotation();
673 rot = (rot+mRotation.toInt())%360; 689 rot = (rot+mRotation.toInt())%360;
674 QCString old = getenv("QWS_DISPLAY"); 690 QCString old = getenv("QWS_DISPLAY");
675 setenv("QWS_DISPLAY", QString("Transformed:Rot%1:0").arg(rot), 1); 691 setenv("QWS_DISPLAY", QString("Transformed:Rot%1:0").arg(rot), 1);
676 invoke(args); 692 invoke(args);
677 setenv("QWS_DISPLAY", old.data(), 1); 693 setenv("QWS_DISPLAY", old.data(), 1);
678 } else 694 } else
679#endif 695#endif
680 invoke(args); 696 invoke(args);
681} 697}
682 698
683/*! 699/*!
684 Invokes the application associated with this AppLnk, with 700 Invokes the application associated with this AppLnk, with
685 \a args as arguments. Rotation is not taken into account by 701 \a args as arguments. Rotation is not taken into account by
686 this function, so you should not call it directly. 702 this function, so you should not call it directly.
687 703
688 \sa execute() 704 \sa execute()
689*/ 705*/
690void AppLnk::invoke(const QStringList& args) const 706void AppLnk::invoke(const QStringList& args) const
691{ 707{
692 Global::execute( exec(), args[0] ); 708 Global::execute( exec(), args[0] );
693} 709}
694 710
695/*! 711/*!
696 Sets the Exec property to \a exec. 712 Sets the Exec property to \a exec.
697 713
698 \sa exec() name() 714 \sa exec() name()
699*/ 715*/
700void AppLnk::setExec( const QString& exec ) 716void AppLnk::setExec( const QString& exec )
701{ 717{
702 mExec = exec; 718 mExec = exec;
703} 719}
704 720
705#if 0 // this was inlined for better BC 721#if 0 // this was inlined for better BC
706/*! 722/*!
707 Sets the Rotation property to \a rot. 723 Sets the Rotation property to \a rot.
708 724
709 \sa rotation() 725 \sa rotation()
710*/ 726*/
711void AppLnk::setRotation ( const QString &rot ) 727void AppLnk::setRotation ( const QString &rot )
712{ 728{
713 mRotation = rot; 729 mRotation = rot;
714} 730}
715#endif 731#endif
716 732
717/*! 733/*!
718 Sets the Name property to \a docname. 734 Sets the Name property to \a docname.
719 735
720 \sa name() 736 \sa name()
721*/ 737*/
722void AppLnk::setName( const QString& docname ) 738void AppLnk::setName( const QString& docname )
723{ 739{
724 mName = docname; 740 mName = docname;
725} 741}
726 742
727/*! 743/*!
728 Sets the File property to \a filename. 744 Sets the File property to \a filename.
729 745
730 \sa file() name() 746 \sa file() name()
731*/ 747*/
732void AppLnk::setFile( const QString& filename ) 748void AppLnk::setFile( const QString& filename )
733{ 749{
734 mFile = filename; 750 mFile = filename;
735} 751}
736 752
737/*! 753/*!
738 Sets the LinkFile property to \a filename. 754 Sets the LinkFile property to \a filename.
739 755
740 \sa linkFile() 756 \sa linkFile()
741*/ 757*/
742void AppLnk::setLinkFile( const QString& filename ) 758void AppLnk::setLinkFile( const QString& filename )
743{ 759{
744 mLinkFile = filename; 760 mLinkFile = filename;
745} 761}
746 762
747/*! 763/*!
748 Sets the Comment property to \a comment. 764 Sets the Comment property to \a comment.
749 765
750 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
751 user uses the 'press-and-hold' gesture. 767 user uses the 'press-and-hold' gesture.
752 768
753 \sa comment() 769 \sa comment()
754*/ 770*/
755void AppLnk::setComment( const QString& comment ) 771void AppLnk::setComment( const QString& comment )
756{ 772{
757 mComment = comment; 773 mComment = comment;
758} 774}
759 775
760/*! 776/*!
761 Sets the Type property to \a type. 777 Sets the Type property to \a type.
762 778
763 For applications, games and settings the type should be \c 779 For applications, games and settings the type should be \c
764 Application; for documents the type should be the document's MIME 780 Application; for documents the type should be the document's MIME
765 type. 781 type.
766 782
767 \sa type() 783 \sa type()
768*/ 784*/
769void AppLnk::setType( const QString& type ) 785void AppLnk::setType( const QString& type )
770{ 786{
771 mType = type; 787 mType = type;
772} 788}
773 789
774/*! 790/*!
775 \fn QString AppLnk::icon() const 791 \fn QString AppLnk::icon() const
776 792
777 Returns the Icon property. 793 Returns the Icon property.
778 794
779 \sa setIcon() 795 \sa setIcon()
780*/ 796*/
781 797
782/*! 798/*!
783 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
784 which the pixmap() and bigPixmap() are obtained. 800 which the pixmap() and bigPixmap() are obtained.
785 801
786 \sa icon() setSmallIconSize() setBigIconSize() 802 \sa icon() setSmallIconSize() setBigIconSize()
787*/ 803*/
788void AppLnk::setIcon( const QString& iconname ) 804void AppLnk::setIcon( const QString& iconname )
789{ 805{
790 mIconFile = iconname; 806 mIconFile = iconname;
791 QImage unscaledIcon = Resource::loadImage( mIconFile ); 807 QImage unscaledIcon = Resource::loadImage( mIconFile );
792 d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) ); 808 d->mPixmaps[0].convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
793 d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) ); 809 d->mPixmaps[1].convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
794} 810}
795 811
796/*! 812/*!
797 Sets the Categories property to \a c. 813 Sets the Categories property to \a c.
798 814
799 See the CategoryWidget for more details. 815 See the CategoryWidget for more details.
800 816
801 \sa categories() 817 \sa categories()
802*/ 818*/
803void AppLnk::setCategories( const QArray<int>& c ) 819void AppLnk::setCategories( const QArray<int>& c )
804{ 820{
805 d->mCat = c; 821 d->mCat = c;
806 d->updateCatListFromArray(); 822 d->updateCatListFromArray();
807} 823}
808 824
809/*! 825/*!
810 \fn QStringList AppLnk::mimeTypeIcons() const 826 \fn QStringList AppLnk::mimeTypeIcons() const
811 827
812 Returns the MimeTypeIcons property of the AppLnk. 828 Returns the MimeTypeIcons property of the AppLnk.
813*/ 829*/
814 830
815/*! 831/*!
816 Attempts to ensure that the link file for this AppLnk exists, 832 Attempts to ensure that the link file for this AppLnk exists,
817 including creating any required directories. Returns TRUE if 833 including creating any required directories. Returns TRUE if
818 successful; otherwise returns FALSE. 834 successful; otherwise returns FALSE.
819 835
820 You should not need to use this function. 836 You should not need to use this function.
821*/ 837*/
822bool AppLnk::ensureLinkExists() const 838bool AppLnk::ensureLinkExists() const
823{ 839{
824 QString lf = linkFile(); 840 QString lf = linkFile();
825 return prepareDirectories(lf); 841 return prepareDirectories(lf);
826} 842}
827 843
828/*! 844/*!
829 Commits the AppLnk to disk. Returns TRUE if the operation succeeded; 845 Commits the AppLnk to disk. Returns TRUE if the operation succeeded;
830 otherwise returns FALSE. 846 otherwise returns FALSE.
831 847
832 In addition, the "linkChanged(QString)" message is sent to the 848 In addition, the "linkChanged(QString)" message is sent to the
833 "QPE/System" \link qcop.html QCop\endlink channel. 849 "QPE/System" \link qcop.html QCop\endlink channel.
834*/ 850*/
835bool AppLnk::writeLink() const 851bool AppLnk::writeLink() const
836{ 852{
837 // Only re-writes settable parts 853 // Only re-writes settable parts
838 QString lf = linkFile(); 854 QString lf = linkFile();
839 if ( !ensureLinkExists() ) 855 if ( !ensureLinkExists() )
840 return FALSE; 856 return FALSE;
841 storeLink(); 857 storeLink();
842 return TRUE; 858 return TRUE;
843} 859}
844 860
845/*! 861/*!
846 \internal 862 \internal
847*/ 863*/
848void AppLnk::storeLink() const 864void AppLnk::storeLink() const
849{ 865{
850 Config config( mLinkFile, Config::File ); 866 Config config( mLinkFile, Config::File );
851 config.setGroup("Desktop Entry"); 867 config.setGroup("Desktop Entry");
852 config.writeEntry("Name",mName); 868 config.writeEntry("Name",mName);
853 if ( !mIconFile.isNull() ) config.writeEntry("Icon",mIconFile); 869 if ( !mIconFile.isNull() ) config.writeEntry("Icon",mIconFile);
854 config.writeEntry("Type",type()); 870 config.writeEntry("Type",type());
855 if(!rotation().isEmpty()) 871 if(!rotation().isEmpty())
856 config.writeEntry("Rotation",rotation()); 872 config.writeEntry("Rotation",rotation());
857 else 873 else
858 config.removeEntry("Rotation"); 874 config.removeEntry("Rotation");
859 if ( !mComment.isNull() ) config.writeEntry("Comment",mComment); 875 if ( !mComment.isNull() ) config.writeEntry("Comment",mComment);
860 QString f = file(); 876 QString f = file();
861 int i = 0; 877 int i = 0;
862 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] )
863 i++; 879 i++;
864 while ( i && f[i] != '/' ) 880 while ( i && f[i] != '/' )
865 i--; 881 i--;
866 // simple case where in the same directory 882 // simple case where in the same directory
867 if ( mLinkFile.find( '/', i + 1 ) < 0 ) 883 if ( mLinkFile.find( '/', i + 1 ) < 0 )
868 f = f.mid(i+1); 884 f = f.mid(i+1);
869 // ### could do relative ie ../../otherDocs/file.doc 885 // ### could do relative ie ../../otherDocs/file.doc
870 config.writeEntry("File",f); 886 config.writeEntry("File",f);
871 config.writeEntry( "Categories", d->mCatList, ';' ); 887 config.writeEntry( "Categories", d->mCatList, ';' );
872 888
873#ifndef QT_NO_COP 889#ifndef QT_NO_COP
874 QCopEnvelope e("QPE/System", "linkChanged(QString)"); 890 QCopEnvelope e("QPE/System", "linkChanged(QString)");
875 e << mLinkFile; 891 e << mLinkFile;
876#endif 892#endif
877} 893}
878 894
879/*! 895/*!
880 Sets the property named \a key to \a value. 896 Sets the property named \a key to \a value.
881 897
882 \sa property() 898 \sa property()
883*/ 899*/
884void AppLnk::setProperty(const QString& key, const QString& value) 900void AppLnk::setProperty(const QString& key, const QString& value)
885{ 901{
886 if ( ensureLinkExists() ) { 902 if ( ensureLinkExists() ) {
887 Config cfg(linkFile(), Config::File); 903 Config cfg(linkFile(), Config::File);
888 cfg.writeEntry(key,value); 904 cfg.writeEntry(key,value);
889 } 905 }
890} 906}
891 907
892/*! 908/*!
893 Returns the property named \a key. 909 Returns the property named \a key.
894 910
895 \sa setProperty() 911 \sa setProperty()
896*/ 912*/
897QString AppLnk::property(const QString& key) const 913QString AppLnk::property(const QString& key) const
898{ 914{
899 QString lf = linkFile(); 915 QString lf = linkFile();
900 if ( !QFile::exists(lf) ) 916 if ( !QFile::exists(lf) )
901 return QString::null; 917 return QString::null;
902 Config cfg(lf, Config::File); 918 Config cfg(lf, Config::File);
903 return cfg.readEntry(key); 919 return cfg.readEntry(key);
904} 920}
905 921
906bool AppLnk::isPreloaded() const { 922bool AppLnk::isPreloaded() const {
907 // Preload information is stored in the Launcher config in v1.5. 923 // Preload information is stored in the Launcher config in v1.5.
908 Config cfg("Launcher"); 924 Config cfg("Launcher");
909 cfg.setGroup("Preload"); 925 cfg.setGroup("Preload");
910 QStringList apps = cfg.readListEntry("Apps",','); 926 QStringList apps = cfg.readListEntry("Apps",',');
911 if (apps.contains(exec())) 927 if (apps.contains(exec()))
912 return true; 928 return true;
913 return false; 929 return false;
914} 930}
915 931
916void AppLnk::setPreloaded(bool yesNo) { 932void AppLnk::setPreloaded(bool yesNo) {
917 // Preload information is stored in the Launcher config in v1.5. 933 // Preload information is stored in the Launcher config in v1.5.
918 Config cfg("Launcher"); 934 Config cfg("Launcher");
919 cfg.setGroup("Preload"); 935 cfg.setGroup("Preload");
920 QStringList apps = cfg.readListEntry("Apps", ','); 936 QStringList apps = cfg.readListEntry("Apps", ',');
921 if (apps.contains(exec()) && !yesNo) 937 if (apps.contains(exec()) && !yesNo)
922 apps.remove(exec()); 938 apps.remove(exec());
923 else if (yesNo && !apps.contains(exec())) 939 else if (yesNo && !apps.contains(exec()))
924 apps.append(exec()); 940 apps.append(exec());
925 cfg.writeEntry("Apps", apps, ','); 941 cfg.writeEntry("Apps", apps, ',');
926} 942}
927 943
928 944
929/*! 945/*!
930 Deletes both the linkFile() and the file() associated with this AppLnk. 946 Deletes both the linkFile() and the file() associated with this AppLnk.
931 947
932 \sa removeLinkFile() 948 \sa removeLinkFile()
933*/ 949*/
934void AppLnk::removeFiles() 950void AppLnk::removeFiles()
935{ 951{
936 bool valid = isValid(); 952 bool valid = isValid();
937 if ( !valid || !linkFileKnown() || QFile::remove(linkFile()) ) { 953 if ( !valid || !linkFileKnown() || QFile::remove(linkFile()) ) {
938 if ( QFile::remove(file()) ) { 954 if ( QFile::remove(file()) ) {
939#ifndef QT_NO_COP 955#ifndef QT_NO_COP
940 QCopEnvelope e("QPE/System", "linkChanged(QString)"); 956 QCopEnvelope e("QPE/System", "linkChanged(QString)");
941 if ( linkFileKnown() ) 957 if ( linkFileKnown() )
942 e << linkFile(); 958 e << linkFile();
943 else 959 else
944 e << file(); 960 e << file();
945#endif 961#endif
946 } else if ( valid ) { 962 } else if ( valid ) {
947 // restore link 963 // restore link
948 writeLink(); 964 writeLink();
949 } 965 }
950 } 966 }
951} 967}
952 968
953/*! 969/*!
954 Deletes the linkFile(), leaving any file() untouched. 970 Deletes the linkFile(), leaving any file() untouched.
955 971
956 \sa removeFiles() 972 \sa removeFiles()
957*/ 973*/
958void AppLnk::removeLinkFile() 974void AppLnk::removeLinkFile()
959{ 975{
960 if ( isValid() && linkFileKnown() && QFile::remove(linkFile()) ) { 976 if ( isValid() && linkFileKnown() && QFile::remove(linkFile()) ) {
961#ifndef QT_NO_COP 977#ifndef QT_NO_COP
962 QCopEnvelope e("QPE/System", "linkChanged(QString)"); 978 QCopEnvelope e("QPE/System", "linkChanged(QString)");
963 e << linkFile(); 979 e << linkFile();
964#endif 980#endif
965 } 981 }
966} 982}
967 983
968class AppLnkSetPrivate { 984class AppLnkSetPrivate {
969public: 985public:
970 AppLnkSetPrivate() 986 AppLnkSetPrivate()
971 { 987 {
972 typPix.setAutoDelete(TRUE); 988 typPix.setAutoDelete(TRUE);
973 typPixBig.setAutoDelete(TRUE); 989 typPixBig.setAutoDelete(TRUE);
974 typName.setAutoDelete(TRUE); 990 typName.setAutoDelete(TRUE);
975 } 991 }
976 992
977 QDict<QPixmap> typPix; 993 QDict<QPixmap> typPix;
978 QDict<QPixmap> typPixBig; 994 QDict<QPixmap> typPixBig;
979 QDict<QString> typName; 995 QDict<QString> typName;
980}; 996};
981 997
982/*! 998/*!
983 \class AppLnkSet applnk.h 999 \class AppLnkSet applnk.h
984 \brief The AppLnkSet class is a set of AppLnk objects. 1000 \brief The AppLnkSet class is a set of AppLnk objects.
985*/ 1001*/
986 1002
987/*! 1003/*!
988 \fn QStringList AppLnkSet::types() const 1004 \fn QStringList AppLnkSet::types() const
989 1005
990 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.
991 1007
992 For applications, games and settings the type is \c Application; 1008 For applications, games and settings the type is \c Application;
993 for documents the type is the document's MIME type. 1009 for documents the type is the document's MIME type.
994 1010
995 \sa AppLnk::type(), typeName(), typePixmap(), typeBigPixmap() 1011 \sa AppLnk::type(), typeName(), typePixmap(), typeBigPixmap()
996*/ 1012*/
997 1013
998/*! 1014/*!
999 \fn const QList<AppLnk>& AppLnkSet::children() const 1015 \fn const QList<AppLnk>& AppLnkSet::children() const
1000 1016
1001 Returns the members of the set. 1017 Returns the members of the set.
1002*/ 1018*/
1003 1019
1004/*! 1020/*!
1005 Constructs an empty AppLnkSet. 1021 Constructs an empty AppLnkSet.
1006*/ 1022*/
1007AppLnkSet::AppLnkSet() : 1023AppLnkSet::AppLnkSet() :
1008 d(new AppLnkSetPrivate) 1024 d(new AppLnkSetPrivate)
1009{ 1025{
1010} 1026}
1011 1027
1012/*! 1028/*!
1013 Constructs an AppLnkSet that contains AppLnk objects representing 1029 Constructs an AppLnkSet that contains AppLnk objects representing
1014 all the files in the given \a directory (and any subdirectories 1030 all the files in the given \a directory (and any subdirectories
1015 recursively). 1031 recursively).
1016 1032
1017 \omit 1033 \omit
1018 The directories may contain ".directory" files which override 1034 The directories may contain ".directory" files which override
1019 any AppLnk::type() values for AppLnk objects found in the directory. 1035 any AppLnk::type() values for AppLnk objects found in the directory.
1020 This allows simple localization of application types. 1036 This allows simple localization of application types.
1021 \endomit 1037 \endomit
1022*/ 1038*/
1023AppLnkSet::AppLnkSet( const QString &directory ) : 1039AppLnkSet::AppLnkSet( const QString &directory ) :
1024 d(new AppLnkSetPrivate) 1040 d(new AppLnkSetPrivate)
1025{ 1041{
1026 QDir dir( directory ); 1042 QDir dir( directory );
1027 mFile = directory; 1043 mFile = directory;
1028 findChildren(directory,QString::null,QString::null); 1044 findChildren(directory,QString::null,QString::null);
1029} 1045}
1030 1046
1031/*! 1047/*!
1032 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
1033 the caller becomes responsible for deleting the AppLnk objects. 1049 the caller becomes responsible for deleting the AppLnk objects.
1034*/ 1050*/
1035void AppLnkSet::detachChildren() 1051void AppLnkSet::detachChildren()
1036{ 1052{
1037 QListIterator<AppLnk> it( mApps ); 1053 QListIterator<AppLnk> it( mApps );
1038 for ( ; it.current(); ) { 1054 for ( ; it.current(); ) {
1039 AppLnk* a = *it; 1055 AppLnk* a = *it;
1040 ++it; 1056 ++it;
1041 a->mId = 0; 1057 a->mId = 0;
1042 } 1058 }
1043 mApps.clear(); 1059 mApps.clear();
1044} 1060}
1045 1061
1046/*! 1062/*!
1047 Destroys the set, deleting all the AppLnk objects it contains. 1063 Destroys the set, deleting all the AppLnk objects it contains.
1048 1064
1049 \sa detachChildren() 1065 \sa detachChildren()
1050*/ 1066*/
1051AppLnkSet::~AppLnkSet() 1067AppLnkSet::~AppLnkSet()
1052{ 1068{
1053 QListIterator<AppLnk> it( mApps ); 1069 QListIterator<AppLnk> it( mApps );
1054 for ( ; it.current(); ) { 1070 for ( ; it.current(); ) {
1055 AppLnk* a = *it; 1071 AppLnk* a = *it;
1056 ++it; 1072 ++it;
1057 a->mId = 0; 1073 a->mId = 0;
1058 delete a; 1074 delete a;
1059 } 1075 }
1060 delete d; 1076 delete d;
1061} 1077}
1062 1078
1063void 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)
1064{ 1080{
1065 depth++; 1081 depth++;
1066 if ( depth > 10 ) 1082 if ( depth > 10 )
1067 return; 1083 return;
1068 1084
1069 QDir dir( dr ); 1085 QDir dir( dr );
1070 QString typNameLocal = typName; 1086 QString typNameLocal = typName;
1071 1087
1072 if ( dir.exists( ".directory" ) ) { 1088 if ( dir.exists( ".directory" ) ) {
1073 Config config( dr + "/.directory", Config::File ); 1089 Config config( dr + "/.directory", Config::File );
1074 config.setGroup( "Desktop Entry" ); 1090 config.setGroup( "Desktop Entry" );
1075 typNameLocal = config.readEntry( "Name", typNameLocal ); 1091 typNameLocal = config.readEntry( "Name", typNameLocal );
1076 if ( !typ.isEmpty() ) { 1092 if ( !typ.isEmpty() ) {
1077 QString iconFile = config.readEntry( "Icon", "AppsIcon" ); 1093 QString iconFile = config.readEntry( "Icon", "AppsIcon" );
1078 QImage unscaledIcon = Resource::loadImage( iconFile ); 1094 QImage unscaledIcon = Resource::loadImage( iconFile );
1079 QPixmap pm, bpm; 1095 QPixmap pm, bpm;
1080 pm.convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) ); 1096 pm.convertFromImage( unscaledIcon.smoothScale( smallSize, smallSize ) );
1081 bpm.convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) ); 1097 bpm.convertFromImage( unscaledIcon.smoothScale( bigSize, bigSize ) );
1082 d->typPix.insert(typ, new QPixmap(pm)); 1098 d->typPix.insert(typ, new QPixmap(pm));
1083 d->typPixBig.insert(typ, new QPixmap(bpm)); 1099 d->typPixBig.insert(typ, new QPixmap(bpm));
1084 d->typName.insert(typ, new QString(typNameLocal)); 1100 d->typName.insert(typ, new QString(typNameLocal));
1085 } 1101 }
1086 } 1102 }
1087 1103
1088 const QFileInfoList *list = dir.entryInfoList(); 1104 const QFileInfoList *list = dir.entryInfoList();
1089 if ( list ) { 1105 if ( list ) {
1090 QFileInfo* fi; 1106 QFileInfo* fi;
1091 bool cadded=FALSE; 1107 bool cadded=FALSE;
1092 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) { 1108 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) {
1093 QString bn = fi->fileName(); 1109 QString bn = fi->fileName();
1094 if ( bn[0] != '.' && bn != "CVS" ) { 1110 if ( bn[0] != '.' && bn != "CVS" ) {
1095 if ( fi->isDir() ) { 1111 if ( fi->isDir() ) {
1096 QString c = typ.isNull() ? bn : typ+"/"+bn; 1112 QString c = typ.isNull() ? bn : typ+"/"+bn;
1097 QString d = typNameLocal.isNull() ? bn : typNameLocal+"/"+bn; 1113 QString d = typNameLocal.isNull() ? bn : typNameLocal+"/"+bn;
1098 findChildren(fi->filePath(), c, d, depth ); 1114 findChildren(fi->filePath(), c, d, depth );
1099 } else { 1115 } else {
1100 if ( fi->extension(FALSE) == "desktop" ) { 1116 if ( fi->extension(FALSE) == "desktop" ) {
1101 AppLnk* app = new AppLnk( fi->filePath() ); 1117 AppLnk* app = new AppLnk( fi->filePath() );
1102#ifdef QT_NO_QWS_MULTIPROCESS 1118#ifdef QT_NO_QWS_MULTIPROCESS
1103 if ( !Global::isBuiltinCommand( app->exec() ) ) 1119 if ( !Global::isBuiltinCommand( app->exec() ) )
1104 delete app; 1120 delete app;
1105 else 1121 else
1106#endif 1122#endif
1107 { 1123 {
1108 if ( !typ.isEmpty() ) { 1124 if ( !typ.isEmpty() ) {
1109 if ( !cadded ) { 1125 if ( !cadded ) {
1110 typs.append(typ); 1126 typs.append(typ);
1111 cadded = TRUE; 1127 cadded = TRUE;
1112 } 1128 }
1113 app->setType(typ); 1129 app->setType(typ);
1114 } 1130 }
1115 add(app); 1131 add(app);
1116 } 1132 }
1117 } 1133 }
1118 } 1134 }
1119 } 1135 }
1120 } 1136 }
1121 } 1137 }
1122} 1138}
1123 1139
1124/*! 1140/*!
1125 Adds AppLnk \a f to the set. The set takes responsibility for 1141 Adds AppLnk \a f to the set. The set takes responsibility for
1126 deleting \a f. 1142 deleting \a f.
1127 1143
1128 \sa remove() 1144 \sa remove()
1129*/ 1145*/
1130void AppLnkSet::add( AppLnk *f ) 1146void AppLnkSet::add( AppLnk *f )
1131{ 1147{
1132 if ( f->mId == 0 ) { 1148 if ( f->mId == 0 ) {
1133 AppLnk::lastId++; 1149 AppLnk::lastId++;
1134 f->mId = AppLnk::lastId; 1150 f->mId = AppLnk::lastId;
1135 mApps.append( f ); 1151 mApps.append( f );
1136 } else { 1152 } else {
1137 qWarning("Attempt to add an AppLnk twice"); 1153 qWarning("Attempt to add an AppLnk twice");
1138 } 1154 }
1139} 1155}
1140 1156
1141/*! 1157/*!
1142 Removes AppLnk \a f to the set. The caller becomes responsible for 1158 Removes AppLnk \a f to the set. The caller becomes responsible for
1143 deleting \a f. Returns TRUE if \a f was in the set; otherwise 1159 deleting \a f. Returns TRUE if \a f was in the set; otherwise
1144 returns FALSE. 1160 returns FALSE.
1145 1161
1146 \sa add() 1162 \sa add()
1147*/ 1163*/
1148bool AppLnkSet::remove( AppLnk *f ) 1164bool AppLnkSet::remove( AppLnk *f )
1149{ 1165{
1150 if ( mApps.remove( f ) ) { 1166 if ( mApps.remove( f ) ) {
1151 f->mId = 0; 1167 f->mId = 0;
1152 return TRUE; 1168 return TRUE;
1153 } 1169 }
1154 return FALSE; 1170 return FALSE;
1155} 1171}
1156 1172
1157 1173
1158/*! 1174/*!
1159 Returns the localized name for type \a t. 1175 Returns the localized name for type \a t.
1160 1176
1161 For applications, games and settings the type is \c Application; 1177 For applications, games and settings the type is \c Application;
1162 for documents the type is the document's MIME type. 1178 for documents the type is the document's MIME type.
1163*/ 1179*/
1164QString AppLnkSet::typeName( const QString& t ) const 1180QString AppLnkSet::typeName( const QString& t ) const
1165{ 1181{
1166 QString *st = d->typName.find(t); 1182 QString *st = d->typName.find(t);
1167 return st ? *st : QString::null; 1183 return st ? *st : QString::null;
1168} 1184}
1169 1185
1170/*! 1186/*!
1171 Returns the small pixmap associated with type \a t. 1187 Returns the small pixmap associated with type \a t.
1172 1188
1173 For applications, games and settings the type is \c Application; 1189 For applications, games and settings the type is \c Application;
1174 for documents the type is the document's MIME type. 1190 for documents the type is the document's MIME type.
1175*/ 1191*/
1176QPixmap AppLnkSet::typePixmap( const QString& t ) const 1192QPixmap AppLnkSet::typePixmap( const QString& t ) const
1177{ 1193{
1178 QPixmap *pm = d->typPix.find(t); 1194 QPixmap *pm = d->typPix.find(t);
1179 return pm ? *pm : QPixmap(); 1195 return pm ? *pm : QPixmap();
1180} 1196}
1181 1197
1182/*! 1198/*!
1183 Returns the large pixmap associated with type \a t. 1199 Returns the large pixmap associated with type \a t.
1184 1200
1185 For applications, games and settings the type is \c Application; 1201 For applications, games and settings the type is \c Application;
1186 for documents the type is the document's MIME type. 1202 for documents the type is the document's MIME type.
1187*/ 1203*/
1188QPixmap AppLnkSet::typeBigPixmap( const QString& t ) const 1204QPixmap AppLnkSet::typeBigPixmap( const QString& t ) const
1189{ 1205{
1190 QPixmap *pm = d->typPixBig.find(t); 1206 QPixmap *pm = d->typPixBig.find(t);
1191 return pm ? *pm : QPixmap(); 1207 return pm ? *pm : QPixmap();
1192} 1208}
1193 1209
1194/*! 1210/*!
1195 Returns the AppLnk with the given \a id. 1211 Returns the AppLnk with the given \a id.
1196*/ 1212*/
1197const AppLnk *AppLnkSet::find( int id ) const 1213const AppLnk *AppLnkSet::find( int id ) const
1198{ 1214{
1199 QListIterator<AppLnk> it( children() ); 1215 QListIterator<AppLnk> it( children() );
1200 1216
1201 for ( ; it.current(); ++it ) { 1217 for ( ; it.current(); ++it ) {
1202 const AppLnk *app = it.current(); 1218 const AppLnk *app = it.current();
1203 if ( app->id() == id ) 1219 if ( app->id() == id )
1204 return app; 1220 return app;
1205 } 1221 }
1206 1222
1207 return 0; 1223 return 0;
1208} 1224}
1209 1225
1210/*! 1226/*!
1211 Returns the AppLnk with the given \a exec attribute. 1227 Returns the AppLnk with the given \a exec attribute.
1212*/ 1228*/
1213const AppLnk *AppLnkSet::findExec( const QString& exec ) const 1229const AppLnk *AppLnkSet::findExec( const QString& exec ) const
1214{ 1230{
1215 QListIterator<AppLnk> it( children() ); 1231 QListIterator<AppLnk> it( children() );
1216 1232
1217 for ( ; it.current(); ++it ) { 1233 for ( ; it.current(); ++it ) {
1218 const AppLnk *app = it.current(); 1234 const AppLnk *app = it.current();
1219 if ( app->exec() == exec ) 1235 if ( app->exec() == exec )
1220 return app; 1236 return app;
1221 } 1237 }
1222 1238
1223 return 0; 1239 return 0;
1224} 1240}
1225 1241
1226/*! 1242/*!
1227 \class DocLnkSet applnk.h 1243 \class DocLnkSet applnk.h
1228 \brief The DocLnkSet class is a set of DocLnk objects. 1244 \brief The DocLnkSet class is a set of DocLnk objects.
1229*/ 1245*/
1230 1246
1231/*! 1247/*!
1232 \fn const QList<DocLnk>& DocLnkSet::children() const 1248 \fn const QList<DocLnk>& DocLnkSet::children() const
1233 1249
1234 Returns the members of the set. 1250 Returns the members of the set.
1235*/ 1251*/
1236 1252
1237/*! 1253/*!
1238 Constructs an empty DocLnkSet. 1254 Constructs an empty DocLnkSet.
1239 1255
1240 \sa appendFrom() 1256 \sa appendFrom()
1241*/ 1257*/
1242DocLnkSet::DocLnkSet() 1258DocLnkSet::DocLnkSet()
1243{ 1259{
1244} 1260}
1245 1261
1246/*! 1262/*!
1247 Constructs a DocLnkSet that contains DocLnk objects representing all 1263 Constructs a DocLnkSet that contains DocLnk objects representing all
1248 the files in the \a directory (and any subdirectories, recursively). 1264 the files in the \a directory (and any subdirectories, recursively).
1249 1265
1250 If \a mimefilter is not null, 1266 If \a mimefilter is not null,
1251 only documents with a MIME type matching \a mimefilter are selected. 1267 only documents with a MIME type matching \a mimefilter are selected.
1252 The value may contain multiple wild-card patterns separated by ";", 1268 The value may contain multiple wild-card patterns separated by ";",
1253 such as \c{*o/mpeg;audio/x-wav}. 1269 such as \c{*o/mpeg;audio/x-wav}.
1254 1270
1255 See also \link applnk.html#files-and-links Files and Links\endlink. 1271 See also \link applnk.html#files-and-links Files and Links\endlink.
1256 1272
1257*/ 1273*/
1258DocLnkSet::DocLnkSet( const QString &directory, const QString& mimefilter ) : 1274DocLnkSet::DocLnkSet( const QString &directory, const QString& mimefilter ) :
1259 AppLnkSet() 1275 AppLnkSet()
1260{ 1276{
1261 QDir dir( directory ); 1277 QDir dir( directory );
1262 mFile = dir.dirName(); 1278 mFile = dir.dirName();
1263 QDict<void> reference; 1279 QDict<void> reference;
1264 1280
1265 QStringList subFilter = QStringList::split(";", mimefilter); 1281 QStringList subFilter = QStringList::split(";", mimefilter);
1266 QValueList<QRegExp> mimeFilters; 1282 QValueList<QRegExp> mimeFilters;
1267 for( QStringList::Iterator it = subFilter.begin(); it != subFilter.end(); ++ it ) 1283 for( QStringList::Iterator it = subFilter.begin(); it != subFilter.end(); ++ it )
1268 mimeFilters.append( QRegExp(*it, FALSE, TRUE) ); 1284 mimeFilters.append( QRegExp(*it, FALSE, TRUE) );
1269 1285
1270 findChildren(directory, mimeFilters, reference); 1286 findChildren(directory, mimeFilters, reference);
1271 1287
1272 const QList<DocLnk> &list = children(); 1288 const QList<DocLnk> &list = children();
1273 for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) { 1289 for ( QListIterator<DocLnk> it( list ); it.current(); ++it ) {
1274 reference.remove( (*it)->file() ); 1290 reference.remove( (*it)->file() );
1275 } 1291 }
1276 1292
1277 for ( QDictIterator<void> dit(reference); dit.current(); ++dit ) { 1293 for ( QDictIterator<void> dit(reference); dit.current(); ++dit ) {
1278 if ( dit.current() == (void*)2 ) { 1294 if ( dit.current() == (void*)2 ) {
1279 // Unreferenced, make an unwritten link 1295 // Unreferenced, make an unwritten link
1280 DocLnk* dl = new DocLnk; 1296 DocLnk* dl = new DocLnk;
1281 QFileInfo fi( dit.currentKey() ); 1297 QFileInfo fi( dit.currentKey() );
1282 dl->setFile(fi.filePath()); 1298 dl->setFile(fi.filePath());
1283 dl->setName(fi.baseName()); 1299 dl->setName(fi.baseName());
1284 // #### default to current path? 1300 // #### default to current path?
1285 // dl->setCategories( ... ); 1301 // dl->setCategories( ... );
1286 bool match = mimefilter.isNull(); 1302 bool match = mimefilter.isNull();
1287 if ( !match ) 1303 if ( !match )
1288 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 )
1289 if ( (*it).match(dl->type()) >= 0 ) 1305 if ( (*it).match(dl->type()) >= 0 )
1290 match = TRUE; 1306 match = TRUE;
1291 if ( match /* && dl->type() != "application/octet-stream" */ 1307 if ( match /* && dl->type() != "application/octet-stream" */
1292 && !!dl->exec() ) 1308 && !!dl->exec() )
1293 add(dl); 1309 add(dl);
1294 else 1310 else
1295 delete dl; 1311 delete dl;
1296 } 1312 }
1297 } 1313 }
1298} 1314}
1299 1315
1300// other becomes empty 1316// other becomes empty
1301/*! 1317/*!
1302 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
1303 empty. 1319 empty.
1304*/ 1320*/
1305void DocLnkSet::appendFrom( DocLnkSet& other ) 1321void DocLnkSet::appendFrom( DocLnkSet& other )
1306{ 1322{
1307 if ( &other == this ) 1323 if ( &other == this )
1308 return; 1324 return;
1309 QListIterator<AppLnk> it( other.mApps ); 1325 QListIterator<AppLnk> it( other.mApps );
1310 for ( ; it.current(); ) { 1326 for ( ; it.current(); ) {
1311 mApps.append(*it); 1327 mApps.append(*it);
1312 ++it; 1328 ++it;
1313 } 1329 }
1314 other.mApps.clear(); 1330 other.mApps.clear();
1315} 1331}
1316 1332
1317void 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)
1318{ 1334{
1319 depth++; 1335 depth++;
1320 if ( depth > 10 ) 1336 if ( depth > 10 )
1321 return; 1337 return;
1322 1338
1323 QDir dir( dr ); 1339 QDir dir( dr );
1324 1340
1325 /* Opie got a different approach 1341 /* Opie got a different approach
1326 * I guess it's geek vs. consumer 1342 * I guess it's geek vs. consumer
1327 * in this case to be discussed 1343 * in this case to be discussed
1328 */ 1344 */
1329 if ( dir.exists( ".Qtopia-ignore" ) ) 1345 if ( dir.exists( ".Qtopia-ignore" ) )
1330 return; 1346 return;
1331 1347
1332 const QFileInfoList *list = dir.entryInfoList(); 1348 const QFileInfoList *list = dir.entryInfoList();
1333 if ( list ) { 1349 if ( list ) {
1334 QFileInfo* fi; 1350 QFileInfo* fi;
1335 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) { 1351 for ( QFileInfoListIterator it(*list); (fi=*it); ++it ) {
1336 QString bn = fi->fileName(); 1352 QString bn = fi->fileName();
1337 if ( bn[0] != '.' ) { 1353 if ( bn[0] != '.' ) {
1338 if ( fi->isDir() ) { 1354 if ( fi->isDir() ) {
1339 if ( bn != "CVS" && bn != "Qtopia" && bn != "QtPalmtop" ) 1355 if ( bn != "CVS" && bn != "Qtopia" && bn != "QtPalmtop" )
1340 findChildren(fi->filePath(), mimeFilters, reference, depth); 1356 findChildren(fi->filePath(), mimeFilters, reference, depth);
1341 } else { 1357 } else {
1342 if ( fi->extension(FALSE) == "desktop" ) { 1358 if ( fi->extension(FALSE) == "desktop" ) {
1343 DocLnk* dl = new DocLnk( fi->filePath() ); 1359 DocLnk* dl = new DocLnk( fi->filePath() );
1344 QFileInfo fi2(dl->file()); 1360 QFileInfo fi2(dl->file());
1345 bool match = FALSE; 1361 bool match = FALSE;
1346 if ( !fi2.exists() ) { 1362 if ( !fi2.exists() ) {
1347 dir.remove( dl->file() ); 1363 dir.remove( dl->file() );
1348 } 1364 }
1349 if ( mimeFilters.count() == 0 ) { 1365 if ( mimeFilters.count() == 0 ) {
1350 add( dl ); 1366 add( dl );
1351 match = TRUE; 1367 match = TRUE;
1352 } else { 1368 } else {
1353 for( QValueList<QRegExp>::ConstIterator it = mimeFilters.begin(); it != mimeFilters.end(); ++ it ) { 1369 for( QValueList<QRegExp>::ConstIterator it = mimeFilters.begin(); it != mimeFilters.end(); ++ it ) {
1354 if ( (*it).match(dl->type()) >= 0 ) { 1370 if ( (*it).match(dl->type()) >= 0 ) {
1355 add(dl); 1371 add(dl);
1356 match = TRUE; 1372 match = TRUE;
1357 } 1373 }
1358 } 1374 }
1359 } 1375 }
1360 if ( !match ) 1376 if ( !match )
1361 delete dl; 1377 delete dl;
1362 } else { 1378 } else {
1363 if ( !reference.find(fi->fileName()) ) 1379 if ( !reference.find(fi->fileName()) )
1364 reference.insert(fi->filePath(), (void*)2); 1380 reference.insert(fi->filePath(), (void*)2);
1365 } 1381 }
1366 } 1382 }
1367 } 1383 }
1368 } 1384 }
1369 } 1385 }
1370} 1386}
1371 1387
1372/*! 1388/*!
1373 \class DocLnk applnk.h 1389 \class DocLnk applnk.h
1374 \brief The DocLnk class represents loaded document references. 1390 \brief The DocLnk class represents loaded document references.
1375*/ 1391*/
1376 1392
1377/*! 1393/*!
1378 \fn DocLnk::DocLnk( const DocLnk &o ) 1394 \fn DocLnk::DocLnk( const DocLnk &o )
1379 1395
1380 Copies \a o. 1396 Copies \a o.
1381*/ 1397*/
1382 1398
1383/*! 1399/*!
1384 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
1385 \a file for other files. 1401 \a file for other files.
1386*/ 1402*/
1387DocLnk::DocLnk( const QString &file ) : 1403DocLnk::DocLnk( const QString &file ) :
1388 AppLnk(file) 1404 AppLnk(file)
1389{ 1405{
1390 init(file); 1406 init(file);
1391} 1407}
1392 1408
1393/*! 1409/*!
1394 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
1395 \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
1396 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
1397 is read as a normal file. 1413 is read as a normal file.
1398*/ 1414*/
1399DocLnk::DocLnk( const QString &file, bool may_be_desktopfile ) : 1415DocLnk::DocLnk( const QString &file, bool may_be_desktopfile ) :
1400 AppLnk(may_be_desktopfile ? file : QString::null) 1416 AppLnk(may_be_desktopfile ? file : QString::null)
1401{ 1417{
1402 init(file); 1418 init(file);
1403} 1419}
1404 1420
1405void DocLnk::init(const QString &file) 1421void DocLnk::init(const QString &file)
1406{ 1422{
1407 if ( isValid() ) { 1423 if ( isValid() ) {
1408#ifndef FORCED_DIR_STRUCTURE_WAY 1424#ifndef FORCED_DIR_STRUCTURE_WAY
1409 if ( mType.isNull() ) 1425 if ( mType.isNull() )
1410 // try to infer it 1426 // try to infer it
1411#endif 1427#endif
1412 { 1428 {
1413 int s0 = file.findRev('/'); 1429 int s0 = file.findRev('/');
1414 if ( s0 > 0 ) { 1430 if ( s0 > 0 ) {
1415 int s1 = file.findRev('/',s0-1); 1431 int s1 = file.findRev('/',s0-1);
1416 if ( s1 > 0 ) { 1432 if ( s1 > 0 ) {
1417 int s2 = file.findRev('/',s1-1); 1433 int s2 = file.findRev('/',s1-1);
1418 if ( s2 > 0 ) { 1434 if ( s2 > 0 ) {
1419 mType = file.mid(s2+1,s0-s2-1); 1435 mType = file.mid(s2+1,s0-s2-1);
1420 } 1436 }
1421 } 1437 }
1422 } 1438 }
1423 } 1439 }
1424 } else if ( QFile::exists(file) ) { 1440 } else if ( QFile::exists(file) ) {
1425 QString n = file; 1441 QString n = file;
1426 n.replace(QRegExp(".*/"),""); 1442 n.replace(QRegExp(".*/"),"");
1427 n.replace(QRegExp("\\..*"),""); 1443 n.replace(QRegExp("\\..*"),"");
1428 setName( n ); 1444 setName( n );
1429 setFile( file ); 1445 setFile( file );
1430 } 1446 }
1431 MimeType mt(mType); 1447 MimeType mt(mType);
1432 if( mt.application() ) 1448 if( mt.application() )
1433 mExec = mt.application()->exec(); 1449 mExec = mt.application()->exec();
1434} 1450}
1435 1451
1436/*! 1452/*!
1437 Constructs an invalid DocLnk. 1453 Constructs an invalid DocLnk.
1438*/ 1454*/
1439DocLnk::DocLnk() 1455DocLnk::DocLnk()
1440{ 1456{
1441} 1457}
1442 1458
1443/*! 1459/*!
1444 Destroys the DocLnk. Just like AppLnk objects, a run-time error 1460 Destroys the DocLnk. Just like AppLnk objects, a run-time error
1445 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).
1446*/ 1462*/
1447DocLnk::~DocLnk() 1463DocLnk::~DocLnk()
1448{ 1464{
1449} 1465}
1450 1466
1451/*! 1467/*!
1452 \reimp 1468 \reimp
1453*/ 1469*/
1454QString DocLnk::exec() const 1470QString DocLnk::exec() const
1455{ 1471{
1456 MimeType mt(type()); 1472 MimeType mt(type());
1457 const AppLnk* app = mt.application(); 1473 const AppLnk* app = mt.application();
1458 if ( app ) 1474 if ( app )
1459 return app->exec(); 1475 return app->exec();
1460 else 1476 else
1461 return QString::null; 1477 return QString::null;
1462} 1478}
1463 1479
1464/*! 1480/*!
1465 \reimp 1481 \reimp
1466*/ 1482*/
1467void DocLnk::invoke(const QStringList& args) const 1483void DocLnk::invoke(const QStringList& args) const
1468{ 1484{
1469 MimeType mt(type()); 1485 MimeType mt(type());
1470 const AppLnk* app = mt.application(); 1486 const AppLnk* app = mt.application();
1471 if ( app ) { 1487 if ( app ) {
1472 QStringList a = args; 1488 QStringList a = args;
1473 if ( linkFileKnown() && QFile::exists( linkFile() ) ) 1489 if ( linkFileKnown() && QFile::exists( linkFile() ) )
1474 a.append(linkFile()); 1490 a.append(linkFile());
1475 else 1491 else
1476 a.append(file()); 1492 a.append(file());
1477 app->execute(a); 1493 app->execute(a);
1478 } 1494 }
1479} 1495}
1480 1496
1481 1497