mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-08 07:07:05 +02:00
* Added SocialWidget, tweet or share your latest music obsessions.
This commit is contained in:
@@ -136,6 +136,7 @@
|
|||||||
<file>data/images/grooveshark.png</file>
|
<file>data/images/grooveshark.png</file>
|
||||||
<file>data/images/lastfm-icon.png</file>
|
<file>data/images/lastfm-icon.png</file>
|
||||||
<file>data/images/playlist-header-tiled.png</file>
|
<file>data/images/playlist-header-tiled.png</file>
|
||||||
|
<file>data/images/share.png</file>
|
||||||
<file>data/sql/dbmigrate-27_to_28.sql</file>
|
<file>data/sql/dbmigrate-27_to_28.sql</file>
|
||||||
<file>data/images/process-stop.png</file>
|
<file>data/images/process-stop.png</file>
|
||||||
<file>data/icons/tomahawk-icon-128x128-grayscale.png</file>
|
<file>data/icons/tomahawk-icon-128x128-grayscale.png</file>
|
||||||
|
@@ -87,6 +87,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
|
|||||||
LoadXSPFDialog.cpp
|
LoadXSPFDialog.cpp
|
||||||
AccountFactoryWrapper.cpp
|
AccountFactoryWrapper.cpp
|
||||||
AccountFactoryWrapperDelegate.cpp
|
AccountFactoryWrapperDelegate.cpp
|
||||||
|
SocialWidget.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
IF( WITH_BREAKPAD )
|
IF( WITH_BREAKPAD )
|
||||||
@@ -102,10 +103,9 @@ SET( tomahawkUI ${tomahawkUI}
|
|||||||
accounts/lastfm/LastFmConfig.ui
|
accounts/lastfm/LastFmConfig.ui
|
||||||
|
|
||||||
audiocontrols.ui
|
audiocontrols.ui
|
||||||
|
|
||||||
LoadXSPFDialog.ui
|
LoadXSPFDialog.ui
|
||||||
|
|
||||||
AccountFactoryWrapper.ui
|
AccountFactoryWrapper.ui
|
||||||
|
SocialWidget.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(
|
INCLUDE_DIRECTORIES(
|
||||||
|
262
src/SocialWidget.cpp
Normal file
262
src/SocialWidget.cpp
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright 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 "SocialWidget.h"
|
||||||
|
#include "ui_SocialWidget.h"
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QPropertyAnimation>
|
||||||
|
|
||||||
|
#include "globalactionmanager.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
|
||||||
|
#define CORNER_ROUNDNESS 8.0
|
||||||
|
#define FADING_DURATION 500
|
||||||
|
#define FONT_SIZE 16
|
||||||
|
#define OPACITY 0.70
|
||||||
|
|
||||||
|
|
||||||
|
SocialWidget::SocialWidget( QWidget* parent )
|
||||||
|
: QWidget( parent ) // this is on purpose!
|
||||||
|
, ui( new Ui::SocialWidget )
|
||||||
|
, m_opacity( 0.00 )
|
||||||
|
, m_parent( parent )
|
||||||
|
, m_parentRect( parent->rect() )
|
||||||
|
{
|
||||||
|
ui->setupUi( this );
|
||||||
|
|
||||||
|
setAttribute( Qt::WA_TranslucentBackground, true );
|
||||||
|
setOpacity( m_opacity );
|
||||||
|
|
||||||
|
m_timer.setSingleShot( true );
|
||||||
|
connect( &m_timer, SIGNAL( timeout() ), this, SLOT( hide() ) );
|
||||||
|
|
||||||
|
#ifdef Q_WS_MAC
|
||||||
|
QFont f( font() );
|
||||||
|
f.setPointSize( f.pointSize() - 2 );
|
||||||
|
setFont( f );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ui->charsLeftLabel->setForegroundRole( QPalette::HighlightedText );
|
||||||
|
|
||||||
|
m_parent->installEventFilter( this );
|
||||||
|
|
||||||
|
connect( ui->buttonBox, SIGNAL( accepted() ), SLOT( accept() ) );
|
||||||
|
connect( ui->buttonBox, SIGNAL( rejected() ), SLOT( deleteLater() ) );
|
||||||
|
connect( ui->textEdit, SIGNAL( textChanged() ), SLOT( onChanged() ) );
|
||||||
|
connect( ui->facebookButton, SIGNAL( clicked( bool ) ), SLOT( onChanged() ) );
|
||||||
|
connect( ui->twitterButton, SIGNAL( clicked( bool ) ), SLOT( onChanged() ) );
|
||||||
|
connect( GlobalActionManager::instance(), SIGNAL( shortLinkReady( QUrl, QUrl, QVariant ) ), SLOT( onShortLinkReady( QUrl, QUrl, QVariant ) ) );
|
||||||
|
|
||||||
|
onChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SocialWidget::~SocialWidget()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SocialWidget::setOpacity( qreal opacity )
|
||||||
|
{
|
||||||
|
m_opacity = opacity;
|
||||||
|
|
||||||
|
if ( m_opacity == 0.00 && !isHidden() )
|
||||||
|
{
|
||||||
|
QWidget::hide();
|
||||||
|
}
|
||||||
|
else if ( m_opacity > 0.00 && isHidden() )
|
||||||
|
{
|
||||||
|
QWidget::show();
|
||||||
|
}
|
||||||
|
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SocialWidget::show( int timeoutSecs )
|
||||||
|
{
|
||||||
|
if ( !isEnabled() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
QPropertyAnimation* animation = new QPropertyAnimation( this, "opacity" );
|
||||||
|
animation->setDuration( FADING_DURATION );
|
||||||
|
animation->setEndValue( 1.0 );
|
||||||
|
animation->start();
|
||||||
|
|
||||||
|
if( timeoutSecs > 0 )
|
||||||
|
m_timer.start( timeoutSecs * 1000 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SocialWidget::hide()
|
||||||
|
{
|
||||||
|
if ( !isEnabled() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
QPropertyAnimation* animation = new QPropertyAnimation( this, "opacity" );
|
||||||
|
animation->setDuration( FADING_DURATION );
|
||||||
|
animation->setEndValue( 0.00 );
|
||||||
|
animation->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
SocialWidget::shown() const
|
||||||
|
{
|
||||||
|
if ( !isEnabled() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return m_opacity == OPACITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SocialWidget::paintEvent( QPaintEvent* event )
|
||||||
|
{
|
||||||
|
Q_UNUSED( event );
|
||||||
|
|
||||||
|
QPoint position( m_position - QPoint( size().width(), size().height() ) );
|
||||||
|
if ( position != pos() )
|
||||||
|
{
|
||||||
|
move( position );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainter p( this );
|
||||||
|
QRect r = contentsRect();
|
||||||
|
|
||||||
|
p.setBackgroundMode( Qt::TransparentMode );
|
||||||
|
p.setRenderHint( QPainter::Antialiasing );
|
||||||
|
p.setOpacity( m_opacity );
|
||||||
|
|
||||||
|
QPen pen( palette().dark().color(), .5 );
|
||||||
|
p.setPen( pen );
|
||||||
|
p.setBrush( QColor( 30, 30, 30, 255.0 * OPACITY ) );
|
||||||
|
|
||||||
|
p.drawRoundedRect( r, CORNER_ROUNDNESS, CORNER_ROUNDNESS );
|
||||||
|
|
||||||
|
QWidget::paintEvent( event );
|
||||||
|
return;
|
||||||
|
|
||||||
|
QTextOption to( Qt::AlignCenter );
|
||||||
|
to.setWrapMode( QTextOption::WrapAtWordBoundaryOrAnywhere );
|
||||||
|
|
||||||
|
// shrink to fit if needed
|
||||||
|
QFont f( font() );
|
||||||
|
f.setPointSize( FONT_SIZE );
|
||||||
|
f.setBold( true );
|
||||||
|
|
||||||
|
QRectF textRect = r.adjusted( 8, 8, -8, -8 );
|
||||||
|
qreal availHeight = textRect.height();
|
||||||
|
|
||||||
|
QFontMetricsF fm( f );
|
||||||
|
qreal textHeight = fm.boundingRect( textRect, Qt::AlignCenter | Qt::TextWordWrap, "SocialWidget" ).height();
|
||||||
|
while( textHeight > availHeight )
|
||||||
|
{
|
||||||
|
if( f.pointSize() <= 4 ) // don't try harder
|
||||||
|
break;
|
||||||
|
|
||||||
|
f.setPointSize( f.pointSize() - 1 );
|
||||||
|
fm = QFontMetricsF( f );
|
||||||
|
textHeight = fm.boundingRect( textRect, Qt::AlignCenter | Qt::TextWordWrap, "SocialWidget" ).height();
|
||||||
|
}
|
||||||
|
|
||||||
|
p.setFont( f );
|
||||||
|
p.setPen( palette().highlightedText().color() );
|
||||||
|
p.drawText( r.adjusted( 8, 8, -8, -8 ), "SocialWidget", to );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SocialWidget::onShortLinkReady( const QUrl& longUrl, const QUrl& shortUrl, const QVariant& callbackObj )
|
||||||
|
{
|
||||||
|
ui->textEdit->setText( tr( "Listening to \"%1\" by %2 on \"%3\" and loving it! %4" ).arg( m_query->track() ).arg( m_query->artist() ).arg( m_query->album() ).arg( shortUrl.toString() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SocialWidget::setQuery( const Tomahawk::query_ptr& query )
|
||||||
|
{
|
||||||
|
m_query = query;
|
||||||
|
ui->coverImage->setPixmap( query->cover( ui->coverImage->size() ) );
|
||||||
|
onChanged();
|
||||||
|
|
||||||
|
QUrl longUrl = GlobalActionManager::instance()->openLinkFromQuery( query );
|
||||||
|
GlobalActionManager::instance()->shortenLink( longUrl );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SocialWidget::onChanged()
|
||||||
|
{
|
||||||
|
const int remaining = charsAvailable() - ui->textEdit->toPlainText().length();
|
||||||
|
ui->charsLeftLabel->setText( tr( "%1 characters left" ).arg( remaining ) );
|
||||||
|
ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( remaining >= 0 && ( ui->facebookButton->isChecked() || ui->twitterButton->isChecked() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SocialWidget::accept()
|
||||||
|
{
|
||||||
|
tDebug() << "Sharing social link!";
|
||||||
|
|
||||||
|
deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
SocialWidget::charsAvailable() const
|
||||||
|
{
|
||||||
|
if ( ui->twitterButton->isChecked() )
|
||||||
|
return 140;
|
||||||
|
|
||||||
|
return 420; // facebook max length
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SocialWidget::onGeometryUpdate()
|
||||||
|
{
|
||||||
|
QPoint p( m_parent->rect().width() - m_parentRect.width(), m_parent->rect().height() - m_parentRect.height() );
|
||||||
|
m_position += p;
|
||||||
|
m_parentRect = m_parent->rect();
|
||||||
|
|
||||||
|
QPoint position( m_position - QPoint( size().width(), size().height() ) );
|
||||||
|
if ( position != pos() )
|
||||||
|
{
|
||||||
|
move( position );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
SocialWidget::eventFilter( QObject* object, QEvent* event )
|
||||||
|
{
|
||||||
|
if ( event->type() == QEvent::Resize )
|
||||||
|
{
|
||||||
|
onGeometryUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QObject::eventFilter( object, event );
|
||||||
|
}
|
84
src/SocialWidget.h
Normal file
84
src/SocialWidget.h
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright 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 SOCIALWIDGET_H
|
||||||
|
#define SOCIALWIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QAbstractItemView>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "query.h"
|
||||||
|
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class SocialWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SocialWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY( qreal opacity READ opacity WRITE setOpacity )
|
||||||
|
|
||||||
|
public:
|
||||||
|
SocialWidget( QWidget* parent );
|
||||||
|
~SocialWidget();
|
||||||
|
|
||||||
|
Tomahawk::query_ptr query() const { return m_query; }
|
||||||
|
void setQuery( const Tomahawk::query_ptr& query );
|
||||||
|
|
||||||
|
qreal opacity() const { return m_opacity; }
|
||||||
|
void setOpacity( qreal opacity );
|
||||||
|
|
||||||
|
QPoint position() const { return m_position; }
|
||||||
|
void setPosition( QPoint position ) { m_position = position; }
|
||||||
|
|
||||||
|
bool shown() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void show( int timeoutSecs = 0 );
|
||||||
|
void hide();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// void changeEvent( QEvent* e );
|
||||||
|
void paintEvent( QPaintEvent* event );
|
||||||
|
bool eventFilter( QObject* object, QEvent* event );
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void accept();
|
||||||
|
void onChanged();
|
||||||
|
void onShortLinkReady( const QUrl& longUrl, const QUrl& shortUrl, const QVariant& callbackObj );
|
||||||
|
|
||||||
|
void onGeometryUpdate();
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned int charsAvailable() const;
|
||||||
|
|
||||||
|
Ui::SocialWidget* ui;
|
||||||
|
|
||||||
|
Tomahawk::query_ptr m_query;
|
||||||
|
|
||||||
|
qreal m_opacity;
|
||||||
|
QPoint m_position;
|
||||||
|
|
||||||
|
QWidget* m_parent;
|
||||||
|
QRect m_parentRect;
|
||||||
|
QTimer m_timer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SOCIALWIDGET_H
|
118
src/SocialWidget.ui
Normal file
118
src/SocialWidget.ui
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>SocialWidget</class>
|
||||||
|
<widget class="QWidget" name="SocialWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>365</width>
|
||||||
|
<height>190</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="facebookButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Facebook</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="twitterButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Twitter</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="coverImage">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>96</width>
|
||||||
|
<height>96</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>96</width>
|
||||||
|
<height>96</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Cover</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTextEdit" name="textEdit">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>96</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="charsLeftLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@@ -32,6 +32,7 @@
|
|||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
#include "album.h"
|
#include "album.h"
|
||||||
#include "dropjob.h"
|
#include "dropjob.h"
|
||||||
|
#include "SocialWidget.h"
|
||||||
#include "globalactionmanager.h"
|
#include "globalactionmanager.h"
|
||||||
#include "viewmanager.h"
|
#include "viewmanager.h"
|
||||||
|
|
||||||
@@ -44,6 +45,7 @@ AudioControls::AudioControls( QWidget* parent )
|
|||||||
, m_repeatMode( PlaylistInterface::NoRepeat )
|
, m_repeatMode( PlaylistInterface::NoRepeat )
|
||||||
, m_shuffled( false )
|
, m_shuffled( false )
|
||||||
, m_lastSliderCheck( 0 )
|
, m_lastSliderCheck( 0 )
|
||||||
|
, m_parent( parent )
|
||||||
{
|
{
|
||||||
ui->setupUi( this );
|
ui->setupUi( this );
|
||||||
setAcceptDrops( true );
|
setAcceptDrops( true );
|
||||||
@@ -82,6 +84,7 @@ AudioControls::AudioControls( QWidget* parent )
|
|||||||
ui->repeatButton->setPixmap( RESPATH "images/repeat-off-pressed.png", QIcon::Off, QIcon::Active );
|
ui->repeatButton->setPixmap( RESPATH "images/repeat-off-pressed.png", QIcon::Off, QIcon::Active );
|
||||||
ui->volumeLowButton->setPixmap( RESPATH "images/volume-icon-muted.png" );
|
ui->volumeLowButton->setPixmap( RESPATH "images/volume-icon-muted.png" );
|
||||||
ui->volumeHighButton->setPixmap( RESPATH "images/volume-icon-full.png" );
|
ui->volumeHighButton->setPixmap( RESPATH "images/volume-icon-full.png" );
|
||||||
|
ui->socialButton->setPixmap( RESPATH "images/share.png" );
|
||||||
ui->loveButton->setPixmap( RESPATH "images/not-loved.png" );
|
ui->loveButton->setPixmap( RESPATH "images/not-loved.png" );
|
||||||
ui->loveButton->setCheckable( true );
|
ui->loveButton->setCheckable( true );
|
||||||
|
|
||||||
@@ -118,8 +121,9 @@ AudioControls::AudioControls( QWidget* parent )
|
|||||||
connect( ui->shuffleButton, SIGNAL( clicked() ), SLOT( onShuffleClicked() ) );
|
connect( ui->shuffleButton, SIGNAL( clicked() ), SLOT( onShuffleClicked() ) );
|
||||||
|
|
||||||
connect( ui->artistTrackLabel, SIGNAL( clickedArtist() ), SLOT( onArtistClicked() ) );
|
connect( ui->artistTrackLabel, SIGNAL( clickedArtist() ), SLOT( onArtistClicked() ) );
|
||||||
connect( ui->artistTrackLabel, SIGNAL( clickedTrack() ), SLOT( onTrackClicked() ) );
|
connect( ui->artistTrackLabel, SIGNAL( clickedTrack() ), SLOT( onTrackClicked() ) );
|
||||||
connect( ui->albumLabel, SIGNAL( clickedAlbum() ), SLOT( onAlbumClicked() ) );
|
connect( ui->albumLabel, SIGNAL( clickedAlbum() ), SLOT( onAlbumClicked() ) );
|
||||||
|
connect( ui->socialButton, SIGNAL( clicked() ), SLOT( onSocialButtonClicked() ) );
|
||||||
connect( ui->loveButton, SIGNAL( clicked( bool ) ), SLOT( onLoveButtonClicked( bool ) ) );
|
connect( ui->loveButton, SIGNAL( clicked( bool ) ), SLOT( onLoveButtonClicked( bool ) ) );
|
||||||
|
|
||||||
// <From AudioEngine>
|
// <From AudioEngine>
|
||||||
@@ -247,6 +251,8 @@ AudioControls::onPlaybackLoading( const Tomahawk::result_ptr& result )
|
|||||||
|
|
||||||
ui->loveButton->setEnabled( true );
|
ui->loveButton->setEnabled( true );
|
||||||
ui->loveButton->setVisible( true );
|
ui->loveButton->setVisible( true );
|
||||||
|
ui->socialButton->setEnabled( true );
|
||||||
|
ui->socialButton->setVisible( true );
|
||||||
|
|
||||||
setCover();
|
setCover();
|
||||||
setSocialActions();
|
setSocialActions();
|
||||||
@@ -319,7 +325,6 @@ AudioControls::onPlaybackResumed()
|
|||||||
{
|
{
|
||||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
|
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
|
||||||
ui->stackedLayout->setCurrentWidget( ui->pauseButton );
|
ui->stackedLayout->setCurrentWidget( ui->pauseButton );
|
||||||
ui->loveButton->setVisible( true );
|
|
||||||
m_sliderTimeLine.resume();
|
m_sliderTimeLine.resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,6 +359,8 @@ AudioControls::onPlaybackStopped()
|
|||||||
ui->stackedLayout->setCurrentWidget( ui->playPauseButton );
|
ui->stackedLayout->setCurrentWidget( ui->playPauseButton );
|
||||||
ui->loveButton->setEnabled( false );
|
ui->loveButton->setEnabled( false );
|
||||||
ui->loveButton->setVisible( false );
|
ui->loveButton->setVisible( false );
|
||||||
|
ui->socialButton->setEnabled( false );
|
||||||
|
ui->socialButton->setVisible( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -590,6 +597,16 @@ AudioControls::droppedTracks( QList< query_ptr > tracks )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioControls::onSocialButtonClicked()
|
||||||
|
{
|
||||||
|
SocialWidget* sw = new SocialWidget( m_parent );
|
||||||
|
sw->setPosition( QCursor::pos() );
|
||||||
|
sw->setQuery( m_currentTrack->toQuery() );
|
||||||
|
sw->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioControls::onLoveButtonClicked( bool checked )
|
AudioControls::onLoveButtonClicked( bool checked )
|
||||||
{
|
{
|
||||||
|
@@ -78,6 +78,7 @@ private slots:
|
|||||||
void onArtistClicked();
|
void onArtistClicked();
|
||||||
void onAlbumClicked();
|
void onAlbumClicked();
|
||||||
void onTrackClicked();
|
void onTrackClicked();
|
||||||
|
void onSocialButtonClicked();
|
||||||
void onLoveButtonClicked( bool );
|
void onLoveButtonClicked( bool );
|
||||||
|
|
||||||
void droppedTracks( QList<Tomahawk::query_ptr> );
|
void droppedTracks( QList<Tomahawk::query_ptr> );
|
||||||
@@ -89,7 +90,7 @@ private:
|
|||||||
void setCover();
|
void setCover();
|
||||||
void setSocialActions();
|
void setSocialActions();
|
||||||
|
|
||||||
Ui::AudioControls *ui;
|
Ui::AudioControls* ui;
|
||||||
|
|
||||||
Tomahawk::result_ptr m_currentTrack;
|
Tomahawk::result_ptr m_currentTrack;
|
||||||
Tomahawk::PlaylistInterface::RepeatMode m_repeatMode;
|
Tomahawk::PlaylistInterface::RepeatMode m_repeatMode;
|
||||||
@@ -101,6 +102,8 @@ private:
|
|||||||
qint64 m_lastSliderCheck;
|
qint64 m_lastSliderCheck;
|
||||||
bool m_noTimeChange;
|
bool m_noTimeChange;
|
||||||
qint64 m_lastTextSecondShown;
|
qint64 m_lastTextSecondShown;
|
||||||
|
|
||||||
|
QWidget* m_parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AUDIOCONTROLS_H
|
#endif // AUDIOCONTROLS_H
|
||||||
|
@@ -287,6 +287,22 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="ImageButton" name="socialButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>PointingHandCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>social</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="ImageButton" name="loveButton">
|
<widget class="ImageButton" name="loveButton">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||||
Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||||
|
Copyright (C) 2011-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -45,7 +46,6 @@
|
|||||||
#include "playlist/topbar/topbar.h"
|
#include "playlist/topbar/topbar.h"
|
||||||
#include "playlist/playlistview.h"
|
#include "playlist/playlistview.h"
|
||||||
|
|
||||||
|
|
||||||
#include <QtGui/QApplication>
|
#include <QtGui/QApplication>
|
||||||
#include <QtGui/QClipboard>
|
#include <QtGui/QClipboard>
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ GlobalActionManager::openLink( const QString& title, const QString& artist, cons
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
GlobalActionManager::shortenLink( const QUrl& url, const QVariant &callbackObj )
|
GlobalActionManager::shortenLink( const QUrl& url, const QVariant& callbackObj )
|
||||||
{
|
{
|
||||||
if ( QThread::currentThread() != thread() )
|
if ( QThread::currentThread() != thread() )
|
||||||
{
|
{
|
||||||
@@ -148,7 +148,8 @@ GlobalActionManager::copyPlaylistToClipboard( const dynplaylist_ptr& playlist )
|
|||||||
{
|
{
|
||||||
QUrl link( QString( "%1/%2/create/" ).arg( hostname() ).arg( playlist->mode() == OnDemand ? "station" : "autoplaylist" ) );
|
QUrl link( QString( "%1/%2/create/" ).arg( hostname() ).arg( playlist->mode() == OnDemand ? "station" : "autoplaylist" ) );
|
||||||
|
|
||||||
if( playlist->generator()->type() != "echonest" ) {
|
if ( playlist->generator()->type() != "echonest" )
|
||||||
|
{
|
||||||
tLog() << "Only echonest generators are supported";
|
tLog() << "Only echonest generators are supported";
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
@@ -157,19 +158,25 @@ GlobalActionManager::copyPlaylistToClipboard( const dynplaylist_ptr& playlist )
|
|||||||
link.addQueryItem( "title", playlist->title() );
|
link.addQueryItem( "title", playlist->title() );
|
||||||
|
|
||||||
QList< dyncontrol_ptr > controls = playlist->generator()->controls();
|
QList< dyncontrol_ptr > controls = playlist->generator()->controls();
|
||||||
foreach( const dyncontrol_ptr& c, controls ) {
|
foreach ( const dyncontrol_ptr& c, controls )
|
||||||
if( c->selectedType() == "Artist" ) {
|
{
|
||||||
if( c->match().toInt() == Echonest::DynamicPlaylist::ArtistType )
|
if ( c->selectedType() == "Artist" )
|
||||||
|
{
|
||||||
|
if ( c->match().toInt() == Echonest::DynamicPlaylist::ArtistType )
|
||||||
link.addQueryItem( "artist_limitto", c->input() );
|
link.addQueryItem( "artist_limitto", c->input() );
|
||||||
else
|
else
|
||||||
link.addQueryItem( "artist", c->input() );
|
link.addQueryItem( "artist", c->input() );
|
||||||
} else if( c->selectedType() == "Artist Description" ) {
|
}
|
||||||
|
else if ( c->selectedType() == "Artist Description" )
|
||||||
|
{
|
||||||
link.addQueryItem( "description", c->input() );
|
link.addQueryItem( "description", c->input() );
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
QString name = c->selectedType().toLower().replace( " ", "_" );
|
QString name = c->selectedType().toLower().replace( " ", "_" );
|
||||||
Echonest::DynamicPlaylist::PlaylistParam p = static_cast< Echonest::DynamicPlaylist::PlaylistParam >( c->match().toInt() );
|
Echonest::DynamicPlaylist::PlaylistParam p = static_cast< Echonest::DynamicPlaylist::PlaylistParam >( c->match().toInt() );
|
||||||
// if it is a max, set that too
|
// if it is a max, set that too
|
||||||
if( p == Echonest::DynamicPlaylist::MaxTempo || p == Echonest::DynamicPlaylist::MaxDuration || p == Echonest::DynamicPlaylist::MaxLoudness
|
if ( p == Echonest::DynamicPlaylist::MaxTempo || p == Echonest::DynamicPlaylist::MaxDuration || p == Echonest::DynamicPlaylist::MaxLoudness
|
||||||
|| p == Echonest::DynamicPlaylist::MaxDanceability || p == Echonest::DynamicPlaylist::MaxEnergy || p == Echonest::DynamicPlaylist::ArtistMaxFamiliarity
|
|| p == Echonest::DynamicPlaylist::MaxDanceability || p == Echonest::DynamicPlaylist::MaxEnergy || p == Echonest::DynamicPlaylist::ArtistMaxFamiliarity
|
||||||
|| p == Echonest::DynamicPlaylist::ArtistMaxHotttnesss || p == Echonest::DynamicPlaylist::SongMaxHotttnesss || p == Echonest::DynamicPlaylist::ArtistMaxLatitude
|
|| p == Echonest::DynamicPlaylist::ArtistMaxHotttnesss || p == Echonest::DynamicPlaylist::SongMaxHotttnesss || p == Echonest::DynamicPlaylist::ArtistMaxLatitude
|
||||||
|| p == Echonest::DynamicPlaylist::ArtistMaxLongitude )
|
|| p == Echonest::DynamicPlaylist::ArtistMaxLongitude )
|
||||||
@@ -204,7 +211,8 @@ GlobalActionManager::xspfCreated( const QByteArray& xspf )
|
|||||||
QString filename = sender()->property( "filename" ).toString();
|
QString filename = sender()->property( "filename" ).toString();
|
||||||
|
|
||||||
QFile f( filename );
|
QFile f( filename );
|
||||||
if( !f.open( QIODevice::WriteOnly ) ) {
|
if ( !f.open( QIODevice::WriteOnly ) )
|
||||||
|
{
|
||||||
qWarning() << "Failed to open file to save XSPF:" << filename;
|
qWarning() << "Failed to open file to save XSPF:" << filename;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -220,7 +228,7 @@ void
|
|||||||
GlobalActionManager::copyToClipboard( const query_ptr& query )
|
GlobalActionManager::copyToClipboard( const query_ptr& query )
|
||||||
{
|
{
|
||||||
m_clipboardLongUrl = openLinkFromQuery( query );
|
m_clipboardLongUrl = openLinkFromQuery( query );
|
||||||
GlobalActionManager::instance()->shortenLink( m_clipboardLongUrl );
|
shortenLink( m_clipboardLongUrl );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -228,10 +236,11 @@ bool
|
|||||||
GlobalActionManager::parseTomahawkLink( const QString& urlIn )
|
GlobalActionManager::parseTomahawkLink( const QString& urlIn )
|
||||||
{
|
{
|
||||||
QString url = urlIn;
|
QString url = urlIn;
|
||||||
if( urlIn.startsWith( "http://toma.hk" ) )
|
if ( urlIn.startsWith( "http://toma.hk" ) )
|
||||||
url.replace( "http://toma.hk/", "tomahawk://" );
|
url.replace( "http://toma.hk/", "tomahawk://" );
|
||||||
|
|
||||||
if( url.contains( "tomahawk://" ) ) {
|
if ( url.contains( "tomahawk://" ) )
|
||||||
|
{
|
||||||
QString cmd = url.mid( 11 );
|
QString cmd = url.mid( 11 );
|
||||||
cmd.replace( "%2B", "%20" );
|
cmd.replace( "%2B", "%20" );
|
||||||
tLog() << "Parsing tomahawk link command" << cmd;
|
tLog() << "Parsing tomahawk link command" << cmd;
|
||||||
@@ -240,8 +249,10 @@ GlobalActionManager::parseTomahawkLink( const QString& urlIn )
|
|||||||
QUrl u = QUrl::fromEncoded( cmd.toUtf8() );
|
QUrl u = QUrl::fromEncoded( cmd.toUtf8() );
|
||||||
|
|
||||||
// for backwards compatibility
|
// for backwards compatibility
|
||||||
if( cmdType == "load" ) {
|
if ( cmdType == "load" )
|
||||||
if( u.hasQueryItem( "xspf" ) ) {
|
{
|
||||||
|
if ( u.hasQueryItem( "xspf" ) )
|
||||||
|
{
|
||||||
QUrl xspf = QUrl::fromUserInput( u.queryItemValue( "xspf" ) );
|
QUrl xspf = QUrl::fromUserInput( u.queryItemValue( "xspf" ) );
|
||||||
XSPFLoader* l = new XSPFLoader( true, this );
|
XSPFLoader* l = new XSPFLoader( true, this );
|
||||||
tDebug() << "Loading spiff:" << xspf.toString();
|
tDebug() << "Loading spiff:" << xspf.toString();
|
||||||
@@ -249,7 +260,9 @@ GlobalActionManager::parseTomahawkLink( const QString& urlIn )
|
|||||||
connect( l, SIGNAL( ok( Tomahawk::playlist_ptr ) ), ViewManager::instance(), SLOT( show( Tomahawk::playlist_ptr ) ) );
|
connect( l, SIGNAL( ok( Tomahawk::playlist_ptr ) ), ViewManager::instance(), SLOT( show( Tomahawk::playlist_ptr ) ) );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if( u.hasQueryItem( "jspf" ) ) {
|
}
|
||||||
|
else if ( u.hasQueryItem( "jspf" ) )
|
||||||
|
{
|
||||||
QUrl jspf = QUrl::fromUserInput( u.queryItemValue( "jspf" ) );
|
QUrl jspf = QUrl::fromUserInput( u.queryItemValue( "jspf" ) );
|
||||||
JSPFLoader* l = new JSPFLoader( true, this );
|
JSPFLoader* l = new JSPFLoader( true, this );
|
||||||
|
|
||||||
@@ -261,31 +274,54 @@ GlobalActionManager::parseTomahawkLink( const QString& urlIn )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( cmdType == "playlist" ) {
|
if ( cmdType == "playlist" )
|
||||||
|
{
|
||||||
return handlePlaylistCommand( u );
|
return handlePlaylistCommand( u );
|
||||||
} else if( cmdType == "collection" ) {
|
}
|
||||||
|
else if ( cmdType == "collection" )
|
||||||
|
{
|
||||||
return handleCollectionCommand( u );
|
return handleCollectionCommand( u );
|
||||||
} else if( cmdType == "queue" ) {
|
}
|
||||||
|
else if ( cmdType == "queue" )
|
||||||
|
{
|
||||||
return handleQueueCommand( u );
|
return handleQueueCommand( u );
|
||||||
} else if( cmdType == "station" ) {
|
}
|
||||||
|
else if ( cmdType == "station" )
|
||||||
|
{
|
||||||
return handleStationCommand( u );
|
return handleStationCommand( u );
|
||||||
} else if( cmdType == "autoplaylist" ) {
|
}
|
||||||
|
else if ( cmdType == "autoplaylist" )
|
||||||
|
{
|
||||||
return handleAutoPlaylistCommand( u );
|
return handleAutoPlaylistCommand( u );
|
||||||
} else if( cmdType == "search" ) {
|
}
|
||||||
|
else if ( cmdType == "search" )
|
||||||
|
{
|
||||||
return handleSearchCommand( u );
|
return handleSearchCommand( u );
|
||||||
} else if( cmdType == "play" ) {
|
}
|
||||||
|
else if ( cmdType == "play" )
|
||||||
|
{
|
||||||
return handlePlayCommand( u );
|
return handlePlayCommand( u );
|
||||||
} else if( cmdType == "bookmark" ) {
|
}
|
||||||
|
else if ( cmdType == "bookmark" )
|
||||||
|
{
|
||||||
return handlePlayCommand( u );
|
return handlePlayCommand( u );
|
||||||
} else if( cmdType == "open" ) {
|
}
|
||||||
|
else if ( cmdType == "open" )
|
||||||
|
{
|
||||||
return handleOpenCommand( u );
|
return handleOpenCommand( u );
|
||||||
} else if( cmdType == "view" ) {
|
}
|
||||||
|
else if ( cmdType == "view" )
|
||||||
|
{
|
||||||
return handleViewCommand( u );
|
return handleViewCommand( u );
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tLog() << "Tomahawk link not supported, command not known!" << cmdType << u.path();
|
tLog() << "Tomahawk link not supported, command not known!" << cmdType << u.path();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tLog() << "Not a tomahawk:// link!";
|
tLog() << "Not a tomahawk:// link!";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -296,13 +332,16 @@ bool
|
|||||||
GlobalActionManager::handlePlaylistCommand( const QUrl& url )
|
GlobalActionManager::handlePlaylistCommand( const QUrl& url )
|
||||||
{
|
{
|
||||||
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
||||||
if( parts.isEmpty() ) {
|
if ( parts.isEmpty() )
|
||||||
|
{
|
||||||
tLog() << "No specific playlist command:" << url.toString();
|
tLog() << "No specific playlist command:" << url.toString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( parts[ 0 ] == "import" ) {
|
if ( parts[ 0 ] == "import" )
|
||||||
if( !url.hasQueryItem( "xspf" ) ) {
|
{
|
||||||
|
if ( !url.hasQueryItem( "xspf" ) )
|
||||||
|
{
|
||||||
tDebug() << "No xspf to load...";
|
tDebug() << "No xspf to load...";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -313,15 +352,21 @@ GlobalActionManager::handlePlaylistCommand( const QUrl& url )
|
|||||||
l->load( xspf );
|
l->load( xspf );
|
||||||
connect( l, SIGNAL( ok( Tomahawk::playlist_ptr ) ), this, SLOT( playlistCreatedToShow( Tomahawk::playlist_ptr) ) );
|
connect( l, SIGNAL( ok( Tomahawk::playlist_ptr ) ), this, SLOT( playlistCreatedToShow( Tomahawk::playlist_ptr) ) );
|
||||||
|
|
||||||
} else if( parts [ 0 ] == "new" ) {
|
}
|
||||||
if( !url.hasQueryItem( "title" ) ) {
|
else if ( parts [ 0 ] == "new" )
|
||||||
|
{
|
||||||
|
if ( !url.hasQueryItem( "title" ) )
|
||||||
|
{
|
||||||
tLog() << "New playlist command needs a title...";
|
tLog() << "New playlist command needs a title...";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
playlist_ptr pl = Playlist::create( SourceList::instance()->getLocal(), uuid(), url.queryItemValue( "title" ), QString(), QString(), false );
|
playlist_ptr pl = Playlist::create( SourceList::instance()->getLocal(), uuid(), url.queryItemValue( "title" ), QString(), QString(), false );
|
||||||
ViewManager::instance()->show( pl );
|
ViewManager::instance()->show( pl );
|
||||||
} else if( parts[ 0 ] == "add" ) {
|
}
|
||||||
if( !url.hasQueryItem( "playlistid" ) || !url.hasQueryItem( "title" ) || !url.hasQueryItem( "artist" ) ) {
|
else if ( parts[ 0 ] == "add" )
|
||||||
|
{
|
||||||
|
if ( !url.hasQueryItem( "playlistid" ) || !url.hasQueryItem( "title" ) || !url.hasQueryItem( "artist" ) )
|
||||||
|
{
|
||||||
tLog() << "Add to playlist command needs playlistid, track, and artist..." << url.toString();
|
tLog() << "Add to playlist command needs playlistid, track, and artist..." << url.toString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -353,12 +398,14 @@ bool
|
|||||||
GlobalActionManager::handleCollectionCommand( const QUrl& url )
|
GlobalActionManager::handleCollectionCommand( const QUrl& url )
|
||||||
{
|
{
|
||||||
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
||||||
if( parts.isEmpty() ) {
|
if ( parts.isEmpty() )
|
||||||
|
{
|
||||||
tLog() << "No specific collection command:" << url.toString();
|
tLog() << "No specific collection command:" << url.toString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( parts[ 0 ] == "add" ) {
|
if ( parts[ 0 ] == "add" )
|
||||||
|
{
|
||||||
// TODO implement
|
// TODO implement
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,7 +417,8 @@ bool
|
|||||||
GlobalActionManager::handleOpenCommand(const QUrl& url)
|
GlobalActionManager::handleOpenCommand(const QUrl& url)
|
||||||
{
|
{
|
||||||
QStringList parts = url.path().split( "/" ).mid( 1 );
|
QStringList parts = url.path().split( "/" ).mid( 1 );
|
||||||
if( parts.isEmpty() ) {
|
if ( parts.isEmpty() )
|
||||||
|
{
|
||||||
tLog() << "No specific type to open:" << url.toString();
|
tLog() << "No specific type to open:" << url.toString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -385,7 +433,8 @@ GlobalActionManager::handleOpenTrack ( const query_ptr& q )
|
|||||||
ViewManager::instance()->queue()->model()->append( q );
|
ViewManager::instance()->queue()->model()->append( q );
|
||||||
ViewManager::instance()->showQueue();
|
ViewManager::instance()->showQueue();
|
||||||
|
|
||||||
if( !AudioEngine::instance()->isPlaying() && !AudioEngine::instance()->isPaused() ) {
|
if ( !AudioEngine::instance()->isPlaying() && !AudioEngine::instance()->isPaused() )
|
||||||
|
{
|
||||||
connect( q.data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( waitingForResolved( bool ) ) );
|
connect( q.data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( waitingForResolved( bool ) ) );
|
||||||
m_waitingToPlay = q;
|
m_waitingToPlay = q;
|
||||||
}
|
}
|
||||||
@@ -403,14 +452,18 @@ bool
|
|||||||
GlobalActionManager::handleQueueCommand( const QUrl& url )
|
GlobalActionManager::handleQueueCommand( const QUrl& url )
|
||||||
{
|
{
|
||||||
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
||||||
if( parts.isEmpty() ) {
|
if ( parts.isEmpty() )
|
||||||
|
{
|
||||||
tLog() << "No specific queue command:" << url.toString();
|
tLog() << "No specific queue command:" << url.toString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( parts[ 0 ] == "add" ) {
|
if ( parts[ 0 ] == "add" )
|
||||||
|
{
|
||||||
doQueueAdd( parts.mid( 1 ), url.queryItems() );
|
doQueueAdd( parts.mid( 1 ), url.queryItems() );
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tLog() << "Only queue/add/track is support at the moment, got:" << parts;
|
tLog() << "Only queue/add/track is support at the moment, got:" << parts;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -422,46 +475,55 @@ GlobalActionManager::handleQueueCommand( const QUrl& url )
|
|||||||
bool
|
bool
|
||||||
GlobalActionManager::doQueueAdd( const QStringList& parts, const QList< QPair< QString, QString > >& queryItems )
|
GlobalActionManager::doQueueAdd( const QStringList& parts, const QList< QPair< QString, QString > >& queryItems )
|
||||||
{
|
{
|
||||||
if( parts.size() && parts[ 0 ] == "track" ) {
|
if ( parts.size() && parts[ 0 ] == "track" )
|
||||||
|
{
|
||||||
|
|
||||||
if( queueSpotify( parts, queryItems ) )
|
if ( queueSpotify( parts, queryItems ) )
|
||||||
return true;
|
return true;
|
||||||
else if( queueRdio( parts, queryItems ) )
|
else if ( queueRdio( parts, queryItems ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
QPair< QString, QString > pair;
|
QPair< QString, QString > pair;
|
||||||
|
|
||||||
QString title, artist, album, urlStr;
|
QString title, artist, album, urlStr;
|
||||||
foreach( pair, queryItems ) {
|
foreach ( pair, queryItems ) {
|
||||||
pair.second = pair.second.replace( "+", " " ); // QUrl::queryItems doesn't decode + to a space :(
|
pair.second = pair.second.replace( "+", " " ); // QUrl::queryItems doesn't decode + to a space :(
|
||||||
if( pair.first == "title" )
|
if ( pair.first == "title" )
|
||||||
title = pair.second;
|
title = pair.second;
|
||||||
else if( pair.first == "artist" )
|
else if ( pair.first == "artist" )
|
||||||
artist = pair.second;
|
artist = pair.second;
|
||||||
else if( pair.first == "album" )
|
else if ( pair.first == "album" )
|
||||||
album = pair.second;
|
album = pair.second;
|
||||||
else if( pair.first == "url" )
|
else if ( pair.first == "url" )
|
||||||
urlStr = pair.second;
|
urlStr = pair.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !title.isEmpty() || !artist.isEmpty() || !album.isEmpty() ) { // an individual; query to add to queue
|
if ( !title.isEmpty() || !artist.isEmpty() || !album.isEmpty() )
|
||||||
|
{
|
||||||
|
// an individual; query to add to queue
|
||||||
query_ptr q = Query::get( artist, title, album, uuid(), false );
|
query_ptr q = Query::get( artist, title, album, uuid(), false );
|
||||||
if( !urlStr.isEmpty() )
|
if ( !urlStr.isEmpty() )
|
||||||
q->setResultHint( urlStr );
|
q->setResultHint( urlStr );
|
||||||
Pipeline::instance()->resolve( q, true );
|
Pipeline::instance()->resolve( q, true );
|
||||||
|
|
||||||
handleOpenTrack( q );
|
handleOpenTrack( q );
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
} else { // a list of urls to add to the queue
|
else
|
||||||
foreach( pair, queryItems ) {
|
{ // a list of urls to add to the queue
|
||||||
if( pair.first != "url" )
|
foreach ( pair, queryItems )
|
||||||
|
{
|
||||||
|
if ( pair.first != "url" )
|
||||||
continue;
|
continue;
|
||||||
QUrl track = QUrl::fromUserInput( pair.second );
|
QUrl track = QUrl::fromUserInput( pair.second );
|
||||||
//FIXME: isLocalFile is Qt 4.8
|
//FIXME: isLocalFile is Qt 4.8
|
||||||
if( track.toString().startsWith( "file://" ) ) { // it's local, so we see if it's in the DB and load it if so
|
if ( track.toString().startsWith( "file://" ) )
|
||||||
|
{
|
||||||
|
// it's local, so we see if it's in the DB and load it if so
|
||||||
// TODO
|
// TODO
|
||||||
} else { // give it a web result hint
|
}
|
||||||
|
else
|
||||||
|
{ // give it a web result hint
|
||||||
QFileInfo info( track.path() );
|
QFileInfo info( track.path() );
|
||||||
query_ptr q = Query::get( QString(), info.baseName(), QString(), uuid(), false );
|
query_ptr q = Query::get( QString(), info.baseName(), QString(), uuid(), false );
|
||||||
q->setResultHint( track.toString() );
|
q->setResultHint( track.toString() );
|
||||||
@@ -485,14 +547,15 @@ GlobalActionManager::queueSpotify( const QStringList& , const QList< QPair< QStr
|
|||||||
QString url;
|
QString url;
|
||||||
|
|
||||||
QPair< QString, QString > pair;
|
QPair< QString, QString > pair;
|
||||||
foreach( pair, queryItems ) {
|
foreach ( pair, queryItems )
|
||||||
if( pair.first == "spotifyURL" )
|
{
|
||||||
|
if ( pair.first == "spotifyURL" )
|
||||||
url = pair.second;
|
url = pair.second;
|
||||||
else if( pair.first == "spotifyURI" )
|
else if ( pair.first == "spotifyURI" )
|
||||||
url = pair.second;
|
url = pair.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( url.isEmpty() )
|
if ( url.isEmpty() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
openSpotifyLink( url );
|
openSpotifyLink( url );
|
||||||
@@ -507,14 +570,15 @@ GlobalActionManager::queueRdio( const QStringList& , const QList< QPair< QString
|
|||||||
QString url;
|
QString url;
|
||||||
|
|
||||||
QPair< QString, QString > pair;
|
QPair< QString, QString > pair;
|
||||||
foreach( pair, queryItems ) {
|
foreach ( pair, queryItems )
|
||||||
if( pair.first == "rdioURL" )
|
{
|
||||||
|
if ( pair.first == "rdioURL" )
|
||||||
url = pair.second;
|
url = pair.second;
|
||||||
else if( pair.first == "rdioURI" )
|
else if ( pair.first == "rdioURI" )
|
||||||
url = pair.second;
|
url = pair.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( url.isEmpty() )
|
if ( url.isEmpty() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
openRdioLink( url );
|
openRdioLink( url );
|
||||||
@@ -533,16 +597,16 @@ GlobalActionManager::handleSearchCommand( const QUrl& url )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
QStringList query;
|
QStringList query;
|
||||||
if( url.hasQueryItem( "artist" ) )
|
if ( url.hasQueryItem( "artist" ) )
|
||||||
query << url.queryItemValue( "artist" );
|
query << url.queryItemValue( "artist" );
|
||||||
if( url.hasQueryItem( "album" ) )
|
if ( url.hasQueryItem( "album" ) )
|
||||||
query << url.queryItemValue( "album" );
|
query << url.queryItemValue( "album" );
|
||||||
if( url.hasQueryItem( "title" ) )
|
if ( url.hasQueryItem( "title" ) )
|
||||||
query << url.queryItemValue( "title" );
|
query << url.queryItemValue( "title" );
|
||||||
queryStr = query.join( " " );
|
queryStr = query.join( " " );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( queryStr.trimmed().isEmpty() )
|
if ( queryStr.trimmed().isEmpty() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ViewManager::instance()->show( new SearchWidget( queryStr.trimmed() ) );
|
ViewManager::instance()->show( new SearchWidget( queryStr.trimmed() ) );
|
||||||
@@ -554,7 +618,7 @@ bool
|
|||||||
GlobalActionManager::handleViewCommand( const QUrl& url )
|
GlobalActionManager::handleViewCommand( const QUrl& url )
|
||||||
{
|
{
|
||||||
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
||||||
if( parts.isEmpty() ) {
|
if ( parts.isEmpty() ) {
|
||||||
tLog() << "No specific view command:" << url.toString();
|
tLog() << "No specific view command:" << url.toString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -604,135 +668,177 @@ Tomahawk::dynplaylist_ptr
|
|||||||
GlobalActionManager::loadDynamicPlaylist( const QUrl& url, bool station )
|
GlobalActionManager::loadDynamicPlaylist( const QUrl& url, bool station )
|
||||||
{
|
{
|
||||||
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
||||||
if( parts.isEmpty() ) {
|
if ( parts.isEmpty() )
|
||||||
|
{
|
||||||
tLog() << "No specific station command:" << url.toString();
|
tLog() << "No specific station command:" << url.toString();
|
||||||
return Tomahawk::dynplaylist_ptr();
|
return Tomahawk::dynplaylist_ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( parts[ 0 ] == "create" ) {
|
if ( parts[ 0 ] == "create" )
|
||||||
if( !url.hasQueryItem( "title" ) || !url.hasQueryItem( "type" ) ) {
|
{
|
||||||
|
if ( !url.hasQueryItem( "title" ) || !url.hasQueryItem( "type" ) )
|
||||||
|
{
|
||||||
tLog() << "Station create command needs title and type..." << url.toString();
|
tLog() << "Station create command needs title and type..." << url.toString();
|
||||||
return Tomahawk::dynplaylist_ptr();
|
return Tomahawk::dynplaylist_ptr();
|
||||||
}
|
}
|
||||||
QString title = url.queryItemValue( "title" );
|
QString title = url.queryItemValue( "title" );
|
||||||
QString type = url.queryItemValue( "type" );
|
QString type = url.queryItemValue( "type" );
|
||||||
GeneratorMode m = Static;
|
GeneratorMode m = Static;
|
||||||
if( station )
|
if ( station )
|
||||||
m = OnDemand;
|
m = OnDemand;
|
||||||
|
|
||||||
dynplaylist_ptr pl = DynamicPlaylist::create( SourceList::instance()->getLocal(), uuid(), title, QString(), QString(), m, false, type );
|
dynplaylist_ptr pl = DynamicPlaylist::create( SourceList::instance()->getLocal(), uuid(), title, QString(), QString(), m, false, type );
|
||||||
pl->setMode( m );
|
pl->setMode( m );
|
||||||
QList< dyncontrol_ptr > controls;
|
QList< dyncontrol_ptr > controls;
|
||||||
QPair< QString, QString > param;
|
QPair< QString, QString > param;
|
||||||
foreach( param, url.queryItems() ) {
|
foreach ( param, url.queryItems() )
|
||||||
if( param.first == "artist" ) {
|
{
|
||||||
|
if ( param.first == "artist" )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Artist" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Artist" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistRadioType ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistRadioType ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first == "artist_limitto" ) {
|
}
|
||||||
|
else if ( param.first == "artist_limitto" )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Artist" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Artist" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistType ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistType ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first == "description" ) {
|
}
|
||||||
|
else if ( param.first == "description" )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Artist Description" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Artist Description" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistDescriptionType ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistDescriptionType ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first == "variety" ) {
|
}
|
||||||
|
else if ( param.first == "variety" )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Variety" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Variety" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Variety ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Variety ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first.startsWith( "tempo" ) ) {
|
}
|
||||||
|
else if ( param.first.startsWith( "tempo" ) )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Tempo" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Tempo" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinTempo + extra ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinTempo + extra ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first.startsWith( "duration" ) ) {
|
}
|
||||||
|
else if ( param.first.startsWith( "duration" ) )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Duration" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Duration" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinDuration + extra ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinDuration + extra ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first.startsWith( "loudness" ) ) {
|
}
|
||||||
|
else if ( param.first.startsWith( "loudness" ) )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Loudness" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Loudness" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinLoudness + extra ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinLoudness + extra ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first.startsWith( "danceability" ) ) {
|
}
|
||||||
|
else if ( param.first.startsWith( "danceability" ) )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Danceability" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Danceability" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinDanceability + extra ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinDanceability + extra ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first.startsWith( "energy" ) ) {
|
}
|
||||||
|
else if ( param.first.startsWith( "energy" ) )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Energy" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Energy" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinEnergy + extra ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinEnergy + extra ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first.startsWith( "artist_familiarity" ) ) {
|
}
|
||||||
|
else if ( param.first.startsWith( "artist_familiarity" ) )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Artist Familiarity" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Artist Familiarity" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinFamiliarity + extra ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinFamiliarity + extra ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first.startsWith( "artist_hotttnesss" ) ) {
|
}
|
||||||
|
else if ( param.first.startsWith( "artist_hotttnesss" ) )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Artist Hotttnesss" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Artist Hotttnesss" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinHotttnesss + extra ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinHotttnesss + extra ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first.startsWith( "song_hotttnesss" ) ) {
|
}
|
||||||
|
else if ( param.first.startsWith( "song_hotttnesss" ) )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Song Hotttnesss" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Song Hotttnesss" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::SongMinHotttnesss + extra ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::SongMinHotttnesss + extra ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first.startsWith( "longitude" ) ) {
|
}
|
||||||
|
else if ( param.first.startsWith( "longitude" ) )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Longitude" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Longitude" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinLongitude + extra ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinLongitude + extra ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first.startsWith( "latitude" ) ) {
|
}
|
||||||
|
else if ( param.first.startsWith( "latitude" ) )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Latitude" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Latitude" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinLatitude + extra ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinLatitude + extra ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first == "key" ) {
|
}
|
||||||
|
else if ( param.first == "key" )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Key" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Key" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Key ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Key ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first == "mode" ) {
|
}
|
||||||
|
else if ( param.first == "mode" )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Mode" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Mode" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Mode ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Mode ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first == "mood" ) {
|
}
|
||||||
|
else if ( param.first == "mood" )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Mood" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Mood" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Mood ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Mood ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first == "style" ) {
|
}
|
||||||
|
else if ( param.first == "style" )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Style" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Style" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Style ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Style ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
} else if( param.first == "song" ) {
|
}
|
||||||
|
else if ( param.first == "song" )
|
||||||
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Song" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Song" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::SongRadioType ) );
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::SongRadioType ) );
|
||||||
controls << c;
|
controls << c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( m == OnDemand )
|
|
||||||
|
if ( m == OnDemand )
|
||||||
pl->createNewRevision( uuid(), pl->currentrevision(), type, controls );
|
pl->createNewRevision( uuid(), pl->currentrevision(), type, controls );
|
||||||
else
|
else
|
||||||
pl->createNewRevision( uuid(), pl->currentrevision(), type, controls, pl->entries() );
|
pl->createNewRevision( uuid(), pl->currentrevision(), type, controls, pl->entries() );
|
||||||
@@ -756,31 +862,35 @@ bool
|
|||||||
GlobalActionManager::handlePlayCommand( const QUrl& url )
|
GlobalActionManager::handlePlayCommand( const QUrl& url )
|
||||||
{
|
{
|
||||||
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
||||||
if( parts.isEmpty() ) {
|
if ( parts.isEmpty() )
|
||||||
|
{
|
||||||
tLog() << "No specific play command:" << url.toString();
|
tLog() << "No specific play command:" << url.toString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( parts[ 0 ] == "track" ) {
|
if ( parts[ 0 ] == "track" )
|
||||||
if( playSpotify( url ) )
|
{
|
||||||
|
if ( playSpotify( url ) )
|
||||||
return true;
|
return true;
|
||||||
else if( playRdio( url ) )
|
else if ( playRdio( url ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
QPair< QString, QString > pair;
|
QPair< QString, QString > pair;
|
||||||
QString title, artist, album, urlStr;
|
QString title, artist, album, urlStr;
|
||||||
foreach( pair, url.queryItems() ) {
|
foreach ( pair, url.queryItems() )
|
||||||
if( pair.first == "title" )
|
{
|
||||||
|
if ( pair.first == "title" )
|
||||||
title = pair.second;
|
title = pair.second;
|
||||||
else if( pair.first == "artist" )
|
else if ( pair.first == "artist" )
|
||||||
artist = pair.second;
|
artist = pair.second;
|
||||||
else if( pair.first == "album" )
|
else if ( pair.first == "album" )
|
||||||
album = pair.second;
|
album = pair.second;
|
||||||
else if( pair.first == "url" )
|
else if ( pair.first == "url" )
|
||||||
urlStr = pair.second;
|
urlStr = pair.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
query_ptr q = Query::get( artist, title, album );
|
query_ptr q = Query::get( artist, title, album );
|
||||||
if( !urlStr.isEmpty() )
|
if ( !urlStr.isEmpty() )
|
||||||
q->setResultHint( urlStr );
|
q->setResultHint( urlStr );
|
||||||
|
|
||||||
playNow( q );
|
playNow( q );
|
||||||
@@ -794,7 +904,7 @@ GlobalActionManager::handlePlayCommand( const QUrl& url )
|
|||||||
bool
|
bool
|
||||||
GlobalActionManager::playSpotify( const QUrl& url )
|
GlobalActionManager::playSpotify( const QUrl& url )
|
||||||
{
|
{
|
||||||
if( !url.hasQueryItem( "spotifyURI" ) && !url.hasQueryItem( "spotifyURL" ) )
|
if ( !url.hasQueryItem( "spotifyURI" ) && !url.hasQueryItem( "spotifyURL" ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QString spotifyUrl = url.hasQueryItem( "spotifyURI" ) ? url.queryItemValue( "spotifyURI" ) : url.queryItemValue( "spotifyURL" );
|
QString spotifyUrl = url.hasQueryItem( "spotifyURI" ) ? url.queryItemValue( "spotifyURI" ) : url.queryItemValue( "spotifyURL" );
|
||||||
@@ -829,10 +939,9 @@ GlobalActionManager::playOrQueueNow( const query_ptr& q )
|
|||||||
bool
|
bool
|
||||||
GlobalActionManager::playRdio( const QUrl& url )
|
GlobalActionManager::playRdio( const QUrl& url )
|
||||||
{
|
{
|
||||||
if( !url.hasQueryItem( "rdioURI" ) && !url.hasQueryItem( "rdioURL" ) )
|
if ( !url.hasQueryItem( "rdioURI" ) && !url.hasQueryItem( "rdioURL" ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
QString rdioUrl = url.hasQueryItem( "rdioURI" ) ? url.queryItemValue( "spotifyURI" ) : url.queryItemValue( "rdioURL" );
|
QString rdioUrl = url.hasQueryItem( "rdioURI" ) ? url.queryItemValue( "spotifyURI" ) : url.queryItemValue( "rdioURL" );
|
||||||
RdioParser* p = new RdioParser( this );
|
RdioParser* p = new RdioParser( this );
|
||||||
p->parse( rdioUrl );
|
p->parse( rdioUrl );
|
||||||
@@ -845,33 +954,36 @@ GlobalActionManager::playRdio( const QUrl& url )
|
|||||||
bool GlobalActionManager::handleBookmarkCommand(const QUrl& url)
|
bool GlobalActionManager::handleBookmarkCommand(const QUrl& url)
|
||||||
{
|
{
|
||||||
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
||||||
if( parts.isEmpty() ) {
|
if ( parts.isEmpty() )
|
||||||
|
{
|
||||||
tLog() << "No specific bookmark command:" << url.toString();
|
tLog() << "No specific bookmark command:" << url.toString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( parts[ 0 ] == "track" ) {
|
if ( parts[ 0 ] == "track" )
|
||||||
|
{
|
||||||
QPair< QString, QString > pair;
|
QPair< QString, QString > pair;
|
||||||
QString title, artist, album, urlStr;
|
QString title, artist, album, urlStr;
|
||||||
foreach( pair, url.queryItems() ) {
|
foreach ( pair, url.queryItems() )
|
||||||
if( pair.first == "title" )
|
{
|
||||||
|
if ( pair.first == "title" )
|
||||||
title = pair.second;
|
title = pair.second;
|
||||||
else if( pair.first == "artist" )
|
else if ( pair.first == "artist" )
|
||||||
artist = pair.second;
|
artist = pair.second;
|
||||||
else if( pair.first == "album" )
|
else if ( pair.first == "album" )
|
||||||
album = pair.second;
|
album = pair.second;
|
||||||
else if( pair.first == "url" )
|
else if ( pair.first == "url" )
|
||||||
urlStr = pair.second;
|
urlStr = pair.second;
|
||||||
}
|
}
|
||||||
query_ptr q = Query::get( artist, title, album );
|
query_ptr q = Query::get( artist, title, album );
|
||||||
if( !urlStr.isEmpty() )
|
if ( !urlStr.isEmpty() )
|
||||||
q->setResultHint( urlStr );
|
q->setResultHint( urlStr );
|
||||||
Pipeline::instance()->resolve( q, true );
|
Pipeline::instance()->resolve( q, true );
|
||||||
|
|
||||||
// now we add it to the special "bookmarks" playlist, creating it if it doesn't exist. if nothing is playing, start playing the track
|
// now we add it to the special "bookmarks" playlist, creating it if it doesn't exist. if nothing is playing, start playing the track
|
||||||
QSharedPointer< LocalCollection > col = SourceList::instance()->getLocal()->collection().dynamicCast< LocalCollection >();
|
QSharedPointer< LocalCollection > col = SourceList::instance()->getLocal()->collection().dynamicCast< LocalCollection >();
|
||||||
playlist_ptr bookmarkpl = col->bookmarksPlaylist();
|
playlist_ptr bookmarkpl = col->bookmarksPlaylist();
|
||||||
if( bookmarkpl.isNull() ) { // create it and do the deed then
|
if ( bookmarkpl.isNull() ) { // create it and do the deed then
|
||||||
m_waitingToBookmark = q;
|
m_waitingToBookmark = q;
|
||||||
col->createBookmarksPlaylist();
|
col->createBookmarksPlaylist();
|
||||||
connect( col.data(), SIGNAL( bookmarkPlaylistCreated( Tomahawk::playlist_ptr ) ), this, SLOT( bookmarkPlaylistCreated( Tomahawk::playlist_ptr ) ), Qt::UniqueConnection );
|
connect( col.data(), SIGNAL( bookmarkPlaylistCreated( Tomahawk::playlist_ptr ) ), this, SLOT( bookmarkPlaylistCreated( Tomahawk::playlist_ptr ) ), Qt::UniqueConnection );
|
||||||
@@ -894,7 +1006,7 @@ GlobalActionManager::shortenLinkRequestFinished()
|
|||||||
bool error = false;
|
bool error = false;
|
||||||
|
|
||||||
// NOTE: this should never happen
|
// NOTE: this should never happen
|
||||||
if( !reply )
|
if ( !reply )
|
||||||
{
|
{
|
||||||
emit shortLinkReady( QUrl( "" ), QUrl( "" ), QVariantMap() );
|
emit shortLinkReady( QUrl( "" ), QUrl( "" ), QVariantMap() );
|
||||||
return;
|
return;
|
||||||
@@ -908,14 +1020,14 @@ GlobalActionManager::shortenLinkRequestFinished()
|
|||||||
QVariant urlVariant = reply->attribute( QNetworkRequest::RedirectionTargetAttribute );
|
QVariant urlVariant = reply->attribute( QNetworkRequest::RedirectionTargetAttribute );
|
||||||
|
|
||||||
// NOTE: this should never happen
|
// NOTE: this should never happen
|
||||||
if( urlVariant.isNull() || !urlVariant.isValid() )
|
if ( urlVariant.isNull() || !urlVariant.isValid() )
|
||||||
error = true;
|
error = true;
|
||||||
|
|
||||||
QUrl longUrl = reply->request().url();
|
QUrl longUrl = reply->request().url();
|
||||||
QUrl shortUrl = urlVariant.toUrl();
|
QUrl shortUrl = urlVariant.toUrl();
|
||||||
|
|
||||||
// NOTE: this should never happen
|
// NOTE: this should never happen
|
||||||
if( !shortUrl.isValid() )
|
if ( !shortUrl.isValid() )
|
||||||
error = true;
|
error = true;
|
||||||
|
|
||||||
// Success! Here is the short link
|
// Success! Here is the short link
|
||||||
@@ -950,7 +1062,7 @@ GlobalActionManager::shortenLinkRequestError( QNetworkReply::NetworkError error
|
|||||||
QNetworkReply *reply = qobject_cast<QNetworkReply*>( sender() );
|
QNetworkReply *reply = qobject_cast<QNetworkReply*>( sender() );
|
||||||
|
|
||||||
// NOTE: this should never happen
|
// NOTE: this should never happen
|
||||||
if( !reply )
|
if ( !reply )
|
||||||
{
|
{
|
||||||
emit shortLinkReady( QUrl( "" ), QUrl( "" ), QVariantMap() );
|
emit shortLinkReady( QUrl( "" ), QUrl( "" ), QVariantMap() );
|
||||||
return;
|
return;
|
||||||
@@ -999,7 +1111,7 @@ GlobalActionManager::doBookmark( const playlist_ptr& pl, const query_ptr& q )
|
|||||||
void
|
void
|
||||||
GlobalActionManager::showPlaylist()
|
GlobalActionManager::showPlaylist()
|
||||||
{
|
{
|
||||||
if( m_toShow.isNull() )
|
if ( m_toShow.isNull() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ViewManager::instance()->show( m_toShow );
|
ViewManager::instance()->show( m_toShow );
|
||||||
|
@@ -67,7 +67,7 @@ public slots:
|
|||||||
void handlePlayTrack( const Tomahawk::query_ptr& qry );
|
void handlePlayTrack( const Tomahawk::query_ptr& qry );
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void shortLinkReady( QUrl longUrl, QUrl shortUrl, QVariant callbackObj ) const;
|
void shortLinkReady( const QUrl& longUrl, const QUrl& shortUrl, const QVariant& callbackObj );
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void shortenLinkRequestFinished();
|
void shortenLinkRequestFinished();
|
||||||
@@ -83,6 +83,7 @@ private slots:
|
|||||||
|
|
||||||
void playlistCreatedToShow( const Tomahawk::playlist_ptr& pl );
|
void playlistCreatedToShow( const Tomahawk::playlist_ptr& pl );
|
||||||
void playlistReadyToShow();
|
void playlistReadyToShow();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit GlobalActionManager( QObject* parent = 0 );
|
explicit GlobalActionManager( QObject* parent = 0 );
|
||||||
void doBookmark( const Tomahawk::playlist_ptr& pl, const Tomahawk::query_ptr& q );
|
void doBookmark( const Tomahawk::playlist_ptr& pl, const Tomahawk::query_ptr& q );
|
||||||
|
Reference in New Issue
Block a user