File indexing completed on 2024-05-05 04:48:44

0001 /****************************************************************************************
0002  * Copyright (c) 2010 Andreas Hartmetz <ahartmetz@gmail.com>                            *
0003  *                                                                                      *
0004  * This program is free software; you can redistribute it and/or modify it under        *
0005  * the terms of the GNU General Public License as published by the Free Software        *
0006  * Foundation; either version 2 of the License, or (at your option) version 3 or        *
0007  * any later version accepted by the membership of KDE e.V. (or its successor approved  *
0008  * by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of  *
0009  * version 3 of the license.                                                            *
0010  *                                                                                      *
0011  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0012  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0013  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0014  *                                                                                      *
0015  * You should have received a copy of the GNU General Public License along with         *
0016  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0017  ****************************************************************************************/
0018 
0019 #include "PlaylistQueueEditor.h"
0020 
0021 #include "core/meta/Meta.h"
0022 #include "playlist/PlaylistActions.h"
0023 #include "playlist/PlaylistModelStack.h"
0024 
0025 static const int s_idRole = Qt::UserRole;
0026 static const int s_myType = QListWidgetItem::UserType;
0027 
0028 //### due to playlists typically having no more than 10k items and no more than
0029 //    100 queued items we can get away with using simple and slow algorithms.
0030 
0031 PlaylistQueueEditor::PlaylistQueueEditor()
0032     : QDialog(),
0033       m_blockViewUpdates( false )
0034 {
0035     m_ui.setupUi( this );
0036     updateView();
0037     connect( qobject_cast<Playlist::Model*>(The::playlist()->qaim()), &Playlist::Model::queueChanged, this, &PlaylistQueueEditor::queueChanged );
0038     m_ui.upButton->setIcon( QIcon::fromTheme( QStringLiteral("go-up") ) );
0039     m_ui.downButton->setIcon( QIcon::fromTheme( QStringLiteral("go-down") ) );
0040     m_ui.dequeueTrackButton->setIcon( QIcon::fromTheme( QStringLiteral("list-remove") ) );
0041     m_ui.clearButton->setIcon( QIcon::fromTheme( QStringLiteral("edit-clear-list") ) );
0042     connect( m_ui.upButton, &QAbstractButton::clicked, this, &PlaylistQueueEditor::moveUp );
0043     connect( m_ui.downButton, &QAbstractButton::clicked, this, &PlaylistQueueEditor::moveDown );
0044     connect( m_ui.clearButton, &QAbstractButton::clicked, this, &PlaylistQueueEditor::clear );
0045     connect( m_ui.dequeueTrackButton, &QAbstractButton::clicked, this, &PlaylistQueueEditor::dequeueTrack );
0046     connect( m_ui.buttonBox->buttons().first(), &QAbstractButton::clicked, this, &PlaylistQueueEditor::accept );
0047 }
0048 
0049 void
0050 PlaylistQueueEditor::updateView()
0051 {
0052     if ( m_blockViewUpdates )
0053         return;
0054 
0055     m_ui.listWidget->clear();
0056     int i = 1;
0057     foreach( quint64 id, The::playlistActions()->queue() )
0058     {
0059         QListWidgetItem *item = new QListWidgetItem( m_ui.listWidget, s_myType );
0060         item->setData( s_idRole, id );
0061         Meta::TrackPtr track = The::playlist()->trackForId( id );
0062         Meta::ArtistPtr artist = track->artist();
0063         QString itemText = i18nc( "Iten in queue, %1 is position, %2 artist, %3 track",
0064                 "%1: %2 - %3", i++, artist ? artist->prettyName() : i18n( "Unknown Artist" ),
0065                 track->prettyName() );
0066         item->setText( itemText );
0067     }
0068 }
0069 
0070 void
0071 PlaylistQueueEditor::queueChanged()
0072 {
0073     const quint64 id = currentId();
0074     updateView();
0075     if ( id )
0076         setCurrentId( id );
0077 }
0078 
0079 quint64
0080 PlaylistQueueEditor::currentId()
0081 {
0082     if ( QListWidgetItem *item = m_ui.listWidget->currentItem() ) {
0083         bool ok;
0084         quint64 id = item->data( s_idRole ).toULongLong( &ok );
0085         if ( ok )
0086             return id;
0087     }
0088     return 0;
0089 }
0090 
0091 void
0092 PlaylistQueueEditor::setCurrentId( quint64 newCurrentId )
0093 {
0094     for ( int i = 0; i < m_ui.listWidget->count(); i++ ) {
0095         QListWidgetItem *item = m_ui.listWidget->item( i );
0096         bool ok;
0097         quint64 id = item->data( s_idRole ).toULongLong( &ok );
0098         if ( ok && id == newCurrentId ) {
0099             m_ui.listWidget->setCurrentItem( item );
0100             break;
0101         }
0102     }
0103 }
0104 
0105 void
0106 PlaylistQueueEditor::moveUp()
0107 {
0108     const quint64 id = currentId();
0109     if ( !id )
0110         return;
0111     The::playlistActions()->queueMoveUp( id );
0112 }
0113 
0114 void
0115 PlaylistQueueEditor::moveDown()
0116 {
0117     const quint64 id = currentId();
0118     if ( !id )
0119         return;
0120     The::playlistActions()->queueMoveDown( id );
0121 }
0122 
0123 void
0124 PlaylistQueueEditor::dequeueTrack()
0125 {
0126     const quint64 id = currentId();
0127     if ( !id )
0128         return;
0129     The::playlistActions()->dequeue( id );
0130 }
0131 
0132 void
0133 PlaylistQueueEditor::clear()
0134 {
0135     m_blockViewUpdates = true;
0136     QList<int> rowsToDequeue;
0137     foreach ( quint64 id, The::playlistActions()->queue() ) {
0138         Meta::TrackPtr track = The::playlist()->trackForId( id );
0139         foreach ( int row, The::playlist()->allRowsForTrack( track ) )
0140             rowsToDequeue += row;
0141     }
0142     The::playlistActions()->dequeue( rowsToDequeue );
0143     m_blockViewUpdates = false;
0144     updateView();
0145 }