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