~daggerstab/stellarium/add-remove-landscapes

« back to all changes in this revision

Viewing changes to src/core/modules/LandscapeMgr.cpp

  • Committer: Bogdan Marinov
  • Date: 2010-09-05 12:28:04 UTC
  • Revision ID: bogdan.marinov84@gmail.com-20100905122804-y935vv39g4k8vibd
merged the AddRemoveLandscapes plug-in into LandscapeMgr and ViewDialog; added some minor features and bug fixes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Stellarium
3
3
 * Copyright (C) 2006 Fabien Chereau
 
4
 * Copyright (C) 2010 Bogdan Marinov (add/remove landscapes feature)
4
5
 *
5
6
 * This program is free software; you can redistribute it and/or
6
7
 * modify it under the terms of the GNU General Public License
20
21
#include <QDebug>
21
22
#include <QSettings>
22
23
#include <QString>
 
24
#include <QDir>
 
25
#include <QFile>
 
26
#include <QTemporaryFile>
23
27
 
24
28
#ifdef USE_OPENGL_ES2
25
29
 #include "GLES2/gl2.h"
27
31
 #include <QtOpenGL>
28
32
#endif
29
33
 
 
34
#include <stdexcept>
 
35
 
30
36
#include "LandscapeMgr.hpp"
31
37
#include "Landscape.hpp"
32
38
#include "Atmosphere.hpp"
40
46
#include "StelIniParser.hpp"
41
47
#include "StelSkyDrawer.hpp"
42
48
#include "StelPainter.hpp"
 
49
#include "karchive.h"
 
50
#include "kzip.h"
43
51
 
44
52
// Class which manages the cardinal points displaying
45
53
class Cardinals
604
612
}
605
613
 
606
614
 
 
615
QString LandscapeMgr::installLandscapeFromArchive(QString sourceFilePath, bool display, bool toMainDirectory)
 
616
{
 
617
        if (!QFile::exists(sourceFilePath))
 
618
        {
 
619
                qDebug() << "LandscapeMgr: File does not exist:" << sourceFilePath;
 
620
                return QString();
 
621
        }
 
622
 
 
623
        QDir parentDestinationDir;
 
624
        //TODO: Fix the "for all users" option
 
625
        parentDestinationDir.setPath(StelFileMgr::getUserDir());
 
626
 
 
627
        if (!parentDestinationDir.exists("landscapes"))
 
628
        {
 
629
                //qDebug() << "LandscapeMgr: No 'landscapes' subdirectory exists in" << parentDestinationDir.absolutePath();
 
630
                if (!parentDestinationDir.mkdir("landscapes"))
 
631
                {
 
632
                        qWarning() << "LandscapeMgr: Unable to install landscape: Unable to create sub-directory 'landscapes' in" << parentDestinationDir.absolutePath();
 
633
                        return QString();
 
634
                }
 
635
        }
 
636
        QDir destinationDir (parentDestinationDir.absoluteFilePath("landscapes"));
 
637
 
 
638
        KZip sourceArchive(sourceFilePath);
 
639
        if(!sourceArchive.open(QIODevice::ReadOnly))
 
640
        {
 
641
                qWarning() << "LandscapeMgr: Unable to open source archive file:" << sourceFilePath;
 
642
                return QString();
 
643
        }
 
644
 
 
645
        //Detect top directory
 
646
        const KArchiveDirectory * archiveTopDirectory = NULL;
 
647
        QStringList topLevelContents = sourceArchive.directory()->entries();
 
648
        foreach (QString entryPath, topLevelContents)
 
649
        {
 
650
                if (sourceArchive.directory()->entry(entryPath)->isDirectory())
 
651
                {
 
652
                        if((dynamic_cast<const KArchiveDirectory*>(sourceArchive.directory()->entry(entryPath)))->entries().contains("landscape.ini"))
 
653
                        {
 
654
                                archiveTopDirectory = dynamic_cast<const KArchiveDirectory*>(sourceArchive.directory()->entry(entryPath));
 
655
                                break;
 
656
                        }
 
657
                }
 
658
        }
 
659
        if (archiveTopDirectory == NULL)
 
660
        {
 
661
                qWarning() << "LandscapeMgr: Unable to install landscape. There is no directory that contains a 'landscape.ini' file in the source archive.";
 
662
                return QString();
 
663
        }
 
664
 
 
665
        /*
 
666
        qDebug() << "LandscapeMgr: Contents of the source archive:" << endl
 
667
                         << "- top level direcotory:" << archiveTopDirectory->name() << endl
 
668
                         << "- contents:" << archiveTopDirectory->entries();
 
669
        */
 
670
 
 
671
        //Check if the top directory name is unique
 
672
        //TODO: Prompt rename? Rename silently?
 
673
        /*
 
674
        if (destinationDir.exists(archiveTopDirectory->name()))
 
675
        {
 
676
                qWarning() << "LandscapeMgr: Unable to install landscape. A directory named" << archiveTopDirectory->name() << "already exists in" << destinationDir.absolutePath();
 
677
                return QString();
 
678
        }
 
679
        */
 
680
        QString landscapeID = archiveTopDirectory->name();
 
681
        if (getAllLandscapeIDs().contains(landscapeID))
 
682
        {
 
683
                qWarning() << "LandscapeMgr: Unable to install landscape. A directory named" << landscapeID << "already exists.";
 
684
                return QString();
 
685
        }
 
686
 
 
687
        //Read the .ini file and check if the landscape name is unique
 
688
        QTemporaryFile tempLandscapeIni("landscapeXXXXXX.ini");
 
689
        if (tempLandscapeIni.open())
 
690
        {
 
691
                const KZipFileEntry * archLandscapeIni = static_cast<const KZipFileEntry*>(archiveTopDirectory->entry("landscape.ini"));
 
692
                tempLandscapeIni.write(archLandscapeIni->createDevice()->readAll());
 
693
                tempLandscapeIni.close();
 
694
 
 
695
                QSettings confLandscapeIni(tempLandscapeIni.fileName(), StelIniFormat);
 
696
                QString landscapeName = confLandscapeIni.value("landscape/name").toString();
 
697
                if (getAllLandscapeNames().contains(landscapeName))
 
698
                {
 
699
                        qWarning() << "LandscapeMgr: Unable to install landscape. There is already a landscape named" << landscapeName;
 
700
                        return QString();
 
701
                }
 
702
        }
 
703
 
 
704
        //Copy the landscape directory to the target
 
705
        //sourceArchive.directory()->copyTo(destinationDir.absolutePath());
 
706
        if(!destinationDir.mkdir(landscapeID))
 
707
        {
 
708
                qWarning() << "LandscapeMgr: Unable to install landscape. Unable to create" << landscapeID << "directory in" << destinationDir.absolutePath();
 
709
                return QString();
 
710
        }
 
711
        destinationDir.cd(landscapeID);
 
712
        QString destinationDirPath = destinationDir.absolutePath();
 
713
        QStringList landscapeFileEntries = archiveTopDirectory->entries();
 
714
        foreach (QString entry, landscapeFileEntries)
 
715
        {
 
716
                const KArchiveEntry * archEntry = archiveTopDirectory->entry(entry);
 
717
                if(archEntry->isFile())
 
718
                {
 
719
                        static_cast<const KZipFileEntry*>(archEntry)->copyTo(destinationDirPath);
 
720
                }
 
721
        }
 
722
 
 
723
        sourceArchive.close();
 
724
 
 
725
        //If necessary, make the new landscape the current landscape
 
726
        if (display)
 
727
        {
 
728
                setCurrentLandscapeID(landscapeID);
 
729
        }
 
730
 
 
731
        //Make sure that everyone knows that the list of available landscapes has changed
 
732
        emit landscapesChanged();
 
733
 
 
734
        qDebug() << "LandscapeMgr: Successfully installed landscape directory" << landscapeID << "to" << destinationDir.absolutePath();
 
735
        return landscapeID;
 
736
}
 
737
 
 
738
bool LandscapeMgr::removeLandscape(QString landscapeID)
 
739
{
 
740
        if (landscapeID.isEmpty())
 
741
        {
 
742
                qWarning() << "LandscapeMgr: Error! No landscape ID passed to removeLandscape().";
 
743
                return false;
 
744
        }
 
745
 
 
746
        qDebug() << "LandscapeMgr: Trying to remove landscape" << landscapeID;
 
747
 
 
748
        QString landscapePath = getLandscapePath(landscapeID);
 
749
        if (landscapePath.isEmpty())
 
750
                return false;
 
751
 
 
752
        QDir landscapeDir(landscapePath);
 
753
        foreach (QString fileName, landscapeDir.entryList(QDir::Files | QDir::NoDotAndDotDot))
 
754
        {
 
755
                if(!landscapeDir.remove(fileName))
 
756
                {
 
757
                        qDebug() << "LandscapeMgr: Unable to remove" << fileName;
 
758
                        return false;
 
759
                }
 
760
        }
 
761
        landscapeDir.cdUp();
 
762
        if(!landscapeDir.rmdir(landscapeID))
 
763
        {
 
764
                qWarning() << "LandscapeMgr: Error! Landscape" << landscapeID << "could not be removed. Some files were deleted, but not all.";
 
765
                return false;
 
766
        }
 
767
 
 
768
        qDebug() << "LandscapeMgr: Successfully removed" << landscapePath;
 
769
 
 
770
        //If the landscape has been selected, revert to the default one
 
771
        //TODO: Make this optional?
 
772
        if (getCurrentLandscapeID() == landscapeID)
 
773
        {
 
774
                if(getDefaultLandscapeID() == landscapeID)
 
775
                {
 
776
                        setDefaultLandscapeID("guereins");
 
777
                        //TODO: Find what happens if a missing landscape is specified in the configuration file
 
778
                        //TODO: Think of a way to specify centrally a default default landscape
 
779
                }
 
780
 
 
781
                setCurrentLandscapeID(getDefaultLandscapeID());
 
782
        }
 
783
 
 
784
        //Make sure that everyone knows that the list of available landscapes has changed
 
785
        emit landscapesChanged();
 
786
 
 
787
        return true;
 
788
}
 
789
 
 
790
QString LandscapeMgr::getLandscapePath(QString landscapeID)
 
791
{
 
792
        QString result;
 
793
        //Is this necessary? This function is private.
 
794
        if (landscapeID.isEmpty())
 
795
                return result;
 
796
 
 
797
        try
 
798
        {
 
799
                result = StelFileMgr::findFile("landscapes/" + landscapeID, StelFileMgr::Directory);
 
800
        }
 
801
        catch (std::runtime_error &e)
 
802
        {
 
803
                qWarning() << "LandscapeMgr: Error! Unable to find" << landscapeID << ":" << e.what();
 
804
                return result;
 
805
        }
 
806
 
 
807
        return result;
 
808
}
 
809
 
 
810
QString LandscapeMgr::loadLandscapeName(QString landscapeID)
 
811
{
 
812
        QString landscapeName;
 
813
        if (landscapeID.isEmpty())
 
814
        {
 
815
                qWarning() << "LandscapeMgr: Error! No landscape ID passed to loadLandscapeName().";
 
816
                return landscapeName;
 
817
        }
 
818
 
 
819
        QString landscapePath = getLandscapePath(landscapeID);
 
820
        if (landscapePath.isEmpty())
 
821
                return landscapeName;
 
822
 
 
823
        QDir landscapeDir(landscapePath);
 
824
        if (landscapeDir.exists("landscape.ini"))
 
825
        {
 
826
                QString landscapeSettingsPath = landscapeDir.filePath("landscape.ini");
 
827
                QSettings landscapeSettings(landscapeSettingsPath, StelIniFormat);
 
828
                landscapeName = landscapeSettings.value("landscape/name").toString();
 
829
        }
 
830
        else
 
831
        {
 
832
                qWarning() << "LandscapeMgr: Error! Landscape directory" << landscapePath << "does not contain a 'landscape.ini' file";
 
833
        }
 
834
 
 
835
        return landscapeName;
 
836
}
 
837
 
 
838
quint64 LandscapeMgr::loadLandscapeSize(QString landscapeID)
 
839
{
 
840
        quint64 landscapeSize = 0;
 
841
        if (landscapeID.isEmpty())
 
842
        {
 
843
                qWarning() << "LandscapeMgr: Error! No landscape ID passed to loadLandscapeSize().";
 
844
                return landscapeSize;
 
845
        }
 
846
 
 
847
        QString landscapePath = getLandscapePath(landscapeID);
 
848
        if (landscapePath.isEmpty())
 
849
                return landscapeSize;
 
850
 
 
851
        QDir landscapeDir(landscapePath);
 
852
        foreach (QFileInfo file, landscapeDir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot))
 
853
        {
 
854
                //qDebug() << "name:" << file.baseName() << "size:" << file.size();
 
855
                landscapeSize += file.size();
 
856
        }
 
857
 
 
858
        return landscapeSize;
 
859
}