Contents of /branches/extragear/kde3/utils/katapult/plugins/catalogs/amarokcatalog/amarokcatalog.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 679333 - (show annotations) (download)
Sat Jun 23 16:27:58 2007 UTC (10 years, 6 months ago) by mmeredith
File size: 10889 byte(s)
Added SQL patch for Amarok Catalog
1 /***************************************************************************
2 * Copyright (C) 2005 by Bastian Holst *
3 * bastianholst@gmx.de *
4 * Copyright (C) 2006-2007 by Martin Meredith *
5 * mez@thekatapult.org.uk *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
22
23 #include <kapplication.h>
24 #include <ksycocaentry.h>
25 #include <ksycocatype.h>
26 #include <knuminput.h>
27 #include <kurl.h>
28 #include <kapp.h>
29 #include <qstring.h>
30 #include <qcstring.h>
31 #include <qstringlist.h>
32 #include <qdatastream.h>
33 #include <dcopclient.h>
34 #include <qregexp.h>
35
36 #include "actionplaysong.h"
37 #include "actionaddsong.h"
38 #include "actionqueuesong.h"
39 #include "song.h"
40 #include "amarokcatalog.h"
41 #include "actionregistry.h"
42 #include "status.h"
43 #include "settings.h"
44
45 K_EXPORT_COMPONENT_FACTORY( katapult_amarokcatalog,
46 KGenericFactory<AmarokCatalog>( "katapult_amarokcatalog" ) )
47
48 AmarokCatalog::AmarokCatalog(QObject*, const char*, const QStringList&): _result(QString::null)
49 {
50 _minQueryLen = 4;
51 ActionRegistry::self()->registerAction(new ActionPlaySong());
52 ActionRegistry::self()->registerAction(new ActionAddSong());
53 ActionRegistry::self()->registerAction(new ActionQueueSong());
54 _gotCollectionStatus = false;
55 _dynamicCollection = false;
56 checkCollectionType();
57 }
58 AmarokCatalog::~AmarokCatalog()
59 {
60 }
61
62 void AmarokCatalog::queryChanged()
63 {
64 int newStatus = 0;
65 QString queryString = query();
66
67 if((QString(queryString).remove(':').remove('\"').remove(' ').isEmpty()) || (queryString.length() < _minQueryLen)) {
68 reset();
69 setBestMatch(Match());
70 setStatus(0);
71 } else {
72
73 if ( _gotCollectionStatus)
74 {
75
76 if (!_dynamicCollection)
77 {
78
79 // Stuff for Amarok < 1.4.2
80
81 QStringList queryList;
82 //prepares SQL-queryQRegExp
83 QString sqlQuery("SELECT a.name, t.title, t.url, i.path, album.name FROM tags t, artist a, album LEFT JOIN statistics s ON t.url = s.url LEFT JOIN images i ON (a.name = i.artist AND album.name = i.album) WHERE t.album = album.id AND t.artist = a.id"); // AND
84
85 queryList = QStringList::split ( QString(" "), QString(queryString).replace(QChar(':')," ").replace(QChar('\"'), " ").replace(QChar('\"'), "%") );
86 for(QStringList::Iterator it = queryList.begin(); it != queryList.end(); ++it) {
87 sqlQuery.append(QString(" AND (t.title LIKE \"\%%1\%\"").arg(*it));
88 sqlQuery.append(QString(" OR a.name LIKE \"\%%1\%\")").arg(*it));
89 }
90 sqlQuery.append(" ORDER BY a.name, t.title, s.percentage DESC");
91
92 //sending SQL-query to ararok via dcop
93 QByteArray sqlQueryData, replyData;
94 QCString replyType;
95 QDataStream arg(sqlQueryData, IO_WriteOnly);
96 arg << sqlQuery;
97 if (!kapp->dcopClient()->call("amarok", "collection", "query(QString)",
98 sqlQueryData, replyType, replyData)) {
99 newStatus = 0;
100 } else {
101 QDataStream reply(replyData, IO_ReadOnly);
102 if (replyType == "QStringList") {
103 QStringList sqlResult;
104 reply >> sqlResult;
105
106 if(sqlResult.isEmpty()) {
107 newStatus = 0;
108 } else {
109 reset();
110 //Reads information from SQL-Query
111 _result.setArtist(sqlResult[0]);
112 _result.setName(sqlResult[1]);
113 _result.setURL(KURL(sqlResult[2]));
114 _result.setAlbum(sqlResult[4]);
115
116 //_result.setIcon(QString());
117 if ( !sqlResult[3].isEmpty() ) {
118 _result.setIcon(sqlResult[3]);
119 }
120
121 //counts the matched charecters
122 int i = queryString.find( ':' );
123 if ( i != -1 ) {
124 if ( queryString[i+1] != ' ' )
125 queryString.insert(i+1, ' ');
126 if ( queryString[i-1] != ' ' )
127 queryString.insert(i, ' ');
128 }
129 queryList = QStringList::split ( " ", queryString );
130 unsigned int matched = 0;
131 for(QStringList::Iterator it = queryList.begin(); it != queryList.end(); ++it) {
132 if(matched < (_result.text().find(*it, matched, false) + (*it).length()))
133 matched = _result.text().find(*it, matched, false) + (*it).length();
134 }
135 setBestMatch(Match(&_result, 100*queryString.length()/_result.text().length(), matched));
136
137 //Checks if there are multiple results
138 if( !sqlResult[5].isEmpty() )
139 newStatus = S_HasResults | S_Multiple;
140 else
141 newStatus = S_HasResults;
142 }
143 } else {
144 newStatus = 0;
145 }
146 }
147
148 } else { // Dynamic Collection
149
150 // Do same as above here again but with dyn collection stuff
151
152 QStringList queryList;
153 //prepares SQL-queryQRegExp
154 QString sqlQuery("SELECT a.name, t.title, t.deviceid, d.lastmountpoint, t.url, i.path, album.name FROM tags t LEFT JOIN artist a ON t.artist = a.id LEFT JOIN statistics s ON t.url = s.url AND t.deviceid = s.deviceid LEFT JOIN album ON t.album = album.id LEFT JOIN images i ON ( a.name = i.artist AND album.name = i.album) LEFT JOIN devices d ON t.deviceid = d.id WHERE 1");
155
156 queryList = QStringList::split ( QString(" "), QString(queryString).replace(QChar(':')," ").replace(QChar('\"'), " ").replace(QChar('\"'), "%") );
157
158 for(QStringList::Iterator it = queryList.begin(); it != queryList.end(); ++it) {
159
160 sqlQuery.append(QString(" AND (t.title LIKE \"\%%1\%\"").arg(*it));
161 sqlQuery.append(QString(" OR a.name LIKE \"\%%1\%\")").arg(*it));
162 }
163 sqlQuery.append(" ORDER BY s.percentage DESC")
164
165 //sending SQL-query to ararok via dcop
166 QByteArray sqlQueryData, replyData;
167 QCString replyType;
168 QDataStream arg(sqlQueryData, IO_WriteOnly);
169 arg << sqlQuery;
170 if (!kapp->dcopClient()->call("amarok", "collection", "query(QString)",
171 sqlQueryData, replyType, replyData)) {
172 newStatus = 0;
173 } else {
174 QDataStream reply(replyData, IO_ReadOnly);
175 if (replyType == "QStringList") {
176 QStringList sqlResult;
177 reply >> sqlResult;
178
179 if(sqlResult.isEmpty()) {
180 newStatus = 0;
181 } else {
182 reset();
183 //Reads information from SQL-Query
184 _result.setArtist(sqlResult[0]);
185 _result.setName(sqlResult[1]);
186 if (sqlResult[2]!="-1") {
187 KURL absolutePath;
188 absolutePath.setPath( sqlResult[3] );
189 absolutePath.addPath( sqlResult[4] );
190 absolutePath.cleanPath();
191
192 _result.setURL( absolutePath );
193 } else {
194 KURL absolutePath;
195 absolutePath.setPath( "/" );
196 absolutePath.addPath( sqlResult[4] );
197 absolutePath.cleanPath();
198
199 _result.setURL( absolutePath );
200 }
201
202 _result.setAlbum(sqlResult[6]);
203
204 //_result.setIcon(QString());
205 if ( !sqlResult[3].isEmpty() ) {
206 _result.setIcon(sqlResult[5]);
207 }
208
209 //counts the matched charecters
210 int i = queryString.find( ':' );
211 if ( i != -1 ) {
212 if ( queryString[i+1] != ' ' )
213 queryString.insert(i+1, ' ');
214 if ( queryString[i-1] != ' ' )
215 queryString.insert(i, ' ');
216 }
217 queryList = QStringList::split ( " ", queryString );
218 unsigned int matched = 0;
219 for(QStringList::Iterator it = queryList.begin(); it != queryList.end(); ++it) {
220 if(matched < (_result.text().find(*it, matched, false) + (*it).length()))
221 matched = _result.text().find(*it, matched, false) + (*it).length();
222 }
223 setBestMatch(Match(&_result, 100*queryString.length()/_result.text().length(), matched));
224
225 //Checks if there are multiple results
226 if( !sqlResult[7].isEmpty() )
227 newStatus = S_HasResults | S_Multiple;
228 else
229 newStatus = S_HasResults;
230 }
231 } else {
232 newStatus = 0;
233 }
234 }
235
236
237 } //end of >1.4.2 section
238 setStatus(newStatus);
239
240 } else { //We haven't got the collection status
241
242 checkCollectionType();
243 reset();
244 setBestMatch(Match());
245 setStatus(0);
246 }
247
248
249 } //dont go after this while fixing
250
251 }
252
253 void AmarokCatalog::reset()
254 {
255 _result.setName(QString::null);
256 _result.setArtist(QString::null);
257 _result.setAlbum(QString::null);
258 _result.setIcon(QString::null);
259 }
260
261 void AmarokCatalog::checkCollectionType()
262 {
263 QString sqlQuery("SELECT COUNT(*) FROM admin WHERE noption = 'Database Devices Version'");
264
265 QByteArray sqlQueryData, replyData;
266 QCString replyType;
267 QDataStream arg(sqlQueryData, IO_WriteOnly);
268 arg << sqlQuery;
269 if (!kapp->dcopClient()->call("amarok", "collection", "query(QString)", sqlQueryData, replyType, replyData))
270 {
271 _gotCollectionStatus = false;
272
273 }
274 else
275 {
276 QDataStream reply(replyData, IO_ReadOnly);
277 if (replyType == "QStringList")
278 {
279 QStringList sqlResult;
280 reply >> sqlResult;
281
282 if (sqlResult[0] == "1")
283 {
284 _dynamicCollection = true;
285
286 }
287 else
288 {
289 _dynamicCollection = false;
290
291 }
292 _gotCollectionStatus = true;
293 }
294 else
295 {
296 _gotCollectionStatus = false;
297 }
298 }
299 }
300
301 /*
302 void AmarokCatalog::initialize()
303 {
304 }
305 */
306
307 unsigned int AmarokCatalog::minQueryLen() const
308 {
309 return _minQueryLen;
310 }
311
312 QWidget * AmarokCatalog::configure()
313 {
314 AmarokCatalogSettings *settings = new AmarokCatalogSettings();
315
316 settings->minQueryLen->setValue(_minQueryLen);
317 connect(settings->minQueryLen, SIGNAL(valueChanged(int)), this, SLOT(minQueryLenChanged(int)));
318 return settings;
319 }
320
321 void AmarokCatalog::minQueryLenChanged(int _minQueryLen)
322 {
323 this->_minQueryLen = _minQueryLen;
324 }
325
326 void AmarokCatalog::readSettings(KConfigBase *config)
327 {
328 _minQueryLen = config->readUnsignedNumEntry("MinQueryLen", 4);
329 }
330
331 void AmarokCatalog::writeSettings(KConfigBase *config)
332 {
333 config->writeEntry("MinQueryLen", _minQueryLen);
334 }