summaryrefslogtreecommitdiff
Unidiff
Diffstat (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
@@ -9,24 +9,26 @@
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
@@ -39,31 +41,41 @@
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.
@@ -274,77 +286,93 @@ QString AppLnk::type() const
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;
@@ -505,64 +533,62 @@ void AppLnk::setCategories( const QArray<int>& c )
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}
@@ -577,41 +603,44 @@ QString AppLnk::property(const QString& key) const
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);
@@ -1074,20 +1103,20 @@ QString DocLnk::exec() const
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