/src/libtomahawk/TomahawkSettings.cpp
Relevant Search: With Applications for Solr and Elasticsearch
For more in depth reading about search, ranking and generally everything you could ever want to know about how lucene, elasticsearch or solr work under the hood I highly suggest this book. Easily one of the most interesting technical books I have read in a long time. If you are tasked with solving search relevance problems even if not in Solr or Elasticsearch it should be your first reference. Amazon Affiliate LinkC++ | 1764 lines | 1323 code | 386 blank | 55 comment | 123 complexity | dfe280214602c850b81f1dd9c9da8477 MD5 | raw file
1/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === 2 * 3 * Copyright 2010-2015, Christian Muehlhaeuser <muesli@tomahawk-player.org> 4 * Copyright 2010-2011 Leo Franchi <lfranchi@kde.org> 5 * Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org> 6 * 7 * Tomahawk 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 3 of the License, or 10 * (at your option) any later version. 11 * 12 * Tomahawk 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 Tomahawk. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21#include "TomahawkSettings.h" 22 23#include "collection/Collection.h" 24#include "database/DatabaseCommand_UpdateSearchIndex.h" 25#include "database/Database.h" 26#include "database/fuzzyindex/DatabaseFuzzyIndex.h" 27#include "infosystem/InfoSystemCache.h" 28#include "playlist/PlaylistUpdaterInterface.h" 29#include "utils/Logger.h" 30#include "utils/Json.h" 31#include "utils/TomahawkUtils.h" 32 33#include "PlaylistEntry.h" 34#include "PlaylistInterface.h" 35#include "Source.h" 36 37#include <qt5keychain/keychain.h> 38#include <QStandardPaths> 39#include <QDir> 40 41using namespace Tomahawk; 42 43TomahawkSettings* TomahawkSettings::s_instance = 0; 44 45 46inline QDataStream& 47operator<<(QDataStream& out, const SerializedUpdaters& updaters) 48{ 49 out << TOMAHAWK_SETTINGS_VERSION; 50 out << (quint32)updaters.count(); 51 SerializedUpdaters::const_iterator iter = updaters.begin(); 52 int count = 0; 53 for ( ; iter != updaters.end(); ++iter ) 54 { 55 out << iter.key() << iter->type << iter->customData; 56 count++; 57 } 58 Q_ASSERT( count == updaters.count() ); 59 return out; 60} 61 62 63inline QDataStream& 64operator>>(QDataStream& in, SerializedUpdaters& updaters) 65{ 66 quint32 count = 0, version = 0; 67 in >> version; 68 in >> count; 69 70 for ( uint i = 0; i < count; i++ ) 71 { 72 QString key, type; 73 QVariantHash customData; 74 in >> key; 75 in >> type; 76 in >> customData; 77 updaters.insert( key, SerializedUpdater( type, customData ) ); 78 } 79 80 return in; 81} 82 83 84TomahawkSettings* 85TomahawkSettings::instance() 86{ 87 return s_instance; 88} 89 90 91TomahawkSettings::TomahawkSettings( QObject* parent ) 92 : QSettings( parent ) 93{ 94 s_instance = this; 95 96 #if !(defined(Q_OS_MAC) && defined(Q_OS_WIN)) 97 QFile file( fileName() ); 98 file.setPermissions( file.permissions() & ~( QFile::ReadGroup | QFile::WriteGroup | QFile::ExeGroup | QFile::ReadOther | QFile::WriteOther | QFile::ExeOther ) ); 99 #endif 100 101 if ( !contains( "configversion" ) ) 102 { 103 setValue( "configversion", TOMAHAWK_SETTINGS_VERSION ); 104 doInitialSetup(); 105 } 106 else if ( value( "configversion" ).toUInt() != TOMAHAWK_SETTINGS_VERSION ) 107 { 108 qDebug() << "Config version outdated, old:" << value( "configversion" ).toUInt() 109 << "new:" << TOMAHAWK_SETTINGS_VERSION 110 << "Doing upgrade, if any, and backing up"; 111 112// QString newname = QString( "%1.v%2" ).arg( dbname ).arg( version ); 113 if ( format() == IniFormat || 114 ( format() == NativeFormat 115#ifdef Q_OS_WIN 116 && false 117#endif 118 ) ) 119 { 120 qDebug() << "Backing up old ini-style config file"; 121 const QString path = fileName(); 122 const QString newname = path + QString( ".v%1" ).arg( value( "configversion" ).toString() ); 123 QFile::copy( path, newname ); 124 125 } 126 int current = value( "configversion" ).toUInt(); 127 while ( current < TOMAHAWK_SETTINGS_VERSION ) 128 { 129 doUpgrade( current, current + 1 ); 130 131 current++; 132 } 133 // insert upgrade code here as required 134 setValue( "configversion", TOMAHAWK_SETTINGS_VERSION ); 135 } 136 137 // Ensure last.fm and spotify accounts always exist 138 QString spotifyAcct, lastfmAcct; 139 foreach ( const QString& acct, value( "accounts/allaccounts" ).toStringList() ) 140 { 141 if ( acct.startsWith( "lastfmaccount_" ) ) 142 lastfmAcct = acct; 143 else if ( acct.startsWith( "spotifyaccount_" ) ) 144 spotifyAcct = acct; 145 } 146 147 if ( spotifyAcct.isEmpty() ) 148 createSpotifyAccount(); 149 if ( lastfmAcct.isEmpty() ) 150 createLastFmAccount(); 151} 152 153 154TomahawkSettings::~TomahawkSettings() 155{ 156 s_instance = 0; 157} 158 159 160void 161TomahawkSettings::doInitialSetup() 162{ 163 // by default we add a local network resolver 164 addAccount( "sipzeroconf_autocreated" ); 165 166 createLastFmAccount(); 167 createSpotifyAccount(); 168} 169 170 171void 172TomahawkSettings::createLastFmAccount() 173{ 174 // Add a last.fm account for scrobbling and infosystem 175 const QString accountKey = QString( "lastfmaccount_%1" ).arg( QUuid::createUuid().toString().mid( 1, 8 ) ); 176 addAccount( accountKey ); 177 178 beginGroup( "accounts/" + accountKey ); 179 setValue( "enabled", false ); 180 setValue( "autoconnect", true ); 181 setValue( "types", QStringList() << "ResolverType" << "StatusPushType" ); 182 endGroup(); 183 184 QStringList allAccounts = value( "accounts/allaccounts" ).toStringList(); 185 allAccounts << accountKey; 186 setValue( "accounts/allaccounts", allAccounts ); 187} 188 189 190void 191TomahawkSettings::createSpotifyAccount() 192{ 193 const QString accountKey = QString( "spotifyaccount_%1" ).arg( QUuid::createUuid().toString().mid( 1, 8 ) ); 194 beginGroup( "accounts/" + accountKey ); 195 setValue( "enabled", false ); 196 setValue( "types", QStringList() << "ResolverType" ); 197 setValue( "configuration", QVariantHash() ); 198 setValue( "accountfriendlyname", "Spotify" ); 199 endGroup(); 200 201 QStringList allAccounts = value( "accounts/allaccounts" ).toStringList(); 202 allAccounts << accountKey; 203 setValue( "accounts/allaccounts", allAccounts ); 204} 205 206 207void 208TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) 209{ 210 Q_UNUSED( newVersion ); 211 212 if ( oldVersion == 1 ) 213 { 214 qDebug() << "Migrating config from version 1 to 2: script resolver config name"; 215 if( contains( "script/resolvers" ) ) { 216 setValue( "script/loadedresolvers", value( "script/resolvers" ) ); 217 remove( "script/resolvers" ); 218 } 219 } 220 else if ( oldVersion == 2 ) 221 { 222 qDebug() << "Migrating config from version 2 to 3: Converting jabber and twitter accounts to new SIP Factory approach"; 223 // migrate old accounts to new system. only jabber and twitter, and max one each. create a new plugin for each if needed 224 // not pretty as we hardcode a plugin id and assume that we know how the config layout is, but hey, this is migration after all 225 if ( contains( "jabber/username" ) && contains( "jabber/password" ) ) 226 { 227 QString sipName = "sipjabber"; 228 if ( value( "jabber/username" ).toString().contains( "@gmail" ) ) 229 sipName = "sipgoogle"; 230 231 setValue( QString( "%1_legacy/username" ).arg( sipName ), value( "jabber/username" ) ); 232 setValue( QString( "%1_legacy/password" ).arg( sipName ), value( "jabber/password" ) ); 233 setValue( QString( "%1_legacy/autoconnect" ).arg( sipName ), value( "jabber/autoconnect" ) ); 234 setValue( QString( "%1_legacy/port" ).arg( sipName ), value( "jabber/port" ) ); 235 setValue( QString( "%1_legacy/server" ).arg( sipName ), value( "jabber/server" ) ); 236 237 addSipPlugin( QString( "%1_legacy" ).arg( sipName ) ); 238 239 remove( "jabber/username" ); 240 remove( "jabber/password" ); 241 remove( "jabber/autoconnect" ); 242 remove( "jabber/server" ); 243 remove( "jabber/port" ); 244 } 245 if ( contains( "twitter/ScreenName" ) && contains( "twitter/OAuthToken" ) ) 246 { 247 setValue( "siptwitter_legacy/ScreenName", value( "twitter/ScreenName" ) ); 248 setValue( "siptwitter_legacy/OAuthToken", value( "twitter/OAuthToken" ) ); 249 setValue( "siptwitter_legacy/OAuthTokenSecret", value( "twitter/OAuthTokenSecret" ) ); 250 setValue( "siptwitter_legacy/CachedFriendsSinceID", value( "twitter/CachedFriendsSinceID" ) ); 251 setValue( "siptwitter_legacy/CachedMentionsSinceID", value( "twitter/CachedMentionsSinceID" ) ); 252 setValue( "siptwitter_legacy/CachedDirectMessagesSinceID", value( "twitter/CachedDirectMessagesSinceID" ) ); 253 setValue( "siptwitter_legacy/CachedPeers", value( "twitter/CachedPeers" ) ); 254 setValue( "siptwitter_legacy/AutoConnect", value( "jabber/autoconnect" ) ); 255 256 addSipPlugin( "siptwitter_legacy" ); 257 remove( "twitter/ScreenName" ); 258 remove( "twitter/OAuthToken" ); 259 remove( "twitter/OAuthTokenSecret" ); 260 remove( "twitter/CachedFriendsSinceID" ); 261 remove( "twitter/CachedMentionsSinceID" ); 262 remove( "twitter/CachedDirectMessagesSinceID" ); 263 } 264 // create a zeroconf plugin too 265 addSipPlugin( "sipzeroconf_legacy" ); 266 } 267 else if ( oldVersion == 3 ) 268 { 269 if ( contains( "script/atticaresolverstates" ) ) 270 { 271 // Do messy binary upgrade. remove attica resolvers :( 272 setValue( "script/atticaresolverstates", QVariant() ); 273 274 QDir resolverDir = TomahawkUtils::appDataDir(); 275 if ( !resolverDir.cd( QString( "atticaresolvers" ) ) ) 276 return; 277 278 QStringList toremove; 279 QStringList resolvers = resolverDir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ); 280 QStringList listedResolvers = value( "script/resolvers" ).toStringList(); 281 QStringList enabledResolvers = value( "script/loadedresolvers" ).toStringList(); 282 foreach ( const QString& resolver, resolvers ) 283 { 284 foreach ( const QString& r, listedResolvers ) 285 { 286 if ( r.contains( resolver ) ) 287 { 288 tDebug() << "Deleting listed resolver:" << r; 289 listedResolvers.removeAll( r ); 290 } 291 } 292 foreach ( const QString& r, enabledResolvers ) 293 { 294 if ( r.contains( resolver ) ) 295 { 296 tDebug() << "Deleting enabled resolver:" << r; 297 enabledResolvers.removeAll( r ); 298 } 299 } 300 } 301 setValue( "script/resolvers", listedResolvers ); 302 setValue( "script/loadedresolvers", enabledResolvers ); 303 tDebug() << "UPGRADING AND DELETING:" << resolverDir.absolutePath(); 304 TomahawkUtils::removeDirectory( resolverDir.absolutePath() ); 305 } 306 } 307 else if ( oldVersion == 4 || oldVersion == 5 ) 308 { 309 // 0.3.0 contained a bug which prevent indexing local files. Force a reindex. 310 Tomahawk::DatabaseFuzzyIndex::wipeIndex(); 311 updateIndex(); 312 } 313 else if ( oldVersion == 6 ) 314 { 315 // Migrate to accounts from sipplugins. 316 // collect old connected and enabled sip plugins 317 const QStringList allSip = sipPlugins(); 318 const QStringList enabledSip = enabledSipPlugins(); 319 320 QStringList accounts; 321 foreach ( const QString& sipPlugin, allSip ) 322 { 323 const QStringList parts = sipPlugin.split( "_" ); 324 Q_ASSERT( parts.size() == 2 ); 325 326 const QString pluginName = parts[ 0 ]; 327 const QString pluginId = parts[ 1 ]; 328 329 // new key, <plugin>account_<id> 330 QString rawpluginname = pluginName; 331 rawpluginname.replace( "sip", "" ); 332 if ( rawpluginname.contains( "jabber" ) ) 333 rawpluginname.replace( "jabber", "xmpp" ); 334 335 QString accountKey = QString( "%1account_%2" ).arg( rawpluginname ).arg( pluginId ); 336 337 if ( pluginName == "sipjabber" || pluginName == "sipgoogle" ) 338 { 339 QVariantHash credentials; 340 credentials[ "username" ] = value( sipPlugin + "/username" ); 341 credentials[ "password" ] = value( sipPlugin + "/password" ); 342 343 QVariantHash configuration; 344 configuration[ "port" ] = value( sipPlugin + "/port" ); 345 configuration[ "server" ] = value( sipPlugin + "/server" ); 346 347 setValue( QString( "accounts/%1/credentials" ).arg( accountKey ), credentials ); 348 setValue( QString( "accounts/%1/configuration" ).arg( accountKey ), configuration ); 349 setValue( QString( "accounts/%1/accountfriendlyname" ).arg( accountKey ), value( sipPlugin + "/username" ) ); 350 351 } 352 else if ( pluginName == "siptwitter" ) 353 { 354 // Only port twitter plugin if there's a valid twitter config 355 if ( value( sipPlugin + "/oauthtokensecret" ).toString().isEmpty() && 356 value( sipPlugin + "/oauthtoken" ).toString().isEmpty() && 357 value( sipPlugin + "/screenname" ).toString().isEmpty() ) 358 continue; 359 360 QVariantMap credentials; 361 credentials[ "oauthtoken" ] = value( sipPlugin + "/oauthtoken" ); 362 credentials[ "oauthtokensecret" ] = value( sipPlugin + "/oauthtokensecret" ); 363 credentials[ "username" ] = value( sipPlugin + "/screenname" ); 364 365 QVariantHash configuration; 366 configuration[ "cachedfriendssinceid" ] = value( sipPlugin + "/cachedfriendssinceid" ); 367 configuration[ "cacheddirectmessagessinceid" ] = value( sipPlugin + "/cacheddirectmessagessinceid" ); 368 configuration[ "cachedpeers" ] = value( sipPlugin + "/cachedpeers" ); 369 qDebug() << "FOUND CACHED PEERS:" << value( sipPlugin + "/cachedpeers" ).toHash(); 370 configuration[ "cachedmentionssinceid" ] = value( sipPlugin + "/cachedmentionssinceid" ); 371 configuration[ "saveddbid" ] = value( sipPlugin + "/saveddbid" ); 372 373 setValue( QString( "accounts/%1/credentials" ).arg( accountKey ), credentials ); 374 setValue( QString( "accounts/%1/configuration" ).arg( accountKey ), configuration ); 375 setValue( QString( "accounts/%1/accountfriendlyname" ).arg( accountKey ), "@" + value( sipPlugin + "/screenname" ).toString() ); 376 sync(); 377 } 378 else if ( pluginName == "sipzeroconf" ) 379 { 380 setValue( QString( "accounts/%1/accountfriendlyname" ).arg( accountKey ), tr( "Local Network" ) ); 381 } 382 383 beginGroup( "accounts/" + accountKey ); 384 setValue( "enabled", enabledSip.contains( sipPlugin ) == true ); 385 setValue( "autoconnect", true ); 386 setValue( "acl", QVariantHash() ); 387 setValue( "types", QStringList() << "SipType" ); 388 endGroup(); 389 accounts << accountKey; 390 391 remove( sipPlugin ); 392 } 393 remove( "sip" ); 394 395 // Migrate all resolvers from old resolvers settings to new accounts system 396 const QStringList allResolvers = value( "script/resolvers" ).toStringList(); 397 const QStringList enabledResolvers = value( "script/loadedresolvers" ).toStringList(); 398 399 foreach ( const QString& resolver, allResolvers ) 400 { 401 // We handle last.fm resolvers differently. 402 if ( resolver.contains( "lastfm" ) ) 403 continue; 404 405 const QString accountKey = QString( "resolveraccount_%1" ).arg( QUuid::createUuid().toString().mid( 1, 8 ) ); 406 accounts << accountKey; 407 408 beginGroup( "accounts/" + accountKey ); 409 setValue( "accountfriendlyname", resolver ); 410 setValue( "enabled", enabledResolvers.contains( resolver ) == true ); 411 setValue( "autoconnect", true ); 412 setValue( "types", QStringList() << "ResolverType" ); 413 414 QVariantHash configuration; 415 configuration[ "path" ] = resolver; 416 417 // reasonably ugly check for attica resolvers 418 if ( resolver.contains( "atticaresolvers" ) && resolver.contains( "code" ) ) 419 { 420 setValue( "atticaresolver", true ); 421 422 QFileInfo info( resolver ); 423 configuration[ "atticaId" ] = info.baseName(); 424 } 425 426 setValue( "configuration", configuration ); 427 endGroup(); 428 } 429 430 // Add a Last.Fm account since we now moved the infoplugin into the account 431 const QString accountKey = QString( "lastfmaccount_%1" ).arg( QUuid::createUuid().toString().mid( 1, 8 ) ); 432 accounts << accountKey; 433 const QString lfmUsername = value( "lastfm/username" ).toString(); 434 const QString lfmPassword = value( "lastfm/password" ).toString(); 435 const bool scrobble = value( "lastfm/enablescrobbling", false ).toBool(); 436 beginGroup( "accounts/" + accountKey ); 437 bool hasLastFmEnabled = false; 438 foreach ( const QString& r, enabledResolvers ) 439 { 440 if ( r.contains( "lastfm" ) ) 441 { 442 hasLastFmEnabled = true; 443 break; 444 } 445 } 446 setValue( "enabled", hasLastFmEnabled ); 447 setValue( "autoconnect", true ); 448 setValue( "types", QStringList() << "ResolverType" << "StatusPushType" ); 449 QVariantMap credentials; 450 credentials[ "username" ] = lfmUsername; 451 credentials[ "password" ] = lfmPassword; 452 credentials[ "session" ] = value( "lastfm/session" ).toString(); 453 setValue( "credentials", credentials ); 454 QVariantHash configuration; 455 configuration[ "scrobble" ] = scrobble; 456 setValue( "configuration", configuration ); 457 endGroup(); 458 459 remove( "lastfm" ); 460 461 remove( "script/resolvers" ); 462 remove( "script/loadedresolvers" ); 463 464 setValue( "accounts/allaccounts", accounts ); 465 } 466 else if ( oldVersion == 7 ) 467 { 468 // Upgrade spotify resolver to standalone account, if one exists 469 beginGroup( "accounts" ); 470 QStringList allAccounts = value( "allaccounts" ).toStringList(); 471 foreach ( const QString& account, allAccounts ) 472 { 473 if ( account.startsWith( "resolveraccount_" ) && value( QString( "%1/accountfriendlyname" ).arg( account ) ).toString().endsWith( "spotify_tomahawkresolver" ) ) 474 { 475 // This is a spotify resolver, convert! 476 const QVariantHash configuration = value( QString( "%1/configuration" ).arg( account ) ).toHash(); 477 const bool enabled = value( QString( "%1/enabled" ).arg( account ) ).toBool(); 478 const bool autoconnect = value( QString( "%1/autoconnect" ).arg( account ) ).toBool(); 479 480 qDebug() << "Migrating Spotify resolver from legacy resolver type, path is:" << configuration[ "path" ].toString(); 481 482 remove( account ); 483 484 // Create new account 485 QString newAccount = account; 486 newAccount.replace( "resolveraccount_", "spotifyaccount_" ); 487 beginGroup( newAccount ); 488 setValue( "enabled", enabled ); 489 setValue( "autoconnect", autoconnect ); 490 setValue( "types", QStringList() << "ResolverType" ); 491 setValue( "accountfriendlyname", "Spotify" ); 492 setValue( "configuration", configuration ); 493 endGroup(); 494 495 allAccounts.replace( allAccounts.indexOf( account ), newAccount ); 496 } 497 } 498 499 setValue( "allaccounts", allAccounts ); 500 endGroup(); 501 } 502 else if ( oldVersion == 8 ) 503 { 504 // Some users got duplicate accounts for some reason, so make them unique if we can 505 QSet< QString > uniqueFriendlyNames; 506 beginGroup("accounts"); 507 const QStringList accounts = childGroups(); 508 QStringList allAccounts = value( "allaccounts" ).toStringList(); 509 510// qDebug() << "Got accounts to migrate:" << accounts; 511 foreach ( const QString& account, accounts ) 512 { 513 if ( !allAccounts.contains( account ) ) // orphan 514 { 515 qDebug() << "Found account not in allaccounts list!" << account << "is a dup!"; 516 remove( account ); 517 continue; 518 } 519 520 const QString friendlyName = value( QString( "%1/accountfriendlyname" ).arg( account ) ).toString(); 521 if ( !uniqueFriendlyNames.contains( friendlyName ) ) 522 { 523 uniqueFriendlyNames.insert( friendlyName ); 524 continue; 525 } 526 else 527 { 528 // Duplicate..? 529 qDebug() << "Found duplicate account friendly name:" << account << friendlyName << "is a dup!"; 530 remove( account ); 531 allAccounts.removeAll( account ); 532 } 533 } 534 qDebug() << "Ended up with all accounts list:" << allAccounts << "and all accounts:" << childGroups(); 535 setValue( "allaccounts", allAccounts ); 536 endGroup(); 537 } 538 else if ( oldVersion == 9 ) 539 { 540 // Upgrade single-updater-per-playlist to list-per-playlist 541 beginGroup( "playlistupdaters" ); 542 const QStringList playlists = childGroups(); 543 544 SerializedUpdaters updaters; 545 foreach ( const QString& playlist, playlists ) 546 { 547 beginGroup( playlist ); 548 const QString type = value( "type" ).toString(); 549 550 QVariantHash extraData; 551 foreach ( const QString& key, childKeys() ) 552 { 553 if ( key == "type" ) 554 continue; 555 556 extraData[ key ] = value( key ); 557 } 558 559 updaters.insert( playlist, SerializedUpdater( type, extraData ) ); 560 561 endGroup(); 562 } 563 564 endGroup(); 565 remove( "playlistupdaters" ); 566 567 setValue( "playlists/updaters", QVariant::fromValue< SerializedUpdaters >( updaters ) ); 568 569 } 570 else if ( oldVersion == 11 ) 571 { 572 // If the user doesn't have a spotify account, create one, since now it 573 // is like the last.fm account and always exists 574 QStringList allAccounts = value( "accounts/allaccounts" ).toStringList(); 575 QString acct; 576 foreach ( const QString& account, allAccounts ) 577 { 578 if ( account.startsWith( "spotifyaccount_" ) ) 579 { 580 acct = account; 581 break; 582 } 583 } 584 585 if ( !acct.isEmpty() ) 586 { 587 beginGroup( "accounts/" + acct ); 588 QVariantHash conf = value( "configuration" ).toHash(); 589 foreach ( const QString& key, conf.keys() ) 590 qDebug() << key << conf[ key ].toString(); 591 endGroup(); 592 } 593 else 594 { 595 createSpotifyAccount(); 596 } 597 } 598 else if ( oldVersion == 12 ) 599 { 600 // Force attica resolver pixmap cache refresh 601 QDir cacheDir = TomahawkUtils::appDataDir(); 602 if ( cacheDir.cd( "atticacache" ) ) 603 { 604 QStringList files = cacheDir.entryList( QStringList() << "*.png" ); 605 foreach ( const QString& file, files ) 606 { 607 const bool removed = cacheDir.remove( file ); 608 tDebug() << "Tried to remove cached image, succeeded?" << removed << cacheDir.filePath( file ); 609 } 610 } 611 } 612 else if ( oldVersion == 13 ) 613 { 614 //Delete old echonest_stylesandmoods.dat file 615 QFile dataFile( TomahawkUtils::appDataDir().absoluteFilePath( "echonest_stylesandmoods.dat" ) ); 616 const bool removed = dataFile.remove(); 617 tDebug() << "Tried to remove echonest_stylesandmoods.dat, succeeded?" << removed; 618 } 619 else if ( oldVersion == 14 ) 620 { 621 //No upgrade on OSX: we keep storing credentials in TomahawkSettings 622 //because QtKeychain and/or OSX Keychain is flaky. --Teo 12/2013 623#ifndef Q_OS_MAC 624 const QStringList accounts = value( "accounts/allaccounts" ).toStringList(); 625 tDebug() << "About to move these accounts to QtKeychain:" << accounts; 626 627 //Move storage of Credentials from QSettings to QtKeychain 628 foreach ( const QString& account, accounts ) 629 { 630 tDebug() << "beginGroup" << QString( "accounts/%1" ).arg( account ); 631 beginGroup( QString( "accounts/%1" ).arg( account ) ); 632 const QVariantHash hash = value( "credentials" ).toHash(); 633 tDebug() << hash[ "username" ] 634 << ( hash[ "password" ].isNull() ? ", no password" : ", has password" ); 635 636 QVariantMap creds; 637 for ( QVariantHash::const_iterator it = hash.constBegin(); it != hash.constEnd(); ++it ) 638 { 639 creds.insert( it.key(), it.value() ); 640 641 } 642 if ( !creds.isEmpty() ) 643 { 644 QKeychain::WritePasswordJob* j = new QKeychain::WritePasswordJob( QLatin1String( "Tomahawk" ), this ); 645 j->setKey( account ); 646 j->setAutoDelete( true ); 647#if defined( Q_OS_UNIX ) && !defined( Q_OS_MAC ) 648 j->setInsecureFallback( true ); 649#endif 650 bool ok; 651 QByteArray data = TomahawkUtils::toJson( creds, &ok ); 652 653 if ( ok ) 654 { 655 tDebug() << "Performing upgrade for account" << account; 656 } 657 else 658 { 659 tDebug() << "Upgrade error: cannot serialize credentials to JSON for account" << account; 660 } 661 662 j->setTextData( data ); 663 j->start(); 664 } 665 666 remove( "credentials" ); 667 668 endGroup(); 669 } 670#endif //Q_OS_MAC 671 } 672 else if ( oldVersion == 15 ) 673 { 674 // 0.8.0 switches to Lucene++. Force a reindex. 675 // (obsoleted by version 16 update) 676 } 677 else if ( oldVersion == 16 ) 678 { 679 Tomahawk::DatabaseFuzzyIndex::wipeIndex(); 680 updateIndex(); 681 } 682} 683 684 685void 686TomahawkSettings::setAcceptedLegalWarning( bool accept ) 687{ 688 setValue( "acceptedLegalWarning", accept ); 689} 690 691 692bool 693TomahawkSettings::acceptedLegalWarning() const 694{ 695 return value( "acceptedLegalWarning", false ).toBool(); 696} 697 698 699void 700TomahawkSettings::setInfoSystemCacheVersion( uint version ) 701{ 702 setValue( "infosystemcacheversion", version ); 703} 704 705 706uint 707TomahawkSettings::infoSystemCacheVersion() const 708{ 709 return value( "infosystemcacheversion", 0 ).toUInt(); 710} 711 712 713void 714TomahawkSettings::setGenericCacheVersion( uint version ) 715{ 716 setValue( "genericcacheversion", version ); 717} 718 719 720uint 721TomahawkSettings::genericCacheVersion() const 722{ 723 return value( "genericcacheversion", 0 ).toUInt(); 724} 725 726 727QString 728TomahawkSettings::storageCacheLocation() const 729{ 730 return QStandardPaths::writableLocation( QStandardPaths::CacheLocation ); 731} 732 733 734QStringList 735TomahawkSettings::scannerPaths() const 736{ 737 QString musicLocation; 738 739 musicLocation = QStandardPaths::writableLocation( QStandardPaths::MusicLocation ); 740 741 return value( "scanner/paths", musicLocation ).toStringList(); 742} 743 744 745void 746TomahawkSettings::setScannerPaths( const QStringList& paths ) 747{ 748 setValue( "scanner/paths", paths ); 749} 750 751 752bool 753TomahawkSettings::hasScannerPaths() const 754{ 755 //FIXME: After enough time, remove this hack 756 return contains( "scanner/paths" ) || contains( "scannerpath" ) || contains( "scannerpaths" ); 757} 758 759 760uint 761TomahawkSettings::scannerTime() const 762{ 763 return value( "scanner/intervaltime", 60 ).toUInt(); 764} 765 766 767void 768TomahawkSettings::setScannerTime( uint time ) 769{ 770 setValue( "scanner/intervaltime", time ); 771} 772 773 774bool 775TomahawkSettings::watchForChanges() const 776{ 777 return value( "scanner/watchforchanges", false ).toBool(); 778} 779 780 781void 782TomahawkSettings::setWatchForChanges( bool watch ) 783{ 784 setValue( "scanner/watchforchanges", watch ); 785} 786 787 788QString 789TomahawkSettings::downloadsPreferredFormat() const 790{ 791 return value( "downloadmanager/preferredFormat", "MP3" ).toString(); 792} 793 794 795void 796TomahawkSettings::setDownloadsPreferredFormat( const QString& format ) 797{ 798 setValue( "downloadmanager/preferredFormat", format ); 799} 800 801 802QString 803TomahawkSettings::downloadsPath() const 804{ 805 QString musicLocation; 806 if ( !scannerPaths().isEmpty() ) 807 musicLocation = scannerPaths().first(); 808 809 return value( "downloadmanager/path", musicLocation ).toString(); 810} 811 812 813void 814TomahawkSettings::setDownloadsPath( const QString& path ) 815{ 816 setValue( "downloadmanager/path", path ); 817} 818 819 820QVariantList 821TomahawkSettings::downloadStates() const 822{ 823 return value( "downloadmanager/states", QVariantList() ).toList(); 824} 825 826 827void 828TomahawkSettings::setDownloadStates( const QVariantList& downloads ) 829{ 830 setValue( "downloadmanager/states", downloads ); 831} 832 833 834bool 835TomahawkSettings::httpEnabled() const 836{ 837 return value( "network/http", true ).toBool(); 838} 839 840 841void 842TomahawkSettings::setHttpEnabled( bool enable ) 843{ 844 setValue( "network/http", enable ); 845} 846 847 848bool 849TomahawkSettings::httpBindAll() const 850{ 851 return value ( "network/httpbindall", false ).toBool(); 852} 853 854 855void 856TomahawkSettings::setHttpBindAll( bool bindAll ) 857{ 858 setValue( "network/httpbindall", bindAll ); 859} 860 861 862bool 863TomahawkSettings::crashReporterEnabled() const 864{ 865 return value( "ui/crashReporter", true ).toBool(); 866} 867 868 869void 870TomahawkSettings::setCrashReporterEnabled( bool enable ) 871{ 872 setValue( "ui/crashReporter", enable ); 873} 874 875 876bool 877TomahawkSettings::songChangeNotificationEnabled() const 878{ 879 return value( "ui/songChangeNotification", true ).toBool(); 880} 881 882 883void 884TomahawkSettings::setSongChangeNotificationEnabled(bool enable) 885{ 886 setValue( "ui/songChangeNotification", enable ); 887} 888 889 890bool 891TomahawkSettings::autoDetectExternalIp() const 892{ 893 return value( "network/auto-detect-external-ip" ).toBool(); 894} 895 896 897void 898TomahawkSettings::setAutoDetectExternalIp( bool autoDetect ) 899{ 900 setValue( "network/auto-detect-external-ip", autoDetect ); 901} 902 903 904unsigned int 905TomahawkSettings::volume() const 906{ 907 return value( "audio/volume", 75 ).toUInt(); 908} 909 910 911void 912TomahawkSettings::setVolume( unsigned int volume ) 913{ 914 setValue( "audio/volume", volume ); 915} 916 917 918bool 919TomahawkSettings::muted() const 920{ 921 return value( "audio/muted" ).toBool(); 922} 923 924 925void 926TomahawkSettings::setMuted( bool muted ) 927{ 928 setValue( "audio/muted", muted ); 929} 930 931 932QString 933TomahawkSettings::proxyHost() const 934{ 935 return value( "network/proxy/host", QString() ).toString(); 936} 937 938 939void 940TomahawkSettings::setProxyHost( const QString& host ) 941{ 942 setValue( "network/proxy/host", host ); 943} 944 945 946QString 947TomahawkSettings::proxyNoProxyHosts() const 948{ 949 return value( "network/proxy/noproxyhosts", QString() ).toString(); 950} 951 952 953void 954TomahawkSettings::setProxyNoProxyHosts( const QString& hosts ) 955{ 956 setValue( "network/proxy/noproxyhosts", hosts ); 957} 958 959 960qulonglong 961TomahawkSettings::proxyPort() const 962{ 963 return value( "network/proxy/port", 1080 ).toULongLong(); 964} 965 966 967void 968TomahawkSettings::setProxyPort( const qulonglong port ) 969{ 970 setValue( "network/proxy/port", port ); 971} 972 973 974QString 975TomahawkSettings::proxyUsername() const 976{ 977 return value( "network/proxy/username", QString() ).toString(); 978} 979 980 981void 982TomahawkSettings::setProxyUsername( const QString& username ) 983{ 984 setValue( "network/proxy/username", username ); 985} 986 987 988QString 989TomahawkSettings::proxyPassword() const 990{ 991 return value( "network/proxy/password", QString() ).toString(); 992} 993 994 995void 996TomahawkSettings::setProxyPassword( const QString& password ) 997{ 998 setValue( "network/proxy/password", password ); 999} 1000 1001 1002QNetworkProxy::ProxyType 1003TomahawkSettings::proxyType() const 1004{ 1005 return static_cast< QNetworkProxy::ProxyType>( value( "network/proxy/type", QNetworkProxy::NoProxy ).toInt() ); 1006} 1007 1008 1009void 1010TomahawkSettings::setProxyType( const QNetworkProxy::ProxyType type ) 1011{ 1012 setValue( "network/proxy/type", static_cast< uint >( type ) ); 1013} 1014 1015 1016bool 1017TomahawkSettings::proxyDns() const 1018{ 1019 return value( "network/proxy/dns", false ).toBool(); 1020} 1021 1022 1023void 1024TomahawkSettings::setProxyDns( bool lookupViaProxy ) 1025{ 1026 setValue( "network/proxy/dns", lookupViaProxy ); 1027} 1028 1029 1030QVariantList 1031TomahawkSettings::aclEntries() const 1032{ 1033 QVariant retVal = value( "acl/entries", QVariantList() ); 1034 if ( retVal.isValid() && retVal.canConvert< QVariantList >() ) 1035 return retVal.toList(); 1036 1037 return QVariantList(); 1038} 1039 1040 1041void 1042TomahawkSettings::setAclEntries( const QVariantList &entries ) 1043{ 1044 tDebug() << "Setting entries"; 1045 setValue( "acl/entries", entries ); 1046 sync(); 1047 tDebug() << "Done setting entries"; 1048} 1049 1050 1051bool 1052TomahawkSettings::isSslCertKnown( const QByteArray& sslDigest ) const 1053{ 1054 return value( "network/ssl/certs" ).toMap().contains( sslDigest ); 1055} 1056 1057 1058bool 1059TomahawkSettings::isSslCertTrusted( const QByteArray& sslDigest ) const 1060{ 1061 return value( "network/ssl/certs" ).toMap().value( sslDigest, false ).toBool(); 1062} 1063 1064 1065void 1066TomahawkSettings::setSslCertTrusted( const QByteArray& sslDigest, bool trusted ) 1067{ 1068 QVariantMap map = value( "network/ssl/certs" ).toMap(); 1069 map[ sslDigest ] = trusted; 1070 1071 setValue( "network/ssl/certs", map ); 1072} 1073 1074 1075QByteArray 1076TomahawkSettings::mainWindowGeometry() const 1077{ 1078 return value( "ui/mainwindow/geometry" ).toByteArray(); 1079} 1080 1081 1082void 1083TomahawkSettings::setMainWindowGeometry( const QByteArray& geom ) 1084{ 1085 setValue( "ui/mainwindow/geometry", geom ); 1086} 1087 1088 1089QByteArray 1090TomahawkSettings::mainWindowState() const 1091{ 1092 return value( "ui/mainwindow/state" ).toByteArray(); 1093} 1094 1095 1096void 1097TomahawkSettings::setMainWindowState( const QByteArray& state ) 1098{ 1099 setValue( "ui/mainwindow/state", state ); 1100} 1101 1102 1103QByteArray 1104TomahawkSettings::mainWindowSplitterState() const 1105{ 1106 return value( "ui/mainwindow/splitterState" ).toByteArray(); 1107} 1108 1109 1110void 1111TomahawkSettings::setMainWindowSplitterState( const QByteArray& state ) 1112{ 1113 setValue( "ui/mainwindow/splitterState", state ); 1114} 1115 1116 1117bool 1118TomahawkSettings::verboseNotifications() const 1119{ 1120 return value( "ui/notifications/verbose", false ).toBool(); 1121} 1122 1123 1124void 1125TomahawkSettings::setVerboseNotifications( bool notifications ) 1126{ 1127 setValue( "ui/notifications/verbose", notifications ); 1128} 1129 1130 1131bool 1132TomahawkSettings::menuBarVisible() const 1133{ 1134#ifndef Q_OS_MAC 1135 return value( "ui/mainwindow/menuBarVisible", true ).toBool(); 1136#else 1137 return true; 1138#endif 1139} 1140 1141 1142void 1143TomahawkSettings::setMenuBarVisible( bool visible ) 1144{ 1145#ifndef Q_OS_MAC 1146 setValue( "ui/mainwindow/menuBarVisible", visible ); 1147#endif 1148} 1149 1150 1151bool 1152TomahawkSettings::fullscreenEnabled() const 1153{ 1154 return value( "ui/mainwindow/fullscreenEnabled", false ).toBool(); 1155} 1156 1157 1158void 1159TomahawkSettings::setFullscreenEnabled( bool enabled ) 1160{ 1161 setValue( "ui/mainwindow/fullscreenEnabled", enabled ); 1162} 1163 1164 1165bool 1166TomahawkSettings::showOfflineSources() const 1167{ 1168 return value( "collection/sources/showoffline", false ).toBool(); 1169} 1170 1171 1172void 1173TomahawkSettings::setShowOfflineSources( bool show ) 1174{ 1175 setValue( "collection/sources/showoffline", show ); 1176} 1177 1178 1179bool 1180TomahawkSettings::enableEchonestCatalogs() const 1181{ 1182 return value( "collection/enable_catalogs", false ).toBool(); 1183} 1184 1185 1186void 1187TomahawkSettings::setEnableEchonestCatalogs( bool enable ) 1188{ 1189 setValue( "collection/enable_catalogs", enable ); 1190} 1191 1192 1193QByteArray 1194TomahawkSettings::playlistColumnSizes( const QString& playlistid ) const 1195{ 1196 return value( QString( "ui/playlist/%1/columnSizes" ).arg( playlistid ) ).toByteArray(); 1197} 1198 1199 1200void 1201TomahawkSettings::setPlaylistColumnSizes( const QString& playlistid, const QByteArray& state ) 1202{ 1203 if ( playlistid.isEmpty() ) 1204 return; 1205 1206 setValue( QString( "ui/playlist/%1/columnSizes" ).arg( playlistid ), state ); 1207} 1208 1209 1210bool 1211TomahawkSettings::shuffleState( const QString& playlistid ) const 1212{ 1213 return value( QString( "ui/playlist/%1/shuffleState" ).arg( playlistid ) ).toBool(); 1214} 1215 1216 1217void 1218TomahawkSettings::setShuffleState( const QString& playlistid, bool state) 1219{ 1220 setValue( QString( "ui/playlist/%1/shuffleState" ).arg( playlistid ), state ); 1221} 1222 1223 1224void 1225TomahawkSettings::removePlaylistSettings( const QString& playlistid ) 1226{ 1227 remove( QString( "ui/playlist/%1/shuffleState" ).arg( playlistid ) ); 1228 remove( QString( "ui/playlist/%1/repeatMode" ).arg( playlistid ) ); 1229} 1230 1231 1232QVariant 1233TomahawkSettings::queueState() const 1234{ 1235 return value( QString( "playlists/queue/state" ) ); 1236} 1237 1238 1239void 1240TomahawkSettings::setQueueState( const QVariant& state ) 1241{ 1242 setValue( QString( "playlists/queue/state" ), state ); 1243} 1244 1245 1246void 1247TomahawkSettings::setRepeatMode( const QString& playlistid, Tomahawk::PlaylistModes::RepeatMode mode ) 1248{ 1249 setValue( QString( "ui/playlist/%1/repeatMode" ).arg( playlistid ), (int)mode ); 1250} 1251 1252 1253Tomahawk::PlaylistModes::RepeatMode 1254TomahawkSettings::repeatMode( const QString& playlistid ) 1255{ 1256 return (PlaylistModes::RepeatMode)value( QString( "ui/playlist/%1/repeatMode" ).arg( playlistid ) ).toInt(); 1257} 1258 1259 1260QStringList 1261TomahawkSettings::recentlyPlayedPlaylistGuids( unsigned int amount ) const 1262{ 1263 QStringList p = value( "playlists/recentlyPlayed" ).toStringList(); 1264 1265 while ( amount && p.count() > (int)amount ) 1266 p.removeAt( 0 ); 1267 1268 return p; 1269} 1270 1271 1272void 1273TomahawkSettings::appendRecentlyPlayedPlaylist( const QString& playlistguid, int sourceId ) 1274{ 1275 QStringList playlist_guids = value( "playlists/recentlyPlayed" ).toStringList(); 1276 1277 playlist_guids.removeAll( playlistguid ); 1278 playlist_guids.append( playlistguid ); 1279 1280 setValue( "playlists/recentlyPlayed", playlist_guids ); 1281 1282 emit recentlyPlayedPlaylistAdded( playlistguid, sourceId ); 1283} 1284 1285 1286QString 1287TomahawkSettings::bookmarkPlaylist() const 1288{ 1289 return value( "playlists/bookmark", QString() ).toString(); 1290} 1291 1292 1293void 1294TomahawkSettings::setBookmarkPlaylist( const QString& guid ) 1295{ 1296 setValue( "playlists/bookmark", guid ); 1297} 1298 1299 1300QStringList 1301TomahawkSettings::sipPlugins() const 1302{ 1303 return value( "sip/allplugins", QStringList() ).toStringList(); 1304} 1305 1306 1307void 1308TomahawkSettings::setSipPlugins( const QStringList& plugins ) 1309{ 1310 setValue( "sip/allplugins", plugins ); 1311} 1312 1313 1314QStringList 1315TomahawkSettings::enabledSipPlugins() const 1316{ 1317 return value( "sip/enabledplugins", QStringList() ).toStringList(); 1318} 1319 1320 1321void 1322TomahawkSettings::setEnabledSipPlugins( const QStringList& list ) 1323{ 1324 setValue( "sip/enabledplugins", list ); 1325} 1326 1327 1328void 1329TomahawkSettings::enableSipPlugin( const QString& pluginId ) 1330{ 1331 QStringList list = enabledSipPlugins(); 1332 list << pluginId; 1333 setEnabledSipPlugins( list ); 1334} 1335 1336 1337void 1338TomahawkSettings::disableSipPlugin( const QString& pluginId ) 1339{ 1340 QStringList list = enabledSipPlugins(); 1341 list.removeAll( pluginId ); 1342 setEnabledSipPlugins( list ); 1343} 1344 1345 1346void 1347TomahawkSettings::addSipPlugin( const QString& pluginId, bool enable ) 1348{ 1349 QStringList list = sipPlugins(); 1350 list << pluginId; 1351 setSipPlugins( list ); 1352 1353 if ( enable ) 1354 enableSipPlugin( pluginId ); 1355} 1356 1357 1358void 1359TomahawkSettings::removeSipPlugin( const QString& pluginId ) 1360{ 1361 QStringList list = sipPlugins(); 1362 list.removeAll( pluginId ); 1363 setSipPlugins( list ); 1364 1365 if( enabledSipPlugins().contains( pluginId ) ) 1366 disableSipPlugin( pluginId ); 1367} 1368 1369 1370QStringList 1371TomahawkSettings::accounts() const 1372{ 1373 QStringList accounts = value( "accounts/allaccounts", QStringList() ).toStringList(); 1374 accounts.removeDuplicates(); 1375 1376 return accounts; 1377} 1378 1379 1380void 1381TomahawkSettings::setAccounts( const QStringList& accountIds ) 1382{ 1383 QStringList accounts = accountIds; 1384 accounts.removeDuplicates(); 1385 1386 setValue( "accounts/allaccounts", accounts ); 1387} 1388 1389 1390void 1391TomahawkSettings::addAccount( const QString& accountId ) 1392{ 1393 QStringList list = accounts(); 1394 list << accountId; 1395 setAccounts( list ); 1396} 1397 1398 1399void 1400TomahawkSettings::removeAccount( const QString& accountId ) 1401{ 1402 QStringList list = accounts(); 1403 list.removeAll( accountId ); 1404 setAccounts( list ); 1405} 1406 1407 1408Tomahawk::Network::ExternalAddress::Mode 1409TomahawkSettings::externalAddressMode() 1410{ 1411 if ( value( "network/prefer-static-host-and-port", false ).toBool() ) 1412 { 1413 remove( "network/prefer-static-host-and-port" ); 1414 setValue( "network/external-address-mode", Tomahawk::Network::ExternalAddress::Static ); 1415 } 1416 return (Tomahawk::Network::ExternalAddress::Mode) value( "network/external-address-mode", Tomahawk::Network::ExternalAddress::Upnp ).toInt(); 1417} 1418 1419 1420void 1421TomahawkSettings::setExternalAddressMode( Tomahawk::Network::ExternalAddress::Mode externalAddressMode ) 1422{ 1423 setValue( "network/external-address-mode", externalAddressMode ); 1424} 1425 1426 1427QString 1428TomahawkSettings::externalHostname() const 1429{ 1430 return value( "network/external-hostname" ).toString(); 1431} 1432 1433 1434void 1435TomahawkSettings::setExternalHostname(const QString& externalHostname) 1436{ 1437 setValue( "network/external-hostname", externalHostname ); 1438} 1439 1440 1441int 1442TomahawkSettings::defaultPort() const 1443{ 1444 return 50210; 1445} 1446 1447 1448int 1449TomahawkSettings::externalPort() const 1450{ 1451 return value( "network/external-port", 50210 ).toInt(); 1452} 1453 1454 1455void 1456TomahawkSettings::setExternalPort(int externalPort) 1457{ 1458 if ( externalPort == 0 ) 1459 setValue( "network/external-port", 50210); 1460 else 1461 setValue( "network/external-port", externalPort); 1462} 1463 1464 1465QString 1466TomahawkSettings::xmppBotServer() const 1467{ 1468 return value( "xmppBot/server", QString() ).toString(); 1469} 1470 1471 1472void 1473TomahawkSettings::setXmppBotServer( const QString& server ) 1474{ 1475 setValue( "xmppBot/server", server ); 1476} 1477 1478 1479QString 1480TomahawkSettings::xmppBotJid() const 1481{ 1482 return value( "xmppBot/jid", QString() ).toString(); 1483} 1484 1485 1486void 1487TomahawkSettings::setXmppBotJid( const QString& component ) 1488{ 1489 setValue( "xmppBot/jid", component ); 1490} 1491 1492 1493QString 1494TomahawkSettings::xmppBotPassword() const 1495{ 1496 return value( "xmppBot/password", QString() ).toString(); 1497} 1498 1499 1500void 1501TomahawkSettings::setXmppBotPassword( const QString& password ) 1502{ 1503 setValue( "xmppBot/password", password ); 1504} 1505 1506 1507int 1508TomahawkSettings::xmppBotPort() const 1509{ 1510 return value( "xmppBot/port", -1 ).toInt(); 1511} 1512 1513 1514void 1515TomahawkSettings::setXmppBotPort( const int port ) 1516{ 1517 setValue( "xmppBot/port", port ); 1518} 1519 1520 1521QString 1522TomahawkSettings::scriptDefaultPath() const 1523{ 1524 return value( "script/defaultpath", QDir::homePath() ).toString(); 1525} 1526 1527 1528void 1529TomahawkSettings::setScriptDefaultPath( const QString& path ) 1530{ 1531 setValue( "script/defaultpath", path ); 1532} 1533 1534 1535QString 1536TomahawkSettings::playlistDefaultPath() const 1537{ 1538 return value( "playlists/defaultpath", QDir::homePath() ).toString(); 1539} 1540 1541 1542void 1543TomahawkSettings::setPlaylistDefaultPath( const QString& path ) 1544{ 1545 setValue( "playlists/defaultpath", path ); 1546} 1547 1548 1549bool 1550TomahawkSettings::nowPlayingEnabled() const 1551{ 1552 return value( "adium/enablenowplaying", false ).toBool(); 1553} 1554 1555 1556void 1557TomahawkSettings::setNowPlayingEnabled( bool enable ) 1558{ 1559 setValue( "adium/enablenowplaying", enable ); 1560} 1561 1562 1563TomahawkSettings::PrivateListeningMode 1564TomahawkSettings::privateListeningMode() const 1565{ 1566 return ( TomahawkSettings::PrivateListeningMode ) value( "privatelisteningmode", TomahawkSettings::PublicListening ).toInt(); 1567} 1568 1569 1570void 1571TomahawkSettings::setPrivateListeningMode( TomahawkSettings::PrivateListeningMode mode ) 1572{ 1573 setValue( "privatelisteningmode", mode ); 1574} 1575 1576 1577void 1578TomahawkSettings::updateIndex() 1579{ 1580 if ( !Database::instance() || !Database::instance()->isReady() ) 1581 { 1582 QTimer::singleShot( 0, this, SLOT( updateIndex() ) ); 1583 return; 1584 } 1585 1586 tDebug() << Q_FUNC_INFO << "Updating fuzzy index."; 1587 1588 Tomahawk::DatabaseCommand* cmd = new Tomahawk::DatabaseCommand_UpdateSearchIndex(); 1589 Database::instance()->enqueue( QSharedPointer<Tomahawk::DatabaseCommand>( cmd ) ); 1590} 1591 1592 1593QString 1594TomahawkSettings::importPlaylistPath() const 1595{ 1596 if ( contains( "importPlaylistPath" ) ) 1597 return value( "importPlaylistPath" ).toString(); 1598 else 1599 return QDir::homePath(); 1600} 1601 1602 1603void 1604TomahawkSettings::setImportPlaylistPath( const QString& path ) 1605{ 1606 setValue( "importPlaylistPath", path ); 1607} 1608 1609 1610SerializedUpdaters 1611TomahawkSettings::playlistUpdaters() const 1612{ 1613 return value( "playlists/updaters" ).value< SerializedUpdaters >(); 1614} 1615 1616 1617void 1618TomahawkSettings::setPlaylistUpdaters( const SerializedUpdaters& updaters ) 1619{ 1620 setValue( "playlists/updaters", QVariant::fromValue< SerializedUpdaters >( updaters ) ); 1621} 1622 1623 1624void 1625TomahawkSettings::setLastChartIds( const QMap<QString, QVariant>& ids ){ 1626 1627 setValue( "chartIds", QVariant::fromValue<QMap<QString, QVariant> >( ids ) ); 1628} 1629 1630 1631QMap<QString, QVariant> TomahawkSettings::lastChartIds(){ 1632 1633 return value( "chartIds" ).value<QMap<QString, QVariant> >(); 1634} 1635 1636 1637inline QDataStream& 1638operator<<( QDataStream& out, const AtticaManager::StateHash& states ) 1639{ 1640 out << TOMAHAWK_SETTINGS_VERSION; 1641 out << (quint32)states.count(); 1642 foreach( const QString& key, states.keys() ) 1643 { 1644 AtticaManager::Resolver resolver = states[ key ]; 1645 out << key << resolver.version << resolver.scriptPath << (qint32)resolver.state << resolver.userRating << resolver.binary; 1646 } 1647 return out; 1648} 1649 1650 1651inline QDataStream& 1652operator>>( QDataStream& in, AtticaManager::StateHash& states ) 1653{ 1654 quint32 count = 0, configVersion = 0; 1655 in >> configVersion; 1656 in >> count; 1657 for ( uint i = 0; i < count; i++ ) 1658 { 1659 QString key, version, scriptPath; 1660 qint32 state, userRating; 1661 bool binary = false; 1662 in >> key; 1663 in >> version; 1664 in >> scriptPath; 1665 in >> state; 1666 in >> userRating; 1667 if ( configVersion > 10 ) 1668 { 1669 // V11 includes 'bool binary' flag 1670 in >> binary; 1671 } 1672 states[ key ] = AtticaManager::Resolver( version, scriptPath, userRating, (AtticaManager::ResolverState)state, binary ); 1673 } 1674 return in; 1675} 1676 1677 1678void 1679TomahawkSettings::registerCustomSettingsHandlers() 1680{ 1681 qRegisterMetaType< Tomahawk::SerializedUpdater >( "Tomahawk::SerializedUpdater" ); 1682 qRegisterMetaType< Tomahawk::SerializedUpdaters >( "Tomahawk::SerializedUpdaters" ); 1683 qRegisterMetaTypeStreamOperators< Tomahawk::SerializedUpdaters >( "Tomahawk::SerializedUpdaters" ); 1684 1685 qRegisterMetaType< AtticaManager::StateHash >( "AtticaManager::StateHash" ); 1686 qRegisterMetaTypeStreamOperators< AtticaManager::StateHash >( "AtticaManager::StateHash" ); 1687} 1688 1689 1690void 1691TomahawkSettings::setAtticaResolverState( const QString& resolver, AtticaManager::ResolverState state ) 1692{ 1693 AtticaManager::StateHash resolvers = value( "script/atticaresolverstates" ).value< AtticaManager::StateHash >(); 1694 AtticaManager::Resolver r = resolvers.value( resolver ); 1695 r.state = state; 1696 resolvers.insert( resolver, r ); 1697 setValue( "script/atticaresolverstates", QVariant::fromValue< AtticaManager::StateHash >( resolvers ) ); 1698 1699 sync(); 1700} 1701 1702 1703AtticaManager::StateHash 1704TomahawkSettings::atticaResolverStates() const 1705{ 1706 return value( "script/atticaresolverstates" ).value< AtticaManager::StateHash >(); 1707} 1708 1709 1710void 1711TomahawkSettings::setAtticaResolverStates( const AtticaManager::StateHash states ) 1712{ 1713 setValue( "script/atticaresolverstates", QVariant::fromValue< AtticaManager::StateHash >( states ) ); 1714} 1715 1716 1717void 1718TomahawkSettings::removeAtticaResolverState ( const QString& resolver ) 1719{ 1720 AtticaManager::StateHash resolvers = value( "script/atticaresolverstates" ).value< AtticaManager::StateHash >(); 1721 resolvers.remove( resolver ); 1722 setValue( "script/atticaresolverstates", QVariant::fromValue< AtticaManager::StateHash >( resolvers ) ); 1723} 1724 1725 1726QByteArray 1727TomahawkSettings::playdarCertificate() const 1728{ 1729 return value( "playdar/certificate").value< QByteArray >(); 1730} 1731 1732 1733void 1734TomahawkSettings::setPlaydarCertificate( const QByteArray& cert ) 1735{ 1736 setValue( "playdar/certificate", cert ); 1737} 1738 1739 1740QByteArray 1741TomahawkSettings::playdarKey() const 1742{ 1743 return value( "playdar/key" ).value< QByteArray >(); 1744} 1745 1746 1747void 1748TomahawkSettings::setPlaydarKey( const QByteArray& key ) 1749{ 1750 setValue( "playdar/key", key ); 1751} 1752 1753QString 1754TomahawkSettings::vlcArguments() const 1755{ 1756 return value( "vlc/cmdline_args" ).value< QString >(); 1757} 1758 1759void 1760TomahawkSettings::setVlcArguments( const QString& args ) 1761{ 1762 setValue( "vlc/cmdline_args", args); 1763} 1764