/*************************************************************************** * Copyright (C) 2005 by Bastian Holst * * bastianholst@gmx.de * * Copyright (C) 2006 by Martin Meredith * * mez@thekatapult.org.uk * * * * 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include "actionplaysong.h" #include "song.h" #include "amarokcatalog.h" #include "actionregistry.h" #include "status.h" #include "settings.h" K_EXPORT_COMPONENT_FACTORY( katapult_amarokcatalog, KGenericFactory( "katapult_amarokcatalog" ) ) AmarokCatalog::AmarokCatalog(TQObject*, const char*, const TQStringList&): _result(TQString()) { _minQueryLen = 3; ActionRegistry::self()->registerAction(new ActionPlaySong()); _gotCollectionStatus = false; _dynamicCollection = false; checkCollectionType(); } AmarokCatalog::~AmarokCatalog() { } void AmarokCatalog::queryChanged() { int newStatus = 0; TQString queryString = query(); if((TQString(queryString).remove(':').remove('\"').remove(' ').isEmpty()) || (queryString.length() < _minQueryLen)) { reset(); setBestMatch(Match()); setStatus(0); } else { if ( _gotCollectionStatus) { if (!_dynamicCollection) { // Stuff for Amarok < 1.4.2 TQStringList queryList; //prepares SQL-queryTQRegExp TQString sqlQuery( "SELECT artist.name, tags.title, tags.url, images.path, album.name " "FROM tags" "INNER JOIN album ON (tags.album = album.id) " "INNER JOIN artist ON (tags.artist = artist.id) " "LEFT JOIN statistics ON (tags.url = statistics.url) " "LEFT JOIN images ON (artist.name = images.artist AND album.name = images.album) " "WHERE 1=1 " );// AND queryList = TQStringList::split ( TQString(" "), TQString(queryString).replace(TQChar(':')," ").replace(TQChar('\''), " ").replace(TQChar('\''), "%") ); for(TQStringList::Iterator it = queryList.begin(); it != queryList.end(); ++it) { sqlQuery.append(TQString(" AND (t.title LIKE '\%%1\%'").arg(*it)); sqlQuery.append(TQString(" OR a.name LIKE '\%%1\%')").arg(*it)); } sqlQuery.append(" ORDER BY a.name, t.title, s.percentage DESC"); //sending SQL-query to ararok via dcop TQByteArray sqlQueryData, replyData; TQCString replyType; TQDataStream arg(sqlQueryData, IO_WriteOnly); arg << sqlQuery; if (!kapp->dcopClient()->call("amarok", "collection", "query(TQString)", sqlQueryData, replyType, replyData)) { newStatus = 0; } else { TQDataStream reply(replyData, IO_ReadOnly); if (replyType == TQSTRINGLIST_OBJECT_NAME_STRING) { TQStringList sqlResult; reply >> sqlResult; if(sqlResult.isEmpty()) { newStatus = 0; } else { reset(); //Reads information from SQL-Query _result.setArtist(sqlResult[0]); _result.setName(sqlResult[1]); _result.setURL(KURL(sqlResult[2])); _result.setAlbum(sqlResult[4]); //_result.setIcon(TQString()); if ( !sqlResult[3].isEmpty() ) { _result.setIcon(sqlResult[3]); } //counts the matched charecters int i = queryString.find( ':' ); if ( i != -1 ) { if ( queryString[i+1] != ' ' ) queryString.insert(i+1, ' '); if ( queryString[i-1] != ' ' ) queryString.insert(i, ' '); } queryList = TQStringList::split ( " ", queryString ); unsigned int matched = 0; for(TQStringList::Iterator it = queryList.begin(); it != queryList.end(); ++it) { if(matched < (_result.text().find(*it, matched, false) + (*it).length())) matched = _result.text().find(*it, matched, false) + (*it).length(); } setBestMatch(Match(&_result, 100*queryString.length()/_result.text().length(), matched)); //Checks if there are multiple results if( !sqlResult[5].isEmpty() ) newStatus = S_HasResults | S_Multiple; else newStatus = S_HasResults; } } else { newStatus = 0; } } } else { // Dynamic Collection // Do same as above here again but with dyn collection stuff TQStringList queryList; //prepares SQL-queryTQRegExp TQString sqlQuery("SELECT a.name, t.title, t.deviceid, d.lastmountpoint, t.url, i.path, album.name FROM tags t LEFT JOIN statistics s ON (t.url = s.url AND t.deviceid = s.deviceid) LEFT JOIN artist a ON (t.artist = a.id) 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 "); queryList = TQStringList::split ( TQString(" "), TQString(queryString).replace(TQChar(':')," ").replace(TQChar('\''), " ").replace(TQChar('\''), "%") ); // Let's build each of these clauses TQStringList clauses; for(TQStringList::Iterator it = queryList.begin(); it != queryList.end(); ++it) { clauses += TQString(" (t.title LIKE '\%%1\%'").arg(*it) + TQString(" OR a.name LIKE '\%%1\%')").arg(*it); } sqlQuery.append(clauses.join(TQString(" AND "))); sqlQuery.append(" ORDER BY a.name, t.title, s.percentage DESC"); //sending SQL-query to ararok via dcop TQByteArray sqlQueryData, replyData; TQCString replyType; TQDataStream arg(sqlQueryData, IO_WriteOnly); arg << sqlQuery; if (!kapp->dcopClient()->call("amarok", "collection", "query(TQString)", sqlQueryData, replyType, replyData)) { newStatus = 0; } else { TQDataStream reply(replyData, IO_ReadOnly); if (replyType == TQSTRINGLIST_OBJECT_NAME_STRING) { TQStringList sqlResult; reply >> sqlResult; if(sqlResult.isEmpty()) { newStatus = 0; } else { reset(); //Reads information from SQL-Query _result.setArtist(sqlResult[0]); _result.setName(sqlResult[1]); if (sqlResult[2]!="-1") { KURL absolutePath; absolutePath.setPath( sqlResult[3] ); absolutePath.addPath( sqlResult[4] ); absolutePath.cleanPath(); _result.setURL( absolutePath ); } else { KURL absolutePath; absolutePath.setPath( "/" ); absolutePath.addPath( sqlResult[4] ); absolutePath.cleanPath(); _result.setURL( absolutePath ); } _result.setAlbum(sqlResult[6]); //_result.setIcon(TQString()); if ( !sqlResult[3].isEmpty() ) { _result.setIcon(sqlResult[5]); } //counts the matched charecters int i = queryString.find( ':' ); if ( i != -1 ) { if ( queryString[i+1] != ' ' ) queryString.insert(i+1, ' '); if ( queryString[i-1] != ' ' ) queryString.insert(i, ' '); } queryList = TQStringList::split ( " ", queryString ); unsigned int matched = 0; for(TQStringList::Iterator it = queryList.begin(); it != queryList.end(); ++it) { if(matched < (_result.text().find(*it, matched, false) + (*it).length())) matched = _result.text().find(*it, matched, false) + (*it).length(); } setBestMatch(Match(&_result, 100*queryString.length()/_result.text().length(), matched)); //Checks if there are multiple results if( !sqlResult[7].isEmpty() ) newStatus = S_HasResults | S_Multiple; else newStatus = S_HasResults; } } else { newStatus = 0; } } } //end of >1.4.2 section setStatus(newStatus); } else { //We haven't got the collection status checkCollectionType(); reset(); setBestMatch(Match()); setStatus(0); } } //dont go after this while fixing } void AmarokCatalog::reset() { _result.setName(TQString()); _result.setArtist(TQString()); _result.setAlbum(TQString()); _result.setIcon(TQString()); } void AmarokCatalog::checkCollectionType() { TQString sqlQuery("SELECT COUNT(*) FROM admin WHERE noption = 'Database Devices Version'"); TQByteArray sqlQueryData, replyData; TQCString replyType; TQDataStream arg(sqlQueryData, IO_WriteOnly); arg << sqlQuery; if (!kapp->dcopClient()->call("amarok", "collection", "query(TQString)", sqlQueryData, replyType, replyData)) { _gotCollectionStatus = false; } else { TQDataStream reply(replyData, IO_ReadOnly); if (replyType == TQSTRINGLIST_OBJECT_NAME_STRING) { TQStringList sqlResult; reply >> sqlResult; if (sqlResult[0] == "1") { _dynamicCollection = true; } else { _dynamicCollection = false; } _gotCollectionStatus = true; } else { _gotCollectionStatus = false; } } } /* void AmarokCatalog::initialize() { } */ unsigned int AmarokCatalog::minQueryLen() const { return _minQueryLen; } TQWidget * AmarokCatalog::configure() { AmarokCatalogSettings *settings = new AmarokCatalogSettings(); settings->minQueryLen->setValue(_minQueryLen); connect(settings->minQueryLen, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(minQueryLenChanged(int))); return settings; } void AmarokCatalog::minQueryLenChanged(int _minQueryLen) { this->_minQueryLen = _minQueryLen; } void AmarokCatalog::readSettings(TDEConfigBase *config) { _minQueryLen = config->readUnsignedNumEntry("MinQueryLen", 3); } void AmarokCatalog::writeSettings(TDEConfigBase *config) { config->writeEntry("MinQueryLen", _minQueryLen); }