/src/resolversmodel.cpp

http://github.com/tomahawk-player/tomahawk · C++ · 251 lines · 192 code · 42 blank · 17 comment · 32 complexity · e147ecf68b3c8cf20be92d3f466eaf44 MD5 · raw file

  1. /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2. *
  3. * Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
  4. *
  5. * Tomahawk is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * Tomahawk is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "resolversmodel.h"
  19. #include <QFileInfo>
  20. #include "tomahawksettings.h"
  21. #include "tomahawkapp.h"
  22. #include "ExternalResolverGui.h"
  23. #include "pipeline.h"
  24. #include "config.h"
  25. #include "AtticaManager.h"
  26. #include "utils/logger.h"
  27. ResolversModel::ResolversModel( QObject* parent )
  28. : QAbstractListModel( parent )
  29. {
  30. addInstalledResolvers();
  31. }
  32. ResolversModel::~ResolversModel()
  33. {
  34. }
  35. QVariant
  36. ResolversModel::data( const QModelIndex& index, int role ) const
  37. {
  38. if( !index.isValid() || !hasIndex( index.row(), index.column(), QModelIndex() ) )
  39. return QVariant();
  40. Tomahawk::ExternalResolver* r = Tomahawk::Pipeline::instance()->scriptResolvers().at( index.row() );
  41. Tomahawk::ExternalResolverGui* res = qobject_cast< Tomahawk::ExternalResolverGui* >( r );
  42. Q_ASSERT(res); // this is part of the gui, so there should be no non-gui resolvers
  43. switch( role )
  44. {
  45. case Qt::DisplayRole:
  46. case ResolversModel::ResolverName:
  47. return res->name();
  48. case ResolversModel::ResolverPath:
  49. return res->filePath();
  50. case ResolversModel::HasConfig:
  51. return res->configUI() != 0;
  52. case ResolversModel::ErrorState:
  53. return res->error();
  54. case Qt::CheckStateRole:
  55. return res->running() ? Qt::Checked : Qt::Unchecked;
  56. case Qt::ToolTipRole:
  57. return res->filePath();
  58. default:
  59. return QVariant();
  60. }
  61. }
  62. bool
  63. ResolversModel::setData( const QModelIndex& index, const QVariant& value, int role )
  64. {
  65. if ( !hasIndex( index.row(), index.column(), QModelIndex() ) )
  66. return false;
  67. Tomahawk::ExternalResolver* r = Tomahawk::Pipeline::instance()->scriptResolvers().at( index.row() );
  68. if ( r && r->error() == Tomahawk::ExternalResolver::FileNotFound ) // give it a shot to see if the user manually fixed paths
  69. {
  70. r->reload();
  71. if( r->error() == Tomahawk::ExternalResolver::FileNotFound ) // Nope, no luck. Doesn't exist on disk, don't let user mess with it
  72. return false;
  73. }
  74. else if ( !r && !QFile::exists( r->filePath() ) )
  75. {
  76. return false;
  77. }
  78. if ( role == Qt::CheckStateRole )
  79. {
  80. Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() );
  81. if ( state == Qt::Checked && !r->running() ) {
  82. r->start();
  83. }
  84. else if ( state == Qt::Unchecked )
  85. {
  86. r->stop();
  87. }
  88. emit dataChanged( index, index );
  89. return true;
  90. }
  91. return false;
  92. }
  93. int
  94. ResolversModel::rowCount( const QModelIndex& parent ) const
  95. {
  96. Q_UNUSED( parent );
  97. return Tomahawk::Pipeline::instance()->scriptResolvers().count();
  98. }
  99. int
  100. ResolversModel::columnCount(const QModelIndex& parent) const
  101. {
  102. Q_UNUSED( parent );
  103. return 1;
  104. }
  105. Qt::ItemFlags
  106. ResolversModel::flags( const QModelIndex& index ) const
  107. {
  108. return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable;
  109. }
  110. void
  111. ResolversModel::addResolver( const QString& resolver, bool enable )
  112. {
  113. const int count = rowCount( QModelIndex() );
  114. beginInsertRows( QModelIndex(), count, count );
  115. Tomahawk::ExternalResolver* r = Tomahawk::Pipeline::instance()->addScriptResolver( resolver, enable );
  116. Tomahawk::ExternalResolverGui* res = qobject_cast< Tomahawk::ExternalResolverGui* >( r );
  117. Q_ASSERT(res); // this is part of the gui, so there should be no non-gui resolvers
  118. connect( res, SIGNAL( changed() ), this, SLOT( resolverChanged() ) );
  119. endInsertRows();
  120. if ( res->configUI() )
  121. emit openConfig( res->filePath() );
  122. else
  123. m_waitingForLoad << resolver;
  124. }
  125. void
  126. ResolversModel::atticaResolverInstalled( const QString& resolverId )
  127. {
  128. #ifdef LIBATTICA_FOUND
  129. Tomahawk::ExternalResolver* r = Tomahawk::Pipeline::instance()->resolverForPath( AtticaManager::instance()->pathFromId( resolverId ) );
  130. if ( !r )
  131. return;
  132. const int idx = Tomahawk::Pipeline::instance()->scriptResolvers().indexOf( r );
  133. if ( idx >= 0 )
  134. {
  135. beginInsertRows( QModelIndex(), idx, idx );
  136. endInsertRows();
  137. }
  138. #endif
  139. }
  140. void
  141. ResolversModel::removeResolver( const QString& resolver )
  142. {
  143. const int idx = Tomahawk::Pipeline::instance()->scriptResolvers().indexOf( Tomahawk::Pipeline::instance()->resolverForPath( resolver ) );
  144. if ( idx < 0 )
  145. return;
  146. beginRemoveRows( QModelIndex(), idx, idx );
  147. Tomahawk::Pipeline::instance()->removeScriptResolver( resolver );
  148. endRemoveRows();
  149. }
  150. void
  151. ResolversModel::resolverChanged()
  152. {
  153. Tomahawk::ExternalResolver* res = qobject_cast< Tomahawk::ExternalResolver* >( sender() );
  154. Q_ASSERT( res );
  155. if ( Tomahawk::Pipeline::instance()->scriptResolvers().contains( res ) )
  156. {
  157. qDebug() << "Got resolverChanged signal, does it have a config UI yet?" << qobject_cast< Tomahawk::ExternalResolverGui* >(res)->configUI();
  158. const QModelIndex idx = index( Tomahawk::Pipeline::instance()->scriptResolvers().indexOf( res ), 0, QModelIndex() );
  159. emit dataChanged( idx, idx );
  160. if ( m_waitingForLoad.contains( res->filePath() ) )
  161. {
  162. m_waitingForLoad.remove( res->filePath() );
  163. emit openConfig( res->filePath() );
  164. }
  165. }
  166. }
  167. void
  168. ResolversModel::addInstalledResolvers()
  169. {
  170. QList< QDir > pluginDirs;
  171. QDir appDir( qApp->applicationDirPath() );
  172. QDir libDir( CMAKE_INSTALL_PREFIX "/lib" );
  173. QDir libexecDir( CMAKE_INSTALL_FULL_LIBEXECDIR );
  174. QDir lib64Dir( appDir );
  175. lib64Dir.cdUp();
  176. lib64Dir.cd( "lib64" );
  177. pluginDirs << appDir << libDir << lib64Dir << libexecDir;
  178. foreach ( const QDir& pluginDir, pluginDirs )
  179. {
  180. qDebug() << "Checking directory for resolvers:" << pluginDir;
  181. foreach ( QString fileName, pluginDir.entryList( QStringList() << "*_tomahawkresolver*", QDir::Files ) ){
  182. if ( fileName.contains( "_tomahawkresolver" ) ) {
  183. const QString path = pluginDir.absoluteFilePath( fileName );
  184. bool found = false;
  185. foreach ( Tomahawk::ExternalResolver* res, Tomahawk::Pipeline::instance()->scriptResolvers() )
  186. {
  187. if ( res->filePath() == path )
  188. found = true;
  189. }
  190. if ( !found ) {
  191. Tomahawk::Pipeline::instance()->addScriptResolver( path, false );
  192. }
  193. }
  194. }
  195. }
  196. }
  197. void
  198. ResolversModel::saveScriptResolvers()
  199. {
  200. QStringList enabled, all;
  201. foreach ( Tomahawk::ExternalResolver* res, Tomahawk::Pipeline::instance()->scriptResolvers() )
  202. {
  203. all << res->filePath();
  204. if ( res->running() )
  205. enabled << res->filePath();
  206. }
  207. TomahawkSettings::instance()->setAllScriptResolvers( all );
  208. TomahawkSettings::instance()->setEnabledScriptResolvers( enabled );
  209. }