mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-03-25 10:19:41 +01:00
Merge branch 'master' into spotifyplaylists
Conflicts: src/accounts/lastfm/lastfmplugin.h src/libtomahawk/playlist.h src/libtomahawk/resolvers/scriptresolver.cpp src/main.cpp src/tomahawkapp.h
This commit is contained in:
commit
059d0374c6
@ -26,8 +26,21 @@ add_definitions( "-fvisibility=hidden" )
|
||||
# build options
|
||||
option(BUILD_GUI "Build Tomahawk with GUI" ON)
|
||||
option(BUILD_RELEASE "Generate TOMAHAWK_VERSION without GIT info" OFF)
|
||||
option(WITH_BREAKPAD "Build with breakpad integration" ON)
|
||||
option(WITH_CRASHREPORTER "Build with CrashReporter" ON)
|
||||
option(LEGACY_KDE_INTEGRATION "Install tomahawk.protocol file, deprecated since 4.6.0" OFF)
|
||||
|
||||
IF( CMAKE_SYSTEM_PROCESSOR MATCHES "arm" )
|
||||
message(STATUS "Build of breakpad library disabled on this platform.")
|
||||
SET(WITH_BREAKPAD OFF)
|
||||
SET(WITH_CRASHREPORTER OFF)
|
||||
ENDIF()
|
||||
|
||||
# add definitions based on build options
|
||||
IF(WITH_BREAKPAD)
|
||||
message(STATUS "Build with support for breakpad.")
|
||||
ENDIF()
|
||||
|
||||
# generate version string
|
||||
|
||||
# base string used in release and unstable builds
|
||||
@ -200,9 +213,3 @@ ADD_SUBDIRECTORY( src/libtomahawk )
|
||||
SET( TOMAHAWK_LIBRARIES tomahawklib )
|
||||
ADD_SUBDIRECTORY( src )
|
||||
ADD_SUBDIRECTORY( admin )
|
||||
|
||||
IF( BUILD_GUI )
|
||||
IF( NOT DISABLE_CRASHREPORTER )
|
||||
ADD_SUBDIRECTORY( src/breakpad/CrashReporter )
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
3505
lang/tomahawk_bg.ts
Normal file
3505
lang/tomahawk_bg.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -4,6 +4,8 @@
|
||||
<file>tomahawk_de.qm</file>
|
||||
<file>tomahawk_sv.qm</file>
|
||||
<file>tomahawk_es.qm</file>
|
||||
<file>tomahawk_bg.qm</file>
|
||||
<file>tomahawk_pl.qm</file>
|
||||
<file>tomahawk_pt_BR.qm</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -42,6 +42,7 @@ public:
|
||||
};
|
||||
|
||||
explicit AccountFactoryWrapper( Tomahawk::Accounts::AccountFactory* factory, QWidget* parent = 0 );
|
||||
virtual ~AccountFactoryWrapper() {}
|
||||
|
||||
public slots:
|
||||
void openAccountConfig( Tomahawk::Accounts::Account* );
|
||||
|
@ -68,8 +68,6 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
|
||||
sourcetree/items/groupitem.cpp
|
||||
sourcetree/items/historyitem.cpp
|
||||
|
||||
breakpad/BreakPad.cpp
|
||||
|
||||
utils/guihelpers.cpp
|
||||
|
||||
accounts/lastfm/LastFmAccount.cpp
|
||||
@ -93,6 +91,10 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
|
||||
AccountFactoryWrapperDelegate.cpp
|
||||
)
|
||||
|
||||
IF( WITH_BREAKPAD )
|
||||
LIST(APPEND tomahawkSourcesGui breakpad/BreakPad.cpp)
|
||||
ENDIF()
|
||||
|
||||
SET( tomahawkUI ${tomahawkUI}
|
||||
tomahawkwindow.ui
|
||||
diagnosticsdialog.ui
|
||||
@ -174,6 +176,10 @@ SET( final_src ${final_src} ${tomahawkMoc} ${tomahawkSources} ${trans_outfile})
|
||||
IF( BUILD_GUI )
|
||||
LIST(APPEND tomahawkSources ${tomahawkSourcesGui})
|
||||
qt4_wrap_ui( tomahawkUI_H ${tomahawkUI} )
|
||||
|
||||
IF( WITH_CRASHREPORTER )
|
||||
ADD_SUBDIRECTORY( breakpad/CrashReporter )
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
kde4_add_app_icon( tomahawkSources "${CMAKE_SOURCE_DIR}/data/icons/tomahawk-icon-*.png" )
|
||||
@ -206,9 +212,11 @@ ENDIF(GLOOX_FOUND)
|
||||
IF(QCA2_FOUND)
|
||||
SET(LINK_LIBRARIES ${LINK_LIBRARIES} ${QCA2_LIBRARIES} )
|
||||
ENDIF(QCA2_FOUND)
|
||||
IF(WITH_BREAKPAD)
|
||||
SET(LINK_LIBRARIES ${LINK_LIBRARIES} tomahawk_breakpad)
|
||||
ENDIF()
|
||||
|
||||
TARGET_LINK_LIBRARIES( tomahawk
|
||||
tomahawk_breakpad
|
||||
${LINK_LIBRARIES}
|
||||
${TOMAHAWK_LIBRARIES}
|
||||
${PHONON_LIBS}
|
||||
|
@ -270,6 +270,7 @@ LastFmAccount::hookupResolver()
|
||||
const Attica::Content res = AtticaManager::instance()->resolverForId( "lastfm" );
|
||||
const AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( res );
|
||||
Q_ASSERT( state == AtticaManager::Installed );
|
||||
Q_UNUSED( state );
|
||||
|
||||
const AtticaManager::Resolver data = AtticaManager::instance()->resolverData( res.id() );
|
||||
|
||||
|
@ -585,6 +585,8 @@ LastFmPlugin::topTracksReturned()
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
|
||||
|
||||
QStringList topTracks = lastfm::Artist::getTopTracks( reply );
|
||||
topTracks.removeDuplicates();
|
||||
|
||||
QVariantMap returnedData;
|
||||
returnedData["tracks"] = topTracks;
|
||||
|
||||
|
@ -14,6 +14,7 @@ set( xmppAccountSources
|
||||
sip/tomahawkxmppmessagefactory.cpp
|
||||
sip/avatarmanager.cpp
|
||||
sip/xmlconsole.cpp
|
||||
XmppInfoPlugin.cpp
|
||||
)
|
||||
|
||||
set( xmppAccountHeaders
|
||||
@ -22,6 +23,7 @@ set( xmppAccountHeaders
|
||||
sip/xmppsip.h
|
||||
sip/avatarmanager.h
|
||||
sip/xmlconsole.h
|
||||
XmppInfoPlugin.h
|
||||
)
|
||||
|
||||
set( xmppAccountUI
|
||||
|
143
src/accounts/xmpp/XmppInfoPlugin.cpp
Normal file
143
src/accounts/xmpp/XmppInfoPlugin.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2012, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk 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 Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "XmppInfoPlugin.h"
|
||||
|
||||
#include "globalactionmanager.h"
|
||||
#include "sip/xmppsip.h"
|
||||
#include "utils/logger.h"
|
||||
|
||||
#include <jreen/tune.h>
|
||||
#include <jreen/pubsubmanager.h>
|
||||
#include <jreen/jid.h>
|
||||
|
||||
#include <jreen/client.h>
|
||||
|
||||
// remove now playing status after PAUSE_TIMEOUT seconds
|
||||
static const int PAUSE_TIMEOUT = 60;
|
||||
|
||||
Tomahawk::InfoSystem::XmppInfoPlugin::XmppInfoPlugin(XmppSipPlugin* sipPlugin)
|
||||
: m_sipPlugin( sipPlugin )
|
||||
, m_pubSubManager( 0 )
|
||||
, m_pauseTimer( this )
|
||||
{
|
||||
Q_ASSERT( sipPlugin->m_client );
|
||||
|
||||
m_supportedPushTypes << InfoNowPlaying << InfoNowPaused << InfoNowResumed << InfoNowStopped;
|
||||
|
||||
m_pubSubManager = new Jreen::PubSub::Manager( sipPlugin->m_client );
|
||||
m_pubSubManager->addEntityType< Jreen::Tune >();
|
||||
|
||||
m_pauseTimer.setSingleShot( true );
|
||||
connect( &m_pauseTimer, SIGNAL( timeout() ),
|
||||
this, SLOT( audioStopped() ) );
|
||||
}
|
||||
|
||||
|
||||
Tomahawk::InfoSystem::XmppInfoPlugin::~XmppInfoPlugin()
|
||||
{
|
||||
delete m_pubSubManager;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Tomahawk::InfoSystem::XmppInfoPlugin::pushInfo(QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input)
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << m_sipPlugin->m_client->jid().full();
|
||||
|
||||
if( m_sipPlugin->m_account->configuration().value("publishtracks").toBool() == false )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << m_sipPlugin->m_client->jid().full() << "Not publishing now playing info (disabled in account config)";
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case InfoNowPlaying:
|
||||
case InfoNowResumed:
|
||||
m_pauseTimer.stop();
|
||||
if ( input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
|
||||
audioStarted( input.value< Tomahawk::InfoSystem::InfoStringHash >() );
|
||||
break;
|
||||
case InfoNowPaused:
|
||||
m_pauseTimer.start( PAUSE_TIMEOUT * 1000 );
|
||||
audioPaused();
|
||||
break;
|
||||
case InfoNowStopped:
|
||||
m_pauseTimer.stop();
|
||||
audioStopped();
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Tomahawk::InfoSystem::XmppInfoPlugin::audioStarted(const Tomahawk::InfoSystem::InfoStringHash& info)
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << m_sipPlugin->m_client->jid().full() << info;
|
||||
|
||||
Jreen::Tune::Ptr tune( new Jreen::Tune() );
|
||||
|
||||
tune->setTitle( info.value( "title" ) );
|
||||
tune->setArtist( info.value( "artist" ) );
|
||||
tune->setLength( info.value("duration").toInt() );
|
||||
tune->setTrack( info.value("albumpos") );
|
||||
tune->setUri( GlobalActionManager::instance()->openLink( info.value( "title" ), info.value( "artist" ), info.value( "album" ) ) );
|
||||
|
||||
//TODO: provide a rating once available in Tomahawk
|
||||
tune->setRating( 10 );
|
||||
|
||||
//TODO: it would be nice to set Spotify, Dilandau etc here, but not the jabber ids of friends
|
||||
tune->setSource( "Tomahawk" );
|
||||
|
||||
m_pubSubManager->publishItems( QList<Jreen::Payload::Ptr>() << tune, Jreen::JID() );
|
||||
}
|
||||
|
||||
void
|
||||
Tomahawk::InfoSystem::XmppInfoPlugin::audioPaused()
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << m_sipPlugin->m_client->jid().full();
|
||||
}
|
||||
|
||||
void
|
||||
Tomahawk::InfoSystem::XmppInfoPlugin::audioStopped()
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << m_sipPlugin->m_client->jid().full();
|
||||
|
||||
Jreen::Tune::Ptr tune( new Jreen::Tune() );
|
||||
m_pubSubManager->publishItems(QList<Jreen::Payload::Ptr>() << tune, Jreen::JID());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Tomahawk::InfoSystem::XmppInfoPlugin::getInfo(Tomahawk::InfoSystem::InfoRequestData requestData)
|
||||
{
|
||||
Q_UNUSED( requestData );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Tomahawk::InfoSystem::XmppInfoPlugin::notInCacheSlot(const Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData)
|
||||
{
|
||||
Q_UNUSED( criteria );
|
||||
Q_UNUSED( requestData );
|
||||
}
|
68
src/accounts/xmpp/XmppInfoPlugin.h
Normal file
68
src/accounts/xmpp/XmppInfoPlugin.h
Normal file
@ -0,0 +1,68 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2012, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk 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 Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMPPINFOPLUGIN_H
|
||||
#define XMPPINFOPLUGIN_H
|
||||
|
||||
#include "infosystem/infosystem.h"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
namespace Jreen {
|
||||
namespace PubSub {
|
||||
class Manager;
|
||||
}
|
||||
}
|
||||
|
||||
class XmppSipPlugin;
|
||||
|
||||
namespace Tomahawk {
|
||||
|
||||
namespace InfoSystem {
|
||||
|
||||
class XmppInfoPlugin : public InfoPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
XmppInfoPlugin(XmppSipPlugin* parent);
|
||||
virtual ~XmppInfoPlugin();
|
||||
|
||||
public slots:
|
||||
void notInCacheSlot( const Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
protected slots:
|
||||
void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input );
|
||||
void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
private slots:
|
||||
void audioStarted( const Tomahawk::InfoSystem::InfoStringHash& info );
|
||||
void audioStopped();
|
||||
void audioPaused();
|
||||
|
||||
private:
|
||||
XmppSipPlugin* m_sipPlugin;
|
||||
Jreen::PubSub::Manager* m_pubSubManager;
|
||||
QTimer m_pauseTimer;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // XMPPINFOPLUGIN_H
|
@ -7,6 +7,7 @@ set( googleHeaders
|
||||
../sip/xmppsip.h
|
||||
../sip/avatarmanager.h
|
||||
../sip/xmlconsole.h
|
||||
../XmppInfoPlugin.h
|
||||
googlewrapper.h )
|
||||
|
||||
set( googleSources
|
||||
@ -17,6 +18,7 @@ set( googleSources
|
||||
../sip/tomahawkxmppmessagefactory.cpp
|
||||
../sip/avatarmanager.cpp
|
||||
../sip/xmlconsole.cpp
|
||||
../XmppInfoPlugin.cpp
|
||||
|
||||
googlewrapper.cpp )
|
||||
|
||||
|
@ -56,6 +56,7 @@
|
||||
|
||||
#include <utils/tomahawkutilsgui.h>
|
||||
#include "utils/logger.h"
|
||||
#include "XmppInfoPlugin.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
using namespace Accounts;
|
||||
@ -85,6 +86,7 @@ JreenMessageHandler(QtMsgType type, const char *msg)
|
||||
|
||||
XmppSipPlugin::XmppSipPlugin( Account *account )
|
||||
: SipPlugin( account )
|
||||
, m_infoPlugin( 0 )
|
||||
, m_state( Account::Disconnected )
|
||||
#ifndef ENABLE_HEADLESS
|
||||
, m_menu( 0 )
|
||||
@ -163,6 +165,7 @@ XmppSipPlugin::XmppSipPlugin( Account *account )
|
||||
|
||||
XmppSipPlugin::~XmppSipPlugin()
|
||||
{
|
||||
delete m_infoPlugin;
|
||||
delete m_avatarManager;
|
||||
delete m_roster;
|
||||
#ifndef ENABLE_HEADLESS
|
||||
@ -172,6 +175,13 @@ XmppSipPlugin::~XmppSipPlugin()
|
||||
}
|
||||
|
||||
|
||||
InfoSystem::InfoPlugin*
|
||||
XmppSipPlugin::infoPlugin()
|
||||
{
|
||||
return m_infoPlugin;
|
||||
}
|
||||
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
QMenu*
|
||||
XmppSipPlugin::menu()
|
||||
@ -255,6 +265,13 @@ XmppSipPlugin::onConnect()
|
||||
// load roster
|
||||
m_roster->load();
|
||||
|
||||
// load XmppInfoPlugin
|
||||
if( !m_infoPlugin )
|
||||
{
|
||||
m_infoPlugin = new Tomahawk::InfoSystem::XmppInfoPlugin( this );
|
||||
InfoSystem::InfoSystem::instance()->addInfoPlugin( m_infoPlugin );
|
||||
}
|
||||
|
||||
//FIXME: this implementation is totally broken atm, so it's disabled to avoid harm :P
|
||||
// join MUC with bare jid as nickname
|
||||
//TODO: make the room a list of rooms and make that configurable
|
||||
|
@ -52,10 +52,14 @@
|
||||
|
||||
#include "accounts/accountdllmacro.h"
|
||||
|
||||
#include "XmppInfoPlugin.h"
|
||||
|
||||
class ACCOUNTDLLEXPORT XmppSipPlugin : public SipPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class Tomahawk::InfoSystem::XmppInfoPlugin;
|
||||
|
||||
public:
|
||||
XmppSipPlugin( Tomahawk::Accounts::Account* account );
|
||||
virtual ~XmppSipPlugin();
|
||||
@ -63,6 +67,8 @@ public:
|
||||
//FIXME: Make this more correct
|
||||
virtual bool isValid() const { return true; }
|
||||
|
||||
Tomahawk::InfoSystem::InfoPlugin* infoPlugin();
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
virtual QMenu* menu();
|
||||
#endif
|
||||
@ -123,10 +129,11 @@ private:
|
||||
QString m_currentPassword;
|
||||
QString m_currentServer;
|
||||
int m_currentPort;
|
||||
Tomahawk::Accounts::Account::ConnectionState m_state;
|
||||
|
||||
QString m_currentResource;
|
||||
|
||||
Tomahawk::InfoSystem::InfoPlugin* m_infoPlugin;
|
||||
Tomahawk::Accounts::Account::ConnectionState m_state;
|
||||
|
||||
// sort out
|
||||
Jreen::Client *m_client;
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "xmppconfigwidget.h"
|
||||
#include "sip/SipPlugin.h"
|
||||
#include "ui_xmppconfigwidget.h"
|
||||
#include "XmppInfoPlugin.h"
|
||||
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
@ -90,6 +91,16 @@ XmppAccount::saveConfig()
|
||||
}
|
||||
|
||||
|
||||
InfoSystem::InfoPlugin*
|
||||
XmppAccount::infoPlugin()
|
||||
{
|
||||
if( !m_xmppSipPlugin.isNull() )
|
||||
return m_xmppSipPlugin.data()->infoPlugin();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
SipPlugin*
|
||||
XmppAccount::sipPlugin()
|
||||
{
|
||||
|
@ -69,7 +69,8 @@ public:
|
||||
void deauthenticate();
|
||||
bool isAuthenticated() const;
|
||||
|
||||
Tomahawk::InfoSystem::InfoPlugin* infoPlugin() { return 0; }
|
||||
Tomahawk::InfoSystem::InfoPlugin* infoPlugin();
|
||||
|
||||
SipPlugin* sipPlugin();
|
||||
|
||||
QWidget* configurationWidget() { return m_configWidget.data(); }
|
||||
@ -81,6 +82,7 @@ public:
|
||||
protected:
|
||||
QWeakPointer< QWidget > m_configWidget; // so the google wrapper can change the config dialog a bit
|
||||
QWeakPointer< XmppSipPlugin > m_xmppSipPlugin;
|
||||
QWeakPointer< Tomahawk::InfoSystem::XmppInfoPlugin > m_xmppInfoPlugin;
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -43,6 +43,7 @@ XmppConfigWidget::XmppConfigWidget( XmppAccount* account, QWidget *parent ) :
|
||||
m_ui->xmppPassword->setText( account->credentials().contains( "password" ) ? account->credentials()[ "password" ].toString() : QString() );
|
||||
m_ui->xmppServer->setText( account->configuration().contains( "server" ) ? account->configuration()[ "server" ].toString() : QString() );
|
||||
m_ui->xmppPort->setValue( account->configuration().contains( "port" ) ? account->configuration()[ "port" ].toInt() : 5222 );
|
||||
m_ui->xmppPublishTracksCheckbox->setChecked( account->configuration().contains( "publishtracks" ) ? account->configuration()[ "publishtracks" ].toBool() : true);
|
||||
m_ui->jidExistsLabel->hide();
|
||||
|
||||
connect( m_ui->xmppUsername, SIGNAL( textChanged( QString ) ), SLOT( onCheckJidExists( QString ) ) );
|
||||
@ -64,6 +65,7 @@ XmppConfigWidget::saveConfig()
|
||||
QVariantHash configuration = m_account->configuration();
|
||||
configuration[ "server" ] = m_ui->xmppServer->text().trimmed();
|
||||
configuration[ "port" ] = m_ui->xmppPort->text().trimmed();
|
||||
configuration[ "publishtracks"] = m_ui->xmppPublishTracksCheckbox->checkState() == Qt::Checked;
|
||||
|
||||
m_account->setAccountFriendlyName( m_ui->xmppUsername->text() );
|
||||
m_account->setCredentials( credentials );
|
||||
|
@ -209,7 +209,7 @@
|
||||
<property name="title">
|
||||
<string>Advanced Xmpp Settings</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
@ -293,6 +293,16 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="xmppPublishTracksCheckbox">
|
||||
<property name="toolTip">
|
||||
<string>Lots of servers don't support this (e.g. GTalk, jabber.org)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Publish currently playing track</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -278,7 +278,7 @@ void
|
||||
AudioControls::onSocialActionsLoaded()
|
||||
{
|
||||
Query* query = qobject_cast< Query* >( sender() );
|
||||
if ( !query || !m_currentTrack || query != m_currentTrack->toQuery().data() )
|
||||
if ( !query || !m_currentTrack || !query->equals( m_currentTrack->toQuery() ) )
|
||||
return;
|
||||
|
||||
setSocialActions();
|
||||
|
@ -142,7 +142,7 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="coverImage">
|
||||
<widget class="FadingPixmap" name="coverImage">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
@ -561,6 +561,11 @@
|
||||
<extends>QLabel</extends>
|
||||
<header>widgets/querylabel.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>FadingPixmap</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>widgets/FadingPixmap.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
@ -17,6 +17,9 @@
|
||||
#cmakedefine LEOPARD
|
||||
#cmakedefine HAVE_SPARKLE
|
||||
|
||||
#cmakedefine WITH_BREAKPAD
|
||||
#cmakedefine WITH_CRASHREPORTER
|
||||
|
||||
#cmakedefine LIBLASTFM_FOUND
|
||||
#cmakedefine GLOOX_FOUND
|
||||
#cmakedefine QCA2_FOUND
|
||||
|
@ -119,6 +119,7 @@ set( libGuiSources
|
||||
utils/dropjobnotifier.cpp
|
||||
utils/proxystyle.cpp
|
||||
utils/tomahawkutilsgui.cpp
|
||||
utils/closure.cpp
|
||||
|
||||
widgets/animatedcounterlabel.cpp
|
||||
widgets/checkdirtree.cpp
|
||||
@ -141,6 +142,7 @@ set( libGuiSources
|
||||
widgets/HeaderWidget.cpp
|
||||
widgets/combobox.cpp
|
||||
widgets/ToggleButton.cpp
|
||||
widgets/FadingPixmap.cpp
|
||||
widgets/SocialPlaylistWidget.cpp
|
||||
widgets/infowidgets/sourceinfowidget.cpp
|
||||
widgets/infowidgets/ArtistInfoWidget.cpp
|
||||
@ -151,9 +153,6 @@ set( libGuiSources
|
||||
|
||||
IF(QCA2_FOUND)
|
||||
set( libGuiSources ${libGuiSources} utils/groovesharkparser.cpp )
|
||||
ENDIF(QCA2_FOUND)
|
||||
|
||||
IF(QCA2_FOUND)
|
||||
set( libGuiHeaders ${libGuiHeaders} utils/groovesharkparser.h )
|
||||
ENDIF(QCA2_FOUND)
|
||||
|
||||
|
@ -46,7 +46,6 @@ accountTypeToString( AccountType type )
|
||||
Account::Account( const QString& accountId )
|
||||
: QObject()
|
||||
, m_enabled( false )
|
||||
, m_autoConnect( false )
|
||||
, m_accountId( accountId )
|
||||
{
|
||||
connect( this, SIGNAL( error( int, QString ) ), this, SLOT( onError( int,QString ) ) );
|
||||
@ -126,7 +125,6 @@ Account::syncConfig()
|
||||
s->beginGroup( "accounts/" + m_accountId );
|
||||
s->setValue( "accountfriendlyname", m_accountFriendlyName );
|
||||
s->setValue( "enabled", m_enabled );
|
||||
s->setValue( "autoconnect", m_autoConnect );
|
||||
s->setValue( "credentials", m_credentials );
|
||||
s->setValue( "configuration", m_configuration );
|
||||
s->setValue( "acl", m_acl );
|
||||
@ -144,7 +142,6 @@ Account::loadFromConfig( const QString& accountId )
|
||||
s->beginGroup( "accounts/" + m_accountId );
|
||||
m_accountFriendlyName = s->value( "accountfriendlyname", QString() ).toString();
|
||||
m_enabled = s->value( "enabled", false ).toBool();
|
||||
m_autoConnect = s->value( "autoconnect", false ).toBool();
|
||||
m_credentials = s->value( "credentials", QVariantHash() ).toHash();
|
||||
m_configuration = s->value( "configuration", QVariantHash() ).toHash();
|
||||
m_acl = s->value( "acl", QVariantMap() ).toMap();
|
||||
@ -160,7 +157,6 @@ Account::removeFromConfig()
|
||||
s->beginGroup( "accounts/" + m_accountId );
|
||||
s->remove( "accountfriendlyname" );
|
||||
s->remove( "enabled" );
|
||||
s->remove( "autoconnect" );
|
||||
s->remove( "credentials" );
|
||||
s->remove( "configuration" );
|
||||
s->remove( "acl" );
|
||||
|
@ -78,7 +78,6 @@ public:
|
||||
QString accountServiceName() const { QMutexLocker locker( &m_mutex ); return m_accountServiceName; } // e.g. "Twitter", "Last.fm"
|
||||
QString accountFriendlyName() const { QMutexLocker locker( &m_mutex ); return m_accountFriendlyName; } // e.g. screen name on the service, JID, etc.
|
||||
bool enabled() const { QMutexLocker locker( &m_mutex ); return m_enabled; }
|
||||
bool autoConnect() const { QMutexLocker locker( &m_mutex ); return m_autoConnect; }
|
||||
QString accountId() const { QMutexLocker locker( &m_mutex ); return m_accountId; }
|
||||
|
||||
QVariantHash configuration() const { QMutexLocker locker( &m_mutex ); return m_configuration; }
|
||||
@ -109,7 +108,6 @@ public:
|
||||
void setAccountServiceName( const QString &serviceName ) { QMutexLocker locker( &m_mutex ); m_accountServiceName = serviceName; }
|
||||
void setAccountFriendlyName( const QString &friendlyName ) { QMutexLocker locker( &m_mutex ); m_accountFriendlyName = friendlyName; }
|
||||
void setEnabled( bool enabled ) { QMutexLocker locker( &m_mutex ); m_enabled = enabled; }
|
||||
void setAutoConnect( bool autoConnect ) { QMutexLocker locker( &m_mutex ); m_autoConnect = autoConnect; }
|
||||
void setAccountId( const QString &accountId ) { QMutexLocker locker( &m_mutex ); m_accountId = accountId; }
|
||||
void setCredentials( const QVariantHash &credentialHash ) { QMutexLocker locker( &m_mutex ); m_credentials = credentialHash; }
|
||||
void setConfiguration( const QVariantHash &configuration ) { QMutexLocker locker( &m_mutex ); m_configuration = configuration; }
|
||||
@ -148,7 +146,6 @@ private:
|
||||
QString m_accountFriendlyName;
|
||||
QString m_cachedError;
|
||||
bool m_enabled;
|
||||
bool m_autoConnect;
|
||||
QString m_accountId;
|
||||
QVariantHash m_credentials;
|
||||
QVariantHash m_configuration;
|
||||
|
@ -374,7 +374,7 @@ AccountManager::hookupAndEnable( Account* account, bool startup )
|
||||
if ( p )
|
||||
SipHandler::instance()->hookUpPlugin( p );
|
||||
|
||||
if ( account->enabled() && ( !startup || account->autoConnect() ) )
|
||||
if ( account->enabled() )
|
||||
{
|
||||
account->authenticate();
|
||||
m_enabledAccounts << account;
|
||||
|
@ -82,13 +82,6 @@ Album::Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr&
|
||||
, m_cover( 0 )
|
||||
#endif
|
||||
{
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( finished( QString ) ),
|
||||
SLOT( infoSystemFinished( QString ) ) );
|
||||
}
|
||||
|
||||
|
||||
@ -131,6 +124,14 @@ Album::cover( const QSize& size, bool forceLoad ) const
|
||||
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo );
|
||||
requestData.customData = QVariantMap();
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( finished( QString ) ),
|
||||
SLOT( infoSystemFinished( QString ) ) );
|
||||
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
|
||||
}
|
||||
|
||||
@ -190,6 +191,12 @@ Album::infoSystemFinished( QString target )
|
||||
if ( target != m_uuid )
|
||||
return;
|
||||
|
||||
disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
this, SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
|
||||
disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ),
|
||||
this, SLOT( infoSystemFinished( QString ) ) );
|
||||
|
||||
m_infoLoaded = true;
|
||||
emit updated();
|
||||
}
|
||||
|
@ -82,14 +82,6 @@ Artist::Artist( unsigned int id, const QString& name )
|
||||
#endif
|
||||
{
|
||||
m_sortname = DatabaseImpl::sortname( name, true );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( finished( QString ) ),
|
||||
SLOT( infoSystemFinished( QString ) ) );
|
||||
}
|
||||
|
||||
|
||||
@ -122,6 +114,14 @@ Artist::cover( const QSize& size, bool forceLoad ) const
|
||||
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo );
|
||||
requestData.customData = QVariantMap();
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( finished( QString ) ),
|
||||
SLOT( infoSystemFinished( QString ) ) );
|
||||
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
|
||||
}
|
||||
|
||||
@ -181,6 +181,12 @@ Artist::infoSystemFinished( QString target )
|
||||
if ( target != m_uuid )
|
||||
return;
|
||||
|
||||
disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
this, SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
|
||||
disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ),
|
||||
this, SLOT( infoSystemFinished( QString ) ) );
|
||||
|
||||
m_infoLoaded = true;
|
||||
emit updated();
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ AudioEngine::AudioEngine()
|
||||
connect( m_audioOutput, SIGNAL( volumeChanged( qreal ) ), SLOT( onVolumeChanged( qreal ) ) );
|
||||
|
||||
connect( this, SIGNAL( sendWaitingNotification() ), SLOT( sendWaitingNotificationSlot() ), Qt::QueuedConnection );
|
||||
|
||||
|
||||
onVolumeChanged( m_audioOutput->volume() );
|
||||
|
||||
#ifndef Q_WS_X11
|
||||
@ -134,14 +134,22 @@ AudioEngine::play()
|
||||
{
|
||||
m_mediaObject->play();
|
||||
emit resumed();
|
||||
Tomahawk::InfoSystem::InfoStringHash trackInfo;
|
||||
|
||||
trackInfo["title"] = m_currentTrack->track();
|
||||
trackInfo["artist"] = m_currentTrack->artist()->name();
|
||||
trackInfo["album"] = m_currentTrack->album()->name();
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||
s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowResumed,
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ) );
|
||||
if ( TomahawkSettings::instance()->privateListeningMode() != TomahawkSettings::FullyPrivate )
|
||||
{
|
||||
Tomahawk::InfoSystem::InfoStringHash trackInfo;
|
||||
|
||||
trackInfo["title"] = m_currentTrack->track();
|
||||
trackInfo["artist"] = m_currentTrack->artist()->name();
|
||||
trackInfo["album"] = m_currentTrack->album()->name();
|
||||
trackInfo["albumpos"] = QString::number( m_currentTrack->albumpos() );
|
||||
trackInfo["duration"] = QString::number( m_currentTrack->duration() );
|
||||
|
||||
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||
s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowResumed,
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
next();
|
||||
@ -319,7 +327,7 @@ AudioEngine::sendWaitingNotificationSlot() const
|
||||
//since it's async, after this is triggered our result could come in, so don't show the popup in that case
|
||||
if ( !m_playlist.isNull() && m_playlist->hasNextItem() )
|
||||
return;
|
||||
|
||||
|
||||
QVariantMap retryInfo;
|
||||
retryInfo["message"] = QString( "The current track could not be resolved. Tomahawk will pick back up with the next resolvable track from this source." );
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||
@ -460,6 +468,8 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
|
||||
trackInfo["title"] = m_currentTrack->track();
|
||||
trackInfo["artist"] = m_currentTrack->artist()->name();
|
||||
trackInfo["album"] = m_currentTrack->album()->name();
|
||||
trackInfo["duration"] = QString::number( m_currentTrack->duration() );
|
||||
trackInfo["albumpos"] = QString::number( m_currentTrack->albumpos() );
|
||||
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||
s_aeInfoIdentifier,
|
||||
@ -506,6 +516,16 @@ AudioEngine::loadNextTrack()
|
||||
|
||||
Tomahawk::result_ptr result;
|
||||
|
||||
if ( !m_stopAfterTrack.isNull() )
|
||||
{
|
||||
if ( m_stopAfterTrack->equals( m_currentTrack->toQuery() ) )
|
||||
{
|
||||
m_stopAfterTrack.clear();
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_queue && m_queue->trackCount() )
|
||||
{
|
||||
result = m_queue->nextItem();
|
||||
@ -545,7 +565,9 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk:
|
||||
m_currentTrackPlaylist = playlist;
|
||||
|
||||
if ( !result.isNull() )
|
||||
{
|
||||
loadTrack( result );
|
||||
}
|
||||
else if ( !m_playlist.isNull() && m_playlist.data()->retryMode() == PlaylistInterface::Retry )
|
||||
{
|
||||
m_waitingOnNewTrack = true;
|
||||
@ -668,6 +690,9 @@ AudioEngine::timerTriggered( qint64 time )
|
||||
void
|
||||
AudioEngine::setPlaylist( Tomahawk::playlistinterface_ptr playlist )
|
||||
{
|
||||
if ( m_playlist == playlist )
|
||||
return;
|
||||
|
||||
if ( !m_playlist.isNull() )
|
||||
{
|
||||
if ( m_playlist.data() && m_playlist.data()->retryMode() == PlaylistInterface::Retry )
|
||||
@ -681,8 +706,9 @@ AudioEngine::setPlaylist( Tomahawk::playlistinterface_ptr playlist )
|
||||
emit playlistChanged( playlist );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_playlist = playlist;
|
||||
m_stopAfterTrack.clear();
|
||||
|
||||
if ( !m_playlist.isNull() && m_playlist.data() && m_playlist.data()->retryMode() == PlaylistInterface::Retry )
|
||||
connect( m_playlist.data(), SIGNAL( nextTrackReady() ), SLOT( onPlaylistNextTrackReady() ) );
|
||||
@ -694,16 +720,16 @@ AudioEngine::setPlaylist( Tomahawk::playlistinterface_ptr playlist )
|
||||
void
|
||||
AudioEngine::setCurrentTrack( const Tomahawk::result_ptr& result )
|
||||
{
|
||||
m_lastTrack = m_currentTrack;
|
||||
if ( !m_lastTrack.isNull() )
|
||||
Tomahawk::result_ptr lastTrack = m_currentTrack;
|
||||
if ( !lastTrack.isNull() )
|
||||
{
|
||||
if ( TomahawkSettings::instance()->privateListeningMode() == TomahawkSettings::PublicListening )
|
||||
{
|
||||
DatabaseCommand_LogPlayback* cmd = new DatabaseCommand_LogPlayback( m_lastTrack, DatabaseCommand_LogPlayback::Finished, m_timeElapsed );
|
||||
DatabaseCommand_LogPlayback* cmd = new DatabaseCommand_LogPlayback( lastTrack, DatabaseCommand_LogPlayback::Finished, m_timeElapsed );
|
||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
|
||||
}
|
||||
|
||||
emit finished( m_lastTrack );
|
||||
emit finished( lastTrack );
|
||||
}
|
||||
|
||||
m_currentTrack = result;
|
||||
|
@ -64,6 +64,8 @@ public:
|
||||
Tomahawk::playlistinterface_ptr playlist() const { return m_playlist; }
|
||||
|
||||
Tomahawk::result_ptr currentTrack() const { return m_currentTrack; }
|
||||
|
||||
Tomahawk::query_ptr stopAfterTrack() const { return m_stopAfterTrack; }
|
||||
|
||||
qint64 currentTime() const { return m_mediaObject->currentTime(); }
|
||||
qint64 currentTrackTotalTime() const { return m_mediaObject->totalTime(); }
|
||||
@ -91,6 +93,8 @@ public slots:
|
||||
void playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::result_ptr& result );
|
||||
void setPlaylist( Tomahawk::playlistinterface_ptr playlist );
|
||||
void setQueue( Tomahawk::playlistinterface_ptr queue ) { m_queue = queue; }
|
||||
|
||||
void setStopAfterTrack( const Tomahawk::query_ptr& query ) { m_stopAfterTrack = query; }
|
||||
|
||||
signals:
|
||||
void loading( const Tomahawk::result_ptr& track );
|
||||
@ -141,8 +145,8 @@ private:
|
||||
|
||||
QSharedPointer<QIODevice> m_input;
|
||||
|
||||
Tomahawk::query_ptr m_stopAfterTrack;
|
||||
Tomahawk::result_ptr m_currentTrack;
|
||||
Tomahawk::result_ptr m_lastTrack;
|
||||
Tomahawk::playlistinterface_ptr m_playlist;
|
||||
Tomahawk::playlistinterface_ptr m_currentTrackPlaylist;
|
||||
Tomahawk::playlistinterface_ptr m_queue;
|
||||
|
@ -38,6 +38,8 @@ RelatedArtistsContext::RelatedArtistsContext()
|
||||
m_relatedModel->setColumnStyle( TreeModel::TrackOnly );
|
||||
m_relatedView->setTreeModel( m_relatedModel );
|
||||
m_relatedView->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
||||
m_relatedView->setSortingEnabled( false );
|
||||
m_relatedView->proxyModel()->sort( -1 );
|
||||
|
||||
QPalette pal = m_relatedView->palette();
|
||||
pal.setColor( QPalette::Window, QColor( 0, 0, 0, 0 ) );
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
@ -37,7 +38,7 @@ ContextMenu::ContextMenu( QWidget* parent )
|
||||
m_sigmap = new QSignalMapper( this );
|
||||
connect( m_sigmap, SIGNAL( mapped( int ) ), SLOT( onTriggered( int ) ) );
|
||||
|
||||
m_supportedActions = ActionPlay | ActionQueue | ActionCopyLink | ActionLove;
|
||||
m_supportedActions = ActionPlay | ActionQueue | ActionCopyLink | ActionLove | ActionStopAfter;
|
||||
}
|
||||
|
||||
|
||||
@ -80,6 +81,14 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
|
||||
if ( m_supportedActions & ActionQueue )
|
||||
m_sigmap->setMapping( addAction( tr( "Add to &Queue" ) ), ActionQueue );
|
||||
|
||||
if ( m_supportedActions & ActionStopAfter && itemCount() == 1 )
|
||||
{
|
||||
if ( AudioEngine::instance()->stopAfterTrack() == queries.first() )
|
||||
m_sigmap->setMapping( addAction( tr( "&Continue playback after this track" ) ), ActionStopAfter );
|
||||
else
|
||||
m_sigmap->setMapping( addAction( tr( "&Stop playback after this track" ) ), ActionStopAfter );
|
||||
}
|
||||
|
||||
addSeparator();
|
||||
|
||||
if ( m_supportedActions & ActionLove && itemCount() == 1 )
|
||||
@ -110,7 +119,6 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
|
||||
void
|
||||
ContextMenu::setQuery( const Tomahawk::query_ptr& query )
|
||||
{
|
||||
|
||||
QList<query_ptr> queries;
|
||||
queries << query;
|
||||
setQueries( queries );
|
||||
@ -212,6 +220,13 @@ ContextMenu::onTriggered( int action )
|
||||
m_queries.first()->setLoved( !m_queries.first()->loved() );
|
||||
break;
|
||||
|
||||
case ActionStopAfter:
|
||||
if ( m_queries.first()->equals( AudioEngine::instance()->stopAfterTrack() ) )
|
||||
AudioEngine::instance()->setStopAfterTrack( query_ptr() );
|
||||
else
|
||||
AudioEngine::instance()->setStopAfterTrack( m_queries.first() );
|
||||
break;
|
||||
|
||||
default:
|
||||
emit triggered( action );
|
||||
}
|
||||
|
@ -40,7 +40,8 @@ public:
|
||||
ActionQueue = 2,
|
||||
ActionDelete = 4,
|
||||
ActionCopyLink = 8,
|
||||
ActionLove = 16
|
||||
ActionLove = 16,
|
||||
ActionStopAfter = 32
|
||||
};
|
||||
|
||||
explicit ContextMenu( QWidget* parent = 0 );
|
||||
|
@ -89,12 +89,13 @@ GlobalActionManager::openLinkFromQuery( const query_ptr& query ) const
|
||||
{
|
||||
QString title, artist, album;
|
||||
|
||||
if( !query->results().isEmpty() && !query->results().first().isNull() )
|
||||
if ( !query->results().isEmpty() && !query->results().first().isNull() )
|
||||
{
|
||||
title = query->results().first()->track();
|
||||
artist = query->results().first()->artist().isNull() ? QString() : query->results().first()->artist()->name();
|
||||
album = query->results().first()->album().isNull() ? QString() : query->results().first()->album()->name();
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
title = query->track();
|
||||
artist = query->artist();
|
||||
@ -110,11 +111,11 @@ GlobalActionManager::openLink( const QString& title, const QString& artist, cons
|
||||
{
|
||||
QUrl link( QString( "%1/open/track/" ).arg( hostname() ) );
|
||||
|
||||
if( !title.isEmpty() )
|
||||
link.addQueryItem( "title", title );
|
||||
if( !artist.isEmpty() )
|
||||
if ( !artist.isEmpty() )
|
||||
link.addQueryItem( "artist", artist );
|
||||
if( !album.isEmpty() )
|
||||
if ( !title.isEmpty() )
|
||||
link.addQueryItem( "title", title );
|
||||
if ( !album.isEmpty() )
|
||||
link.addQueryItem( "album", album );
|
||||
|
||||
return link;
|
||||
|
@ -85,7 +85,7 @@ InfoBar::InfoBar( QWidget* parent )
|
||||
m_autoUpdate->setText( tr( "Automatically update" ) );
|
||||
m_autoUpdate->setLayoutDirection( Qt::RightToLeft );
|
||||
m_autoUpdate->setPalette( whitePal );
|
||||
connect( m_autoUpdate, SIGNAL( stateChanged( int ) ), this, SIGNAL( autoUpdateChanged( int ) ) );
|
||||
connect( m_autoUpdate, SIGNAL( toggled( bool ) ), this, SIGNAL( autoUpdateChanged( bool ) ) );
|
||||
|
||||
ui->horizontalLayout->addWidget( m_autoUpdate );
|
||||
|
||||
|
@ -60,7 +60,7 @@ public slots:
|
||||
void setAutoUpdateAvailable( bool b );
|
||||
signals:
|
||||
void filterTextChanged( const QString& filter );
|
||||
void autoUpdateChanged( int state );
|
||||
void autoUpdateChanged( bool checked );
|
||||
|
||||
protected:
|
||||
void changeEvent( QEvent* e );
|
||||
|
@ -188,8 +188,7 @@ public:
|
||||
|
||||
|
||||
QList<plentry_ptr> entriesFromQueries( const QList<Tomahawk::query_ptr>& queries, bool clearFirst = false );
|
||||
|
||||
void setUpdater( PlaylistUpdaterInterface* interface ) { m_updater = interface; }
|
||||
void setUpdater( PlaylistUpdaterInterface* pluinterface ) { m_updater = pluinterface; }
|
||||
PlaylistUpdaterInterface* updater() const { return m_updater; }
|
||||
|
||||
Tomahawk::playlistinterface_ptr playlistInterface();
|
||||
|
@ -40,10 +40,11 @@
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
PlaylistLargeItemDelegate::PlaylistLargeItemDelegate( TrackView* parent, TrackProxyModel* proxy )
|
||||
PlaylistLargeItemDelegate::PlaylistLargeItemDelegate( DisplayMode mode, TrackView* parent, TrackProxyModel* proxy )
|
||||
: QStyledItemDelegate( (QObject*)parent )
|
||||
, m_view( parent )
|
||||
, m_model( proxy )
|
||||
, m_mode( mode )
|
||||
{
|
||||
m_topOption = QTextOption( Qt::AlignTop );
|
||||
m_topOption.setWrapMode( QTextOption::NoWrap );
|
||||
@ -149,8 +150,7 @@ PlaylistLargeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem&
|
||||
return;
|
||||
|
||||
QPixmap pixmap, avatar;
|
||||
QString artist, track, upperText, lowerText;
|
||||
source_ptr source = item->query()->playedBy().first;
|
||||
QString artist, track, lowerText;
|
||||
unsigned int duration = 0;
|
||||
|
||||
if ( item->query()->results().count() )
|
||||
@ -165,14 +165,11 @@ PlaylistLargeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem&
|
||||
track = item->query()->track();
|
||||
}
|
||||
|
||||
lowerText = item->query()->socialActionDescription( "Love", Query::Detailed );
|
||||
|
||||
if ( source.isNull() )
|
||||
QSize avatarSize( 32, 32 );
|
||||
source_ptr source = item->query()->playedBy().first;
|
||||
if ( m_mode == RecentlyPlayed && !source.isNull() )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
upperText = QString( "%1 - %2" ).arg( artist ).arg( track );
|
||||
avatar = source->avatar( Source::FancyStyle, avatarSize );
|
||||
QString playtime = TomahawkUtils::ageToString( QDateTime::fromTime_t( item->query()->playedBy().second ), true );
|
||||
|
||||
if ( source == SourceList::instance()->getLocal() )
|
||||
@ -181,6 +178,16 @@ PlaylistLargeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem&
|
||||
lowerText = QString( tr( "played %1 by %2" ) ).arg( playtime ).arg( source->friendlyName() );
|
||||
}
|
||||
|
||||
if ( m_mode == LatestAdditions && item->query()->numResults() )
|
||||
{
|
||||
QString playtime = TomahawkUtils::ageToString( QDateTime::fromTime_t( item->query()->results().first()->modificationTime() ), true );
|
||||
|
||||
lowerText = QString( tr( "added %1" ) ).arg( playtime );
|
||||
}
|
||||
|
||||
if ( m_mode == LovedTracks )
|
||||
lowerText = item->query()->socialActionDescription( "Love", Query::Detailed );
|
||||
|
||||
painter->save();
|
||||
{
|
||||
QRect r = opt.rect.adjusted( 3, 6, 0, -6 );
|
||||
@ -197,14 +204,10 @@ PlaylistLargeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem&
|
||||
|
||||
painter->setPen( opt.palette.text().color() );
|
||||
|
||||
QSize avatarSize( 32, 32 );
|
||||
QRect pixmapRect = r.adjusted( 6, 0, -option.rect.width() + option.rect.height() - 6 + r.left(), 0 );
|
||||
QRect avatarRect = r.adjusted( option.rect.width() - r.left() - 12 - avatarSize.width(), ( option.rect.height() - avatarSize.height() ) / 2 - 5, 0, 0 );
|
||||
avatarRect.setSize( avatarSize );
|
||||
|
||||
if ( source )
|
||||
avatar = source->avatar( Source::FancyStyle, avatarRect.size() );
|
||||
|
||||
pixmap = item->query()->cover( pixmapRect.size(), false );
|
||||
if ( !pixmap )
|
||||
{
|
||||
|
@ -35,7 +35,10 @@ class DLLEXPORT PlaylistLargeItemDelegate : public QStyledItemDelegate
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PlaylistLargeItemDelegate( TrackView* parent = 0, TrackProxyModel* proxy = 0 );
|
||||
enum DisplayMode
|
||||
{ LovedTracks, RecentlyPlayed, LatestAdditions };
|
||||
|
||||
PlaylistLargeItemDelegate( DisplayMode mode, TrackView* parent = 0, TrackProxyModel* proxy = 0 );
|
||||
|
||||
protected:
|
||||
void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
@ -52,6 +55,7 @@ private:
|
||||
|
||||
TrackView* m_view;
|
||||
TrackProxyModel* m_model;
|
||||
DisplayMode m_mode;
|
||||
};
|
||||
|
||||
#endif // PLAYLISTLARGEITEMDELEGATE_H
|
||||
|
@ -79,8 +79,6 @@ PlaylistUpdaterInterface::PlaylistUpdaterInterface( const playlist_ptr& pl )
|
||||
connect( m_timer, SIGNAL( timeout() ), this, SLOT( updateNow() ) );
|
||||
|
||||
QTimer::singleShot( 0, this, SLOT( doSave() ) );
|
||||
|
||||
setAutoUpdate( m_autoUpdate );
|
||||
}
|
||||
|
||||
PlaylistUpdaterInterface::PlaylistUpdaterInterface( const playlist_ptr& pl, int interval, bool autoUpdate )
|
||||
|
@ -40,6 +40,8 @@ RecentlyPlayedModel::RecentlyPlayedModel( const source_ptr& source, QObject* par
|
||||
{
|
||||
if ( source.isNull() )
|
||||
{
|
||||
onSourcesReady();
|
||||
|
||||
connect( SourceList::instance(), SIGNAL( ready() ), SLOT( onSourcesReady() ) );
|
||||
connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) );
|
||||
}
|
||||
|
@ -55,8 +55,15 @@ XspfUpdater::~XspfUpdater()
|
||||
void
|
||||
XspfUpdater::updateNow()
|
||||
{
|
||||
if ( m_url.isEmpty() )
|
||||
{
|
||||
qWarning() << "XspfUpdater not updating because we have an empty url...";
|
||||
return;
|
||||
}
|
||||
|
||||
XSPFLoader* l = new XSPFLoader( false, false );
|
||||
l->setAutoResolveTracks( false );
|
||||
l->setErrorTitle( playlist()->title() );
|
||||
l->load( m_url );
|
||||
connect( l, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SLOT( playlistLoaded( QList<Tomahawk::query_ptr> ) ) );
|
||||
}
|
||||
|
@ -597,7 +597,9 @@ EchonestGenerator::sentenceSummary()
|
||||
suffix = ", ";
|
||||
else
|
||||
suffix = ".";
|
||||
} else
|
||||
} else if ( i < required.size() - 2 ) // An item in the list that is before the second to last one, don't use ", and", we only want that for the last item
|
||||
suffix += ", ";
|
||||
else
|
||||
suffix += ", and ";
|
||||
}
|
||||
sentence += center + suffix;
|
||||
|
@ -97,10 +97,13 @@ PlaylistItemDelegate::prepareStyleOption( QStyleOptionViewItemV4* option, const
|
||||
if ( item->isPlaying() )
|
||||
{
|
||||
option->palette.setColor( QPalette::Highlight, option->palette.color( QPalette::Mid ) );
|
||||
option->state |= QStyle::State_Selected;
|
||||
|
||||
option->backgroundBrush = option->palette.color( QPalette::Mid );
|
||||
option->palette.setColor( QPalette::Text, option->palette.color( QPalette::Text ) );
|
||||
|
||||
}
|
||||
|
||||
if ( option->state & QStyle::State_Selected )
|
||||
if ( option->state & QStyle::State_Selected && !item->isPlaying() )
|
||||
{
|
||||
option->palette.setColor( QPalette::Text, option->palette.color( QPalette::HighlightedText ) );
|
||||
}
|
||||
@ -203,7 +206,10 @@ PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem&
|
||||
QRect ir = r.adjusted( 4, 0, -option.rect.width() + option.rect.height() - 8 + r.left(), 0 );
|
||||
|
||||
if ( useAvatars )
|
||||
pixmap = source->avatar( Source::FancyStyle, ir.size() );
|
||||
{
|
||||
if ( !source.isNull() )
|
||||
pixmap = source->avatar( Source::FancyStyle, ir.size() );
|
||||
}
|
||||
else
|
||||
pixmap = item->query()->cover( ir.size(), false );
|
||||
|
||||
|
@ -82,10 +82,7 @@ TrackModelItem::entry() const
|
||||
const Tomahawk::query_ptr&
|
||||
TrackModelItem::query() const
|
||||
{
|
||||
if ( !m_entry.isNull() )
|
||||
return m_entry->query();
|
||||
else
|
||||
return m_query;
|
||||
return m_query;
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "dynamic/widgets/LoadingSpinner.h"
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "utils/logger.h"
|
||||
#include "utils/closure.h"
|
||||
#include "dropjob.h"
|
||||
#include "artist.h"
|
||||
#include "album.h"
|
||||
@ -205,6 +206,41 @@ TrackView::onScrollTimeout()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackView::startPlayingFromStart()
|
||||
{
|
||||
if ( m_proxyModel->rowCount() == 0 )
|
||||
return;
|
||||
|
||||
const QModelIndex index = m_proxyModel->index( 0, 0 );
|
||||
startAutoPlay( index );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackView::autoPlayResolveFinished( const query_ptr& query, int row )
|
||||
{
|
||||
Q_ASSERT( !query.isNull() );
|
||||
Q_ASSERT( row >= 0 );
|
||||
|
||||
if ( query.isNull() || row < 0 || query != m_autoPlaying )
|
||||
return;
|
||||
|
||||
const QModelIndex index = m_proxyModel->index( row, 0 );
|
||||
if ( query->playable() )
|
||||
{
|
||||
onItemActivated( index );
|
||||
return;
|
||||
}
|
||||
|
||||
// Try the next one..
|
||||
const QModelIndex sib = index.sibling( index.row() + 1, index.column() );
|
||||
if ( sib.isValid() )
|
||||
startAutoPlay( sib );
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackView::currentChanged( const QModelIndex& current, const QModelIndex& previous )
|
||||
{
|
||||
@ -227,15 +263,48 @@ TrackView::onItemActivated( const QModelIndex& index )
|
||||
if ( !index.isValid() )
|
||||
return;
|
||||
|
||||
tryToPlayItem( index );
|
||||
emit itemActivated( index );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackView::startAutoPlay( const QModelIndex& index )
|
||||
{
|
||||
if ( tryToPlayItem( index ) )
|
||||
return;
|
||||
|
||||
// item isn't playable but still resolving
|
||||
TrackModelItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( index ) );
|
||||
if ( item && !item->query().isNull() && !item->query()->resolvingFinished() )
|
||||
{
|
||||
m_autoPlaying = item->query(); // So we can kill it if user starts autoplaying this playlist again
|
||||
NewClosure( item->query().data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( autoPlayResolveFinished( Tomahawk::query_ptr, int ) ),
|
||||
item->query(), index.row() );
|
||||
return;
|
||||
}
|
||||
|
||||
// not playable at all, try next
|
||||
const QModelIndex sib = index.sibling( index.row() + 1, index.column() );
|
||||
if ( sib.isValid() )
|
||||
startAutoPlay( sib );
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
TrackView::tryToPlayItem( const QModelIndex& index )
|
||||
{
|
||||
TrackModelItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( index ) );
|
||||
if ( item && !item->query().isNull() && item->query()->numResults() )
|
||||
{
|
||||
tDebug() << "Result activated:" << item->query()->toString() << item->query()->results().first()->url();
|
||||
m_proxyModel->setCurrentIndex( index );
|
||||
AudioEngine::instance()->playItem( m_proxyModel->playlistInterface(), item->query()->results().first() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
emit itemActivated( index );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -489,7 +558,12 @@ TrackView::onCustomContextMenu( const QPoint& pos )
|
||||
|
||||
TrackModelItem* item = proxyModel()->itemFromIndex( proxyModel()->mapToSource( index ) );
|
||||
if ( item && !item->query().isNull() )
|
||||
queries << item->query();
|
||||
{
|
||||
if ( item->query()->numResults() > 0 )
|
||||
queries << item->query()->results().first()->toQuery();
|
||||
else
|
||||
queries << item->query();
|
||||
}
|
||||
}
|
||||
|
||||
m_contextMenu->setQueries( queries );
|
||||
|
@ -66,6 +66,9 @@ public:
|
||||
bool updatesContextView() const { return m_updateContextView; }
|
||||
void setUpdatesContextView( bool b ) { m_updateContextView = b; }
|
||||
|
||||
// Starts playing from the beginning if resolved, or waits until a track is playable
|
||||
void startPlayingFromStart();
|
||||
|
||||
public slots:
|
||||
virtual void onItemActivated( const QModelIndex& index );
|
||||
|
||||
@ -103,7 +106,11 @@ private slots:
|
||||
|
||||
void onCustomContextMenu( const QPoint& pos );
|
||||
|
||||
void autoPlayResolveFinished( const Tomahawk::query_ptr& query, int row );
|
||||
|
||||
private:
|
||||
void startAutoPlay( const QModelIndex& index );
|
||||
bool tryToPlayItem( const QModelIndex& index );
|
||||
void updateHoverIndex( const QPoint& pos );
|
||||
|
||||
QString m_guid;
|
||||
@ -122,6 +129,9 @@ private:
|
||||
|
||||
QModelIndex m_hoveredIndex;
|
||||
QModelIndex m_contextMenuIndex;
|
||||
|
||||
Tomahawk::query_ptr m_autoPlaying;
|
||||
|
||||
Tomahawk::ContextMenu* m_contextMenu;
|
||||
|
||||
QTimer m_timer;
|
||||
|
@ -2,6 +2,7 @@
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2012, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -623,7 +624,7 @@ TreeModel::addAlbums( const artist_ptr& artist, const QModelIndex& parent, bool
|
||||
requestData.caller = m_infoId;
|
||||
requestData.customData["row"] = parent.row();
|
||||
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( artistInfo );
|
||||
requestData.customData["refetch"] = QVariant( autoRefetch );
|
||||
requestData.customData["refetch"] = autoRefetch;
|
||||
requestData.type = Tomahawk::InfoSystem::InfoArtistReleases;
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
|
||||
}
|
||||
@ -661,8 +662,8 @@ TreeModel::addTracks( const album_ptr& album, const QModelIndex& parent, bool au
|
||||
m_receivedInfoData.removeAll( artistInfo );
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData;
|
||||
requestData.caller = m_infoId;
|
||||
requestData.customData["rows"] = QVariant( rows );
|
||||
requestData.customData["refetch"] = QVariant( autoRefetch );
|
||||
requestData.customData["rows"] = rows;
|
||||
requestData.customData["refetch"] = autoRefetch;
|
||||
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( artistInfo );
|
||||
requestData.type = Tomahawk::InfoSystem::InfoAlbumSongs;
|
||||
requestData.timeoutMillis = 0;
|
||||
@ -797,7 +798,7 @@ TreeModel::onAlbumsAdded( const QList<Tomahawk::album_ptr>& albums, const QModel
|
||||
albumitem = new TreeModelItem( album, parentItem );
|
||||
albumitem->index = createIndex( parentItem->children.count() - 1, 0, albumitem );
|
||||
connect( albumitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
|
||||
|
||||
|
||||
getCover( albumitem->index );
|
||||
}
|
||||
|
||||
@ -887,7 +888,7 @@ TreeModel::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QV
|
||||
|
||||
QModelIndex idx = index( requestData.customData[ "row" ].toInt(), 0, QModelIndex() );
|
||||
|
||||
if ( requestData.customData[ "refetch" ].toInt() > 0 && !al.count() )
|
||||
if ( requestData.customData[ "refetch" ].toBool() && !al.count() )
|
||||
{
|
||||
setMode( DatabaseMode );
|
||||
|
||||
@ -941,7 +942,13 @@ TreeModel::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QV
|
||||
}
|
||||
else if ( m_receivedInfoData.count() == 2 /* FIXME */ )
|
||||
{
|
||||
if ( requestData.customData[ "refetch" ].toInt() > 0 )
|
||||
// If the second load got no data, but the first load did, don't do anything
|
||||
QList< QVariant > rows = requestData.customData[ "rows" ].toList();
|
||||
QModelIndex idx = index( rows.first().toUInt(), 0, index( rows.at( 1 ).toUInt(), 0, QModelIndex() ) );
|
||||
if ( rowCount( idx ) )
|
||||
return;
|
||||
|
||||
if ( requestData.customData[ "refetch" ].toBool() )
|
||||
{
|
||||
setMode( DatabaseMode );
|
||||
|
||||
|
@ -58,7 +58,6 @@ Query::get( const QString& artist, const QString& track, const QString& album, c
|
||||
query_ptr
|
||||
Query::get( const QString& query, const QID& qid )
|
||||
{
|
||||
|
||||
query_ptr q = query_ptr( new Query( query, qid ), &QObject::deleteLater );
|
||||
q->setWeakRef( q.toWeakRef() );
|
||||
|
||||
@ -164,6 +163,7 @@ Query::addResults( const QList< Tomahawk::result_ptr >& newresults )
|
||||
|
||||
m_results << newresults;
|
||||
qStableSort( m_results.begin(), m_results.end(), Query::resultSorter );
|
||||
query_ptr q = m_ownRef.toStrongRef();
|
||||
|
||||
// hook up signals, and check solved status
|
||||
foreach( const result_ptr& rp, newresults )
|
||||
@ -412,6 +412,18 @@ Query::checkResults()
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Query::equals( const Tomahawk::query_ptr& other ) const
|
||||
{
|
||||
if ( other.isNull() )
|
||||
return false;
|
||||
|
||||
return ( artist() == other->artist() &&
|
||||
album() == other->album() &&
|
||||
track() == other->track() );
|
||||
}
|
||||
|
||||
|
||||
QVariant
|
||||
Query::toVariant() const
|
||||
{
|
||||
@ -538,7 +550,7 @@ Query::parseSocialActions()
|
||||
{
|
||||
Tomahawk::SocialAction socialAction;
|
||||
socialAction = it.next();
|
||||
if ( socialAction.timestamp.toUInt() > highestTimestamp && socialAction.source->id() == SourceList::instance()->getLocal()->id() )
|
||||
if ( socialAction.timestamp.toUInt() > highestTimestamp && socialAction.source->isLocal() )
|
||||
{
|
||||
m_currentSocialActions[ socialAction.action.toString() ] = socialAction.value.toBool();
|
||||
}
|
||||
@ -568,7 +580,7 @@ Query::setLoved( bool loved )
|
||||
query_ptr q = m_ownRef.toStrongRef();
|
||||
if ( q )
|
||||
{
|
||||
m_currentSocialActions[ "Loved" ] = loved;
|
||||
m_currentSocialActions[ "Love" ] = loved;
|
||||
|
||||
Tomahawk::InfoSystem::InfoStringHash trackInfo;
|
||||
trackInfo["title"] = track();
|
||||
@ -581,6 +593,8 @@ Query::setLoved( bool loved )
|
||||
|
||||
DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( q, QString( "Love" ), loved ? QString( "true" ) : QString( "false" ) );
|
||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
|
||||
|
||||
emit socialActionsLoaded();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,6 +91,8 @@ public:
|
||||
void setAlbumPos( unsigned int albumpos ) { m_albumpos = albumpos; }
|
||||
void setDiscNumber( unsigned int discnumber ) { m_discnumber = discnumber; }
|
||||
|
||||
bool equals( const Tomahawk::query_ptr& other ) const;
|
||||
|
||||
QVariant toVariant() const;
|
||||
QString toString() const;
|
||||
|
||||
|
@ -42,6 +42,7 @@ ScriptResolver::ScriptResolver( const QString& exe )
|
||||
, m_ready( false )
|
||||
, m_stopped( true )
|
||||
, m_configSent( false )
|
||||
, m_deleting( false )
|
||||
, m_error( Tomahawk::ExternalResolver::NoError )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "Created script resolver:" << exe;
|
||||
@ -62,15 +63,13 @@ ScriptResolver::ScriptResolver( const QString& exe )
|
||||
ScriptResolver::~ScriptResolver()
|
||||
{
|
||||
disconnect( &m_proc, SIGNAL( finished( int, QProcess::ExitStatus ) ), this, SLOT( cmdExited( int, QProcess::ExitStatus ) ) );
|
||||
m_deleting = true;
|
||||
|
||||
QVariantMap msg;
|
||||
msg[ "_msgtype" ] = "quit";
|
||||
sendMessage( msg );
|
||||
|
||||
// QEventLoop::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
|
||||
// m_proc.terminate();
|
||||
m_proc.waitForFinished( 1000 );
|
||||
m_proc.waitForFinished( 1000 ); // might call handleMsg
|
||||
|
||||
Tomahawk::Pipeline::instance()->removeResolver( this );
|
||||
|
||||
@ -221,6 +220,10 @@ ScriptResolver::handleMsg( const QByteArray& msg )
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO << msg.size() << QString::fromAscii( msg );
|
||||
|
||||
// Might be called from waitForFinished() in ~ScriptResolver, no database in that case, abort.
|
||||
if ( m_deleting )
|
||||
return;
|
||||
|
||||
bool ok;
|
||||
QVariant v = m_parser.parse( msg, &ok );
|
||||
if ( !ok || v.type() != QVariant::Map )
|
||||
|
@ -88,7 +88,7 @@ private:
|
||||
quint32 m_msgsize;
|
||||
QByteArray m_msg;
|
||||
|
||||
bool m_ready, m_stopped, m_configSent;
|
||||
bool m_ready, m_stopped, m_configSent, m_deleting;
|
||||
ExternalResolver::ErrorState m_error;
|
||||
|
||||
QJson::Parser m_parser;
|
||||
|
89
src/libtomahawk/utils/closure.cpp
Normal file
89
src/libtomahawk/utils/closure.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2011, David Sansome <me@davidsansome.com>
|
||||
|
||||
Clementine 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "closure.h"
|
||||
|
||||
namespace _detail {
|
||||
|
||||
Closure::Closure(QObject* sender,
|
||||
const char* signal,
|
||||
QObject* receiver,
|
||||
const char* slot,
|
||||
const ClosureArgumentWrapper* val0,
|
||||
const ClosureArgumentWrapper* val1,
|
||||
const ClosureArgumentWrapper* val2,
|
||||
const ClosureArgumentWrapper* val3)
|
||||
: QObject(receiver),
|
||||
callback_(NULL),
|
||||
val0_(val0),
|
||||
val1_(val1),
|
||||
val2_(val2),
|
||||
val3_(val3) {
|
||||
const QMetaObject* meta_receiver = receiver->metaObject();
|
||||
|
||||
QByteArray normalised_slot = QMetaObject::normalizedSignature(slot + 1);
|
||||
const int index = meta_receiver->indexOfSlot(normalised_slot.constData());
|
||||
Q_ASSERT(index != -1);
|
||||
slot_ = meta_receiver->method(index);
|
||||
|
||||
Connect(sender, signal);
|
||||
}
|
||||
|
||||
Closure::Closure(QObject* sender,
|
||||
const char* signal,
|
||||
std::tr1::function<void()> callback)
|
||||
: callback_(callback) {
|
||||
Connect(sender, signal);
|
||||
}
|
||||
|
||||
Closure::~Closure() {
|
||||
}
|
||||
|
||||
void Closure::Connect(QObject* sender, const char* signal) {
|
||||
bool success = connect(sender, signal, SLOT(Invoked()));
|
||||
Q_ASSERT(success);
|
||||
success = connect(sender, SIGNAL(destroyed()), SLOT(Cleanup()));
|
||||
Q_ASSERT(success);
|
||||
Q_UNUSED(success);
|
||||
}
|
||||
|
||||
void Closure::Invoked() {
|
||||
if (callback_) {
|
||||
callback_();
|
||||
} else {
|
||||
slot_.invoke(
|
||||
parent(),
|
||||
val0_ ? val0_->arg() : QGenericArgument(),
|
||||
val1_ ? val1_->arg() : QGenericArgument(),
|
||||
val2_ ? val2_->arg() : QGenericArgument(),
|
||||
val3_ ? val3_->arg() : QGenericArgument());
|
||||
}
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void Closure::Cleanup() {
|
||||
disconnect();
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
} // namespace _detail
|
||||
|
||||
_detail::Closure* NewClosure(
|
||||
QObject* sender, const char* signal,
|
||||
QObject* receiver, const char* slot) {
|
||||
return new _detail::Closure(sender, signal, receiver, slot);
|
||||
}
|
225
src/libtomahawk/utils/closure.h
Normal file
225
src/libtomahawk/utils/closure.h
Normal file
@ -0,0 +1,225 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2011, David Sansome <me@davidsansome.com>
|
||||
|
||||
Clementine 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CLOSURE_H
|
||||
#define CLOSURE_H
|
||||
|
||||
#include <tr1/functional>
|
||||
|
||||
#include <QMetaMethod>
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
namespace _detail {
|
||||
|
||||
class ClosureArgumentWrapper {
|
||||
public:
|
||||
virtual ~ClosureArgumentWrapper() {}
|
||||
|
||||
virtual QGenericArgument arg() const = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class ClosureArgument : public ClosureArgumentWrapper {
|
||||
public:
|
||||
explicit ClosureArgument(const T& data) : data_(data) {}
|
||||
|
||||
virtual QGenericArgument arg() const {
|
||||
return Q_ARG(T, data_);
|
||||
}
|
||||
|
||||
private:
|
||||
T data_;
|
||||
};
|
||||
|
||||
class Closure : public QObject, boost::noncopyable {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Closure(QObject* sender, const char* signal,
|
||||
QObject* receiver, const char* slot,
|
||||
const ClosureArgumentWrapper* val0 = 0,
|
||||
const ClosureArgumentWrapper* val1 = 0,
|
||||
const ClosureArgumentWrapper* val2 = 0,
|
||||
const ClosureArgumentWrapper* val3 = 0);
|
||||
|
||||
Closure(QObject* sender, const char* signal,
|
||||
std::tr1::function<void()> callback);
|
||||
|
||||
virtual ~Closure();
|
||||
|
||||
private slots:
|
||||
void Invoked();
|
||||
void Cleanup();
|
||||
|
||||
private:
|
||||
void Connect(QObject* sender, const char* signal);
|
||||
|
||||
QMetaMethod slot_;
|
||||
std::tr1::function<void()> callback_;
|
||||
|
||||
boost::scoped_ptr<const ClosureArgumentWrapper> val0_;
|
||||
boost::scoped_ptr<const ClosureArgumentWrapper> val1_;
|
||||
boost::scoped_ptr<const ClosureArgumentWrapper> val2_;
|
||||
boost::scoped_ptr<const ClosureArgumentWrapper> val3_;
|
||||
};
|
||||
|
||||
class SharedPointerWrapper {
|
||||
public:
|
||||
virtual ~SharedPointerWrapper() {}
|
||||
virtual QObject* data() const = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class SharedPointer : public SharedPointerWrapper {
|
||||
public:
|
||||
explicit SharedPointer(QSharedPointer<T> ptr)
|
||||
: ptr_(ptr) {
|
||||
}
|
||||
|
||||
QObject* data() const {
|
||||
return ptr_.data();
|
||||
}
|
||||
|
||||
private:
|
||||
QSharedPointer<T> ptr_;
|
||||
};
|
||||
|
||||
// For use with a QSharedPointer as a sender.
|
||||
class SharedClosure : public Closure {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SharedClosure(SharedPointerWrapper* sender, const char* signal,
|
||||
QObject* receiver, const char* slot,
|
||||
const ClosureArgumentWrapper* val0 = 0,
|
||||
const ClosureArgumentWrapper* val1 = 0,
|
||||
const ClosureArgumentWrapper* val2 = 0,
|
||||
const ClosureArgumentWrapper* val3 = 0)
|
||||
: Closure(sender->data(), signal,
|
||||
receiver, slot,
|
||||
val0, val1, val2, val3),
|
||||
shared_sender_(sender) {
|
||||
}
|
||||
|
||||
private:
|
||||
boost::scoped_ptr<SharedPointerWrapper> shared_sender_;
|
||||
};
|
||||
|
||||
} // namespace _detail
|
||||
|
||||
#define C_ARG(type, data) new _detail::ClosureArgument<type>(data)
|
||||
|
||||
_detail::Closure* NewClosure(
|
||||
QObject* sender,
|
||||
const char* signal,
|
||||
QObject* receiver,
|
||||
const char* slot);
|
||||
|
||||
template <typename T>
|
||||
_detail::Closure* NewClosure(
|
||||
QObject* sender,
|
||||
const char* signal,
|
||||
QObject* receiver,
|
||||
const char* slot,
|
||||
const T& val0) {
|
||||
return new _detail::Closure(
|
||||
sender, signal, receiver, slot,
|
||||
C_ARG(T, val0));
|
||||
}
|
||||
|
||||
template <typename T0, typename T1>
|
||||
_detail::Closure* NewClosure(
|
||||
QObject* sender,
|
||||
const char* signal,
|
||||
QObject* receiver,
|
||||
const char* slot,
|
||||
const T0& val0,
|
||||
const T1& val1) {
|
||||
return new _detail::Closure(
|
||||
sender, signal, receiver, slot,
|
||||
C_ARG(T0, val0), C_ARG(T1, val1));
|
||||
}
|
||||
|
||||
template <typename T0, typename T1, typename T2>
|
||||
_detail::Closure* NewClosure(
|
||||
QObject* sender,
|
||||
const char* signal,
|
||||
QObject* receiver,
|
||||
const char* slot,
|
||||
const T0& val0,
|
||||
const T1& val1,
|
||||
const T2& val2) {
|
||||
return new _detail::Closure(
|
||||
sender, signal, receiver, slot,
|
||||
C_ARG(T0, val0), C_ARG(T1, val1), C_ARG(T2, val2));
|
||||
}
|
||||
|
||||
template <typename T0, typename T1, typename T2, typename T3>
|
||||
_detail::Closure* NewClosure(
|
||||
QObject* sender,
|
||||
const char* signal,
|
||||
QObject* receiver,
|
||||
const char* slot,
|
||||
const T0& val0,
|
||||
const T1& val1,
|
||||
const T2& val2,
|
||||
const T3& val3) {
|
||||
return new _detail::Closure(
|
||||
sender, signal, receiver, slot,
|
||||
C_ARG(T0, val0), C_ARG(T1, val1), C_ARG(T2, val2), C_ARG(T3, val3));
|
||||
}
|
||||
|
||||
template <typename TP>
|
||||
_detail::Closure* NewClosure(
|
||||
QSharedPointer<TP> sender,
|
||||
const char* signal,
|
||||
QObject* receiver,
|
||||
const char* slot) {
|
||||
return new _detail::SharedClosure(
|
||||
new _detail::SharedPointer<TP>(sender), signal, receiver, slot);
|
||||
}
|
||||
|
||||
template <typename TP, typename T0>
|
||||
_detail::Closure* NewClosure(
|
||||
QSharedPointer<TP> sender,
|
||||
const char* signal,
|
||||
QObject* receiver,
|
||||
const char* slot,
|
||||
const T0& val0) {
|
||||
return new _detail::SharedClosure(
|
||||
new _detail::SharedPointer<TP>(sender), signal, receiver, slot,
|
||||
C_ARG(T0, val0));
|
||||
}
|
||||
|
||||
template <typename TP, typename T0, typename T1>
|
||||
_detail::Closure* NewClosure(
|
||||
QSharedPointer<TP> sender,
|
||||
const char* signal,
|
||||
QObject* receiver,
|
||||
const char* slot,
|
||||
const T0& val0,
|
||||
const T1& val1) {
|
||||
return new _detail::SharedClosure(
|
||||
new _detail::SharedPointer<TP>(sender), signal, receiver, slot,
|
||||
C_ARG(T0, val0), C_ARG(T1, val1));
|
||||
}
|
||||
|
||||
#endif // CLOSURE_H
|
@ -316,6 +316,7 @@ QList< QNetworkProxy >
|
||||
NetworkProxyFactory::queryProxy( const QNetworkProxyQuery& query )
|
||||
{
|
||||
//tDebug() << Q_FUNC_INFO << "query hostname is " << query.peerHostName();
|
||||
|
||||
QList< QNetworkProxy > proxies;
|
||||
QString hostname = query.peerHostName();
|
||||
s_noProxyHostsMutex.lock();
|
||||
|
@ -123,7 +123,11 @@ XSPFLoader::reportError()
|
||||
{
|
||||
emit error( FetchError );
|
||||
#ifndef ENABLE_HEADLESS
|
||||
JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( errorToString( FetchError) ) );
|
||||
const QString errorMsg = errorToString( FetchError);
|
||||
if ( !m_errorTitle.isEmpty() )
|
||||
JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( QString( "%1: %2" ).arg( m_errorTitle ).arg( errorMsg ) ) );
|
||||
else
|
||||
JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( errorMsg ) );
|
||||
#endif
|
||||
deleteLater();
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ public:
|
||||
void setOverrideTitle( const QString& newTitle );
|
||||
void setAutoResolveTracks( bool autoResolve ) { m_autoResolve = autoResolve; }
|
||||
void setAutoDelete( bool autoDelete ) { m_autoDelete = autoDelete; }
|
||||
void setErrorTitle( const QString& error ) { m_errorTitle = error; }
|
||||
|
||||
static QString errorToString( XSPFErrorCode error );
|
||||
|
||||
@ -73,7 +74,7 @@ private:
|
||||
bool m_autoCreate, m_autoUpdate, m_autoResolve, m_autoDelete;
|
||||
QString m_NS,m_overrideTitle;
|
||||
QList< Tomahawk::query_ptr > m_entries;
|
||||
QString m_title, m_info, m_creator;
|
||||
QString m_title, m_info, m_creator, m_errorTitle;
|
||||
|
||||
QUrl m_url;
|
||||
QByteArray m_body;
|
||||
|
@ -43,6 +43,7 @@
|
||||
|
||||
#include "customplaylistview.h"
|
||||
#include "PlaylistLargeItemDelegate.h"
|
||||
#include "RecentlyPlayedModel.h"
|
||||
#include "dynamic/widgets/DynamicWidget.h"
|
||||
|
||||
#include "widgets/welcomewidget.h"
|
||||
@ -75,6 +76,7 @@ ViewManager::ViewManager( QObject* parent )
|
||||
, m_welcomeWidget( new WelcomeWidget() )
|
||||
, m_whatsHotWidget( new WhatsHotWidget() )
|
||||
, m_topLovedWidget( 0 )
|
||||
, m_recentPlaysWidget( 0 )
|
||||
, m_currentMode( PlaylistInterface::Tree )
|
||||
, m_loaded( false )
|
||||
{
|
||||
@ -114,7 +116,7 @@ ViewManager::ViewManager( QObject* parent )
|
||||
|
||||
connect( &m_filterTimer, SIGNAL( timeout() ), SLOT( applyFilter() ) );
|
||||
connect( m_infobar, SIGNAL( filterTextChanged( QString ) ), SLOT( setFilter( QString ) ) );
|
||||
connect( m_infobar, SIGNAL( autoUpdateChanged( int ) ), SLOT( autoUpdateChanged( int ) ) );
|
||||
connect( m_infobar, SIGNAL( autoUpdateChanged( bool ) ), SLOT( autoUpdateChanged( bool ) ) );
|
||||
|
||||
connect( this, SIGNAL( tomahawkLoaded() ), m_whatsHotWidget, SLOT( fetchData() ) );
|
||||
connect( this, SIGNAL( tomahawkLoaded() ), m_welcomeWidget, SLOT( loadData() ) );
|
||||
@ -131,6 +133,7 @@ ViewManager::~ViewManager()
|
||||
delete m_whatsHotWidget;
|
||||
delete m_welcomeWidget;
|
||||
delete m_topLovedWidget;
|
||||
delete m_recentPlaysWidget;
|
||||
delete m_contextWidget;
|
||||
delete m_widget;
|
||||
}
|
||||
@ -441,7 +444,7 @@ ViewManager::showTopLovedPage()
|
||||
if ( !m_topLovedWidget )
|
||||
{
|
||||
CustomPlaylistView* view = new CustomPlaylistView( CustomPlaylistView::TopLovedTracks, source_ptr(), m_widget );
|
||||
view->setItemDelegate( new PlaylistLargeItemDelegate( view, view->proxyModel() ) );
|
||||
view->setItemDelegate( new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::LovedTracks, view, view->proxyModel() ) );
|
||||
|
||||
m_topLovedWidget = view;
|
||||
}
|
||||
@ -450,6 +453,28 @@ ViewManager::showTopLovedPage()
|
||||
}
|
||||
|
||||
|
||||
Tomahawk::ViewPage*
|
||||
ViewManager::showRecentPlaysPage()
|
||||
{
|
||||
if ( !m_recentPlaysWidget )
|
||||
{
|
||||
PlaylistView* pv = new PlaylistView( m_widget );
|
||||
pv->setFrameShape( QFrame::NoFrame );
|
||||
pv->setAttribute( Qt::WA_MacShowFocusRect, 0 );
|
||||
|
||||
RecentlyPlayedModel* raModel = new RecentlyPlayedModel( source_ptr(), pv );
|
||||
raModel->setStyle( TrackModel::Large );
|
||||
|
||||
pv->setItemDelegate( new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::RecentlyPlayed, pv, pv->proxyModel() ) );
|
||||
pv->setPlaylistModel( raModel );
|
||||
|
||||
m_recentPlaysWidget = pv;
|
||||
}
|
||||
|
||||
return show( m_recentPlaysWidget );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ViewManager::setTableMode()
|
||||
{
|
||||
@ -544,9 +569,9 @@ ViewManager::applyFilter()
|
||||
|
||||
|
||||
void
|
||||
ViewManager::autoUpdateChanged( int state )
|
||||
ViewManager::autoUpdateChanged( bool toggled )
|
||||
{
|
||||
currentPage()->setAutoUpdate( state == Qt::Checked );
|
||||
currentPage()->setAutoUpdate( toggled );
|
||||
}
|
||||
|
||||
|
||||
|
@ -85,13 +85,14 @@ public:
|
||||
|
||||
Tomahawk::playlistinterface_ptr currentPlaylistInterface() const;
|
||||
Tomahawk::ViewPage* currentPage() const;
|
||||
Tomahawk::ViewPage* pageForInterface( Tomahawk::playlistinterface_ptr interface ) const;
|
||||
Tomahawk::ViewPage* pageForInterface( Tomahawk::playlistinterface_ptr plInterface ) const;
|
||||
|
||||
Tomahawk::ViewPage* show( Tomahawk::ViewPage* page );
|
||||
|
||||
Tomahawk::ViewPage* welcomeWidget() const { return m_welcomeWidget; }
|
||||
Tomahawk::ViewPage* whatsHotWidget() const { return m_whatsHotWidget; }
|
||||
Tomahawk::ViewPage* topLovedWidget() const { return m_topLovedWidget; }
|
||||
Tomahawk::ViewPage* recentPlaysWidget() const { return m_recentPlaysWidget; }
|
||||
ArtistView* superCollectionView() const { return m_superCollectionView; }
|
||||
|
||||
/// Get the view page for the given item. Not pretty...
|
||||
@ -140,6 +141,7 @@ public slots:
|
||||
Tomahawk::ViewPage* showWelcomePage();
|
||||
Tomahawk::ViewPage* showWhatsHotPage();
|
||||
Tomahawk::ViewPage* showTopLovedPage();
|
||||
Tomahawk::ViewPage* showRecentPlaysPage();
|
||||
void showCurrentTrack();
|
||||
|
||||
// Returns the shown viewpage
|
||||
@ -175,7 +177,7 @@ private slots:
|
||||
void setFilter( const QString& filter );
|
||||
void applyFilter();
|
||||
|
||||
void autoUpdateChanged( int );
|
||||
void autoUpdateChanged( bool );
|
||||
|
||||
void onWidgetDestroyed( QWidget* widget );
|
||||
|
||||
@ -186,9 +188,9 @@ private:
|
||||
void saveCurrentPlaylistSettings();
|
||||
void loadCurrentPlaylistSettings();
|
||||
|
||||
Tomahawk::playlist_ptr playlistForInterface( Tomahawk::playlistinterface_ptr interface ) const;
|
||||
Tomahawk::dynplaylist_ptr dynamicPlaylistForInterface( Tomahawk::playlistinterface_ptr interface ) const;
|
||||
Tomahawk::collection_ptr collectionForInterface( Tomahawk::playlistinterface_ptr interface ) const;
|
||||
Tomahawk::playlist_ptr playlistForInterface( Tomahawk::playlistinterface_ptr plInterface ) const;
|
||||
Tomahawk::dynplaylist_ptr dynamicPlaylistForInterface( Tomahawk::playlistinterface_ptr plInterface ) const;
|
||||
Tomahawk::collection_ptr collectionForInterface( Tomahawk::playlistinterface_ptr plInterface ) const;
|
||||
|
||||
QWidget* m_widget;
|
||||
InfoBar* m_infobar;
|
||||
@ -204,6 +206,7 @@ private:
|
||||
WelcomeWidget* m_welcomeWidget;
|
||||
WhatsHotWidget* m_whatsHotWidget;
|
||||
Tomahawk::ViewPage* m_topLovedWidget;
|
||||
Tomahawk::ViewPage* m_recentPlaysWidget;
|
||||
|
||||
QList< Tomahawk::collection_ptr > m_superCollections;
|
||||
|
||||
|
114
src/libtomahawk/widgets/FadingPixmap.cpp
Normal file
114
src/libtomahawk/widgets/FadingPixmap.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011 - 2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk 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 Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "FadingPixmap.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
#define ANIMATION_TIME 1000
|
||||
|
||||
FadingPixmap::FadingPixmap( QWidget* parent )
|
||||
: QLabel( parent )
|
||||
, m_fadePct( 100 )
|
||||
{
|
||||
// setCursor( Qt::PointingHandCursor );
|
||||
|
||||
m_timeLine = new QTimeLine( ANIMATION_TIME, this );
|
||||
m_timeLine->setUpdateInterval( 20 );
|
||||
m_timeLine->setEasingCurve( QEasingCurve::Linear );
|
||||
|
||||
connect( m_timeLine, SIGNAL( frameChanged( int ) ), SLOT( onAnimationStep( int ) ) );
|
||||
connect( m_timeLine, SIGNAL( finished() ), SLOT( onAnimationFinished() ) );
|
||||
}
|
||||
|
||||
|
||||
FadingPixmap::~FadingPixmap()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FadingPixmap::onAnimationStep( int frame )
|
||||
{
|
||||
m_fadePct = (float)frame / 10.0;
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FadingPixmap::onAnimationFinished()
|
||||
{
|
||||
m_oldPixmap = QPixmap();
|
||||
repaint();
|
||||
|
||||
if ( m_pixmapQueue.count() )
|
||||
{
|
||||
setPixmap( m_pixmapQueue.takeFirst() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FadingPixmap::setPixmap( const QPixmap& pixmap, bool clearQueue )
|
||||
{
|
||||
if ( m_timeLine->state() == QTimeLine::Running )
|
||||
{
|
||||
if ( clearQueue )
|
||||
m_pixmapQueue.clear();
|
||||
|
||||
m_pixmapQueue << pixmap;
|
||||
return;
|
||||
}
|
||||
|
||||
m_oldPixmap = m_pixmap;
|
||||
m_pixmap = pixmap;
|
||||
|
||||
m_timeLine->setFrameRange( 0, 1000 );
|
||||
m_timeLine->setDirection( QTimeLine::Forward );
|
||||
m_timeLine->start();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FadingPixmap::mouseReleaseEvent( QMouseEvent* event )
|
||||
{
|
||||
QFrame::mouseReleaseEvent( event );
|
||||
|
||||
emit clicked();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FadingPixmap::paintEvent( QPaintEvent* event )
|
||||
{
|
||||
Q_UNUSED( event );
|
||||
|
||||
QPainter p( this );
|
||||
QRect r = contentsRect();
|
||||
|
||||
p.save();
|
||||
p.setRenderHint( QPainter::Antialiasing );
|
||||
|
||||
p.setOpacity( float( 100.0 - m_fadePct ) / 100.0 );
|
||||
p.drawPixmap( r, m_oldPixmap );
|
||||
|
||||
p.setOpacity( float( m_fadePct ) / 100.0 );
|
||||
p.drawPixmap( r, m_pixmap );
|
||||
|
||||
p.restore();
|
||||
}
|
64
src/libtomahawk/widgets/FadingPixmap.h
Normal file
64
src/libtomahawk/widgets/FadingPixmap.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011 - 2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk 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 Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef FADINGPIXMAP_H
|
||||
#define FADINGPIXMAP_H
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPaintEvent>
|
||||
#include <QTimeLine>
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
/**
|
||||
* \class FadingPixmap
|
||||
* \brief Fades to the new image when calling setPixmap.
|
||||
*/
|
||||
class DLLEXPORT FadingPixmap : public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FadingPixmap( QWidget* parent = 0 );
|
||||
virtual ~FadingPixmap();
|
||||
|
||||
public slots:
|
||||
virtual void setPixmap( const QPixmap& pixmap, bool clearQueue = true );
|
||||
|
||||
signals:
|
||||
void clicked();
|
||||
|
||||
protected:
|
||||
virtual void paintEvent( QPaintEvent* );
|
||||
void mouseReleaseEvent( QMouseEvent* event );
|
||||
|
||||
private slots:
|
||||
void onAnimationStep( int frame );
|
||||
void onAnimationFinished();
|
||||
|
||||
private:
|
||||
QPixmap m_pixmap;
|
||||
QPixmap m_oldPixmap;
|
||||
|
||||
QList<QPixmap> m_pixmapQueue;
|
||||
|
||||
QTimeLine* m_timeLine;
|
||||
int m_fadePct;
|
||||
};
|
||||
|
||||
#endif
|
@ -2,6 +2,7 @@
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -232,7 +233,7 @@ AlbumInfoWidget::loadAlbums( bool autoRefetch )
|
||||
artistInfo["artist"] = m_album->artist()->name();
|
||||
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData;
|
||||
requestData.customData["refetch"] = QVariant( autoRefetch );
|
||||
requestData.customData["refetch"] = autoRefetch;
|
||||
requestData.caller = m_infoId;
|
||||
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( artistInfo );
|
||||
requestData.type = Tomahawk::InfoSystem::InfoArtistReleases;
|
||||
@ -309,7 +310,7 @@ AlbumInfoWidget::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestDa
|
||||
tDebug() << "Adding" << al.count() << "albums";
|
||||
gotAlbums( al );
|
||||
}
|
||||
else if ( requestData.customData[ "refetch" ].toInt() > 0 )
|
||||
else if ( requestData.customData[ "refetch" ].toBool() )
|
||||
{
|
||||
tDebug() << "Auto refetching";
|
||||
m_buttonAlbums->setChecked( false );
|
||||
|
@ -2,6 +2,7 @@
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -80,7 +80,7 @@ void
|
||||
QueryLabel::init()
|
||||
{
|
||||
m_contextMenu = new ContextMenu( this );
|
||||
m_contextMenu->setSupportedActions( ContextMenu::ActionQueue | ContextMenu::ActionCopyLink );
|
||||
m_contextMenu->setSupportedActions( ContextMenu::ActionQueue | ContextMenu::ActionCopyLink | ContextMenu::ActionStopAfter | ContextMenu::ActionLove );
|
||||
|
||||
m_hoverType = None;
|
||||
setContentsMargins( 0, 0, 0, 0 );
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "thirdparty/kdsingleapplicationguard/kdsingleapplicationguard.h"
|
||||
#include "ubuntuunityhack.h"
|
||||
#include "tomahawksettings.h"
|
||||
#include "config.h"
|
||||
|
||||
#include <QTranslator>
|
||||
|
||||
@ -123,8 +124,11 @@ main( int argc, char *argv[] )
|
||||
new TomahawkSettingsGui( &a );
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
new BreakPad( QDir::tempPath(), TomahawkSettings::instance()->crashReporterEnabled() );
|
||||
|
||||
#ifndef ENABLE_HEADLESSs
|
||||
#ifdef WITH_BREAKPAD
|
||||
new BreakPad( QDir::tempPath(), TomahawkSettings::instance()->crashReporterEnabled() );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
KDSingleApplicationGuard guard( &a, KDSingleApplicationGuard::AutoKillOtherInstances );
|
||||
|
@ -296,6 +296,7 @@ CategoryAddItem::playlistToRenameLoaded()
|
||||
QTimer::singleShot( 400, APP->mainWindow()->sourceTreeView(), SLOT( renamePlaylist() ) );
|
||||
|
||||
disconnect( pl, SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ), this, SLOT( playlistToRenameLoaded() ) );
|
||||
disconnect( pl, SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( playlistToRenameLoaded() ) );
|
||||
}
|
||||
|
||||
|
||||
@ -307,8 +308,7 @@ CategoryAddItem::parsedDroppedTracks( const QList< query_ptr >& tracks )
|
||||
playlist_ptr newpl = Playlist::create( SourceList::instance()->getLocal(), uuid(), "New Playlist", "", SourceList::instance()->getLocal()->friendlyName(), false, tracks );
|
||||
ViewManager::instance()->show( newpl );
|
||||
|
||||
// Give a shot to try to rename it. The playlist has to be created first. ugly.
|
||||
QTimer::singleShot( 300, APP->mainWindow()->sourceTreeView(), SLOT( renamePlaylist() ) );
|
||||
connect( newpl.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( playlistToRenameLoaded() ) );
|
||||
} else if( m_categoryType == SourcesModel::StationsCategory ) {
|
||||
// seed the playlist with these song or artist filters
|
||||
QString name;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "query.h"
|
||||
#include "viewmanager.h"
|
||||
#include "playlist/dynamic/GeneratorInterface.h"
|
||||
#include "playlist/playlistview.h"
|
||||
#include "categoryitems.h"
|
||||
#include "sourceitem.h"
|
||||
#include "utils/tomahawkutils.h"
|
||||
@ -136,6 +137,17 @@ PlaylistItem::activate()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistItem::doubleClicked()
|
||||
{
|
||||
ViewPage* p = ViewManager::instance()->currentPage();
|
||||
if ( PlaylistView* view = dynamic_cast< PlaylistView* >( p ) )
|
||||
{
|
||||
view->startPlayingFromStart();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistItem::setLoaded( bool loaded )
|
||||
{
|
||||
|
@ -31,7 +31,6 @@ public:
|
||||
virtual QString text() const;
|
||||
virtual Tomahawk::playlist_ptr playlist() const;
|
||||
virtual Qt::ItemFlags flags() const;
|
||||
virtual void activate();
|
||||
virtual bool willAcceptDrag( const QMimeData* data ) const;
|
||||
virtual DropTypes supportedDropTypes( const QMimeData* data ) const;
|
||||
virtual bool dropMimeData( const QMimeData* data, Qt::DropAction action );
|
||||
@ -43,6 +42,10 @@ public:
|
||||
|
||||
virtual SourceTreeItem* activateCurrent();
|
||||
|
||||
public slots:
|
||||
virtual void activate();
|
||||
virtual void doubleClicked();
|
||||
|
||||
protected:
|
||||
void setLoaded( bool loaded );
|
||||
|
||||
|
@ -504,7 +504,7 @@ SourceItem::lovedTracksClicked()
|
||||
if ( !m_lovedTracksPage )
|
||||
{
|
||||
CustomPlaylistView* view = new CustomPlaylistView( m_source.isNull() ? CustomPlaylistView::TopLovedTracks : CustomPlaylistView::SourceLovedTracks, m_source, ViewManager::instance()->widget() );
|
||||
view->setItemDelegate( new PlaylistLargeItemDelegate( view, view->proxyModel() ) );
|
||||
view->setItemDelegate( new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::LovedTracks, view, view->proxyModel() ) );
|
||||
|
||||
m_lovedTracksPage = view;
|
||||
}
|
||||
@ -533,7 +533,7 @@ SourceItem::latestAdditionsClicked()
|
||||
RecentlyAddedModel* raModel = new RecentlyAddedModel( m_source, cv );
|
||||
raModel->setStyle( TrackModel::Large );
|
||||
|
||||
cv->setItemDelegate( new PlaylistLargeItemDelegate( cv, cv->proxyModel() ) );
|
||||
cv->setItemDelegate( new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::LatestAdditions, cv, cv->proxyModel() ) );
|
||||
cv->setTrackModel( raModel );
|
||||
cv->sortByColumn( TrackModel::Age, Qt::DescendingOrder );
|
||||
|
||||
@ -564,7 +564,7 @@ SourceItem::recentPlaysClicked()
|
||||
RecentlyPlayedModel* raModel = new RecentlyPlayedModel( m_source, pv );
|
||||
raModel->setStyle( TrackModel::Large );
|
||||
|
||||
pv->setItemDelegate( new PlaylistLargeItemDelegate( pv, pv->proxyModel() ) );
|
||||
pv->setItemDelegate( new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::RecentlyPlayed, pv, pv->proxyModel() ) );
|
||||
pv->setPlaylistModel( raModel );
|
||||
|
||||
m_recentPlaysPage = pv;
|
||||
|
@ -78,6 +78,7 @@ public:
|
||||
|
||||
public slots:
|
||||
virtual void activate() {}
|
||||
virtual void doubleClicked() {}
|
||||
|
||||
signals:
|
||||
void updated();
|
||||
|
@ -44,6 +44,7 @@
|
||||
SourceDelegate::SourceDelegate( QAbstractItemView* parent )
|
||||
: QStyledItemDelegate( parent )
|
||||
, m_parent( parent )
|
||||
, m_lastClicked( -1 )
|
||||
{
|
||||
m_dropTypeMap.insert( 0, SourceTreeItem::DropTypeThisTrack );
|
||||
m_dropTypeMap.insert( 1, SourceTreeItem::DropTypeThisAlbum );
|
||||
@ -632,7 +633,27 @@ SourceDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QSt
|
||||
// a mouse press event. Since we want to swallow click events when they are on headphones other action items, here wemake sure we only
|
||||
// emit if we really want to
|
||||
if ( event->type() == QEvent::MouseButtonRelease )
|
||||
emit clicked( index );
|
||||
{
|
||||
if ( m_lastClicked == -1 )
|
||||
{
|
||||
m_lastClicked = QDateTime::currentMSecsSinceEpoch();
|
||||
emit clicked( index );
|
||||
}
|
||||
else
|
||||
{
|
||||
qint64 elapsed = QDateTime::currentMSecsSinceEpoch() - m_lastClicked;
|
||||
if ( elapsed < QApplication::doubleClickInterval() )
|
||||
{
|
||||
m_lastClicked = -1;
|
||||
emit doubleClicked( index );
|
||||
} else
|
||||
{
|
||||
m_lastClicked = QDateTime::currentMSecsSinceEpoch();
|
||||
emit clicked( index );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return QStyledItemDelegate::editorEvent ( event, model, option, index );
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ public:
|
||||
|
||||
signals:
|
||||
void clicked( const QModelIndex& idx );
|
||||
void doubleClicked( const QModelIndex& idx );
|
||||
void latchOn( const Tomahawk::source_ptr& idx );
|
||||
void latchOff( const Tomahawk::source_ptr& idx );
|
||||
void toggleRealtimeLatch( const Tomahawk::source_ptr& idx, bool realtime );
|
||||
@ -73,6 +74,7 @@ private:
|
||||
mutable SourceTreeItem::DropType m_hoveredDropType; // Hack to keep easily track of the current highlighted DropType in paint()
|
||||
QMap< QModelIndex, AnimationHelper* > m_expandedMap;
|
||||
QPixmap m_headphonesOn, m_headphonesOff, m_realtimeLocked, m_realtimeUnlocked, m_nowPlayingSpeaker, m_nowPlayingSpeakerDark;
|
||||
qint64 m_lastClicked;
|
||||
|
||||
QMap< int, SourceTreeItem::DropType > m_dropTypeMap;
|
||||
QMap< int, QString > m_dropTypeTextMap;
|
||||
|
@ -263,13 +263,18 @@ SourcesModel::flags( const QModelIndex& index ) const
|
||||
void
|
||||
SourcesModel::appendGroups()
|
||||
{
|
||||
beginInsertRows( QModelIndex(), rowCount(), rowCount() + 2 );
|
||||
beginInsertRows( QModelIndex(), rowCount(), rowCount() + 3 );
|
||||
|
||||
GroupItem* browse = new GroupItem( this, m_rootItem, tr( "Browse" ), 0 );
|
||||
new HistoryItem( this, m_rootItem, tr( "Search History" ), 1 );
|
||||
// new SourceTreeItem( this, m_rootItem, SourcesModel::Divider, 2 );
|
||||
m_myMusicGroup = new GroupItem( this, m_rootItem, tr( "My Music" ), 3 );
|
||||
|
||||
GenericPageItem* dashboard = new GenericPageItem( this, browse, tr( "Dashboard" ), QIcon( RESPATH "images/dashboard.png" ),
|
||||
boost::bind( &ViewManager::showWelcomePage, ViewManager::instance() ),
|
||||
boost::bind( &ViewManager::welcomeWidget, ViewManager::instance() ) );
|
||||
dashboard->setSortValue( 0 );
|
||||
|
||||
// super collection
|
||||
GenericPageItem* sc = new GenericPageItem( this, browse, tr( "SuperCollection" ), QIcon( RESPATH "images/supercollection.png" ),
|
||||
boost::bind( &ViewManager::showSuperCollection, ViewManager::instance() ),
|
||||
@ -282,15 +287,15 @@ SourcesModel::appendGroups()
|
||||
boost::bind( &ViewManager::topLovedWidget, ViewManager::instance() ) );
|
||||
loved->setSortValue( 2 );
|
||||
|
||||
GenericPageItem* recent = new GenericPageItem( this, browse, tr( "Dashboard" ), QIcon( RESPATH "images/dashboard.png" ),
|
||||
boost::bind( &ViewManager::showWelcomePage, ViewManager::instance() ),
|
||||
boost::bind( &ViewManager::welcomeWidget, ViewManager::instance() ) );
|
||||
recent->setSortValue( 0 );
|
||||
GenericPageItem* recent = new GenericPageItem( this, browse, tr( "Recently Played" ), QIcon( RESPATH "images/recently-played.png" ),
|
||||
boost::bind( &ViewManager::showRecentPlaysPage, ViewManager::instance() ),
|
||||
boost::bind( &ViewManager::recentPlaysWidget, ViewManager::instance() ) );
|
||||
recent->setSortValue( 3 );
|
||||
|
||||
GenericPageItem* hot = new GenericPageItem( this, browse, tr( "Charts" ), QIcon( RESPATH "images/charts.png" ),
|
||||
boost::bind( &ViewManager::showWhatsHotPage, ViewManager::instance() ),
|
||||
boost::bind( &ViewManager::whatsHotWidget, ViewManager::instance() ) );
|
||||
hot->setSortValue( 3 );
|
||||
hot->setSortValue( 4 );
|
||||
|
||||
m_collectionsGroup = new GroupItem( this, m_rootItem, tr( "Friends" ), 4 );
|
||||
|
||||
|
@ -79,6 +79,7 @@ SourceTreeView::SourceTreeView( QWidget* parent )
|
||||
sortByColumn( 0, Qt::AscendingOrder );
|
||||
setVerticalScrollMode( QTreeView::ScrollPerPixel );
|
||||
setMouseTracking( true );
|
||||
setEditTriggers( NoEditTriggers );
|
||||
|
||||
// TODO animation conflicts with the expanding-playlists-when-collection-is-null
|
||||
// so investigate
|
||||
@ -89,6 +90,7 @@ SourceTreeView::SourceTreeView( QWidget* parent )
|
||||
connect( m_delegate, SIGNAL( latchOff( Tomahawk::source_ptr ) ), SLOT( latchOff( Tomahawk::source_ptr ) ) );
|
||||
connect( m_delegate, SIGNAL( toggleRealtimeLatch( Tomahawk::source_ptr, bool ) ), m_latchManager, SLOT( latchModeChangeRequest( Tomahawk::source_ptr,bool ) ) );
|
||||
connect( m_delegate, SIGNAL( clicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
|
||||
connect( m_delegate, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemDoubleClicked( QModelIndex ) ) );
|
||||
|
||||
setItemDelegate( m_delegate );
|
||||
|
||||
@ -97,7 +99,7 @@ SourceTreeView::SourceTreeView( QWidget* parent )
|
||||
|
||||
m_model = new SourcesModel( this );
|
||||
m_proxyModel = new SourcesProxyModel( m_model, this );
|
||||
connect( m_proxyModel, SIGNAL( selectRequest( QPersistentModelIndex ) ), SLOT( selectRequest( QPersistentModelIndex ) ) );
|
||||
connect( m_proxyModel, SIGNAL( selectRequest( QPersistentModelIndex ) ), SLOT( selectRequest( QPersistentModelIndex ) ), Qt::QueuedConnection );
|
||||
connect( m_proxyModel, SIGNAL( expandRequest( QPersistentModelIndex ) ), SLOT( expandRequest( QPersistentModelIndex ) ) );
|
||||
connect( m_proxyModel, SIGNAL( toggleExpandRequest( QPersistentModelIndex ) ), SLOT( toggleExpandRequest( QPersistentModelIndex ) ) );
|
||||
|
||||
@ -231,6 +233,17 @@ SourceTreeView::onItemActivated( const QModelIndex& index )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SourceTreeView::onItemDoubleClicked( const QModelIndex& idx )
|
||||
{
|
||||
if ( !selectionModel()->selectedIndexes().contains( idx ) )
|
||||
onItemActivated( idx );
|
||||
|
||||
SourceTreeItem* item = itemFromIndex< SourceTreeItem >( idx );
|
||||
item->doubleClicked();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SourceTreeView::onItemExpanded( const QModelIndex& idx )
|
||||
{
|
||||
|
@ -67,6 +67,7 @@ private slots:
|
||||
void selectRequest( const QPersistentModelIndex& idx );
|
||||
void expandRequest( const QPersistentModelIndex& idx );
|
||||
void toggleExpandRequest( const QPersistentModelIndex& idx );
|
||||
void onItemDoubleClicked( const QModelIndex& idx );
|
||||
|
||||
void loadPlaylist();
|
||||
void deletePlaylist( const QModelIndex& = QModelIndex() );
|
||||
|
@ -393,7 +393,7 @@
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Playdar HTTP API</string>
|
||||
<string>Allow web browsers to interact with Tomahawk</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
|
@ -270,6 +270,7 @@ TomahawkApp::init()
|
||||
{
|
||||
initHTTP();
|
||||
}
|
||||
connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( initHTTP() ) );
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
if ( !s->hasScannerPaths() )
|
||||
@ -314,6 +315,11 @@ TomahawkApp::~TomahawkApp()
|
||||
{
|
||||
tLog() << "Shutting down Tomahawk...";
|
||||
|
||||
if ( !m_session.isNull() )
|
||||
delete m_session.data();
|
||||
if ( !m_connector.isNull() )
|
||||
delete m_connector.data();
|
||||
|
||||
Pipeline::instance()->stop();
|
||||
|
||||
if ( !m_servent.isNull() )
|
||||
@ -475,15 +481,43 @@ TomahawkApp::initDatabase()
|
||||
void
|
||||
TomahawkApp::initHTTP()
|
||||
{
|
||||
m_session.setPort( 60210 ); //TODO config
|
||||
m_session.setListenInterface( QHostAddress::LocalHost );
|
||||
m_session.setConnector( &m_connector );
|
||||
if ( !TomahawkSettings::instance()->httpEnabled() )
|
||||
{
|
||||
tLog() << "Stopping HTTPd, not enabled";
|
||||
if ( !m_session.isNull() )
|
||||
delete m_session.data();
|
||||
if ( !m_connector.isNull() )
|
||||
delete m_connector.data();
|
||||
return;
|
||||
}
|
||||
|
||||
Api_v1* api = new Api_v1( &m_session );
|
||||
m_session.setStaticContentService( api );
|
||||
if ( m_session )
|
||||
{
|
||||
tLog() << "HTTPd session already exists, returning";
|
||||
return;
|
||||
}
|
||||
|
||||
tLog() << "Starting HTTPd on" << m_session.listenInterface().toString() << m_session.port();
|
||||
m_session.start();
|
||||
m_session = QWeakPointer< QxtHttpSessionManager >( new QxtHttpSessionManager() );
|
||||
m_connector = QWeakPointer< QxtHttpServerConnector >( new QxtHttpServerConnector );
|
||||
if ( m_session.isNull() || m_connector.isNull() )
|
||||
{
|
||||
if ( !m_session.isNull() )
|
||||
delete m_session.data();
|
||||
if ( !m_connector.isNull() )
|
||||
delete m_connector.data();
|
||||
tLog() << "Failed to start HTTPd, could not create object";
|
||||
return;
|
||||
}
|
||||
|
||||
m_session.data()->setPort( 60210 ); //TODO config
|
||||
m_session.data()->setListenInterface( QHostAddress::LocalHost );
|
||||
m_session.data()->setConnector( m_connector.data() );
|
||||
|
||||
Api_v1* api = new Api_v1( m_session.data() );
|
||||
m_session.data()->setStaticContentService( api );
|
||||
|
||||
tLog() << "Starting HTTPd on" << m_session.data()->listenInterface().toString() << m_session.data()->port();
|
||||
m_session.data()->start();
|
||||
}
|
||||
|
||||
|
||||
|
@ -108,6 +108,7 @@ public slots:
|
||||
private slots:
|
||||
void initServent();
|
||||
void initSIP();
|
||||
void initHTTP();
|
||||
|
||||
void spotifyApiCheckFinished();
|
||||
|
||||
@ -121,8 +122,6 @@ private:
|
||||
void initLocalCollection();
|
||||
void initPipeline();
|
||||
|
||||
void initHTTP();
|
||||
|
||||
QWeakPointer<Database> m_database;
|
||||
QWeakPointer<ScanManager> m_scanManager;
|
||||
QWeakPointer<AudioEngine> m_audioEngine;
|
||||
@ -143,8 +142,8 @@ private:
|
||||
|
||||
bool m_headless, m_loaded;
|
||||
|
||||
QxtHttpServerConnector m_connector;
|
||||
QxtHttpSessionManager m_session;
|
||||
QWeakPointer< QxtHttpServerConnector > m_connector;
|
||||
QWeakPointer< QxtHttpSessionManager > m_session;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE( QPersistentModelIndex )
|
||||
|
@ -33,7 +33,6 @@ handleAccountAdded( Tomahawk::Accounts::Account* account, bool added )
|
||||
if ( added )
|
||||
{
|
||||
account->setEnabled( true );
|
||||
account->setAutoConnect( true );
|
||||
account->saveConfig();
|
||||
|
||||
TomahawkSettings::instance()->addAccount( account->accountId() );
|
||||
|
4
thirdparty/CMakeLists.txt
vendored
4
thirdparty/CMakeLists.txt
vendored
@ -1,6 +1,8 @@
|
||||
ADD_SUBDIRECTORY( qxt )
|
||||
ADD_SUBDIRECTORY( liblastfm2 )
|
||||
ADD_SUBDIRECTORY( breakpad )
|
||||
IF( WITH_BREAKPAD )
|
||||
ADD_SUBDIRECTORY( breakpad )
|
||||
ENDIF()
|
||||
IF( APPLE )
|
||||
ADD_SUBDIRECTORY( SPMediaKeyTap )
|
||||
ENDIF()
|
||||
|
@ -575,9 +575,14 @@ void QxtHttpSessionManager::processEvents()
|
||||
*/
|
||||
void QxtHttpSessionManager::chunkReadyRead(int requestID)
|
||||
{
|
||||
if (!connector()) return;
|
||||
|
||||
const QSharedPointer<QIODevice>& dataSource = connector()->getRequestDataSource( requestID );
|
||||
if (!dataSource->bytesAvailable()) return;
|
||||
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
if (!device) return;
|
||||
|
||||
if (!device->bytesToWrite() || qxt_d().connectionState[device].readyRead == false)
|
||||
{
|
||||
qxt_d().connectionState[device].readyRead = true;
|
||||
@ -590,6 +595,9 @@ void QxtHttpSessionManager::chunkReadyRead(int requestID)
|
||||
*/
|
||||
void QxtHttpSessionManager::sendNextChunk(int requestID)
|
||||
{
|
||||
if ( !connector() )
|
||||
return;
|
||||
|
||||
const QSharedPointer<QIODevice>& dataSource = connector()->getRequestDataSource( requestID );
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
QxtHttpSessionManagerPrivate::ConnectionState& state = qxt_d().connectionState[device];
|
||||
|
Loading…
x
Reference in New Issue
Block a user