filerenamer.cpp 4.42 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * filerenamer.cpp - (c) 2003 Frerich Raabe <raabe@kde.org>
 *
 * 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.
 */
#include "filerenamer.h"
#include "playlistitem.h"

#include <kapplication.h>
#include <kconfig.h>
Scott Wheeler's avatar
build  
Scott Wheeler committed
14
#include <kdebug.h>
15
#include <kmacroexpander.h>
16 17 18

#include <qdir.h>

19 20
FileRenamer::Config::Config(KConfigBase *cfg)
    : m_grp(cfg, "FileRenamer")
21 22 23
{
}

24
QString FileRenamer::Config::filenameScheme() const
25
{
26
    return m_grp.readEntry("FilenameScheme");
27 28
}

29
void FileRenamer::Config::setFilenameScheme(const QString &scheme)
30
{
31
    m_grp.writeEntry("FilenameScheme", scheme);
32 33
}

34
QString FileRenamer::Config::getToken(TokenType type) const
35
{
36 37
    return m_grp.readEntry(tokenToString(type) + "Token");
}
38

39 40 41 42
void FileRenamer::Config::setToken(TokenType type, const QString &value)
{
    m_grp.writeEntry(tokenToString(type) + "Token", value);
}
43

44 45 46
bool FileRenamer::Config::tokenNeedsValue(TokenType type) const
{
    return m_grp.readBoolEntry("Need" + tokenToString(type) + "Value");
47 48
}

49
void FileRenamer::Config::setTokenNeedsValue(TokenType type, bool needsValue)
50
{
51
    m_grp.writeEntry("Need" + tokenToString(type) + "Value", needsValue);
52 53
}

54
QString FileRenamer::tokenToString(TokenType type)
55
{
56 57 58 59 60 61 62 63
    switch(type) {
        case Title: return "Title";
        case Artist: return "Artist";
        case Album: return "Album";
        case Track: return "Track";
        case Comment: return "Comment";
    }
    return QString::null;
64 65
}

66 67
FileRenamer::FileRenamer()
    : m_cfg(kapp->config())
68 69 70
{
}

71 72
FileRenamer::FileRenamer(const PlaylistItem *item)
    : m_cfg(kapp->config())
73
{
74
    rename(item);
75 76
}

77
QString FileRenamer::expandToken(TokenType type, const QString &value) const
78
{
79 80 81 82 83 84 85
    const bool needValue = m_cfg.tokenNeedsValue(type);
    if(needValue && value.isEmpty())
        return QString();

    QString token = m_cfg.getToken(type);
    token.replace("%s", value);
    return token;
86 87
}

88

89 90 91 92 93
void FileRenamer::rename(const PlaylistItem *item)
{
    if(item == 0 || item->tag() == 0)
        return;

94 95 96 97 98 99
    QString newFilename = rename(item->absFilePath(), *item->tag());
    moveFile(item->absFilePath(), newFilename);
}

QString FileRenamer::rename(const QString &filename, const Tag &tag) const
{
100
    QString newFilename = m_cfg.filenameScheme();
101 102

    QMap<QChar, QString> substitutions;
103 104 105 106 107
    substitutions[ 't' ] = expandToken(Title, tag.track());
    substitutions[ 'a' ] = expandToken(Artist, tag.artist());
    substitutions[ 'A' ] = expandToken(Album, tag.album());
    substitutions[ 'T' ] = expandToken(Track, tag.trackNumberString());
    substitutions[ 'c' ] = expandToken(Comment, tag.comment());
108 109 110 111 112

    newFilename = KMacroExpander::expandMacros(newFilename, substitutions);
    newFilename = newFilename.stripWhiteSpace();

    if(QFileInfo(newFilename).isRelative())
113
        newFilename = filename.left( filename.findRev( "/" ) )
114
            + "/" + newFilename;
115
    newFilename += "." + QFileInfo(filename).extension();
116

117
    return newFilename;
118 119 120 121
}

void FileRenamer::moveFile(const QString &src, const QString &dest)
{
Zack Rusin's avatar
Zack Rusin committed
122
    kdDebug(65432) << "Moving file " << src << " to " << dest << endl;
123 124 125 126 127 128 129 130 131 132 133 134

    if(src == dest)
        return;

    QString dest_ = dest.mid(1); // strip the leading "/"
    if(dest_.find("/") > 0) {
        const QStringList components = QStringList::split("/", dest_.left( dest.findRev("/")));
        QStringList::ConstIterator it = components.begin();
        QStringList::ConstIterator end = components.end();
        QString processedComponents;
        for(; it != end; ++it) {
            processedComponents += "/" + *it;
Zack Rusin's avatar
Zack Rusin committed
135
            kdDebug(65432) << "Checking path " << processedComponents << endl;
136 137
            QDir dir(processedComponents);
            if (!dir.exists())
Zack Rusin's avatar
Zack Rusin committed
138
                kdDebug(65432) << "Need to create " << processedComponents << endl;
139 140 141
        }
    }

142
    return;
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160

    QFile srcFile(src);
    if(!srcFile.open(IO_ReadOnly)) {
        kdWarning() << "Could not open" << src << " for reading." << endl;
        return;
    }

    QFile destFile(dest);
    if(!destFile.open(IO_WriteOnly)) {
        kdWarning() << "Could not open " << dest << " for writing." << endl;
        return;
    }

    destFile.writeBlock(srcFile.readAll());

    if(!srcFile.remove())
        kdWarning() << "Could not delete source file " << src << endl;
}
161
// vim:ts=4:sw=4:noet