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