filehandle.cpp 5.07 KB
Newer Older
1 2
/**
 * Copyright (C) 2004 Scott Wheeler <wheeler@kde.org>
3
 * Copyright (C) 2017 Michael Pyne  <mpyne@kde.org>
4 5 6 7 8 9 10 11 12 13 14 15 16
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */
17

18
#include "filehandle.h"
19

20
#include <QFileInfo>
21
#include <QSharedData>
22
#include <QScopedPointer>
23

24
#include "filehandleproperties.h"
25
#include "tag.h"
26
#include "cache.h"
27
#include "coverinfo.h"
Michael Pyne's avatar
Michael Pyne committed
28
#include "juk_debug.h"
29

Dirk Mueller's avatar
Dirk Mueller committed
30 31 32 33 34 35 36 37 38 39 40
AddProperty(Title, tag()->title())
AddProperty(Artist, tag()->artist())
AddProperty(Album, tag()->album())
AddProperty(Genre, tag()->genre())
AddNumberProperty(Track, tag()->track())
AddNumberProperty(Year, tag()->year())
AddProperty(Comment, tag()->comment())
AddNumberProperty(Seconds, tag()->seconds())
AddNumberProperty(Bitrate, tag()->bitrate())
AddProperty(Path, absFilePath())
AddNumberProperty(Size, fileInfo().size())
41
AddProperty(Extension, fileInfo().suffix())
42

43
class FileHandle::FileHandlePrivate : public QSharedData
44 45
{
public:
46 47 48 49 50 51 52 53
    FileHandlePrivate(QFileInfo fInfo)
        : tag(nullptr)
        , coverInfo(nullptr)
        , fileInfo(fInfo)
        , absFilePath(fInfo.canonicalFilePath())
    {
        baseModificationTime = fileInfo.lastModified();
    }
54

55 56
    mutable QScopedPointer<Tag> tag;
    mutable QScopedPointer<CoverInfo> coverInfo;
57
    QFileInfo fileInfo;
58 59
    QString absFilePath;
    QDateTime baseModificationTime;
60
    QDateTime lastModified;
61 62 63 64 65 66
};

////////////////////////////////////////////////////////////////////////////////
// public methods
////////////////////////////////////////////////////////////////////////////////

67 68
FileHandle::FileHandle(const FileHandle &f) :
    d(f.d)
69 70 71
{
}

72 73
FileHandle::FileHandle(const QFileInfo &info) :
    d(new FileHandlePrivate(info))
74
{
75 76 77 78 79
}

FileHandle::FileHandle()
    : FileHandle(QFileInfo()) // delegating ctor
{
80 81
}

82 83
FileHandle::FileHandle(const QString &path)
    : FileHandle(QFileInfo(path)) // delegating ctor
84 85 86
{
}

87
FileHandle::FileHandle(const QString &path, CacheDataStream &s)
88
    : FileHandle(QFileInfo(path)) // delegating ctor
89
{
90 91
    if(d->fileInfo.exists())
        read(s);
92 93
}

94
FileHandle::~FileHandle() = default;
95

96 97 98
void FileHandle::refresh()
{
    d->fileInfo.refresh();
99
    d->tag.reset(new Tag(d->absFilePath));
100 101
}

102 103
void FileHandle::setFile(const QString &path)
{
104
    if(path.isEmpty()) {
105
        qCCritical(JUK_LOG) << "trying to set an empty path";
106 107 108 109
        return;
    }

    if(!QFile::exists(path)) {
110
        qCCritical(JUK_LOG) << "trying to set non-existent file: " << path;
111 112 113
        return;
    }

114
    d = new FileHandlePrivate(QFileInfo(path));
115 116
}

117 118
Tag *FileHandle::tag() const
{
119
    if(Q_UNLIKELY(!d->tag))
120
        d->tag.reset(new Tag(d->absFilePath));
121

122
    return d->tag.data();
123 124
}

125 126
CoverInfo *FileHandle::coverInfo() const
{
127
    if(Q_UNLIKELY(!d->coverInfo))
128
        d->coverInfo.reset(new CoverInfo(*this));
129

130
    return d->coverInfo.data();
131 132
}

133 134 135 136 137 138 139 140 141 142
QString FileHandle::absFilePath() const
{
    return d->absFilePath;
}

const QFileInfo &FileHandle::fileInfo() const
{
    return d->fileInfo;
}

143 144
bool FileHandle::isNull() const
{
145
    return d->absFilePath.isEmpty();
146 147
}

148 149
bool FileHandle::current() const
{
150
    return (d->baseModificationTime.isValid() &&
151
            lastModified().isValid() &&
152
            d->baseModificationTime >= lastModified());
153 154 155 156
}

const QDateTime &FileHandle::lastModified() const
{
157 158 159 160 161 162 163 164 165 166 167 168
    if(d->lastModified.isNull())
        d->lastModified = d->fileInfo.lastModified();

    return d->lastModified;
}

void FileHandle::read(CacheDataStream &s)
{
    switch(s.cacheVersion()) {
    case 1:
    default:
        if(!d->tag)
169
            d->tag.reset(new Tag(d->absFilePath, true));
170

171
        s >> *(d->tag);
172
        s >> d->baseModificationTime;
173 174
        break;
    }
175 176
}

177 178
FileHandle &FileHandle::operator=(const FileHandle &f)
{
179 180
    if(&f != this)
        d = f.d;
181 182 183 184 185 186 187 188

    return *this;
}

bool FileHandle::operator==(const FileHandle &f) const
{
    return d == f.d;
}
189 190 191 192 193 194

bool FileHandle::operator!=(const FileHandle &f) const
{
    return d != f.d;
}

195 196 197 198 199 200 201
QStringList FileHandle::properties() // static
{
    return FileHandleProperties::properties();
}

QString FileHandle::property(const QString &name) const
{
Michael Pyne's avatar
Michael Pyne committed
202
    return FileHandleProperties::property(*this, name.toUtf8());
203 204
}

205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
////////////////////////////////////////////////////////////////////////////////
// related functions
////////////////////////////////////////////////////////////////////////////////

QDataStream &operator<<(QDataStream &s, const FileHandle &f)
{
    s << *(f.tag())
      << f.lastModified();

    return s;
}

CacheDataStream &operator>>(CacheDataStream &s, FileHandle &f)
{
    f.read(s);
    return s;
}
222 223

// vim: set et sw=4 tw=0 sta: