summaryrefslogtreecommitdiff
path: root/library/applnk.cpp
Unidiff
Diffstat (limited to 'library/applnk.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/applnk.cpp83
1 files changed, 56 insertions, 27 deletions
diff --git a/library/applnk.cpp b/library/applnk.cpp
index 2af6cf4..5185b5f 100644
--- a/library/applnk.cpp
+++ b/library/applnk.cpp
@@ -1,81 +1,93 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of 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
22
21#include "applnk.h" 23#include "applnk.h"
22 24
23#include <qpe/qpeapplication.h> 25#include <qpe/qpeapplication.h>
24#include <qpe/categories.h> 26#include <qpe/categories.h>
25#include <qpe/categoryselect.h> 27#include <qpe/categoryselect.h>
26#include <qpe/qcopenvelope_qws.h> 28#include <qpe/qcopenvelope_qws.h>
27#include <qpe/global.h> 29#include <qpe/global.h>
28#include <qpe/mimetype.h> 30#include <qpe/mimetype.h>
29#include <qpe/config.h> 31#include <qpe/config.h>
30#include <qpe/storage.h> 32#include <qpe/storage.h>
31#include <qpe/resource.h> 33#include <qpe/resource.h>
32 34
33#include <qdict.h> 35#include <qdict.h>
34#include <qdir.h> 36#include <qdir.h>
35#include <qregexp.h> 37#include <qregexp.h>
36 38
37#ifdef Q_WS_QWS 39#ifdef Q_WS_QWS
38#include <qgfx_qws.h> 40#include <qgfx_qws.h>
39#endif 41#endif
40 42
41#include <stdlib.h> 43#include <stdlib.h>
42 44
43int AppLnk::lastId = 5000; 45int AppLnk::lastId = 5000;
44 46
45static int smallSize = 14; 47static int smallSize = 14;
46static int bigSize = 32; 48static int bigSize = 32;
47 49
48static QString safeFileName(const QString& n) 50static QString safeFileName(const QString& n)
49{ 51{
50 QString safename=n; 52 QString safename=n;
51 safename.replace(QRegExp("[^0-9A-Za-z.]"),"_"); 53 safename.replace(QRegExp("[^0-9A-Za-z.]"),"_"); // Njaard says this is broken
52 safename.replace(QRegExp("^[^A-Za-z]*"),""); 54 safename.replace(QRegExp("^[^A-Za-z]*"),"");
53 if ( safename.isEmpty() ) 55 if ( safename.isEmpty() )
54 safename = "_"; 56 safename = "_";
55 return safename; 57 return safename;
56} 58}
57 59
60static bool prepareDirectories(const QString& lf)
61{
62 if ( !QFile::exists(lf) ) {
63 // May need to create directories
64 QFileInfo fi(lf);
65 if ( system(("mkdir -p "+fi.dirPath(TRUE))) )
66 return FALSE;
67 }
68 return TRUE;
69}
58 70
59class AppLnkPrivate 71class AppLnkPrivate
60{ 72{
61public: 73public:
62 QArray<int> mCat; 74 QArray<int> mCat;
63}; 75};
64 76
65/*! 77/*!
66 \class AppLnk applnk.h 78 \class AppLnk applnk.h
67 \brief The AppLnk class represents an application available on the system. 79 \brief The AppLnk class represents an application available on the system.
68 80
69 Information about applications are stored in Qtopia as ".desktop" files. 81 Information about applications are stored in Qtopia as ".desktop" files.
70 When read, these files are stored as AppLnk objects. 82 When read, these files are stored as AppLnk objects.
71*/ 83*/
72 84
73/*! 85/*!
74 Sets the size used for small icons to \a small pixels. 86 Sets the size used for small icons to \a small pixels.
75 Only affects AppLnk objects created after the call. 87 Only affects AppLnk objects created after the call.
76*/ 88*/
77void AppLnk::setSmallIconSize(int small) 89void AppLnk::setSmallIconSize(int small)
78{ 90{
79 smallSize = small; 91 smallSize = small;
80} 92}
81 93
@@ -262,101 +274,117 @@ const QPixmap& AppLnk::bigPixmap() const
262} 274}
263 275
264/*! 276/*!
265 Returns the type of the application. 277 Returns the type of the application.
266*/ 278*/
267QString AppLnk::type() const 279QString AppLnk::type() const
268{ 280{
269 if ( mType.isNull() ) { 281 if ( mType.isNull() ) {
270 AppLnk* that = (AppLnk*)this; 282 AppLnk* that = (AppLnk*)this;
271 MimeType mt(file()); 283 MimeType mt(file());
272 that->mType = mt.id(); 284 that->mType = mt.id();
273 return that->mType; 285 return that->mType;
274 } 286 }
275 return mType; 287 return mType;
276} 288}
277 289
278/*! 290/*!
279 Returns the file associated with the AppLnk. 291 Returns the file associated with the AppLnk.
280 292
281 \sa exec() 293 \sa exec()
282*/ 294*/
283QString AppLnk::file() const 295QString AppLnk::file() const
284{ 296{
285 if ( mFile.isNull() ) { 297 if ( mFile.isNull() ) {
286 AppLnk* that = (AppLnk*)this; 298 AppLnk* that = (AppLnk*)this; // copy?
299 QString ext = MimeType(mType).extension();
300 if ( !ext.isEmpty() )
301 ext = "." + ext;
287 if ( !mLinkFile.isEmpty() ) { 302 if ( !mLinkFile.isEmpty() ) {
288 that->mFile = 303 that->mFile =
289 mLinkFile.right(8)==".desktop" // 8 = strlen(".desktop") 304 mLinkFile.right(8)==".desktop" // 8 = strlen(".desktop")
290 ? mLinkFile.left(mLinkFile.length()-8) : mLinkFile; 305 ? mLinkFile.left(mLinkFile.length()-8) : mLinkFile;
291 } else if ( mType.contains('/') ) { 306 } else if ( mType.contains('/') ) {
292 that->mFile = 307 that->mFile =
293 QString(getenv("HOME"))+"/Documents/"+mType+"/"+safeFileName(that->mName); 308 QString(getenv("HOME"))+"/Documents/"+mType+"/"+safeFileName(that->mName);
294 if ( QFile::exists(that->mFile) || QFile::exists(that->mFile+".desktop") ) { 309 if ( QFile::exists(that->mFile+ext) || QFile::exists(that->mFile+".desktop") ) { // a .desktop with the same name exists
295 int n=1; 310 int n=1;
311 qWarning("AppLnk::file() n=1 %s", that->mFile.latin1() );
296 QString nn; 312 QString nn;
297 while (QFile::exists((nn=(that->mFile+"_"+QString::number(n)))) 313 while (QFile::exists((nn=(that->mFile+"_"+QString::number(n)))+ext)
298 || QFile::exists(nn+".desktop")) 314 || QFile::exists(nn+".desktop"))
299 n++; 315 n++;
300 that->mFile = nn; 316 that->mFile = nn;
317 qWarning("AppLnl::file() now mFile is %s", that->mFile.latin1() );
301 } 318 }
302 that->mLinkFile = that->mFile+".desktop"; 319 that->mLinkFile = that->mFile+".desktop";
320 that->mFile += ext;
303 } 321 }
322 prepareDirectories(that->mFile);
323 QFile f(that->mFile);
324 if ( !f.open(IO_WriteOnly) )
325 that->mFile = QString::null;
304 return that->mFile; 326 return that->mFile;
305 } 327 }
306 return mFile; 328 return mFile;
307} 329}
308 330
309/*! 331/*!
310 Returns the desktop file coresponding to this AppLnk. 332 Returns the desktop file coresponding to this AppLnk.
311 333
312 \sa file(), exec() 334 \sa file(), exec()
313*/ 335*/
314QString AppLnk::linkFile() const 336QString AppLnk::linkFile() const
315{ 337{
316 if ( mLinkFile.isNull() ) { 338 if ( mLinkFile.isNull() ) {
317 AppLnk* that = (AppLnk*)this; 339 AppLnk* that = (AppLnk*)this;
318 if ( type().contains('/') ) { 340 if ( type().contains('/') ) {
319 StorageInfo storage; 341 StorageInfo storage;
320 const FileSystem *fs = storage.fileSystemOf( that->mFile ); 342 const FileSystem *fs = storage.fileSystemOf( that->mFile );
321 // qDebug("creating lnkFile for %s", mFile.latin1() );
322 // if ( fs )
323 // qDebug("fs is %s", fs->path().latin1() );
324 if ( fs && fs->isRemovable() ) { 343 if ( fs && fs->isRemovable() ) {
325 // qDebug("isRemovable");
326 that->mLinkFile = fs->path(); 344 that->mLinkFile = fs->path();
327 } else 345 } else
328 that->mLinkFile = getenv( "HOME" ); 346 that->mLinkFile = getenv( "HOME" );
329 that->mLinkFile += "/Documents/"+type()+"/"+safeFileName(that->mName); 347 that->mLinkFile += "/Documents/"+type()+"/"+safeFileName(that->mName);
330 if ( QFile::exists(that->mLinkFile+".desktop") ) { 348 if ( QFile::exists(that->mLinkFile+".desktop") ) { // ok the file exists lets check if we point to the same file
331 int n=1; 349 int n=1;
332 QString nn; 350 QString nn;
333 while (QFile::exists((nn=that->mLinkFile+"_"+QString::number(n))+".desktop")) 351 AppLnk lnk( that->mLinkFile+".desktop" );
352 if(that->file() != lnk.file() ){
353 qWarning("AppLnk::linkFile exists %s", that->mLinkFile.latin1() );
354 while (QFile::exists((nn=that->mLinkFile+"_"+QString::number(n))+".desktop")){
334 n++; 355 n++;
335 that->mLinkFile = nn; 356 AppLnk lnk(nn ); // just to be sure
357 if(lnk.file() ==that->file() ){
358 break;
359 }
360 }
361 that->mLinkFile = nn;
362 }
336 } 363 }
337 that->mLinkFile += ".desktop"; 364 that->mLinkFile += ".desktop";
338 // qDebug("file is %s", mLinkFile.latin1() ); 365 qWarning("AppLnk::linkFile is %s", that->mLinkFile.latin1() );
366 storeLink();
339 } 367 }
340 return that->mLinkFile; 368 return that->mLinkFile;
341 } 369 }
342 return mLinkFile; 370 return mLinkFile;
343} 371}
344 372
345/*! 373/*!
346 Copies \a copy. 374 Copies \a copy.
347*/ 375*/
348AppLnk::AppLnk( const AppLnk &copy ) 376AppLnk::AppLnk( const AppLnk &copy )
349{ 377{
350 mName = copy.mName; 378 mName = copy.mName;
351 mPixmap = copy.mPixmap; 379 mPixmap = copy.mPixmap;
352 mBigPixmap = copy.mBigPixmap; 380 mBigPixmap = copy.mBigPixmap;
353 mExec = copy.mExec; 381 mExec = copy.mExec;
354 mType = copy.mType; 382 mType = copy.mType;
355 mRotation = copy.mRotation; 383 mRotation = copy.mRotation;
356 mComment = copy.mComment; 384 mComment = copy.mComment;
357 mFile = copy.mFile; 385 mFile = copy.mFile;
358 mLinkFile = copy.mLinkFile; 386 mLinkFile = copy.mLinkFile;
359 mIconFile = copy.mIconFile; 387 mIconFile = copy.mIconFile;
360 mMimeTypes = copy.mMimeTypes; 388 mMimeTypes = copy.mMimeTypes;
361 mMimeTypeIcons = copy.mMimeTypeIcons; 389 mMimeTypeIcons = copy.mMimeTypeIcons;
362 mId = 0; 390 mId = 0;
@@ -493,137 +521,138 @@ void AppLnk::setIcon( const QString& iconname )
493 521
494/*! 522/*!
495 Sets the Categories property to \a c. 523 Sets the Categories property to \a c.
496 524
497 \sa categories() 525 \sa categories()
498*/ 526*/
499void AppLnk::setCategories( const QArray<int>& c ) 527void AppLnk::setCategories( const QArray<int>& c )
500{ 528{
501 d->mCat = c; 529 d->mCat = c;
502} 530}
503 531
504/*! 532/*!
505 \fn QStringList AppLnk::mimeTypeIcons() const 533 \fn QStringList AppLnk::mimeTypeIcons() const
506 534
507 Returns the MimeTypeIcons property of the AppLnk. 535 Returns the MimeTypeIcons property of the AppLnk.
508*/ 536*/
509 537
510/*! 538/*!
511 Attempts to ensure that the link file for this AppLnk exists, including 539 Attempts to ensure that the link file for this AppLnk exists, including
512 creating any required directories. Returns TRUE if successful. 540 creating any required directories. Returns TRUE if successful.
513*/ 541*/
514bool AppLnk::ensureLinkExists() const 542bool AppLnk::ensureLinkExists() const
515{ 543{
516 QString lf = linkFile(); 544 QString lf = linkFile();
517 if ( !QFile::exists(lf) ) { 545 return prepareDirectories(lf);
518 // May need to create directories
519 QFileInfo fi(lf);
520 if ( system(("mkdir -p "+fi.dirPath(TRUE))) )
521 return FALSE;
522 }
523 return TRUE;
524} 546}
525 547
526/*! 548/*!
527 Commits the AppLnk to disk. Returns whether the operation succeeded. 549 Commits the AppLnk to disk. Returns whether the operation succeeded.
528 550
529 The "linkChanged(QString)" message is sent to the 551 The "linkChanged(QString)" message is sent to the
530 "QPE/System" QCop channel as a result. 552 "QPE/System" QCop channel as a result.
531*/ 553*/
532bool AppLnk::writeLink() const 554bool AppLnk::writeLink() const
533{ 555{
534 // Only re-writes settable parts 556 // Only re-writes settable parts
535 QString lf = linkFile(); 557 QString lf = linkFile();
536 if ( !ensureLinkExists() ) 558 if ( !ensureLinkExists() )
537 return FALSE; 559 return FALSE;
538 Config config( lf, Config::File ); 560 storeLink();
561 return TRUE;
562}
563
564void AppLnk::storeLink() const
565{
566 Config config( mLinkFile, Config::File );
539 config.setGroup("Desktop Entry"); 567 config.setGroup("Desktop Entry");
540 config.writeEntry("Name",mName); 568 config.writeEntry("Name",mName);
541 if ( !mIconFile.isNull() ) config.writeEntry("Icon",mIconFile); 569 if ( !mIconFile.isNull() ) config.writeEntry("Icon",mIconFile);
542 config.writeEntry("Type",type()); 570 config.writeEntry("Type",type());
543 if ( !mComment.isNull() ) config.writeEntry("Comment",mComment); 571 if ( !mComment.isNull() ) config.writeEntry("Comment",mComment);
544 config.writeEntry("File",file()); 572 config.writeEntry("File",file());
545 // write out the id... 573 // write out the id...
546 int i; 574 int i;
547 QStringList sl; 575 QStringList sl;
548 for ( i = 0; i < int(d->mCat.count()); i++ ) { 576 for ( i = 0; i < int(d->mCat.count()); i++ ) {
549 sl.append( QString::number( d->mCat[i] ) ); 577 sl.append( QString::number( d->mCat[i] ) );
550 } 578 }
551 config.writeEntry( "Categories", sl, ';' ); 579 config.writeEntry( "Categories", sl, ';' );
552 580
553 QCopEnvelope e("QPE/System", "linkChanged(QString)"); 581 QCopEnvelope e("QPE/System", "linkChanged(QString)");
554 e << lf; 582 e << mLinkFile;
555
556 return TRUE;
557} 583}
558 584
559/*! 585/*!
560 Sets the property named \a key to \a value. 586 Sets the property named \a key to \a value.
561*/ 587*/
562void AppLnk::setProperty(const QString& key, const QString& value) 588void AppLnk::setProperty(const QString& key, const QString& value)
563{ 589{
564 if ( ensureLinkExists() ) { 590 if ( ensureLinkExists() ) {
565 Config cfg(linkFile(), Config::File); 591 Config cfg(linkFile(), Config::File);
566 cfg.writeEntry(key,value); 592 cfg.writeEntry(key,value);
567 } 593 }
568} 594}
569 595
570/*! 596/*!
571 Returns the property named \a key. 597 Returns the property named \a key.
572*/ 598*/
573QString AppLnk::property(const QString& key) const 599QString AppLnk::property(const QString& key) const
574{ 600{
575 QString lf = linkFile(); 601 QString lf = linkFile();
576 if ( !QFile::exists(lf) ) 602 if ( !QFile::exists(lf) )
577 return QString::null; 603 return QString::null;
578 Config cfg(lf, Config::File); 604 Config cfg(lf, Config::File);
579 return cfg.readEntry(key); 605 return cfg.readEntry(key);
580} 606}
581 607
582 608
583/*! 609/*!
584 Deletes both the linkFile() and file() associated with this AppLnk. 610 Deletes both the linkFile() and file() associated with this AppLnk.
585*/ 611*/
586void AppLnk::removeFiles() 612void AppLnk::removeFiles()
587{ 613{
588 bool valid = isValid(); 614 bool valid = isValid();
589 if ( !valid || QFile::remove(linkFile()) ) { 615 if ( !valid || !linkFileKnown() || QFile::remove(linkFile()) ) {
590 if ( QFile::remove(file()) ) { 616 if ( QFile::remove(file()) ) {
591 QCopEnvelope e("QPE/System", "linkChanged(QString)"); 617 QCopEnvelope e("QPE/System", "linkChanged(QString)");
592 e << linkFile(); 618 if ( linkFileKnown() )
619 e << linkFile();
620 else
621 e << file();
593 } else if ( valid ) { 622 } else if ( valid ) {
594 // restore link 623 // restore link
595 writeLink(); 624 writeLink();
596 } 625 }
597 } 626 }
598} 627}
599 628
600/*! 629/*!
601 Delete the linkFile(), leaving any file() untouched. 630 Delete the linkFile(), leaving any file() untouched.
602*/ 631*/
603void AppLnk::removeLinkFile() 632void AppLnk::removeLinkFile()
604{ 633{
605 if ( isValid() && QFile::remove(linkFile()) ) { 634 if ( isValid() && linkFileKnown() && QFile::remove(linkFile()) ) {
606 QCopEnvelope e("QPE/System", "linkChanged(QString)"); 635 QCopEnvelope e("QPE/System", "linkChanged(QString)");
607 e << linkFile(); 636 e << linkFile();
608 } 637 }
609} 638}
610 639
611class AppLnkSetPrivate { 640class AppLnkSetPrivate {
612public: 641public:
613 AppLnkSetPrivate() 642 AppLnkSetPrivate()
614 { 643 {
615 typPix.setAutoDelete(TRUE); 644 typPix.setAutoDelete(TRUE);
616 typPixBig.setAutoDelete(TRUE); 645 typPixBig.setAutoDelete(TRUE);
617 typName.setAutoDelete(TRUE); 646 typName.setAutoDelete(TRUE);
618 } 647 }
619 648
620 QDict<QPixmap> typPix; 649 QDict<QPixmap> typPix;
621 QDict<QPixmap> typPixBig; 650 QDict<QPixmap> typPixBig;
622 QDict<QString> typName; 651 QDict<QString> typName;
623}; 652};
624 653
625/*! 654/*!
626 \class AppLnkSet applnk.h 655 \class AppLnkSet applnk.h
627 \brief The AppLnkSet class is a set of AppLnk objects. 656 \brief The AppLnkSet class is a set of AppLnk objects.
628*/ 657*/
629 658
@@ -1062,32 +1091,32 @@ DocLnk::~DocLnk()
1062} 1091}
1063 1092
1064/*! 1093/*!
1065 \reimp 1094 \reimp
1066*/ 1095*/
1067QString DocLnk::exec() const 1096QString DocLnk::exec() const
1068{ 1097{
1069 MimeType mt(type()); 1098 MimeType mt(type());
1070 const AppLnk* app = mt.application(); 1099 const AppLnk* app = mt.application();
1071 if ( app ) 1100 if ( app )
1072 return app->exec(); 1101 return app->exec();
1073 else 1102 else
1074 return QString::null; 1103 return QString::null;
1075} 1104}
1076 1105
1077/*! 1106/*!
1078 \reimp 1107 \reimp
1079*/ 1108*/
1080void DocLnk::invoke(const QStringList& args) const 1109void DocLnk::invoke(const QStringList& args) const
1081{ 1110{
1082 MimeType mt(type()); 1111 MimeType mt(type());
1083 const AppLnk* app = mt.application(); 1112 const AppLnk* app = mt.application();
1084 if ( app ) { 1113 if ( app ) {
1085 QStringList a = args; 1114 QStringList a = args;
1086 if ( QFile::exists( linkFile() ) ) 1115 if ( linkFileKnown() && QFile::exists( linkFile() ) )
1087 a.append(linkFile()); 1116 a.append(linkFile());
1088 else 1117 else
1089 a.append(file()); 1118 a.append(file());
1090 app->execute(a); 1119 app->execute(a);
1091 } 1120 }
1092} 1121}
1093 1122