~ubuntu-branches/ubuntu/saucy/digikam/saucy

« back to all changes in this revision

Viewing changes to digikam/albummanager.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2010-12-21 23:19:11 UTC
  • mfrom: (1.2.33 upstream) (3.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20101221231911-z9jip7s5aht1jqn9
Tags: 2:1.7.0-1ubuntu1
* Merge from Debian Experimental. Remaining Ubuntu changes:
  - Export .pot name and copy to plugins in debian/rules
  - Version build-depends on kipi-plugins-dev to ensure build is against the
    same version on all archs
* Drop debian/patches/kubuntu_01_linker.diff, incoporated upstream
* Remove patches directory and unused patches

Show diffs side-by-side

added added

removed removed

Lines of Context:
113
113
    }
114
114
 
115
115
    PAlbumPath(int albumRootId, const QString& albumPath)
116
 
       : albumRootId(albumRootId), albumPath(albumPath)
 
116
        : albumRootId(albumRootId), albumPath(albumPath)
117
117
    {
118
118
    }
119
119
 
120
 
    PAlbumPath(PAlbum *album)
 
120
    PAlbumPath(PAlbum* album)
121
121
    {
122
122
        if (album->isRoot())
123
123
        {
199
199
    DAlbum*                     rootDAlbum;
200
200
    SAlbum*                     rootSAlbum;
201
201
 
202
 
    QHash<int,Album *>          allAlbumsIdHash;
 
202
    QHash<int,Album*>          allAlbumsIdHash;
203
203
    QHash<PAlbumPath, PAlbum*>  albumPathHash;
204
204
    QHash<int, PAlbum*>         albumRootAlbumHash;
205
205
    Album*                      currentlyMovingAlbum;
243
243
    QString labelForAlbumRootAlbum(const CollectionLocation& location)
244
244
    {
245
245
        QString label = location.label();
 
246
 
246
247
        if (label.isEmpty())
 
248
        {
247
249
            label = location.albumRootPath();
 
250
        }
 
251
 
248
252
        return label;
249
253
    }
250
254
};
253
257
{
254
258
public:
255
259
 
256
 
    ChangingDB(AlbumManagerPriv *d)
 
260
    ChangingDB(AlbumManagerPriv* d)
257
261
        : d(d)
258
262
    {
259
263
        d->changingDB = true;
265
269
    AlbumManagerPriv* const d;
266
270
};
267
271
 
268
 
class AlbumManagerCreator { public: AlbumManager object; };
 
272
class AlbumManagerCreator
 
273
{
 
274
public:
 
275
    AlbumManager object;
 
276
};
269
277
K_GLOBAL_STATIC(AlbumManagerCreator, creator)
270
278
 
271
279
// A friend-class shortcut to circumvent accessing this from within the destructor
272
 
AlbumManager *AlbumManager::internalInstance = 0;
 
280
AlbumManager* AlbumManager::internalInstance = 0;
273
281
 
274
282
AlbumManager* AlbumManager::instance()
275
283
{
277
285
}
278
286
 
279
287
AlbumManager::AlbumManager()
280
 
            : d(new AlbumManagerPriv)
 
288
    : d(new AlbumManagerPriv)
281
289
{
282
290
    internalInstance = this;
283
291
 
375
383
    if (info.exists())
376
384
    {
377
385
        QFileInfo backup(info.dir(), info.fileName() + "-backup-" + QDateTime::currentDateTime().toString(Qt::ISODate));
378
 
        KIO::Job *job = KIO::file_move(info.filePath(), backup.filePath(), -1, KIO::Overwrite | KIO::HideProgressInfo);
 
386
        KIO::Job* job = KIO::file_move(info.filePath(), backup.filePath(), -1, KIO::Overwrite | KIO::HideProgressInfo);
 
387
 
379
388
        if (!KIO::NetAccess::synchronousRun(job, 0))
380
389
        {
381
390
            KMessageBox::error(0, i18n("Failed to backup the existing database file (\"%1\"). "
382
391
                                       "Refusing to replace file without backup, using the existing file.",
383
 
                                        info.filePath()));
 
392
                                       info.filePath()));
384
393
            return false;
385
394
        }
386
395
    }
 
396
 
387
397
    return true;
388
398
}
389
399
 
390
400
static bool copyToNewLocation(const QFileInfo& oldFile, const QFileInfo& newFile, const QString otherMessage = QString())
391
401
{
392
402
    QString message = otherMessage;
 
403
 
393
404
    if (message.isNull())
394
405
        message = i18n("Failed to copy the old database file (\"%1\") "
395
406
                       "to its new location (\"%2\"). "
396
407
                       "Starting with an empty database.",
397
408
                       oldFile.filePath(), newFile.filePath());
398
409
 
399
 
    KIO::Job *job = KIO::file_copy(oldFile.filePath(), newFile.filePath(), -1, KIO::Overwrite /*| KIO::HideProgressInfo*/);
 
410
    KIO::Job* job = KIO::file_copy(oldFile.filePath(), newFile.filePath(), -1, KIO::Overwrite /*| KIO::HideProgressInfo*/);
 
411
 
400
412
    if (!KIO::NetAccess::synchronousRun(job, 0))
401
413
    {
402
414
        KMessageBox::error(0, message);
403
415
        return false;
404
416
    }
 
417
 
405
418
    return true;
406
419
}
407
420
 
423
436
            KGuiItem startFresh(i18n("Create New Database"), "document-new");
424
437
            KGuiItem upgrade(i18n("Upgrade Database"), "view-refresh");
425
438
            int result = KMessageBox::warningYesNo(0,
426
 
                                i18n("<p>You have chosen the folder \"%1\" as the place to store the database. "
427
 
                                     "A database file from an older version of digiKam is found in this folder.</p> "
428
 
                                     "<p>Would you like to upgrade the old database file - confirming "
429
 
                                     "that this database file was indeed created for the pictures located in the folder \"%2\" - "
430
 
                                     "or ignore the old file and start with a new database?</p> ",
431
 
                                    newDir.path(), albumDir.path()),
432
 
                                i18n("Database Folder"),
433
 
                                upgrade, startFresh);
 
439
                                                   i18n("<p>You have chosen the folder \"%1\" as the place to store the database. "
 
440
                                                           "A database file from an older version of digiKam is found in this folder.</p> "
 
441
                                                           "<p>Would you like to upgrade the old database file - confirming "
 
442
                                                           "that this database file was indeed created for the pictures located in the folder \"%2\" - "
 
443
                                                           "or ignore the old file and start with a new database?</p> ",
 
444
                                                           newDir.path(), albumDir.path()),
 
445
                                                   i18n("Database Folder"),
 
446
                                                   upgrade, startFresh);
434
447
 
435
448
            if (result == KMessageBox::Yes)
436
449
            {
456
469
    DatabaseParameters params = DatabaseAccess::parameters();
457
470
 
458
471
    // New database type SQLITE
459
 
    if (newParams.isSQLite()){
 
472
    if (newParams.isSQLite())
 
473
    {
460
474
        QDir newDir(newParams.getDatabaseNameOrDir());
461
475
        QFileInfo newFile(newDir, QString("digikam4.db"));
462
476
 
463
477
        if (!newFile.exists())
 
478
        {
 
479
            QFileInfo digikam3DB(newDir, "digikam3.db");
 
480
            QFileInfo digikamVeryOldDB(newDir, "digikam.db");
 
481
 
 
482
            if (digikam3DB.exists() || digikamVeryOldDB.exists())
464
483
            {
465
 
                QFileInfo digikam3DB(newDir, "digikam3.db");
466
 
                QFileInfo digikamVeryOldDB(newDir, "digikam.db");
 
484
                KGuiItem copyCurrent(i18n("Copy Current Database"), "edit-copy");
 
485
                KGuiItem startFresh(i18n("Create New Database"), "document-new");
 
486
                KGuiItem upgrade(i18n("Upgrade Database"), "view-refresh");
 
487
                int result = -1;
467
488
 
468
 
                if (digikam3DB.exists() || digikamVeryOldDB.exists())
 
489
                if (params.isSQLite())
469
490
                {
470
 
                    KGuiItem copyCurrent(i18n("Copy Current Database"), "edit-copy");
471
 
                    KGuiItem startFresh(i18n("Create New Database"), "document-new");
472
 
                    KGuiItem upgrade(i18n("Upgrade Database"), "view-refresh");
473
 
                    int result = -1;
474
 
                    if (params.isSQLite())
475
 
                    {
476
 
                        result = KMessageBox::warningYesNoCancel(0,
477
 
                                            i18n("<p>You have chosen the folder \"%1\" as the new place to store the database. "
478
 
                                                 "A database file from an older version of digiKam is found in this folder.</p> "
479
 
                                                "<p>Would you like to upgrade the old database file, start with a new database, "
480
 
                                                "or copy the current database to this location and continue using it?</p> ",
481
 
                                                newDir.path()),
482
 
                                            i18n("New database folder"),
483
 
                                            upgrade, startFresh, copyCurrent);
484
 
                    }else{
485
 
                        result = KMessageBox::warningYesNo(0,
486
 
                                            i18n("<p>You have chosen the folder \"%1\" as the new place to store the database. "
487
 
                                                 "A database file from an older version of digiKam is found in this folder.</p> "
488
 
                                                "<p>Would you like to upgrade the old database file or start with a new database?</p>",
489
 
                                                newDir.path()),
490
 
                                            i18n("New database folder"),
491
 
                                            upgrade, startFresh);
492
 
                    }
493
 
 
494
 
                    if (result == KMessageBox::Yes)
495
 
                    {
496
 
                        // SchemaUpdater expects Album Path to point to the album root of the 0.9 db file.
497
 
                        // Restore this situation.
498
 
                        KSharedConfigPtr config = KGlobal::config();
499
 
                        KConfigGroup group = config->group("Album Settings");
500
 
                        group.writeEntry("Album Path", newDir.path());
501
 
                        group.sync();
502
 
                    }
503
 
                    else if (result == KMessageBox::No)
504
 
                    {
505
 
                        moveToBackup(digikam3DB);
506
 
                        moveToBackup(digikamVeryOldDB);
507
 
                    }
508
 
                    else if (result == KMessageBox::Cancel)
509
 
                    {
510
 
                        QDir oldDir(d->dbName);
511
 
                        QFileInfo oldFile(params.SQLiteDatabaseFile());
512
 
                        copyToNewLocation(oldFile, newFile, i18n("Failed to copy the old database file (\"%1\") "
513
 
                                                                 "to its new location (\"%2\"). "
514
 
                                                                 "Trying to upgrade old databases.",
515
 
                                                                 oldFile.filePath(), newFile.filePath()));
516
 
                    }
 
491
                    result = KMessageBox::warningYesNoCancel(0,
 
492
                             i18n("<p>You have chosen the folder \"%1\" as the new place to store the database. "
 
493
                                  "A database file from an older version of digiKam is found in this folder.</p> "
 
494
                                  "<p>Would you like to upgrade the old database file, start with a new database, "
 
495
                                  "or copy the current database to this location and continue using it?</p> ",
 
496
                                  newDir.path()),
 
497
                             i18n("New database folder"),
 
498
                             upgrade, startFresh, copyCurrent);
517
499
                }
518
500
                else
519
501
                {
520
 
                    int result = KMessageBox::Yes;
521
 
                    if (params.isSQLite())
522
 
                    {
523
 
                    KGuiItem copyCurrent(i18n("Copy Current Database"), "edit-copy");
524
 
                    KGuiItem startFresh(i18n("Create New Database"), "document-new");
525
 
                        result = KMessageBox::warningYesNo(0,
526
 
                                            i18n("<p>You have chosen the folder \"%1\" as the new place to store the database.</p>"
527
 
                                                "<p>Would you like to copy the current database to this location "
528
 
                                                "and continue using it, or start with a new database?</p> ",
529
 
                                                newDir.path()),
530
 
                                            i18n("New database folder"),
531
 
                                            startFresh, copyCurrent);
532
 
                    }
 
502
                    result = KMessageBox::warningYesNo(0,
 
503
                                                       i18n("<p>You have chosen the folder \"%1\" as the new place to store the database. "
 
504
                                                            "A database file from an older version of digiKam is found in this folder.</p> "
 
505
                                                            "<p>Would you like to upgrade the old database file or start with a new database?</p>",
 
506
                                                            newDir.path()),
 
507
                                                       i18n("New database folder"),
 
508
                                                       upgrade, startFresh);
 
509
                }
533
510
 
534
 
                    if (result == KMessageBox::No)
535
 
                    {
536
 
                        QDir oldDir(d->dbName);
537
 
                        QFileInfo oldFile(params.SQLiteDatabaseFile());
538
 
                        copyToNewLocation(oldFile, newFile);
539
 
                    }
540
 
                }
541
 
            }
542
 
            else
543
 
            {
544
 
                int result = KMessageBox::No;
545
 
                if (params.isSQLite())
546
 
                {
547
 
                    KGuiItem replaceItem(i18n("Copy Current Database"), "edit-copy");
548
 
                    KGuiItem useExistingItem(i18n("Use Existing File"), "document-open");
549
 
                    result = KMessageBox::warningYesNo(0,
550
 
                                        i18n("<p>You have chosen the folder \"%1\" as the new place to store the database. "
551
 
                                             "There is already a database file in this location.</p> "
552
 
                                             "<p>Would you like to use this existing file as the new database, or remove it "
553
 
                                             "and copy the current database to this place?</p> ",
554
 
                                              newDir.path()),
555
 
                                        i18n("New database folder"),
556
 
                                        replaceItem, useExistingItem);
557
 
                }
558
511
                if (result == KMessageBox::Yes)
559
512
                {
560
 
                    // first backup
561
 
                    if (moveToBackup(newFile))
562
 
                    {
563
 
                        QDir oldDir(d->dbName);
564
 
                        QFileInfo oldFile(params.SQLiteDatabaseFile());
565
 
 
566
 
                        // then copy
567
 
                       copyToNewLocation(oldFile, newFile);
568
 
                    }
569
 
                }
570
 
            }
 
513
                    // SchemaUpdater expects Album Path to point to the album root of the 0.9 db file.
 
514
                    // Restore this situation.
 
515
                    KSharedConfigPtr config = KGlobal::config();
 
516
                    KConfigGroup group = config->group("Album Settings");
 
517
                    group.writeEntry("Album Path", newDir.path());
 
518
                    group.sync();
 
519
                }
 
520
                else if (result == KMessageBox::No)
 
521
                {
 
522
                    moveToBackup(digikam3DB);
 
523
                    moveToBackup(digikamVeryOldDB);
 
524
                }
 
525
                else if (result == KMessageBox::Cancel)
 
526
                {
 
527
                    QDir oldDir(d->dbName);
 
528
                    QFileInfo oldFile(params.SQLiteDatabaseFile());
 
529
                    copyToNewLocation(oldFile, newFile, i18n("Failed to copy the old database file (\"%1\") "
 
530
                                      "to its new location (\"%2\"). "
 
531
                                      "Trying to upgrade old databases.",
 
532
                                      oldFile.filePath(), newFile.filePath()));
 
533
                }
 
534
            }
 
535
            else
 
536
            {
 
537
                int result = KMessageBox::Yes;
 
538
 
 
539
                if (params.isSQLite())
 
540
                {
 
541
                    KGuiItem copyCurrent(i18n("Copy Current Database"), "edit-copy");
 
542
                    KGuiItem startFresh(i18n("Create New Database"), "document-new");
 
543
                    result = KMessageBox::warningYesNo(0,
 
544
                                                       i18n("<p>You have chosen the folder \"%1\" as the new place to store the database.</p>"
 
545
                                                            "<p>Would you like to copy the current database to this location "
 
546
                                                            "and continue using it, or start with a new database?</p> ",
 
547
                                                            newDir.path()),
 
548
                                                       i18n("New database folder"),
 
549
                                                       startFresh, copyCurrent);
 
550
                }
 
551
 
 
552
                if (result == KMessageBox::No)
 
553
                {
 
554
                    QDir oldDir(d->dbName);
 
555
                    QFileInfo oldFile(params.SQLiteDatabaseFile());
 
556
                    copyToNewLocation(oldFile, newFile);
 
557
                }
 
558
            }
 
559
        }
 
560
        else
 
561
        {
 
562
            int result = KMessageBox::No;
 
563
 
 
564
            if (params.isSQLite())
 
565
            {
 
566
                KGuiItem replaceItem(i18n("Copy Current Database"), "edit-copy");
 
567
                KGuiItem useExistingItem(i18n("Use Existing File"), "document-open");
 
568
                result = KMessageBox::warningYesNo(0,
 
569
                                                   i18n("<p>You have chosen the folder \"%1\" as the new place to store the database. "
 
570
                                                        "There is already a database file in this location.</p> "
 
571
                                                        "<p>Would you like to use this existing file as the new database, or remove it "
 
572
                                                        "and copy the current database to this place?</p> ",
 
573
                                                        newDir.path()),
 
574
                                                   i18n("New database folder"),
 
575
                                                   replaceItem, useExistingItem);
 
576
            }
 
577
 
 
578
            if (result == KMessageBox::Yes)
 
579
            {
 
580
                // first backup
 
581
                if (moveToBackup(newFile))
 
582
                {
 
583
                    QDir oldDir(d->dbName);
 
584
                    QFileInfo oldFile(params.SQLiteDatabaseFile());
 
585
 
 
586
                    // then copy
 
587
                    copyToNewLocation(oldFile, newFile);
 
588
                }
 
589
            }
 
590
        }
571
591
    }
572
592
 
573
593
    if (setDatabase(newParams, false))
600
620
    d->changed = true;
601
621
 
602
622
    disconnect(CollectionManager::instance(), 0, this, 0);
 
623
 
603
624
    if (DatabaseAccess::databaseWatch())
 
625
    {
604
626
        disconnect(DatabaseAccess::databaseWatch(), 0, this, 0);
 
627
    }
 
628
 
605
629
    d->dbPathModificationDateList.clear();
606
630
 
607
631
    if (d->dateListJob)
659
683
    if (params.internalServer)
660
684
    {
661
685
        DatabaseServerError result = DatabaseServerStarter::startServerManagerProcess();
 
686
 
662
687
        if (result.getErrorType()!=DatabaseServerError::NoErrors)
663
688
        {
664
689
            QWidget* parent = QWidget::find(0);
665
690
            QString message = i18n("<p><b>An error occurred during the internal server start.</b></p>"
666
 
            "Details:\n %1", result.getErrorText());
 
691
                                   "Details:\n %1", result.getErrorText());
667
692
            QApplication::changeOverrideCursor(Qt::ArrowCursor);
668
693
            KMessageBox::error(parent, message);
669
694
            QApplication::changeOverrideCursor(Qt::WaitCursor);
672
697
 
673
698
    DatabaseAccess::setParameters(params, DatabaseAccess::MainApplication);
674
699
 
675
 
    DatabaseGUIErrorHandler *handler = new DatabaseGUIErrorHandler(DatabaseAccess::parameters());
 
700
    DatabaseGUIErrorHandler* handler = new DatabaseGUIErrorHandler(DatabaseAccess::parameters());
676
701
    DatabaseAccess::initDatabaseErrorHandler(handler);
677
702
 
678
703
    if (!handler->checkDatabaseConnection())
679
704
    {
680
705
        KMessageBox::error(0, i18n("<p>Failed to open the database. "
681
 
                                               "</p><p>You cannot use digiKam without a working database. "
682
 
                                               "digiKam will attempt to start now, but it will <b>not</b> be functional. "
683
 
                                               "Please check the database settings in the <b>configuration menu</b>.</p>"
684
 
                                               ));
 
706
                                   "</p><p>You cannot use digiKam without a working database. "
 
707
                                   "digiKam will attempt to start now, but it will <b>not</b> be functional. "
 
708
                                   "Please check the database settings in the <b>configuration menu</b>.</p>"
 
709
                                  ));
685
710
 
686
711
        DatabaseAccess::setParameters(DatabaseParameters(), DatabaseAccess::DatabaseSlave);
687
712
        QApplication::restoreOverrideCursor();
702
727
        case ScanController::ContinueWithoutDatabase:
703
728
        {
704
729
            QString errorMsg = DatabaseAccess().lastError();
 
730
 
705
731
            if (errorMsg.isEmpty())
706
732
            {
707
733
                KMessageBox::error(0, i18n("<p>Failed to open the database. "
708
 
                                        "</p><p>You cannot use digiKam without a working database. "
709
 
                                        "digiKam will attempt to start now, but it will <b>not</b> be functional. "
710
 
                                        "Please check the database settings in the <b>configuration menu</b>.</p>"
711
 
                                        ));
 
734
                                           "</p><p>You cannot use digiKam without a working database. "
 
735
                                           "digiKam will attempt to start now, but it will <b>not</b> be functional. "
 
736
                                           "Please check the database settings in the <b>configuration menu</b>.</p>"
 
737
                                          ));
712
738
            }
713
739
            else
714
740
            {
719
745
                                           "Please check the database settings in the <b>configuration menu</b>.</p>",
720
746
                                           errorMsg));
721
747
            }
 
748
 
722
749
            return true;
723
750
        }
724
751
        case ScanController::AbortImmediately:
741
768
        // to the database.
742
769
        KSharedConfig::Ptr config = KGlobal::config();
743
770
        KConfigGroup group = config->group("General Settings");
 
771
 
744
772
        if (group.hasKey("Locale"))
745
773
        {
746
774
            kDebug() << "Locale found in configfile";
771
799
    else
772
800
    {
773
801
        if (dbLocale == currLocale)
 
802
        {
774
803
            localeChanged = false;
 
804
        }
775
805
    }
776
806
 
777
807
    if (localeChanged)
792
822
                                           "Otherwise, click 'No' and correct your "
793
823
                                           "locale setting before restarting digiKam.",
794
824
                                           dbLocale, currLocale));
 
825
 
795
826
        if (result != KMessageBox::Yes)
 
827
        {
796
828
            exit(0);
 
829
        }
797
830
 
798
831
        DatabaseAccess().db()->setSetting("Locale",currLocale);
799
832
    }
801
834
    // -- UUID Checking ---------------------------------------------------------
802
835
 
803
836
    QList<CollectionLocation> disappearedLocations = CollectionManager::instance()->checkHardWiredLocations();
804
 
    foreach (const CollectionLocation &loc, disappearedLocations)
 
837
    foreach (const CollectionLocation& loc, disappearedLocations)
805
838
    {
806
839
        QString locDescription;
807
840
        QStringList candidateIds, candidateDescriptions;
808
841
        CollectionManager::instance()->migrationCandidates(loc, &locDescription, &candidateIds, &candidateDescriptions);
809
842
        kDebug() << "Migration candidates for" << locDescription << ":" << candidateIds << candidateDescriptions;
810
843
 
811
 
        KDialog *dialog = new KDialog;
 
844
        KDialog* dialog = new KDialog;
812
845
 
813
 
        QWidget *widget = new QWidget;
814
 
        QGridLayout *mainLayout = new QGridLayout;
 
846
        QWidget* widget = new QWidget;
 
847
        QGridLayout* mainLayout = new QGridLayout;
815
848
        mainLayout->setColumnStretch(1, 1);
816
849
 
817
 
        QLabel *deviceIconLabel = new QLabel;
 
850
        QLabel* deviceIconLabel = new QLabel;
818
851
        deviceIconLabel->setPixmap(KIconLoader::global()->loadIcon("drive-harddisk", KIconLoader::NoGroup, KIconLoader::SizeHuge));
819
852
        mainLayout->addWidget(deviceIconLabel, 0, 0);
820
853
 
821
 
        QLabel *mainLabel = new QLabel(
822
 
                i18n("<p>The collection </p><p><b>%1</b><br/>(%2)</p><p> is currently not found on your system.<br/> "
823
 
                     "Please choose the most appropriate option to handle this situation:</p>",
824
 
                      loc.label(), locDescription));
 
854
        QLabel* mainLabel = new QLabel(
 
855
            i18n("<p>The collection </p><p><b>%1</b><br/>(%2)</p><p> is currently not found on your system.<br/> "
 
856
                 "Please choose the most appropriate option to handle this situation:</p>",
 
857
                 loc.label(), locDescription));
825
858
        mainLabel->setWordWrap(true);
826
859
        mainLayout->addWidget(mainLabel, 0, 1);
827
860
 
828
 
        QGroupBox *groupBox = new QGroupBox;
 
861
        QGroupBox* groupBox = new QGroupBox;
829
862
        mainLayout->addWidget(groupBox, 1, 0, 1, 2);
830
863
 
831
 
        QGridLayout *layout = new QGridLayout;
 
864
        QGridLayout* layout = new QGridLayout;
832
865
        layout->setColumnStretch(1, 1);
833
866
 
834
 
        QRadioButton *migrateButton = 0;
835
 
        KComboBox *migrateChoices = 0;
 
867
        QRadioButton* migrateButton = 0;
 
868
        KComboBox* migrateChoices = 0;
 
869
 
836
870
        if (!candidateIds.isEmpty())
837
871
        {
838
872
            migrateButton = new QRadioButton;
839
 
            QLabel *migrateLabel = new QLabel(
840
 
                    i18n("<p>The collection is still available, but the identifier changed.<br/>"
841
 
                        "This can be caused by restoring a backup, changing the partition layout "
842
 
                        "or the file system settings.<br/>"
843
 
                        "The collection is now located at this place:</p>"));
 
873
            QLabel* migrateLabel = new QLabel(
 
874
                i18n("<p>The collection is still available, but the identifier changed.<br/>"
 
875
                     "This can be caused by restoring a backup, changing the partition layout "
 
876
                     "or the file system settings.<br/>"
 
877
                     "The collection is now located at this place:</p>"));
844
878
            migrateLabel->setWordWrap(true);
845
879
 
846
880
            migrateChoices = new KComboBox;
 
881
 
847
882
            for (int i=0; i<candidateIds.size(); ++i)
 
883
            {
848
884
                migrateChoices->addItem(candidateDescriptions[i], candidateIds[i]);
 
885
            }
849
886
 
850
887
            layout->addWidget(migrateButton, 0, 0, Qt::AlignTop);
851
888
            layout->addWidget(migrateLabel, 0, 1);
852
889
            layout->addWidget(migrateChoices, 1, 1);
853
890
        }
854
891
 
855
 
        QRadioButton *isRemovableButton = new QRadioButton;
856
 
        QLabel *isRemovableLabel = new QLabel(
857
 
                i18n("The collection is located on a storage device which is not always attached. "
858
 
                     "Mark the collection as a removable collection."));
 
892
        QRadioButton* isRemovableButton = new QRadioButton;
 
893
        QLabel* isRemovableLabel = new QLabel(
 
894
            i18n("The collection is located on a storage device which is not always attached. "
 
895
                 "Mark the collection as a removable collection."));
859
896
        isRemovableLabel->setWordWrap(true);
860
897
        layout->addWidget(isRemovableButton, 2, 0, Qt::AlignTop);
861
898
        layout->addWidget(isRemovableLabel, 2, 1);
862
899
 
863
 
        QRadioButton *solveManuallyButton = new QRadioButton;
864
 
        QLabel *solveManuallyLabel = new QLabel(
865
 
                i18n("Take no action now. I would like to solve the problem "
866
 
                     "later using the setup dialog"));
 
900
        QRadioButton* solveManuallyButton = new QRadioButton;
 
901
        QLabel* solveManuallyLabel = new QLabel(
 
902
            i18n("Take no action now. I would like to solve the problem "
 
903
                 "later using the setup dialog"));
867
904
        solveManuallyLabel->setWordWrap(true);
868
905
        layout->addWidget(solveManuallyButton, 3, 0, Qt::AlignTop);
869
906
        layout->addWidget(solveManuallyLabel, 3, 1);
878
915
        // Default option: If there is only one candidate, default to migration.
879
916
        // Otherwise default to do nothing now.
880
917
        if (migrateButton && candidateIds.size() == 1)
 
918
        {
881
919
            migrateButton->setChecked(true);
 
920
        }
882
921
        else
 
922
        {
883
923
            solveManuallyButton->setChecked(true);
 
924
        }
884
925
 
885
926
        if (dialog->exec())
886
927
        {
903
944
    if (CollectionManager::instance()->allLocations().isEmpty())
904
945
    {
905
946
        if (suggestedAlbumRoot.isEmpty())
 
947
        {
906
948
            Setup::execSinglePage(Setup::CollectionsPage);
 
949
        }
907
950
        else
908
951
        {
909
952
            CollectionManager::instance()->addLocation(suggestedAlbumRoot);
927
970
    ThumbnailLoadThread::initializeThumbnailDatabase(DatabaseAccess::parameters().thumbnailParameters(),
928
971
            new DatabaseThumbnailInfoProvider());
929
972
 
930
 
    DatabaseGUIErrorHandler *thumbnailsDBHandler = new DatabaseGUIErrorHandler(ThumbnailDatabaseAccess::parameters());
 
973
    DatabaseGUIErrorHandler* thumbnailsDBHandler = new DatabaseGUIErrorHandler(ThumbnailDatabaseAccess::parameters());
931
974
    ThumbnailDatabaseAccess::initDatabaseErrorHandler(thumbnailsDBHandler);
932
975
 
933
976
    QApplication::restoreOverrideCursor();
948
991
    // -- ---------------------------------------------------------
949
992
 
950
993
#ifdef HAVE_NEPOMUK
 
994
 
951
995
    if (checkNepomukService())
952
996
    {
953
997
        QDBusInterface serviceInterface("org.kde.nepomuk.services.digikamnepomukservice",
954
998
                                        "/digikamnepomukservice", "org.kde.digikam.DigikamNepomukService");
955
999
        kDebug() << "nepomuk service available" << serviceInterface.isValid();
 
1000
 
956
1001
        if (serviceInterface.isValid())
957
1002
        {
958
1003
            DatabaseParameters parameters = DatabaseAccess::parameters();
961
1006
            serviceInterface.call(QDBus::NoBlock, "setDatabase", url.url());
962
1007
        }
963
1008
    }
 
1009
 
964
1010
#endif // HAVE_NEPOMUK
965
1011
 
966
1012
    return true;
976
1022
 
977
1023
    // already running? (normal)
978
1024
    if (serviceInterface.isValid())
 
1025
    {
979
1026
        return true;
 
1027
    }
980
1028
 
981
1029
    // start service
982
1030
    QDBusInterface nepomukInterface("org.kde.NepomukServer",
983
1031
                                    "/servicemanager", "org.kde.nepomuk.ServiceManager");
 
1032
 
984
1033
    if (!nepomukInterface.isValid())
985
1034
    {
986
1035
        kDebug() << "Nepomuk server is not reachable. Cannot start Digikam Nepomuk Service";
988
1037
    }
989
1038
 
990
1039
    QDBusReply<QStringList> availableServicesReply = nepomukInterface.call("availableServices");
 
1040
 
991
1041
    if (!availableServicesReply.isValid() || !availableServicesReply.value().contains("digikamnepomukservice"))
992
1042
    {
993
1043
        kDebug() << "digikamnepomukservice is not available in NepomukServer";
1023
1073
void AlbumManager::startScan()
1024
1074
{
1025
1075
    if (!d->changed)
 
1076
    {
1026
1077
        return;
 
1078
    }
 
1079
 
1027
1080
    d->changed = false;
1028
1081
 
1029
1082
    KDirWatch::Method m = d->dirWatch->internalMethod();
1030
1083
    QString mName("FAM");
 
1084
 
1031
1085
    if (m == KDirWatch::DNotify)
 
1086
    {
1032
1087
        mName = QString("DNotify");
 
1088
    }
1033
1089
    else if (m == KDirWatch::Stat)
 
1090
    {
1034
1091
        mName = QString("Stat");
 
1092
    }
1035
1093
    else if (m == KDirWatch::INotify)
 
1094
    {
1036
1095
        mName = QString("INotify");
 
1096
    }
 
1097
 
1037
1098
    kDebug() << "KDirWatch method = " << mName;
1038
1099
 
1039
1100
    // connect to KDirNotify
1070
1131
    }
1071
1132
 
1072
1133
    // listen to location status changes
1073
 
    connect(CollectionManager::instance(), SIGNAL(locationStatusChanged(const CollectionLocation &, int)),
1074
 
            this, SLOT(slotCollectionLocationStatusChanged(const CollectionLocation &, int)));
1075
 
    connect(CollectionManager::instance(), SIGNAL(locationPropertiesChanged(const CollectionLocation &)),
1076
 
            this, SLOT(slotCollectionLocationPropertiesChanged(const CollectionLocation &)));
 
1134
    connect(CollectionManager::instance(), SIGNAL(locationStatusChanged(const CollectionLocation&, int)),
 
1135
            this, SLOT(slotCollectionLocationStatusChanged(const CollectionLocation&, int)));
 
1136
    connect(CollectionManager::instance(), SIGNAL(locationPropertiesChanged(const CollectionLocation&)),
 
1137
            this, SLOT(slotCollectionLocationPropertiesChanged(const CollectionLocation&)));
1077
1138
 
1078
1139
    // reload albums
1079
1140
    refresh();
1080
1141
 
1081
1142
    // listen to album database changes
1082
 
    connect(DatabaseAccess::databaseWatch(), SIGNAL(albumChange(const AlbumChangeset &)),
1083
 
            this, SLOT(slotAlbumChange(const AlbumChangeset &)));
1084
 
    connect(DatabaseAccess::databaseWatch(), SIGNAL(tagChange(const TagChangeset &)),
1085
 
            this, SLOT(slotTagChange(const TagChangeset &)));
1086
 
    connect(DatabaseAccess::databaseWatch(), SIGNAL(searchChange(const SearchChangeset &)),
1087
 
            this, SLOT(slotSearchChange(const SearchChangeset &)));
 
1143
    connect(DatabaseAccess::databaseWatch(), SIGNAL(albumChange(const AlbumChangeset&)),
 
1144
            this, SLOT(slotAlbumChange(const AlbumChangeset&)));
 
1145
    connect(DatabaseAccess::databaseWatch(), SIGNAL(tagChange(const TagChangeset&)),
 
1146
            this, SLOT(slotTagChange(const TagChangeset&)));
 
1147
    connect(DatabaseAccess::databaseWatch(), SIGNAL(searchChange(const SearchChangeset&)),
 
1148
            this, SLOT(slotSearchChange(const SearchChangeset&)));
1088
1149
    // listen to collection image changes
1089
 
    connect(DatabaseAccess::databaseWatch(), SIGNAL(collectionImageChange(const CollectionImageChangeset &)),
1090
 
            this, SLOT(slotCollectionImageChange(const CollectionImageChangeset &)));
1091
 
    connect(DatabaseAccess::databaseWatch(), SIGNAL(imageTagChange(const ImageTagChangeset &)),
1092
 
            this, SLOT(slotImageTagChange(const ImageTagChangeset &)));
 
1150
    connect(DatabaseAccess::databaseWatch(), SIGNAL(collectionImageChange(const CollectionImageChangeset&)),
 
1151
            this, SLOT(slotCollectionImageChange(const CollectionImageChangeset&)));
 
1152
    connect(DatabaseAccess::databaseWatch(), SIGNAL(imageTagChange(const ImageTagChangeset&)),
 
1153
            this, SLOT(slotImageTagChange(const ImageTagChangeset&)));
1093
1154
 
1094
1155
    emit signalAllAlbumsLoaded();
1095
1156
}
1098
1159
{
1099
1160
    // not before initialization
1100
1161
    if (!d->rootPAlbum)
 
1162
    {
1101
1163
        return;
 
1164
    }
1102
1165
 
1103
1166
    if (location.status() == CollectionLocation::LocationAvailable
1104
1167
        && oldStatus != CollectionLocation::LocationAvailable)
1118
1181
 
1119
1182
void AlbumManager::slotCollectionLocationPropertiesChanged(const CollectionLocation& location)
1120
1183
{
1121
 
    PAlbum *album = d->albumRootAlbumHash.value(location.id());
 
1184
    PAlbum* album = d->albumRootAlbumHash.value(location.id());
 
1185
 
1122
1186
    if (album)
1123
1187
    {
1124
1188
        QString newLabel = d->labelForAlbumRootAlbum(location);
 
1189
 
1125
1190
        if (album->title() != newLabel)
1126
1191
        {
1127
1192
            album->setTitle(newLabel);
1138
1203
        d->dirWatch->addDir(location.albumRootPath(), KDirWatch::WatchSubDirs);
1139
1204
    }
1140
1205
 
1141
 
    PAlbum *album = d->albumRootAlbumHash.value(location.id());
 
1206
    PAlbum* album = d->albumRootAlbumHash.value(location.id());
 
1207
 
1142
1208
    if (!album)
1143
1209
    {
1144
1210
        // Create a PAlbum for the Album Root.
1154
1220
{
1155
1221
    d->dirWatch->removeDir(location.albumRootPath());
1156
1222
    // retrieve and remove from hash
1157
 
    PAlbum *album = d->albumRootAlbumHash.take(location.id());
 
1223
    PAlbum* album = d->albumRootAlbumHash.take(location.id());
 
1224
 
1158
1225
    if (album)
1159
1226
    {
1160
1227
        // delete album and all its children
1184
1251
    d->scanPAlbumsTimer->stop();
1185
1252
 
1186
1253
    // first insert all the current normal PAlbums into a map for quick lookup
1187
 
    QHash<int, PAlbum *> oldAlbums;
 
1254
    QHash<int, PAlbum*> oldAlbums;
1188
1255
    AlbumIterator it(d->rootPAlbum);
 
1256
 
1189
1257
    while (it.current())
1190
1258
    {
1191
1259
        PAlbum* a = (PAlbum*)(*it);
1208
1276
        if (CollectionManager::instance()->locationForAlbumRootId(info.albumRootId).isAvailable())
1209
1277
        {
1210
1278
            if (oldAlbums.contains(info.id))
 
1279
            {
1211
1280
                oldAlbums.remove(info.id);
 
1281
            }
1212
1282
            else
 
1283
            {
1213
1284
                newAlbums << info;
 
1285
            }
1214
1286
        }
1215
1287
    }
1216
1288
 
1222
1294
    // The albums have to be removed with children being removed first,
1223
1295
    // removePAlbum takes care of that.
1224
1296
    // So we only feed it the albums from oldAlbums topmost in hierarchy.
1225
 
    QSet<PAlbum *> topMostOldAlbums;
1226
 
    foreach (PAlbum *album, oldAlbums)
 
1297
    QSet<PAlbum*> topMostOldAlbums;
 
1298
    foreach (PAlbum* album, oldAlbums)
1227
1299
    {
1228
1300
        if (!album->parent() || !oldAlbums.contains(album->parent()->id()))
 
1301
        {
1229
1302
            topMostOldAlbums << album;
 
1303
        }
1230
1304
    }
1231
1305
 
1232
 
    foreach(PAlbum *album, topMostOldAlbums)
 
1306
    foreach (PAlbum* album, topMostOldAlbums)
1233
1307
    {
1234
 
        // this might look like there is memory leak here, since removePAlbum
1235
 
        // doesn't delete albums and looks like child Albums don't get deleted.
1236
 
        // But when the parent album gets deleted, the children are also deleted.
 
1308
        // recursively removes all children and the album
1237
1309
        removePAlbum(album);
1238
1310
    }
1239
1311
 
1244
1316
    foreach (const AlbumInfo& info, newAlbums)
1245
1317
    {
1246
1318
        if (info.relativePath.isEmpty())
 
1319
        {
1247
1320
            continue;
1248
 
 
1249
 
        PAlbum *album, *parent;
 
1321
        }
 
1322
 
 
1323
        PAlbum* album, *parent;
 
1324
 
1250
1325
        if (info.relativePath == "/")
1251
1326
        {
1252
1327
            // Albums that represent the root directory of an album root
1273
1348
            QString parentPath = info.relativePath.section('/', 0, -2);
1274
1349
 
1275
1350
            if (parentPath.isEmpty())
 
1351
            {
1276
1352
                parent = d->albumRootAlbumHash.value(info.albumRootId);
 
1353
            }
1277
1354
            else
 
1355
            {
1278
1356
                parent = d->albumPathHash.value(PAlbumPath(info.albumRootId, parentPath));
 
1357
            }
1279
1358
 
1280
1359
            if (!parent)
1281
1360
            {
1282
1361
                kError() <<  "Could not find parent with url: "
1283
 
                              << parentPath << " for: " << info.relativePath;
 
1362
                         << parentPath << " for: " << info.relativePath;
1284
1363
                continue;
1285
1364
            }
1286
1365
 
1295
1374
        if (info.iconAlbumRootId)
1296
1375
        {
1297
1376
            QString albumRootPath = CollectionManager::instance()->albumRootPath(info.iconAlbumRootId);
 
1377
 
1298
1378
            if (!albumRootPath.isNull())
 
1379
            {
1299
1380
                album->m_icon = albumRootPath + info.iconRelativePath;
 
1381
            }
1300
1382
        }
1301
1383
 
1302
1384
        insertPAlbum(album, parent);
1323
1405
            {
1324
1406
                d->changedPAlbums.remove(info.id);
1325
1407
 
1326
 
                PAlbum *album = findPAlbum(info.id);
 
1408
                PAlbum* album = findPAlbum(info.id);
 
1409
 
1327
1410
                if (album)
1328
1411
                {
1329
1412
                    // Renamed?
1334
1417
                        QString name = info.relativePath.section('/', -1, -1);
1335
1418
                        QString parentPath = info.relativePath;
1336
1419
                        parentPath.chop(name.length());
 
1420
 
1337
1421
                        if (parentPath != album->m_parentPath || info.albumRootId != album->albumRootId())
1338
1422
                        {
1339
1423
                            // Handle actual move operations: trigger ScanPAlbums
1356
1440
 
1357
1441
                    // Icon changed?
1358
1442
                    QString icon;
 
1443
 
1359
1444
                    if (info.iconAlbumRootId)
1360
1445
                    {
1361
1446
                        QString albumRootPath = CollectionManager::instance()->albumRootPath(info.iconAlbumRootId);
 
1447
 
1362
1448
                        if (!albumRootPath.isNull())
 
1449
                        {
1363
1450
                            icon = albumRootPath + info.iconRelativePath;
 
1451
                        }
1364
1452
                    }
 
1453
 
1365
1454
                    if (icon != album->m_icon)
1366
1455
                    {
1367
1456
                        album->m_icon = icon;
1373
1462
    }
1374
1463
 
1375
1464
    if (needScanPAlbums)
 
1465
    {
1376
1466
        scanPAlbums();
 
1467
    }
1377
1468
}
1378
1469
 
1379
1470
void AlbumManager::getAlbumItemsCount()
1381
1472
    d->albumItemCountTimer->stop();
1382
1473
 
1383
1474
    if (!AlbumSettings::instance()->getShowFolderTreeViewItemsCount())
 
1475
    {
1384
1476
        return;
 
1477
    }
1385
1478
 
1386
1479
    // List albums using kioslave
1387
1480
 
1415
1508
    tmap.insert(0, d->rootTAlbum);
1416
1509
 
1417
1510
    AlbumIterator it(d->rootTAlbum);
 
1511
 
1418
1512
    while (it.current())
1419
1513
    {
1420
1514
        TAlbum* t = (TAlbum*)(*it);
1437
1531
        {
1438
1532
            TagInfo info  = *iter;
1439
1533
            TAlbum* album = new TAlbum(info.name, info.id);
 
1534
 
1440
1535
            if (info.icon.isNull())
1441
1536
            {
1442
1537
                // album image icon
1448
1543
                // system icon
1449
1544
                album->m_icon = info.icon;
1450
1545
            }
 
1546
 
1451
1547
            album->m_pid = info.pid;
1452
1548
            tagHash.insert(info.id, album);
1453
1549
        }
 
1550
 
1454
1551
        tList.clear();
1455
1552
 
1456
1553
        // also add root tag
1462
1559
             iter != tagHash.constEnd(); ++iter )
1463
1560
        {
1464
1561
            TAlbum* album = *iter;
 
1562
 
1465
1563
            if (album->m_id == 0)
 
1564
            {
1466
1565
                continue;
 
1566
            }
1467
1567
 
1468
1568
            TAlbum* parent = tagHash.value(album->m_pid);
 
1569
 
1469
1570
            if (parent)
1470
1571
            {
1471
1572
                album->setParent(parent);
1481
1582
 
1482
1583
        // now insert the items into the list. becomes sorted
1483
1584
        AlbumIterator it(rootTag);
 
1585
 
1484
1586
        while (it.current())
1485
1587
        {
1486
1588
            TagInfo info;
1487
1589
            TAlbum* album = static_cast<TAlbum*>(it.current());
 
1590
 
1488
1591
            if (album)
1489
1592
            {
1490
1593
                info.id   = album->m_id;
1492
1595
                info.name = album->m_title;
1493
1596
                info.icon = album->m_icon;
1494
1597
            }
 
1598
 
1495
1599
            tList.append(info);
1496
1600
            ++it;
1497
1601
        }
1506
1610
 
1507
1611
        // check if we have already added this tag
1508
1612
        if (tmap.contains(info.id))
 
1613
        {
1509
1614
            continue;
 
1615
        }
1510
1616
 
1511
1617
        // Its a new album. Find the parent of the album
1512
1618
        TagMap::iterator iter = tmap.find(info.pid);
 
1619
 
1513
1620
        if (iter == tmap.end())
1514
1621
        {
1515
1622
            kWarning() << "Failed to find parent tag for tag "
1571
1678
    QMap<int, SAlbum*> oldSearches;
1572
1679
 
1573
1680
    AlbumIterator it(d->rootSAlbum);
 
1681
 
1574
1682
    while (it.current())
1575
1683
    {
1576
1684
        SAlbum* search = (SAlbum*)(*it);
1588
1696
    {
1589
1697
        if (oldSearches.contains(info.id))
1590
1698
        {
1591
 
            SAlbum *album = oldSearches[info.id];
 
1699
            SAlbum* album = oldSearches[info.id];
 
1700
 
1592
1701
            if (info.name != album->title()
1593
1702
                || info.type != album->searchType()
1594
1703
                || info.query != album->query())
1597
1706
 
1598
1707
                album->setSearch(info.type, info.query);
1599
1708
                album->setTitle(info.name);
 
1709
 
1600
1710
                if (oldName != album->title())
 
1711
                {
1601
1712
                    emit signalAlbumRenamed(album);
 
1713
                }
 
1714
 
1602
1715
                emit signalSearchUpdated(album);
1603
1716
            }
1604
1717
 
1611
1724
    }
1612
1725
 
1613
1726
    // remove old albums that have been deleted
1614
 
    foreach (SAlbum *album, oldSearches)
 
1727
    foreach (SAlbum* album, oldSearches)
1615
1728
    {
1616
1729
        emit signalAlbumAboutToBeDeleted(album);
1617
1730
        d->allAlbumsIdHash.remove(album->globalID());
1661
1774
AlbumList AlbumManager::allPAlbums() const
1662
1775
{
1663
1776
    AlbumList list;
 
1777
 
1664
1778
    if (d->rootPAlbum)
1665
1779
    {
1666
1780
        list.append(d->rootPAlbum);
1667
1781
    }
1668
1782
 
1669
1783
    AlbumIterator it(d->rootPAlbum);
 
1784
 
1670
1785
    while (it.current())
1671
1786
    {
1672
1787
        list.append(*it);
1679
1794
AlbumList AlbumManager::allTAlbums() const
1680
1795
{
1681
1796
    AlbumList list;
 
1797
 
1682
1798
    if (d->rootTAlbum)
1683
1799
    {
1684
1800
        list.append(d->rootTAlbum);
1685
1801
    }
1686
1802
 
1687
1803
    AlbumIterator it(d->rootTAlbum);
 
1804
 
1688
1805
    while (it.current())
1689
1806
    {
1690
1807
        list.append(*it);
1697
1814
AlbumList AlbumManager::allSAlbums() const
1698
1815
{
1699
1816
    AlbumList list;
 
1817
 
1700
1818
    if (d->rootSAlbum)
1701
1819
    {
1702
1820
        list.append(d->rootSAlbum);
1703
1821
    }
1704
1822
 
1705
1823
    AlbumIterator it(d->rootSAlbum);
 
1824
 
1706
1825
    while (it.current())
1707
1826
    {
1708
1827
        list.append(*it);
1715
1834
AlbumList AlbumManager::allDAlbums() const
1716
1835
{
1717
1836
    AlbumList list;
 
1837
 
1718
1838
    if (d->rootDAlbum)
1719
1839
    {
1720
1840
        list.append(d->rootDAlbum);
1721
1841
    }
1722
1842
 
1723
1843
    AlbumIterator it(d->rootDAlbum);
 
1844
 
1724
1845
    while (it.current())
1725
1846
    {
1726
1847
        list.append(*it);
1730
1851
    return list;
1731
1852
}
1732
1853
 
1733
 
void AlbumManager::setCurrentAlbum(Album *album)
 
1854
void AlbumManager::setCurrentAlbum(Album* album)
1734
1855
{
1735
1856
    if (d->currentAlbum == album)
1736
1857
    {
1737
1858
        return;
1738
1859
    }
 
1860
 
1739
1861
    d->currentAlbum = album;
1740
1862
    emit signalAlbumCurrentChanged(album);
1741
1863
}
1758
1880
PAlbum* AlbumManager::findPAlbum(const KUrl& url) const
1759
1881
{
1760
1882
    CollectionLocation location = CollectionManager::instance()->locationForUrl(url);
 
1883
 
1761
1884
    if (location.isNull())
1762
1885
    {
1763
1886
        return 0;
1764
1887
    }
 
1888
 
1765
1889
    return d->albumPathHash.value(PAlbumPath(location.id(), CollectionManager::instance()->album(location, url)));
1766
1890
}
1767
1891
 
1823
1947
    // handle gracefully with or without leading slash
1824
1948
    bool withLeadingSlash = tagPath.startsWith('/');
1825
1949
    AlbumIterator it(d->rootTAlbum);
 
1950
 
1826
1951
    while (it.current())
1827
1952
    {
1828
 
        TAlbum *talbum = static_cast<TAlbum *>(*it);
 
1953
        TAlbum* talbum = static_cast<TAlbum*>(*it);
 
1954
 
1829
1955
        if (talbum->tagPath(withLeadingSlash) == tagPath)
1830
1956
        {
1831
1957
            return talbum;
1832
1958
        }
 
1959
 
1833
1960
        ++it;
1834
1961
    }
 
1962
 
1835
1963
    return 0;
1836
1964
 
1837
1965
}
1845
1973
            return dynamic_cast<SAlbum*>(album);
1846
1974
        }
1847
1975
    }
 
1976
 
1848
1977
    return 0;
1849
1978
}
1850
1979
 
1851
 
void AlbumManager::addGuardedPointer(Album *album, Album **pointer)
 
1980
void AlbumManager::addGuardedPointer(Album* album, Album** pointer)
1852
1981
{
1853
1982
    if (album)
1854
1983
    {
1856
1985
    }
1857
1986
}
1858
1987
 
1859
 
void AlbumManager::removeGuardedPointer(Album *album, Album **pointer)
 
1988
void AlbumManager::removeGuardedPointer(Album* album, Album** pointer)
1860
1989
{
1861
1990
    if (album)
1862
1991
    {
1864
1993
    }
1865
1994
}
1866
1995
 
1867
 
void AlbumManager::changeGuardedPointer(Album *oldAlbum, Album *album, Album **pointer)
 
1996
void AlbumManager::changeGuardedPointer(Album* oldAlbum, Album* album, Album** pointer)
1868
1997
{
1869
1998
    if (oldAlbum)
1870
1999
    {
1871
2000
        d->guardedPointers.remove(oldAlbum, pointer);
1872
2001
    }
 
2002
 
1873
2003
    if (album)
1874
2004
    {
1875
2005
        d->guardedPointers.insert(album, pointer);
1876
2006
    }
1877
2007
}
1878
2008
 
1879
 
void AlbumManager::invalidateGuardedPointers(Album *album)
 
2009
void AlbumManager::invalidateGuardedPointers(Album* album)
1880
2010
{
1881
2011
    if (!album)
1882
2012
    {
1884
2014
    }
1885
2015
 
1886
2016
    QMultiHash<Album*, Album**>::iterator it = d->guardedPointers.find(album);
1887
 
    for( ; it != d->guardedPointers.end() && it.key() == album; ++it)
 
2017
 
 
2018
    for ( ; it != d->guardedPointers.end() && it.key() == album; ++it)
1888
2019
    {
1889
2020
        if (it.value())
1890
2021
        {
1913
2044
        return 0;
1914
2045
    }
1915
2046
 
1916
 
    PAlbum *album = d->albumRootAlbumHash.value(location.id());
 
2047
    PAlbum* album = d->albumRootAlbumHash.value(location.id());
1917
2048
 
1918
2049
    if (!album)
1919
2050
    {
1961
2092
    int albumRootId   = parent->albumRootId();
1962
2093
 
1963
2094
    // first check if we have a sibling album with the same name
1964
 
    PAlbum *child = static_cast<PAlbum *>(parent->m_firstChild);
 
2095
    PAlbum* child = static_cast<PAlbum*>(parent->m_firstChild);
 
2096
 
1965
2097
    while (child)
1966
2098
    {
1967
2099
        if (child->albumRootId() == albumRootId && child->albumPath() == albumPath)
1969
2101
            errMsg = i18n("An existing album has the same name.");
1970
2102
            return 0;
1971
2103
        }
1972
 
        child = static_cast<PAlbum *>(child->m_next);
 
2104
 
 
2105
        child = static_cast<PAlbum*>(child->m_next);
1973
2106
    }
1974
2107
 
1975
2108
    DatabaseUrl url = parent->databaseUrl();
1992
2125
    }
1993
2126
 
1994
2127
    QString parentPath;
 
2128
 
1995
2129
    if (!parent->isAlbumRoot())
 
2130
    {
1996
2131
        parentPath = parent->albumPath();
 
2132
    }
1997
2133
 
1998
 
    PAlbum *album    = new PAlbum(albumRootId, parentPath, name, id);
 
2134
    PAlbum* album    = new PAlbum(albumRootId, parentPath, name, id);
1999
2135
    album->m_caption = caption;
2000
2136
    album->m_category  = category;
2001
2137
    album->m_date    = date;
2053
2189
    // we rename them directly. Faster.
2054
2190
    ScanController::instance()->suspendCollectionScan();
2055
2191
 
2056
 
    KIO::Job *job = KIO::rename(oldUrl, newUrl, KIO::HideProgressInfo);
 
2192
    KIO::Job* job = KIO::rename(oldUrl, newUrl, KIO::HideProgressInfo);
 
2193
 
2057
2194
    if (!KIO::NetAccess::synchronousRun(job, 0))
2058
2195
    {
2059
2196
        errMsg = i18n("Failed to rename Album");
2068
2205
 
2069
2206
        PAlbum* subAlbum = 0;
2070
2207
        AlbumIterator it(album);
 
2208
 
2071
2209
        while ((subAlbum = static_cast<PAlbum*>(it.current())) != 0)
2072
2210
        {
2073
2211
            subAlbum->m_parentPath = newAlbumPath + subAlbum->m_parentPath.mid(oldAlbumPath.length());
2090
2228
    d->albumPathHash.clear();
2091
2229
    AlbumIterator it(d->rootPAlbum);
2092
2230
    PAlbum* subAlbum = 0;
 
2231
 
2093
2232
    while ((subAlbum = static_cast<PAlbum*>(it.current())) != 0)
2094
2233
    {
2095
2234
        d->albumPathHash[subAlbum] = subAlbum;
2098
2237
 
2099
2238
}
2100
2239
 
2101
 
bool AlbumManager::updatePAlbumIcon(PAlbum *album, qlonglong iconID, QString& errMsg)
 
2240
bool AlbumManager::updatePAlbumIcon(PAlbum* album, qlonglong iconID, QString& errMsg)
2102
2241
{
2103
2242
    if (!album)
2104
2243
    {
2118
2257
        access.db()->setAlbumIcon(album->id(), iconID);
2119
2258
        QString iconRelativePath;
2120
2259
        int iconAlbumRootId;
 
2260
 
2121
2261
        if (access.db()->getAlbumIcon(album->id(), &iconAlbumRootId, &iconRelativePath))
2122
2262
        {
2123
2263
            QString albumRootPath = CollectionManager::instance()->albumRootPath(iconAlbumRootId);
2165
2305
 
2166
2306
    ChangingDB changing(d);
2167
2307
    int id = DatabaseAccess().db()->addTag(parent->id(), name, iconkde, 0);
 
2308
 
2168
2309
    if (id == -1)
2169
2310
    {
2170
2311
        errMsg = i18n("Failed to add tag to database");
2171
2312
        return 0;
2172
2313
    }
2173
2314
 
2174
 
    TAlbum *album = new TAlbum(name, id, false);
 
2315
    TAlbum* album = new TAlbum(name, id, false);
2175
2316
    album->m_icon = iconkde;
2176
2317
 
2177
2318
    insertTAlbum(album, parent);
2218
2359
 
2219
2360
        Album* subAlbum = 0;
2220
2361
        AlbumIterator it(album);
 
2362
 
2221
2363
        while ((subAlbum = it.current()) != 0)
2222
2364
        {
2223
2365
            access.db()->deleteTag(subAlbum->id());
2230
2372
    return true;
2231
2373
}
2232
2374
 
2233
 
bool AlbumManager::hasDirectChildAlbumWithTitle(Album *parent, const QString &title)
 
2375
bool AlbumManager::hasDirectChildAlbumWithTitle(Album* parent, const QString& title)
2234
2376
{
2235
2377
 
2236
 
    Album *sibling = parent->m_firstChild;
 
2378
    Album* sibling = parent->m_firstChild;
 
2379
 
2237
2380
    while (sibling)
2238
2381
    {
2239
2382
        if (sibling->title() == title)
2240
2383
        {
2241
2384
            return true;
2242
2385
        }
 
2386
 
2243
2387
        sibling = sibling->m_next;
2244
2388
    }
2245
2389
 
2284
2428
    return true;
2285
2429
}
2286
2430
 
2287
 
bool AlbumManager::moveTAlbum(TAlbum* album, TAlbum *newParent, QString& errMsg)
 
2431
bool AlbumManager::moveTAlbum(TAlbum* album, TAlbum* newParent, QString& errMsg)
2288
2432
{
2289
2433
    if (!album)
2290
2434
    {
2309
2453
    emit signalAlbumAboutToBeMoved(album);
2310
2454
 
2311
2455
    emit signalAlbumAboutToBeDeleted(album);
 
2456
 
2312
2457
    if (album->parent())
2313
2458
    {
2314
2459
        album->parent()->removeChild(album);
2315
2460
    }
 
2461
 
2316
2462
    album->setParent(0);
2317
2463
    emit signalAlbumDeleted(album);
2318
2464
    emit signalAlbumHasBeenDeleted(album);
2350
2496
        access.db()->setTagIcon(album->id(), iconKDE, iconID);
2351
2497
        QString albumRelativePath, iconKDE;
2352
2498
        int albumRootId;
 
2499
 
2353
2500
        if (access.db()->getTagIcon(album->id(), &albumRootId, &albumRelativePath, &iconKDE))
2354
2501
        {
2355
2502
            if (iconKDE.isEmpty())
2393
2540
 
2394
2541
    for (QList<int>::const_iterator it = tagIDs.constBegin(); it != tagIDs.constEnd(); ++it)
2395
2542
    {
2396
 
        TAlbum *album = findTAlbum(*it);
 
2543
        TAlbum* album = findTAlbum(*it);
 
2544
 
2397
2545
        if (album)
2398
2546
        {
2399
2547
            tagPaths.append(album->tagPath(leadingSlash));
2409
2557
 
2410
2558
    foreach(int id, tagIDs)
2411
2559
    {
2412
 
        TAlbum *album = findTAlbum(id);
 
2560
        TAlbum* album = findTAlbum(id);
 
2561
 
2413
2562
        if (album)
2414
2563
        {
2415
2564
            tagNames << album->title();
2423
2572
{
2424
2573
    QHash<int, QString> hash;
2425
2574
    AlbumIterator it(d->rootTAlbum);
 
2575
 
2426
2576
    while (it.current())
2427
2577
    {
2428
2578
        TAlbum* t = (TAlbum*)(*it);
2429
2579
        hash.insert(t->id(), t->tagPath(leadingSlash));
2430
2580
        ++it;
2431
2581
    }
 
2582
 
2432
2583
    return hash;
2433
2584
}
2434
2585
 
2436
2587
{
2437
2588
    QHash<int, QString> hash;
2438
2589
    AlbumIterator it(d->rootTAlbum);
 
2590
 
2439
2591
    while (it.current())
2440
2592
    {
2441
2593
        TAlbum* t = (TAlbum*)(*it);
2442
2594
        hash.insert(t->id(), t->title());
2443
2595
        ++it;
2444
2596
    }
 
2597
 
2445
2598
    return hash;
2446
2599
}
2447
2600
 
2449
2602
{
2450
2603
    QHash<int, QString> hash;
2451
2604
    AlbumIterator it(d->rootPAlbum);
 
2605
 
2452
2606
    while (it.current())
2453
2607
    {
2454
2608
        PAlbum* a = (PAlbum*)(*it);
2455
2609
        hash.insert(a->id(), a->title());
2456
2610
        ++it;
2457
2611
    }
 
2612
 
2458
2613
    return hash;
2459
2614
}
2460
2615
 
2462
2617
{
2463
2618
    // first iterate through all the search albums and see if there's an existing
2464
2619
    // SAlbum with same name. (Remember, SAlbums are arranged in a flat list)
2465
 
    SAlbum *album = findSAlbum(name);
 
2620
    SAlbum* album = findSAlbum(name);
2466
2621
    ChangingDB changing(d);
 
2622
 
2467
2623
    if (album)
2468
2624
    {
2469
2625
        album->setSearch(type, query);
2508
2664
 
2509
2665
    album->setSearch(newType, changedQuery);
2510
2666
    album->setTitle(newName);
 
2667
 
2511
2668
    if (oldName != album->title())
2512
2669
    {
2513
2670
        emit signalAlbumRenamed(album);
2551
2708
    return d->dAlbumsCount;
2552
2709
}
2553
2710
 
2554
 
bool AlbumManager::isMovingAlbum(Album *album) const
 
2711
bool AlbumManager::isMovingAlbum(Album* album) const
2555
2712
{
2556
2713
    return d->currentlyMovingAlbum == album;
2557
2714
}
2558
2715
 
2559
 
void AlbumManager::insertPAlbum(PAlbum *album, PAlbum *parent)
 
2716
void AlbumManager::insertPAlbum(PAlbum* album, PAlbum* parent)
2560
2717
{
2561
2718
    if (!album)
2562
2719
    {
2576
2733
    emit signalAlbumAdded(album);
2577
2734
}
2578
2735
 
2579
 
void AlbumManager::removePAlbum(PAlbum *album)
 
2736
void AlbumManager::removePAlbum(PAlbum* album)
2580
2737
{
2581
2738
    if (!album)
2582
2739
    {
2586
2743
    // remove all children of this album
2587
2744
    Album* child        = album->m_firstChild;
2588
2745
    PAlbum* toBeRemoved = 0;
 
2746
 
2589
2747
    while (child)
2590
2748
    {
2591
 
        Album *next = child->m_next;
 
2749
        Album* next = child->m_next;
2592
2750
        toBeRemoved = static_cast<PAlbum*>(child);
 
2751
 
2593
2752
        if (toBeRemoved)
2594
2753
        {
2595
2754
            removePAlbum(toBeRemoved);
2596
2755
            toBeRemoved = 0;
2597
2756
        }
 
2757
 
2598
2758
        child = next;
2599
2759
    }
2600
2760
 
2610
2770
        emit signalAlbumCurrentChanged(0);
2611
2771
    }
2612
2772
 
 
2773
    if (album->isAlbumRoot())
 
2774
    {
 
2775
        d->albumRootAlbumHash.remove(album->albumRootId());
 
2776
    }
 
2777
 
2613
2778
    emit signalAlbumDeleted(album);
2614
2779
    delete album;
2615
2780
    emit signalAlbumHasBeenDeleted(album);
2616
2781
}
2617
2782
 
2618
 
void AlbumManager::insertTAlbum(TAlbum *album, TAlbum *parent)
 
2783
void AlbumManager::insertTAlbum(TAlbum* album, TAlbum* parent)
2619
2784
{
2620
2785
    if (!album)
2621
2786
    {
2634
2799
    emit signalAlbumAdded(album);
2635
2800
}
2636
2801
 
2637
 
void AlbumManager::removeTAlbum(TAlbum *album)
 
2802
void AlbumManager::removeTAlbum(TAlbum* album)
2638
2803
{
2639
2804
    if (!album)
2640
2805
    {
2644
2809
    // remove all children of this album
2645
2810
    Album* child        = album->m_firstChild;
2646
2811
    TAlbum* toBeRemoved = 0;
 
2812
 
2647
2813
    while (child)
2648
2814
    {
2649
 
        Album *next = child->m_next;
 
2815
        Album* next = child->m_next;
2650
2816
        toBeRemoved = static_cast<TAlbum*>(child);
 
2817
 
2651
2818
        if (toBeRemoved)
2652
2819
        {
2653
2820
            removeTAlbum(toBeRemoved);
2654
2821
            toBeRemoved = 0;
2655
2822
        }
 
2823
 
2656
2824
        child = next;
2657
2825
    }
2658
2826
 
2670
2838
    emit signalAlbumHasBeenDeleted(album);
2671
2839
}
2672
2840
 
2673
 
void AlbumManager::notifyAlbumDeletion(Album *album)
 
2841
void AlbumManager::notifyAlbumDeletion(Album* album)
2674
2842
{
2675
2843
    invalidateGuardedPointers(album);
2676
2844
}
2754
2922
    QMap<int, DAlbum*>   yAlbumMap;
2755
2923
 
2756
2924
    AlbumIterator it(d->rootDAlbum);
 
2925
 
2757
2926
    while (it.current())
2758
2927
    {
2759
2928
        DAlbum* a = (DAlbum*)(*it);
 
2929
 
2760
2930
        if (a->range() == DAlbum::Month)
2761
2931
        {
2762
2932
            mAlbumMap.insert(a->date(), a);
2765
2935
        {
2766
2936
            yAlbumMap.insert(a->date().year(), a);
2767
2937
        }
 
2938
 
2768
2939
        ++it;
2769
2940
    }
2770
2941
 
2774
2945
    ds >> datesStatMap;
2775
2946
 
2776
2947
    QMap<YearMonth, int> yearMonthMap;
 
2948
 
2777
2949
    for (QMap<QDateTime, int>::const_iterator it = datesStatMap.constBegin(); it != datesStatMap.constEnd(); ++it)
2778
2950
    {
2779
2951
        YearMonth yearMonth = YearMonth(it.key().date().year(), it.key().date().month());
2780
2952
 
2781
2953
        QMap<YearMonth, int>::iterator it2 = yearMonthMap.find(yearMonth);
 
2954
 
2782
2955
        if ( it2 == yearMonthMap.end() )
2783
2956
        {
2784
2957
            yearMonthMap.insert( yearMonth, *it );
2790
2963
    }
2791
2964
 
2792
2965
    int year, month;
 
2966
 
2793
2967
    for (QMap<YearMonth, int>::const_iterator iter = yearMonthMap.constBegin();
2794
2968
         iter != yearMonthMap.constEnd(); ++iter)
2795
2969
    {
2814
2988
        }
2815
2989
 
2816
2990
        // Check if Year Album already exist.
2817
 
        DAlbum *yAlbum = 0;
 
2991
        DAlbum* yAlbum = 0;
2818
2992
        AlbumIterator it(d->rootDAlbum);
 
2993
 
2819
2994
        while (it.current())
2820
2995
        {
2821
2996
            DAlbum* a = (DAlbum*)(*it);
 
2997
 
2822
2998
            if (a->date() == QDate(year, 1, 1) && a->range() == DAlbum::Year)
2823
2999
            {
2824
3000
                yAlbum = a;
2825
3001
                break;
2826
3002
            }
 
3003
 
2827
3004
            ++it;
2828
3005
        }
2829
3006
 
2838
3015
        }
2839
3016
 
2840
3017
        // Create Month album
2841
 
        DAlbum *mAlbum = new DAlbum(md);
 
3018
        DAlbum* mAlbum = new DAlbum(md);
2842
3019
        emit signalAlbumAboutToBeAdded(mAlbum, yAlbum, yAlbum->lastChild());
2843
3020
        mAlbum->setParent(yAlbum);
2844
3021
        d->allAlbumsIdHash.insert(mAlbum->globalID(), mAlbum);
2881
3058
        return;
2882
3059
    }
2883
3060
 
2884
 
    switch(changeset.operation())
 
3061
    switch (changeset.operation())
2885
3062
    {
2886
3063
        case AlbumChangeset::Added:
2887
3064
        case AlbumChangeset::Deleted:
 
3065
 
2888
3066
            if (!d->scanPAlbumsTimer->isActive())
2889
3067
            {
2890
3068
                d->scanPAlbumsTimer->start();
2891
3069
            }
 
3070
 
2892
3071
            break;
2893
3072
        case AlbumChangeset::Renamed:
2894
3073
        case AlbumChangeset::PropertiesChanged:
2895
3074
            // mark for rescan
2896
3075
            d->changedPAlbums << changeset.albumId();
 
3076
 
2897
3077
            if (!d->updatePAlbumsTimer->isActive())
2898
3078
            {
2899
3079
                d->updatePAlbumsTimer->start();
2900
3080
            }
 
3081
 
2901
3082
            break;
2902
3083
        case AlbumChangeset::Unknown:
2903
3084
            break;
2911
3092
        return;
2912
3093
    }
2913
3094
 
2914
 
    switch(changeset.operation())
 
3095
    switch (changeset.operation())
2915
3096
    {
2916
3097
        case TagChangeset::Added:
2917
3098
        case TagChangeset::Deleted:
2918
3099
        case TagChangeset::Reparented:
 
3100
 
2919
3101
            if (!d->scanTAlbumsTimer->isActive())
2920
3102
            {
2921
3103
                d->scanTAlbumsTimer->start();
2922
3104
            }
 
3105
 
2923
3106
            break;
2924
3107
        case TagChangeset::Renamed:
2925
3108
        case TagChangeset::IconChanged:
2939
3122
        return;
2940
3123
    }
2941
3124
 
2942
 
    switch(changeset.operation())
 
3125
    switch (changeset.operation())
2943
3126
    {
2944
3127
        case SearchChangeset::Added:
2945
3128
        case SearchChangeset::Deleted:
 
3129
 
2946
3130
            if (!d->scanSAlbumsTimer->isActive())
2947
3131
            {
2948
3132
                d->scanSAlbumsTimer->start();
2949
3133
            }
 
3134
 
2950
3135
            break;
2951
3136
        case SearchChangeset::Changed:
2952
3137
            break;
2958
3143
void AlbumManager::slotCollectionImageChange(const CollectionImageChangeset& changeset)
2959
3144
{
2960
3145
    if (!d->rootDAlbum)
 
3146
    {
2961
3147
        return;
 
3148
    }
2962
3149
 
2963
3150
    switch (changeset.operation())
2964
3151
    {
2965
3152
        case CollectionImageChangeset::Added:
2966
3153
        case CollectionImageChangeset::Removed:
2967
3154
        case CollectionImageChangeset::RemovedAll:
 
3155
 
2968
3156
            if (!d->scanDAlbumsTimer->isActive())
2969
3157
            {
2970
3158
                d->scanDAlbumsTimer->start();
2971
3159
            }
 
3160
 
2972
3161
            if (!d->albumItemCountTimer->isActive())
2973
3162
            {
2974
3163
                d->albumItemCountTimer->start();
2975
3164
            }
 
3165
 
2976
3166
            break;
2977
3167
        default:
2978
3168
            break;
2985
3175
    {
2986
3176
        return;
2987
3177
    }
 
3178
 
2988
3179
    switch (changeset.operation())
2989
3180
    {
2990
3181
        case ImageTagChangeset::Added:
2991
3182
        case ImageTagChangeset::Removed:
2992
3183
        case ImageTagChangeset::RemovedAll:
 
3184
 
2993
3185
            if (!d->tagItemCountTimer->isActive())
2994
3186
            {
2995
3187
                d->tagItemCountTimer->start();
2996
3188
            }
 
3189
 
2997
3190
            break;
2998
3191
        default:
2999
3192
            break;
3009
3202
void AlbumManager::slotDirWatchDirty(const QString& path)
3010
3203
{
3011
3204
    // Filter out dirty signals triggered by changes on the database file
3012
 
    foreach (const QString &bannedFile, d->dirWatchBlackList)
 
3205
    foreach (const QString& bannedFile, d->dirWatchBlackList)
3013
3206
    {
3014
3207
        if (path.endsWith(bannedFile))
3015
3208
        {
3018
3211
    }
3019
3212
 
3020
3213
    DatabaseParameters params = DatabaseAccess::parameters();
 
3214
 
3021
3215
    if (params.isSQLite())
3022
3216
    {
3023
3217
        QFileInfo info(path);
3024
3218
        QDir dir;
 
3219
 
3025
3220
        if (info.isDir())
3026
3221
        {
3027
3222
            dir = QDir(path);
3030
3225
        {
3031
3226
            dir = info.dir();
3032
3227
        }
 
3228
 
3033
3229
        QFileInfo dbFile(params.SQLiteDatabaseFile());
3034
3230
 
3035
3231
        // Workaround for broken KDirWatch in KDE 4.2.4
3089
3285
    if (url.isLocalFile())
3090
3286
    {
3091
3287
        QString path = url.directory();
 
3288
 
3092
3289
        //kDebug() << path << !CollectionManager::instance()->albumRootPath(path).isEmpty();
3093
3290
        // check path is in our collection
3094
3291
        if (CollectionManager::instance()->albumRootPath(path).isNull())
3103
3300
    else
3104
3301
    {
3105
3302
        DatabaseUrl dbUrl(url);
 
3303
 
3106
3304
        if (dbUrl.isAlbumUrl())
3107
3305
        {
3108
3306
            QString path = dbUrl.fileUrl().directory();