1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-02-24 03:43:56 +01:00

Handle resolver file paths becoming invalid properly. Show user file is not found, etc.

This commit is contained in:
Leo Franchi 2011-07-19 22:26:08 -04:00
parent efd7911efc
commit dabbd38cc7
11 changed files with 141 additions and 27 deletions

View File

@ -97,13 +97,13 @@ ConfigDelegateBase::editorEvent ( QEvent* event, QAbstractItemModel* model, cons
return false;
// eat the double click events inside the check rect
if( event->type() == QEvent::MouseButtonDblClick ) {
return true;
}
if( event->type() == QEvent::MouseButtonDblClick ) {
return true;
}
Qt::CheckState curState = static_cast< Qt::CheckState >( index.data( Qt::CheckStateRole ).toInt() );
Qt::CheckState newState = curState == Qt::Checked ? Qt::Unchecked : Qt::Checked;
return model->setData( index, newState, Qt::CheckStateRole );
Qt::CheckState curState = static_cast< Qt::CheckState >( index.data( Qt::CheckStateRole ).toInt() );
Qt::CheckState newState = curState == Qt::Checked ? Qt::Unchecked : Qt::Checked;
return model->setData( index, newState, Qt::CheckStateRole );
} else if( event->type() == QEvent::MouseButtonPress ) {
QMouseEvent* me = static_cast< QMouseEvent* >( event );

View File

@ -27,6 +27,13 @@
#include <QDir>
#include <QIcon>
Tomahawk::ExternalResolver::ErrorState
Tomahawk::ExternalResolver::error() const
{
return NoError;
}
QVariant
Tomahawk::ExternalResolver::configMsgFromWidget( QWidget* w )
{

View File

@ -59,6 +59,11 @@ class DLLEXPORT ExternalResolver : public Resolver
Q_OBJECT
public:
enum ErrorState {
NoError,
FileNotFound
};
ExternalResolver( const QString& filePath ) { m_filePath = filePath; }
virtual QString filePath() const { return m_filePath; }
@ -66,6 +71,9 @@ public:
virtual QWidget* configUI() const = 0;
virtual void saveConfig() = 0;
virtual void reload() {} // Reloads from file (especially useful to check if file now exists)
virtual ErrorState error() const;
public slots:
virtual void stop() = 0;
@ -76,6 +84,9 @@ protected:
QWidget* widgetFromData( QByteArray& data, QWidget* parent = 0 );
QVariant configMsgFromWidget( QWidget* w );
QByteArray fixDataImagePaths( const QByteArray& data, bool compressed, const QVariantMap& images );
void setFilePath( const QString& path ) { m_filePath = path; }
private:
void addChildProperties( QObject* parent, QVariantMap& m );

View File

@ -20,6 +20,7 @@
#include "resolverconfigdelegate.h"
#include "resolversmodel.h"
#include "resolver.h"
#include <QApplication>
#include <QPainter>
@ -50,6 +51,7 @@ ResolverConfigDelegate::paint( QPainter* painter, const QStyleOptionViewItem& op
path.setItalic( true );
path.setPointSize( path.pointSize() - 1 );
const bool fileFound = (Tomahawk::ExternalResolver::ErrorState)index.data( ResolversModel::ErrorState ).toInt() == Tomahawk::ExternalResolver::FileNotFound;
QFontMetrics bfm( name );
QFontMetrics sfm( path );
@ -92,9 +94,17 @@ ResolverConfigDelegate::paint( QPainter* painter, const QStyleOptionViewItem& op
painter->save();
painter->setFont( path );
painter->setBrush( Qt::gray );
QString pathStr = index.data( ResolversModel::ResolverPath ).toString();
if( fileFound )
{
painter->setPen( QColor( Qt::red ).lighter( 150 ) );
pathStr = tr( "Not found: %1" ).arg( pathStr );
} else
{
painter->setPen( Qt::gray );
}
textRect.moveTop( itemRect.height() / 2 + top );
QString pathStr = sfm.elidedText( index.data( ResolversModel::ResolverPath ).toString(),Qt::ElideMiddle, textRect.width() );
pathStr = sfm.elidedText( pathStr, Qt::ElideMiddle, textRect.width() );
painter->drawText( textRect, pathStr );
painter->restore();

View File

@ -21,7 +21,7 @@
#define RESOLVERCONFIGDELEGATE_H
#include "configdelegatebase.h"
#include "source.h"
class ResolverConfigDelegate : public ConfigDelegateBase
{

View File

@ -108,18 +108,53 @@ QtScriptResolver::QtScriptResolver( const QString& scriptPath )
: Tomahawk::ExternalResolver( scriptPath )
, m_ready( false )
, m_stopped( false )
, m_error( Tomahawk::ExternalResolver::NoError )
, m_resolverHelper( new QtScriptResolverHelper( scriptPath, this ) )
{
qDebug() << Q_FUNC_INFO << scriptPath;
m_engine = new ScriptEngine( this );
QFile scriptFile( scriptPath );
if ( !scriptFile.open( QIODevice::ReadOnly ) )
if ( !QFile::exists( filePath() ) )
{
qDebug() << Q_FUNC_INFO << "Failed loading JavaScript resolver:" << scriptPath;
deleteLater();
m_error = Tomahawk::ExternalResolver::FileNotFound;
} else
{
init();
}
}
QtScriptResolver::~QtScriptResolver()
{
Tomahawk::Pipeline::instance()->removeResolver( this );
delete m_engine;
}
void
QtScriptResolver::reload()
{
if ( QFile::exists( filePath() ) )
{
init();
m_error = Tomahawk::ExternalResolver::NoError;
} else
{
m_error = Tomahawk::ExternalResolver::FileNotFound;
}
}
void
QtScriptResolver::init()
{
QFile scriptFile( filePath() );
if( !scriptFile.open( QIODevice::ReadOnly ) )
{
qWarning() << "Failed to read contents of file:" << filePath() << scriptFile.errorString();
return;
}
const QByteArray scriptContents = scriptFile.readAll();
m_engine->mainFrame()->setHtml( "<html><body></body></html>" );
@ -134,9 +169,8 @@ QtScriptResolver::QtScriptResolver( const QString& scriptPath )
jslib.close();
// add resolver
m_engine->setScriptPath( scriptPath );
m_engine->mainFrame()->evaluateJavaScript( scriptFile.readAll() );
scriptFile.close();
m_engine->setScriptPath( filePath() );
m_engine->mainFrame()->evaluateJavaScript( scriptContents );
// init resolver
resolverInit();
@ -157,14 +191,12 @@ QtScriptResolver::QtScriptResolver( const QString& scriptPath )
Tomahawk::Pipeline::instance()->addResolver( this );
}
QtScriptResolver::~QtScriptResolver()
Tomahawk::ExternalResolver::ErrorState
QtScriptResolver::error() const
{
Tomahawk::Pipeline::instance()->removeResolver( this );
delete m_engine;
return m_error;
}
void
QtScriptResolver::resolve( const Tomahawk::query_ptr& query )
{

View File

@ -110,6 +110,9 @@ public:
virtual QWidget* configUI() const;
virtual void saveConfig();
virtual ExternalResolver::ErrorState error() const;
virtual void reload();
public slots:
virtual void resolve( const Tomahawk::query_ptr& query );
virtual void stop();
@ -118,7 +121,9 @@ signals:
void finished();
private:
virtual void loadUi();
void init();
void loadUi();
QWidget* findWidget( QWidget* widget, const QString& objectName );
void setWidgetData( const QVariant& value, QWidget* widget, const QString& property );
QVariant widgetData( QWidget* widget, const QString& property );
@ -136,6 +141,7 @@ private:
unsigned int m_weight, m_timeout;
bool m_ready, m_stopped;
ExternalResolver::ErrorState m_error;
QtScriptResolverHelper* m_resolverHelper;
QWeakPointer< QWidget > m_configWidget;

View File

@ -33,19 +33,22 @@ ScriptResolver::ScriptResolver( const QString& exe )
, m_msgsize( 0 )
, m_ready( false )
, m_stopped( false )
, m_error( Tomahawk::ExternalResolver::NoError )
{
qDebug() << Q_FUNC_INFO << exe;
connect( &m_proc, SIGNAL( readyReadStandardError() ), SLOT( readStderr() ) );
connect( &m_proc, SIGNAL( readyReadStandardOutput() ), SLOT( readStdout() ) );
connect( &m_proc, SIGNAL( finished( int, QProcess::ExitStatus ) ), SLOT( cmdExited( int, QProcess::ExitStatus ) ) );
QString filepath = filePath();
#ifdef WIN32
// have to enclose in quotes if path contains spaces on windows...
filepath = QString( "\"%1\"" ).arg( filepath );
setFilePath( QString( "\"%1\"" ).arg( filePath() ) );
#endif
m_proc.start( filepath );
if( !QFile::exists( filePath() ) )
m_error = Tomahawk::ExternalResolver::FileNotFound;
else
m_proc.start( filePath() );
}
@ -60,12 +63,29 @@ ScriptResolver::~ScriptResolver()
}
void
ScriptResolver::reload()
{
if( !QFile::exists( filePath() ) )
m_error = Tomahawk::ExternalResolver::FileNotFound;
else
{
m_proc.start( filePath() );
m_error = Tomahawk::ExternalResolver::NoError;
}
}
void
ScriptResolver::readStderr()
{
qDebug() << "SCRIPT_STDERR" << filePath() << m_proc.readAllStandardError();
}
ScriptResolver::ErrorState
ScriptResolver::error() const
{
return m_error;
}
void
ScriptResolver::readStdout()
@ -102,6 +122,8 @@ void
ScriptResolver::sendMsg( const QByteArray& msg )
{
// qDebug() << Q_FUNC_INFO << m_ready << msg << msg.length();
if( !m_proc.isOpen() )
return;
quint32 len;
qToBigEndian( msg.length(), (uchar*) &len );

View File

@ -28,6 +28,7 @@
#include "resolver.h"
#include "query.h"
#include "result.h"
#include "source.h"
class QWidget;
class ScriptResolver : public Tomahawk::ExternalResolver
@ -46,6 +47,9 @@ public:
virtual QWidget* configUI() const;
virtual void saveConfig();
virtual ExternalResolver::ErrorState error() const;
virtual void reload();
signals:
void finished();
@ -73,6 +77,7 @@ private:
QByteArray m_msg;
bool m_ready, m_stopped;
ExternalResolver::ErrorState m_error;
QJson::Parser m_parser;
QJson::Serializer m_serializer;

View File

@ -20,8 +20,9 @@
#include <QFileInfo>
#include <tomahawksettings.h>
#include <tomahawkapp.h>
#include "tomahawksettings.h"
#include "tomahawkapp.h"
#include "resolver.h"
ResolversModel::ResolversModel( const QStringList& allResolvers, const QStringList& enabledResolvers, QObject* parent )
@ -69,8 +70,16 @@ ResolversModel::data( const QModelIndex& index, int role ) const
if( Tomahawk::ExternalResolver* r = TomahawkApp::instance()->resolverForPath( m_allResolvers.at( index.row() ) ) ) // if we have one, it means we are loaded too!
return r->configUI() != 0;
return false;
case ResolversModel::ErrorState:
if( Tomahawk::ExternalResolver* r = TomahawkApp::instance()->resolverForPath( m_allResolvers.at( index.row() ) ) ) // if we have one, it means we are loaded too!
return r->error();
else if( !QFile::exists( m_allResolvers.at( index.row() ) ) )
return Tomahawk::ExternalResolver::FileNotFound;
return Tomahawk::ExternalResolver::NoError;
case Qt::CheckStateRole:
return m_enabledResolvers.contains( m_allResolvers.at( index.row() ) ) ? Qt::Checked : Qt::Unchecked;
case Qt::ToolTipRole:
return m_allResolvers.at( index.row() );
default:
return QVariant();
}
@ -79,6 +88,17 @@ ResolversModel::data( const QModelIndex& index, int role ) const
bool
ResolversModel::setData( const QModelIndex& index, const QVariant& value, int role )
{
Tomahawk::ExternalResolver* r = TomahawkApp::instance()->resolverForPath( m_allResolvers.at( index.row() ) );
if( r && r->error() == Tomahawk::ExternalResolver::FileNotFound ) // give it a shot to see if the user manually fixed paths
{
r->reload();
if( r->error() == Tomahawk::ExternalResolver::FileNotFound ) // Nope, no luck. Doesn't exist on disk, don't let user mess with it
return false;
} else if( !r && !QFile::exists( index.data( ResolverPath ).toString() ) ) {
return false;
}
if( role == Qt::CheckStateRole ) {
Qt::CheckState state = static_cast< Qt::CheckState >( value.toInt() );
QString resolver = m_allResolvers.at( index.row() );

View File

@ -31,7 +31,8 @@ public:
enum Roles {
ResolverName = Qt::UserRole + 15,
ResolverPath = Qt::UserRole + 16,
HasConfig = Qt::UserRole + 17
HasConfig = Qt::UserRole + 17,
ErrorState = Qt::UserRole + 18
};
explicit ResolversModel( const QStringList& allResolvers, const QStringList& enabledResolvers, QObject* parent = 0 );