~neon/juk/master

238 by Frerich Raabe
- Added button to the tag editor which makes JuK try to suggest sensible
1
/*
2
 * tagguesser.cpp - (c) 2003 Frerich Raabe <raabe@kde.org>
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 2 of the License, or
7
 * (at your option) any later version.
8
 */
9
#include "tagguesser.h"
10
11
#include <kapplication.h>
12
#include <kconfig.h>
331 by Frerich Raabe
- Capitalize the first letter of each word in the title, artist and album
13
#include <kdebug.h>
1040 by Scott Wheeler
Switch from KConfigGroupSaver to KConfigGroup
14
#include <kglobal.h>
537 by Scott Wheeler
JuK currently requires a recent kdelibs from HEAD so I'm removing the left
15
#include <kmacroexpander.h>
238 by Frerich Raabe
- Added button to the tag editor which makes JuK try to suggest sensible
16
17
FileNameScheme::FileNameScheme(const QString &s)
18
    : m_regExp(),
19
    m_titleField(-1),
20
    m_artistField(-1),
21
    m_albumField(-1),
22
    m_trackField(-1),
23
    m_commentField(-1)
24
{
25
    int fieldNumber = 1;
26
    int i = s.find('%');
27
    while (i > -1) {
28
        switch (s[ i + 1 ]) {
29
            case 't': m_titleField = fieldNumber++;
30
                      break;
31
            case 'a': m_artistField = fieldNumber++;
32
                      break;
33
            case 'A': m_albumField = fieldNumber++;
34
                      break;
35
            case 'T': m_trackField = fieldNumber++;
36
                      break;
37
            case 'c': m_commentField = fieldNumber++;
38
                      break;
39
            default:
40
                      break;
41
        }
42
        i = s.find('%', i + 1);
43
    }
44
    m_regExp.setPattern(composeRegExp(s));
45
}
46
47
bool FileNameScheme::matches(const QString &fileName) const
48
{
817 by Frerich Raabe
- Accept "." in the album, artist and title fields
49
    /* Strip extension ('.mp3') because '.' may be part of a title, and thus
50
     * does not work as a separator.
51
     */
52
    QString stripped = fileName;
53
    stripped.truncate(stripped.findRev('.'));
54
    return m_regExp.exactMatch(stripped);
238 by Frerich Raabe
- Added button to the tag editor which makes JuK try to suggest sensible
55
}
56
57
QString FileNameScheme::title() const
58
{
59
    if(m_titleField == -1)
60
        return QString::null;
61
    return m_regExp.capturedTexts()[ m_titleField ];
62
}
63
64
QString FileNameScheme::artist() const
65
{
66
    if(m_artistField == -1)
67
        return QString::null;
68
    return m_regExp.capturedTexts()[ m_artistField ];
69
}
70
71
QString FileNameScheme::album() const
72
{
73
    if(m_albumField == -1)
74
        return QString::null;
75
    return m_regExp.capturedTexts()[ m_albumField ];
76
}
77
78
QString FileNameScheme::track() const
79
{
80
    if(m_trackField == -1)
81
        return QString::null;
82
    return m_regExp.capturedTexts()[ m_trackField ];
83
}
84
85
QString FileNameScheme::comment() const
86
{
87
    if(m_commentField == -1)
88
        return QString::null;
89
    return m_regExp.capturedTexts()[ m_commentField ];
90
}
91
92
QString FileNameScheme::composeRegExp(const QString &s) const
93
{
94
    QMap<QChar, QString> substitutions;
278 by Scott Wheeler
Use KConfigGroupSaver
95
1040 by Scott Wheeler
Switch from KConfigGroupSaver to KConfigGroup
96
    KConfigGroup config(KGlobal::config(), "TagGuesser");
278 by Scott Wheeler
Use KConfigGroupSaver
97
1040 by Scott Wheeler
Switch from KConfigGroupSaver to KConfigGroup
98
    substitutions[ 't' ] = config.readEntry("Title regexp", "([\\w\\s'&_,\\.]+)");
99
    substitutions[ 'a' ] = config.readEntry("Artist regexp", "([\\w\\s'&_,\\.]+)");
100
    substitutions[ 'A' ] = config.readEntry("Album regexp", "([\\w\\s'&_,\\.]+)");
101
    substitutions[ 'T' ] = config.readEntry("Track regexp", "(\\d+)");
102
    substitutions[ 'c' ] = config.readEntry("Comment regexp", "([\\w\\s_]+)");
238 by Frerich Raabe
- Added button to the tag editor which makes JuK try to suggest sensible
103
104
    QString regExp = QRegExp::escape(s.simplifyWhiteSpace());
105
    regExp = ".*" + regExp;
106
    regExp.replace(' ', "\\s+");
312 by Frerich Raabe
- Don't ignore KMacroExpander's hard work. It sucks that the compiler does not
107
    regExp = KMacroExpander::expandMacros(regExp, substitutions);
962 by Michael Pyne
Fix Bug #81589 by forcing the user-specified pattern to match at the end
108
    regExp += "[^/]*$";
238 by Frerich Raabe
- Added button to the tag editor which makes JuK try to suggest sensible
109
    return regExp;
110
}
111
239 by Frerich Raabe
- Moved the code for reading the config file (and possibly using the default
112
QStringList TagGuesser::schemeStrings()
238 by Frerich Raabe
- Added button to the tag editor which makes JuK try to suggest sensible
113
{
278 by Scott Wheeler
Use KConfigGroupSaver
114
    QStringList schemes;
115
1040 by Scott Wheeler
Switch from KConfigGroupSaver to KConfigGroup
116
    KConfigGroup config(KGlobal::config(), "TagGuesser");
117
    schemes = config.readListEntry("Filename schemes");
118
238 by Frerich Raabe
- Added button to the tag editor which makes JuK try to suggest sensible
119
    if ( schemes.isEmpty() ) {
120
        schemes += "%a - (%T) - %t [%c]";
121
        schemes += "%a - (%T) - %t (%c)";
122
        schemes += "%a - (%T) - %t";
123
        schemes += "%a - [%T] - %t [%c]";
124
        schemes += "%a - [%T] - %t (%c)";
125
        schemes += "%a - [%T] - %t";
126
        schemes += "%a - %T - %t [%c]";
127
        schemes += "%a - %T - %t (%c)";
128
        schemes += "%a - %T - %t";
129
        schemes += "(%T) %a - %t [%c]";
130
        schemes += "(%T) %a - %t (%c)";
131
        schemes += "(%T) %a - %t";
132
        schemes += "[%T] %a - %t [%c]";
133
        schemes += "[%T] %a - %t (%c)";
134
        schemes += "[%T] %a - %t";
135
        schemes += "%T %a - %t [%c]";
136
        schemes += "%T %a - %t (%c)";
137
        schemes += "%T %a - %t";
138
        schemes += "(%a) %t [%c]";
139
        schemes += "(%a) %t (%c)";
140
        schemes += "(%a) %t";
141
        schemes += "%a - %t [%c]";
142
        schemes += "%a - %t (%c)";
143
        schemes += "%a - %t";
815 by Frerich Raabe
- Schemes which involve directory names should be checked last, they match
144
        schemes += "%a/%A/[%T] %t [%c]";
145
        schemes += "%a/%A/[%T] %t (%c)";
146
        schemes += "%a/%A/[%T] %t";
238 by Frerich Raabe
- Added button to the tag editor which makes JuK try to suggest sensible
147
    }
239 by Frerich Raabe
- Moved the code for reading the config file (and possibly using the default
148
    return schemes;
149
}
150
151
void TagGuesser::setSchemeStrings(const QStringList &schemes)
152
{
243 by Frerich Raabe
- Moved the schemes configuration key into a "Tag guesser" configuration group,
153
    KConfig *cfg = kapp->config();
278 by Scott Wheeler
Use KConfigGroupSaver
154
    {
359 by Scott Wheeler
Forgot to actually add the variable name a few times.
155
        KConfigGroupSaver saver(cfg, "TagGuesser");
331 by Frerich Raabe
- Capitalize the first letter of each word in the title, artist and album
156
        cfg->writeEntry("Filename schemes", schemes);
278 by Scott Wheeler
Use KConfigGroupSaver
157
    }
260 by Frerich Raabe
- Fixed saving of scheme list configuration
158
    cfg->sync();
239 by Frerich Raabe
- Moved the code for reading the config file (and possibly using the default
159
}
160
161
TagGuesser::TagGuesser()
162
{
163
    loadSchemes();
164
}
165
166
TagGuesser::TagGuesser(const QString &absFileName)
167
{
168
    loadSchemes();
169
    guess(absFileName);
170
}
171
172
void TagGuesser::loadSchemes()
173
{
174
    const QStringList schemes = schemeStrings();
238 by Frerich Raabe
- Added button to the tag editor which makes JuK try to suggest sensible
175
    QStringList::ConstIterator it = schemes.begin();
176
    QStringList::ConstIterator end = schemes.end();
177
    for ( ; it != end; ++it )
178
        m_schemes += FileNameScheme( *it );
179
}
180
181
void TagGuesser::guess(const QString &absFileName)
182
{
256 by Frerich Raabe
- Make sure the field values get reset to QString::null for each search. This
183
    m_title = m_artist = m_album = m_track = m_comment = QString::null;
184
238 by Frerich Raabe
- Added button to the tag editor which makes JuK try to suggest sensible
185
    FileNameScheme::List::ConstIterator it = m_schemes.begin();
186
    FileNameScheme::List::ConstIterator end = m_schemes.end();
187
    for (; it != end; ++it) {
188
        const FileNameScheme schema(*it);
189
        if(schema.matches(absFileName)) {
1046 by Michael Pyne
Fix bug 82910 (tag guesser leaves spaces in front of tags), by adding
190
            m_title = capitalizeWords(schema.title().replace('_', " ")).stripWhiteSpace();
191
            m_artist = capitalizeWords(schema.artist().replace('_', " ")).stripWhiteSpace();
192
            m_album = capitalizeWords(schema.album().replace('_', " ")).stripWhiteSpace();
193
            m_track = schema.track().stripWhiteSpace();
194
            m_comment = schema.comment().replace('_', " ").stripWhiteSpace();
1047 by Michael Pyne
CVS_SILENT Broke the spacing of the break statement in my last commit.
195
            break;
238 by Frerich Raabe
- Added button to the tag editor which makes JuK try to suggest sensible
196
        }
197
    }
198
}
199
331 by Frerich Raabe
- Capitalize the first letter of each word in the title, artist and album
200
QString TagGuesser::capitalizeWords(const QString &s)
201
{
202
    if(s.isEmpty())
203
        return s;
204
205
    QString result = s;
206
    result[ 0 ] = result[ 0 ].upper();
207
208
    const QRegExp wordRegExp("\\s\\w");
209
    int i = result.find( wordRegExp );
210
    while ( i > -1 ) {
211
        result[ i + 1 ] = result[ i + 1 ].upper();
212
        i = result.find( wordRegExp, ++i );
213
    }
214
215
    return result;
216
}
217
238 by Frerich Raabe
- Added button to the tag editor which makes JuK try to suggest sensible
218
// vim:ts=4:sw=4:noet