/***************************************************************************
* 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 <kapplication.h>
# include <tdesycocaentry.h>
# include <tdesycocatype.h>
# include <knuminput.h>
# include <kurl.h>
# include <kapp.h>
# include <tqstring.h>
# include <tqcstring.h>
# include <tqstringlist.h>
# include <tqdatastream.h>
# include <dcopclient.h>
# include <tqregexp.h>
# 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 < AmarokCatalog > ( " 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 ) ;
}