-rw-r--r-- | library/applnk.cpp | 83 |
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 | ||
43 | int AppLnk::lastId = 5000; | 45 | int AppLnk::lastId = 5000; |
44 | 46 | ||
45 | static int smallSize = 14; | 47 | static int smallSize = 14; |
46 | static int bigSize = 32; | 48 | static int bigSize = 32; |
47 | 49 | ||
48 | static QString safeFileName(const QString& n) | 50 | static 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 | ||
60 | static 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 | ||
59 | class AppLnkPrivate | 71 | class AppLnkPrivate |
60 | { | 72 | { |
61 | public: | 73 | public: |
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 | */ |
283 | QString AppLnk::file() const | 295 | QString 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 | */ |
314 | QString AppLnk::linkFile() const | 336 | QString 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 | */ |
348 | AppLnk::AppLnk( const AppLnk © ) | 376 | AppLnk::AppLnk( const AppLnk © ) |
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 | */ |
514 | bool AppLnk::ensureLinkExists() const | 542 | bool 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 | */ |
532 | bool AppLnk::writeLink() const | 554 | bool 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 | |||
564 | void 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 | */ |
562 | void AppLnk::setProperty(const QString& key, const QString& value) | 588 | void 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 | */ |
586 | void AppLnk::removeFiles() | 612 | void 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 | */ |
603 | void AppLnk::removeLinkFile() | 632 | void 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 | ||
611 | class AppLnkSetPrivate { | 640 | class AppLnkSetPrivate { |
612 | public: | 641 | public: |
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 | */ |
1080 | void DocLnk::invoke(const QStringList& args) const | 1109 | void 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 | ||