Commit 55eb69bc authored by Jasneet Bhatti's avatar Jasneet Bhatti Committed by Matěj Laitl
Browse files

Ability to move track position bookmarks, better AmarokUrl method name

FEATURES:
 * Ability to move track position bookmarks by dragging; patch by
   Jasneet Bhatti. (BR 214721)

Big thanks to Jasneet for the patch and great cooperation on the review
board.

FEATURE: 214721
FIXED-IN: 2.6
REVIEW: 104307
parent cf666b81
......@@ -4,6 +4,8 @@ Amarok ChangeLog
Version 2.6-Beta 1
FEATURES:
* Ability to move track position bookmarks by dragging; patch by
Jasneet Bhatti. (BR 214721)
* Amarok can now remember whether and how to transcode tracks when
transferring them to a particular collection. (BR 264681)
* "Crop playlist" functionality implemented using drag & drop. (BR 267729, 211811)
......
......@@ -75,7 +75,7 @@ void AmarokUrl::initFromString( const QString & urlString )
QStringList argParts = argument.split( '=' );
debug() << "argument: " << argument << " unescaped: " << unescape( argParts.at( 1 ) );
appendArg( argParts.at( 0 ), unescape( argParts.at( 1 ) ) );
setArg( argParts.at( 0 ), unescape( argParts.at( 1 ) ) );
}
}
......@@ -111,7 +111,7 @@ QMap<QString, QString> AmarokUrl::args() const
return m_arguments;
}
void AmarokUrl::appendArg( const QString &name, const QString &value )
void AmarokUrl::setArg( const QString &name, const QString &value )
{
m_arguments.insert( name, value );
}
......
......@@ -41,10 +41,15 @@ public:
QString prettyCommand() const;
QString path() const;
QMap<QString, QString> args() const;
void setCommand( const QString &command );
void setPath( const QString &path );
void appendArg( const QString &name, const QString &value );
/**
* Sets the url argument named @param name to @param value. Overrides any possible
* previous value.
*/
void setArg( const QString &name, const QString &value );
void setName( const QString &name );
void setDescription( const QString &description );
......
......@@ -565,6 +565,21 @@ BookmarkModel::createNewBookmark()
}
void
BookmarkModel::setBookmarkArg( const QString &name, const QString &key, const QString &value )
{
if( setBookmarkArgRecursively( m_root, name, key, value ) )
{
reloadFromDb();
The::amarokUrlHandler()->updateTimecodes();
}
else
{
warning() << "Cannot set argument" << key << "of the bookmark" << name
<< "to value" << value << "- bookmark not found.";
}
}
void
BookmarkModel::deleteBookmark( const QString& name )
{
......@@ -600,6 +615,29 @@ BookmarkModel::renameBookmark( const QString& oldName, const QString& newName )
debug() << "No such bookmark found!";
}
bool
BookmarkModel::setBookmarkArgRecursively( BookmarkGroupPtr group, const QString& name, const QString& key, const QString &value )
{
foreach( AmarokUrlPtr item, group->childBookmarks() )
{
if( item->name() == name )
{
item->setArg( key, value );
item->saveToDb();
return true;
}
}
//if not found, recurse through child groups
foreach( BookmarkGroupPtr childGroup, group->childGroups() )
{
if( setBookmarkArgRecursively( childGroup, name, key, value ) )
return true;
}
return false;
}
bool
BookmarkModel::deleteBookmarkRecursively( BookmarkGroupPtr group, const QString& name )
......
......@@ -103,6 +103,12 @@ public slots:
void deleteBookmark( const QString &name );
void renameBookmark( const QString &oldName , const QString &newName );
/**
* Sets the bookmark's (whose name is @param name) url argument named @param key
* to @param value. Overrides any possible previous value.
*/
void setBookmarkArg(const QString &name, const QString &key, const QString &value);
signals:
void editIndex( const QModelIndex &index );
......@@ -114,6 +120,7 @@ private:
void deleteTables();
void upgradeTables( int from );
bool setBookmarkArgRecursively( BookmarkGroupPtr group, const QString &name, const QString &key, const QString &value );
bool deleteBookmarkRecursively( BookmarkGroupPtr group, const QString &name );
bool renameBookmarkRecursively( BookmarkGroupPtr group, const QString &oldName, const QString &newName );
......
......@@ -51,7 +51,7 @@ ContextUrlGenerator::createContextBookmark()
AmarokUrl url;
url.setCommand( "context" );
url.appendArg( "applets", pluginNames.join( "," ) );
url.setArg( "applets", pluginNames.join( "," ) );
url.setName( i18n( "Context: %1", appletNames.join( "," ) ) );
......
......@@ -70,7 +70,7 @@ AmarokUrl NavigationUrlGenerator::CreateAmarokUrl()
QString filter = The::mainWindow()->browserDock()->list()->activeCategoryRecursive()->filter();
if ( !filter.isEmpty() )
url.appendArg( "filter", filter );
url.setArg( "filter", filter );
QList<int> levels = The::mainWindow()->browserDock()->list()->activeCategoryRecursive()->levels();
QString sortMode;
......@@ -105,7 +105,7 @@ AmarokUrl NavigationUrlGenerator::CreateAmarokUrl()
sortMode = sortMode.left( sortMode.size() - 1 );
if ( !sortMode.isEmpty() )
url.appendArg( "levels", sortMode );
url.setArg( "levels", sortMode );
//if in the local collection view, also store "show covers" and "show years"
......@@ -114,14 +114,14 @@ AmarokUrl NavigationUrlGenerator::CreateAmarokUrl()
debug() << "bookmarking in local collection";
if( AmarokConfig::showAlbumArt() )
url.appendArg( "show_cover", "true" );
url.setArg( "show_cover", "true" );
else
url.appendArg( "show_cover", "false" );
url.setArg( "show_cover", "false" );
if( AmarokConfig::showYears() )
url.appendArg( "show_years", "true" );
url.setArg( "show_years", "true" );
else
url.appendArg( "show_years", "false" );
url.setArg( "show_years", "false" );
}
//come up with a default name for this url..
......@@ -137,7 +137,7 @@ AmarokUrl NavigationUrlGenerator::CreateAmarokUrl()
FileBrowser * fileBrowser = dynamic_cast<FileBrowser *>( The::mainWindow()->browserDock()->list()->activeCategory() );
if( fileBrowser )
{
url.appendArg( "path", fileBrowser->currentDir() );
url.setArg( "path", fileBrowser->currentDir() );
name = i18n( "Files (%1)", fileBrowser->currentDir() );
}
}
......@@ -172,7 +172,7 @@ AmarokUrl NavigationUrlGenerator::urlFromAlbum( Meta::AlbumPtr album )
}
else
{
url.appendArg( "levels", "album" );
url.setArg( "levels", "album" );
QString artistName;
if ( album->albumArtist() )
......@@ -183,7 +183,7 @@ AmarokUrl NavigationUrlGenerator::urlFromAlbum( Meta::AlbumPtr album )
filter += ( " AND artist:\"" + artistName + "\"" );
}
url.appendArg( "filter", filter );
url.setArg( "filter", filter );
if ( !btc->collectionName().isEmpty() )
url.setName( i18n( "Album \"%1\" from %2", albumName, btc->collectionName() ) );
......@@ -226,11 +226,11 @@ AmarokUrl NavigationUrlGenerator::urlFromArtist( Meta::ArtistPtr artist )
}
else
{
url.appendArg( "levels", "artist-album" );
url.setArg( "levels", "artist-album" );
filter = ( "artist:\"" + artistName + "\"" );
}
url.appendArg( "filter", filter );
url.setArg( "filter", filter );
if ( !btc->collectionName().isEmpty() )
url.setName( i18n( "Artist \"%1\" from %2", artistName, btc->collectionName() ) );
......
......@@ -21,6 +21,7 @@
#include "core/meta/support/MetaUtility.h"
#include "core/support/Debug.h"
#include "EngineController.h"
#include "BookmarkModel.h"
#include <KLocale>
......@@ -61,7 +62,7 @@ PlayUrlGenerator::createTrackBookmark( Meta::TrackPtr track, qint64 miliseconds,
const int seconds = miliseconds / 1000;
const qreal accurateSeconds = (qreal) miliseconds / 1000.0;
QString secondsString = QString::number( accurateSeconds );
AmarokUrl url;
if( !track )
return url;
......@@ -69,7 +70,7 @@ PlayUrlGenerator::createTrackBookmark( Meta::TrackPtr track, qint64 miliseconds,
const QString trackUrl = track->playableUrl().toEncoded().toBase64();
url.setCommand( "play" );
url.setPath( trackUrl );
url.appendArg( "pos", secondsString );
url.setArg( "pos", secondsString );
if( name.isEmpty() )
url.setName( track->prettyName() + " - " + Meta::secToPrettyTime( seconds ) );
......@@ -81,6 +82,20 @@ PlayUrlGenerator::createTrackBookmark( Meta::TrackPtr track, qint64 miliseconds,
return url;
}
void
PlayUrlGenerator::moveTrackBookmark( Meta::TrackPtr track, qint64 newMiliseconds, QString name )
{
qreal seconds = qreal ( newMiliseconds ) / 1000;
QString trackPosition;
trackPosition.setNum( seconds );
QString trackName = track->prettyName();
QString newName = ( trackName + " - " + Meta::msToPrettyTime( newMiliseconds ) );
BookmarkModel::instance()->setBookmarkArg( name, "pos", trackPosition );
BookmarkModel::instance()->renameBookmark( name, newName );
}
QString
PlayUrlGenerator::description()
{
......
......@@ -26,7 +26,7 @@
class AmarokUrl;
/**
* A class used to generate play urls.
* A class used to generate and modify amarok://play/ urls.
*
* The format of a 'play' amarokurl is:
* amarokurl://play/<Base 64 Encoded playableUrl() of the track>/<integer seconds>
......@@ -40,6 +40,15 @@ public:
AmarokUrl createCurrentTrackBookmark();
AmarokUrl createTrackBookmark( Meta::TrackPtr track, qint64 miliseconds, QString name = QString() );
/**
* Updates the position of the bookmark named @param name to @param newMiliseconds
* for the track @param track.
*
* The name should be a valid bookmark name and should include the trailing "- mm:ss".
* Bookmark is renamed according to track title and new position, too.
*/
void moveTrackBookmark( Meta::TrackPtr track, qint64 newMiliseconds, QString name );
QString description();
KIcon icon();
AmarokUrl createUrl();
......
......@@ -567,7 +567,7 @@ ArtistWidget::navigateToArtist()
AmarokUrl url;
url.setCommand( "navigate" );
url.setPath( "collections" );
url.appendArg( "filter", "artist:\"" + AmarokUrl::escape( m_artist->name() ) + '\"' );
url.setArg( "filter", "artist:\"" + AmarokUrl::escape( m_artist->name() ) + '\"' );
url.run();
}
......
......@@ -567,7 +567,7 @@ UpcomingEventsApplet::navigateToArtist()
AmarokUrl url;
url.setCommand( "navigate" );
url.setPath( "collections" );
url.appendArg( "filter", "artist:\"" + m_artistEventsList->name() + "\"" );
url.setArg( "filter", "artist:\"" + m_artistEventsList->name() + "\"" );
url.run();
}
......
......@@ -250,7 +250,7 @@ class FindInSourceCapabilityImpl : public Capabilities::FindInSourceCapability
AmarokUrl url;
url.setCommand( "navigate" );
url.setPath( "collections" );
url.appendArg( "filter", filters.join( QLatin1String(" AND ") ) );
url.setArg( "filter", filters.join( QLatin1String(" AND ") ) );
debug() << "running url: " << url.url();
url.run();
......
......@@ -68,13 +68,13 @@ ViewUrlGenerator::createUrl()
if( !sortPath.isEmpty() )
{
url.appendArg( "sort", sortPath );
url.setArg( "sort", sortPath );
prettyUrlName.append( prettySortPath );
}
if( !filterExpr.isEmpty() )
{
url.appendArg( "filter", filterExpr );
url.appendArg( "matches", onlyMatches );
url.setArg( "filter", filterExpr );
url.setArg( "matches", onlyMatches );
if( !prettyUrlName.isEmpty() )
prettyUrlName.append( " | " );
QString prettyFilterExpr = "\"" + filterExpr + "\"";
......@@ -84,7 +84,7 @@ ViewUrlGenerator::createUrl()
}
if( !layout.isEmpty() )
{
url.appendArg( "layout", layout );
url.setArg( "layout", layout );
if( !prettyUrlName.isEmpty() )
prettyUrlName.append( " | " );
prettyUrlName.append( i18n( "%1 layout", layout ) );
......
......@@ -134,8 +134,8 @@ void ServiceFindInSourceCapability::findInSource( QFlags<TargetTag> tag )
url.setPath( "internet/" + collection );
if( !m_track->simpleFiltering() )
{
url.appendArg( "filter", "artist:\"" + artist + "\" AND album:\"" + album + "\"" );
url.appendArg( "levels", "artist-album" );
url.setArg( "filter", "artist:\"" + artist + "\" AND album:\"" + album + "\"" );
url.setArg( "levels", "artist-album" );
debug() << "running url: " << url.url();
url.run();
}
......
......@@ -24,6 +24,8 @@
#include "MainWindow.h"
#include "core/meta/support/MetaUtility.h"
#include "SvgHandler.h"
#include "EngineController.h"
#include "PlayUrlGenerator.h"
#include <KLocale>
......@@ -32,12 +34,14 @@
#include <QSize>
#include <QSizePolicy>
BookmarkTriangle::BookmarkTriangle ( QWidget *parent, int milliseconds, QString name , bool showPopup)
: QWidget ( parent ),
m_mseconds ( milliseconds ),
m_name ( name ),
m_showPopup ( showPopup ),
m_tooltip ( 0 )
BookmarkTriangle::BookmarkTriangle ( QWidget *parent, int milliseconds, QString name,
int sliderwidth, bool showPopup )
: QWidget ( parent ),
m_mseconds ( milliseconds ),
m_name ( name ),
m_sliderwidth ( sliderwidth ),
m_showPopup ( showPopup ),
m_tooltip ( 0 )
{
}
......@@ -87,16 +91,47 @@ void BookmarkTriangle::showEvent ( QShowEvent * event )
void BookmarkTriangle::mousePressEvent ( QMouseEvent * event )
{
Q_UNUSED ( event )
// we don't do anything here, but we want to prevent the event from being
// propagated to the parent.
event->accept();
m_offset = event->pos();
m_pos = this->x();
}
void BookmarkTriangle::mouseMoveEvent ( QMouseEvent * event )
{
event->accept();
int distance_x = event->x() - m_offset.x();
QPoint pt(distance_x, 0);
move(mapToParent( pt ));
}
void BookmarkTriangle::mouseReleaseEvent ( QMouseEvent * event )
{
Q_UNUSED( event )
event->accept();
emit clicked ( m_mseconds );
if( this->x() == m_pos ){
emit clicked ( m_mseconds );
}
else
{
if( this->x() < 0 || this->x() > m_sliderwidth )
{
this->setGeometry(m_pos, 1, 11, 11);
this->update();
}
else{
qreal percentage = (qreal) ( this->x() ) / (qreal) m_sliderwidth;
long trackLength = The::engineController()->trackLength();
qint64 trackPosition = trackLength * percentage;
moveBookmark( trackPosition, m_name );
}
}
}
void BookmarkTriangle::moveBookmark ( qint64 newMilliseconds, QString name )
{
hidePopup();
Meta::TrackPtr track = The::engineController()->currentTrack();
PlayUrlGenerator::instance()->moveTrackBookmark( track, newMilliseconds, name );
}
void BookmarkTriangle::deleteBookmark ()
......
......@@ -24,6 +24,7 @@
#include <QMouseEvent>
#include <QPaintEvent>
#include <QWidget>
#include <QPoint>
class QSize;
class QSizePolicy;
......@@ -33,7 +34,8 @@ class BookmarkTriangle : public QWidget
{
Q_OBJECT
public:
BookmarkTriangle ( QWidget *parent, int milliseconds, QString name , bool showPopup = false);
BookmarkTriangle( QWidget *parent, int milliseconds, QString name, int sliderwidth,
bool showPopup = false );
~BookmarkTriangle();
virtual QSize sizeHint() const;
virtual QSizePolicy sizePolicy() const;
......@@ -41,12 +43,22 @@ public:
virtual void showEvent ( QShowEvent * event );
virtual void mousePressEvent ( QMouseEvent * event );
virtual void mouseMoveEvent ( QMouseEvent * event );
virtual void mouseReleaseEvent (QMouseEvent *);
virtual void enterEvent ( QEvent * event );
virtual void leaveEvent ( QEvent * event );
virtual void paintEvent ( QPaintEvent* );
virtual void hidePopup();
/**
* Updates the position of the bookmark named @param name to @param newMiliseconds.
*
* The name should be a valid existing bookmark name and should include the trailing
* "- m:ss"
*/
virtual void moveBookmark( qint64 newMilliseconds, QString name );
virtual void deleteBookmark();
virtual int getTimeValue();
......@@ -56,9 +68,13 @@ signals:
private:
void initPopup();
int m_mseconds;
QString m_name;
bool m_showPopup;
BookmarkPopup* m_tooltip;
int m_mseconds; /// position of the bookmark on the slider in terms of milliseconds
QString m_name; /// name of the bookmark
int m_sliderwidth; /// width of the slider on which the bookmark will appear
bool m_showPopup; /// used to determine whether to show the Pop-up on focussing the bookmark
BookmarkPopup* m_tooltip; /// the tooltip that appears on focussing the bookmark
QPoint m_offset; /// used while moving the bookmark, holds the position of the bookmark before moving
int m_pos; /// used while moving the bookmark, holds the x co-ordinate of the bookmark after moving
};
#endif // BOOKMARKTRIANGLE_H
......@@ -44,7 +44,6 @@
#include <QStyleOption>
#include <QPainter>
Amarok::Slider::Slider( Qt::Orientation orientation, uint max, QWidget *parent )
: QSlider( orientation, parent )
, m_sliding( false )
......@@ -356,7 +355,7 @@ void Amarok::TimeSlider::drawTriangle( const QString& name, int milliSeconds, bo
// This mess converts the # of seconds into the pixel width value where the triangle should be drawn
int x_pos = ( ( ( double ) milliSeconds - ( double ) minimum() ) / ( maximum() - minimum() ) ) * ( width() - ( sliderLeftWidth + sliderLeftWidth + s_sliderInsertX * 2 ) );
debug() << "drawing triangle at " << x_pos;
BookmarkTriangle * tri = new BookmarkTriangle( this, milliSeconds, name, showPopup );
BookmarkTriangle * tri = new BookmarkTriangle( this, milliSeconds, name, width(), showPopup );
connect( tri, SIGNAL( clicked( int ) ), SLOT( slotTriangleClicked( int ) ) );
connect( tri, SIGNAL( focused( int ) ), SLOT( slotTriangleFocused( int ) ) );
m_triangles << tri;
......
......@@ -46,8 +46,8 @@ TestAmarokUrls::testConstructUrl()
url.setCommand( "navigate" );
url.setPath( "collections" );
url.appendArg( "filter", "artist:\"Code Monkeys\"" );
url.appendArg( "levels", "artist-album" );
url.setArg( "filter", "artist:\"Code Monkeys\"" );
url.setArg( "levels", "artist-album" );
QCOMPARE( url.command(), QString( "navigate" ) );
QCOMPARE( url.path(), QString( "collections" ) );
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment