summaryrefslogtreecommitdiffstats
path: root/archivemodel.h
blob: 06861d937a4fd58bf32c5d74d419d3d5d45204f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version
  2 of the License, or (at your option) any later version.
*/

#ifndef ARCHIVEMODEL_H
#define ARCHIVEMODEL_H

#include <QSqlDatabase>
#include <QThread>
#include <QDataStream>
#include <QMutex>
#include <QSet>
#include <QStringListModel>

#include "smtreemodel.h"

class ArchiveCollector;

class ArchiveModel : public SmTreeModel {
    Q_OBJECT
    public:
        enum CustomRoles { NameRole = Qt::UserRole + 1, GenericIdRole = Qt::UserRole + 2, SeriesPartIdRole = Qt::UserRole + 3, SeriesPartRole = Qt::UserRole + 4, TypeRole = Qt::UserRole + 5, FavoriteRole = Qt::UserRole + 6, SubtitleRole = Qt::UserRole + 7, CountRole = Qt::UserRole + 8 };
        enum Fields { Name = 0, GenericId = 1, SeriesPartId = 2, SeriesPart = 3, Type = 4, Favorite = 5, Subtitle = 6, Count = 7 };
        enum MetadataFields { ReleaseYear = 0, Source = 1, Subject = 2, ReleaseGroup = 3, EncoderOpts = 4, Comment = 5, Passes = 6, Added = 7 };
        enum { MetadataNumFields = 8 };
        enum Order { SeriesName, Actor, Genre, Local, FavoriteOrder, NoOrder };
        enum { NumFields = 8 };
        enum NodeType { SeriesNode = 1, SeriesPartNode = 2, GenreNode = 4, ActorNode = 8, AllNodes = 15 };
        explicit ArchiveModel(const QStringList &headers, QObject *parent = 0);
        virtual ~ArchiveModel();
        virtual Qt::ItemFlags flags(const QModelIndex &index) const;
        virtual Qt::DropActions supportedDragActions() const;
        const QStringList availableOrders() const;
        const QHash<QString, int> availableOrdersHash() const { return mAvailableOrders; }
        virtual QVariant data(const QModelIndex &index, int role) const;
        virtual bool setData(const QModelIndex &idx, const QVariant &value, int role);
        virtual bool removeNode(const QModelIndex &idx);
        QStringList indexToPath(const QModelIndex &idx) const;
        QModelIndexList pathToIndex(const QStringList &path) const;
        QSet<int> seriesPartIds(const QModelIndex &idx) const;
        QStringList actors(const QSet<int> &partIds) const;
        QStringList allActors() const;
        void setActors(int partId, const QStringList &actors);
        QStringList genres(const QSet<int> &genreIds) const;
        QStringList allGenres() const;
        void setGenres(int partId, const QStringList &genres);
        QString metadata(int partId) const;
        QList<QVariant> metadataList(int partId) const;
        void setMetadata(int partId, const QList<QVariant> &data);
        QStringList allSources() const;
        QStringList allReleaseGroups() const;
        bool setPartNo(int partId, int newPartId, const QString &subtitle);
        bool setFavorite(int partId, bool favorite);
        void addFiles(int partId, const QStringList files);
        bool deleteSeriesPart(int partId);
        bool addSeriesPart(int partno, QString subtitle, const QModelIndex &parent);

    signals:
        void needRefresh();
        void databaseError(const QString &error);
        void message(const QString &msg);
        void windowTitle(const QString &title);

    public slots:
        void setOrder(int order);
        void setOrder(const QString &order);
        void refresh();
        void readConfig();
        void setWindowTitle();

    private slots:
        void collectorFinished(QObject *thread);

    private:
        void emitDatabaseError(const QSqlError &e);
        void writeCache(int o, SmTreeItem *rItem);
        void writeRecursive(SmTreeItem *start, QDataStream &stream);
        void writeItem(SmTreeItem *item, QDataStream &stream);
        SmTreeItem *readCache(int o);
        SmTreeItem *readItem(QDataStream &stream) const;
        const QString cacheFile(int o) const;
        QSqlDatabase mDb;
        QHash<QString, int> mAvailableOrders;
        QList<ArchiveCollector*> mCollectors;
        QHash<int, QIcon> mNodeIcons;
        QMutex mCacheMx;
        QMutex mRootAccessMx;
        int mOrder;
};

class ArchiveFilesModel : public SmTreeModel {
    Q_OBJECT
    public:
        enum CustomRoles { ExpansionRole = Qt::UserRole + 1, SeriesPartIdRole = Qt::UserRole + 2, FilenameRole = Qt::UserRole + 3, Md5SumRole = Qt::UserRole + 4, SizeRole = Qt::UserRole + 5, DvdNoRole = Qt::UserRole + 6, FileTypeRole = Qt::UserRole + 7, FileNumberRole = Qt::UserRole + 8, QualityRole = Qt::UserRole + 9, FileIdRole = Qt::UserRole + 10, SizeDurRole = Qt::UserRole + 11, FullPathRole = Qt::UserRole + 12 };
        enum Fields { Expansion = 0, SeriesPartId = 1, Filename = 2, Md5Sum = 3, Size = 4, DvdNo = 5, FileType = 6, FileNumber = 7, Quality = 8, FileId = 9, SizeDur = 10, FullPath = 11 };
        enum { NumFields = 12 };
        explicit ArchiveFilesModel(const QStringList &headers, QObject *parent = 0);
        virtual QVariant data(const QModelIndex &index, int role) const;
        virtual bool setData(const QModelIndex &idx, const QVariant &value, int role);
        virtual Qt::ItemFlags flags(const QModelIndex &index) const;
        int nextDvd() const;
        bool isMovie(const QModelIndex &idx) const;
        void populate(const QSet<int> &seriesPartIds);
        QStringList filesForSeriespart(int seriesPartId) const;
        void updateSeriesPartForFile(const QString &md5sum, int newSeriesPart);

    public slots:
        void refresh();
        void readConfig();

    private:
        QSet<int> mSeriesPartIds;
        QHash<int, QString> mRoleDbColumnMap;
        QSqlDatabase mDb;
};

class ArchiveCollector : public QThread {
    Q_OBJECT
    public:
        explicit ArchiveCollector(int numFields, int order, QObject *parent = 0);
        SmTreeItem *rootItem();
        int sortOrder() const { return mSortOrder; }
        void setCancelled(bool cancel);
        bool isCancelled() const { return mCancelled; }

    signals:
        void message(const QString message);

    protected:
        virtual void run();

    private:
        SmTreeItem *copyRecursive(SmTreeItem *item, SmTreeItem *parent);
        void populateBySeriesName();
        void populateByGenre();
        void populateByActor();
        void populateByLocal();
        void populateByFavorite();
        void fetchChildren(SmTreeItem *parent);
        void fetchSeries(const QVariant &id, SmTreeItem *parent);
        void fetchParts(const QVariant &id, SmTreeItem *parent);
        bool checkCancelled();
        QSqlDatabase mDb;
        SmTreeItem *mRootItem;
        QMutex mAccessMx;
        QMutex mCancelledMx;
        int mNumFields;
        int mSortOrder;
        bool mCancelled;
};

#endif // ARCHIVEMODEL_H