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
|