Esempio n. 1
0
void PlaylistView::selectSongsByRegExp()
{
    // We can't use selectItemsByRegExp here, because it matches ListModelItemData::text,
    // but for PlaylistModel its value doesn't correspond to what actually displyed, as
    // it uses SongDisplayFormatParser for this job.
    auto resultCallback = [this](const std::string& pattern, LineEdit::Result result)
    {
        if (result == LineEdit::Result::Accepted) {
            GRegex *regex = g_regex_new(pattern.c_str(), G_REGEX_OPTIMIZE,
                                        (GRegexMatchFlags)0, nullptr);
            if (!regex)
                return;

            PlaylistModel *plsModel = static_cast<PlaylistModel*>(model());
            PlaylistItemDelegate *delegate = static_cast<PlaylistItemDelegate*>(itemDelegate());

            selectItems([plsModel, delegate, regex](int item){
                return delegate->matchFormattedString(plsModel->song(item), regex);
            });
            g_regex_unref(regex);
            StatusArea::showMessage("%d items selected", selectedItems().size());
        }
    };
    StatusArea::askQuestion("Select items: ", resultCallback, ".*");
}
Esempio n. 2
0
bool
PlaylistManager::show( const Tomahawk::album_ptr& album )
{
    PlaylistView* view;
    if ( !m_albumViews.contains( album ) )
    {
        view = new PlaylistView();
        PlaylistModel* model = new PlaylistModel();
        view->setModel( model );
        view->setFrameShape( QFrame::NoFrame );
        view->setAttribute( Qt::WA_MacShowFocusRect, 0 );
        model->append( album );

        m_albumViews.insert( album, view );
    }
    else
    {
        view = m_albumViews.value( album );
    }
    
    setPage( view );
    emit numSourcesChanged( 1 );

    return true;
}
void FilterPlaylistModel::setCurrentIndex(int presentIndex)
{
    QModelIndex i = index(presentIndex, 0);
    PlaylistModel *playlistmodel = static_cast<PlaylistModel*>(sourceModel());
    playlistmodel->setCurrentIndex(mapToSource(i).row());
    emit currentIndexChanged();
}
Esempio n. 4
0
void PlaylistView::addFile(const std::string& path)
{
    PlaylistModel *plsModel = static_cast<PlaylistModel*>(model());

    const std::string::size_type slashPos = path.rfind('/');
    const std::string fileName = slashPos != std::string::npos
                                 ? path.substr(slashPos + 1)
                                 : path;

    const Utils::FileType fileType = Utils::getFileType(path);
    switch (fileType) {
        case Utils::FileType::Media:
            m_xmmsClient->playlistAddUrl(plsModel->playlist(),
                                         std::string("file://").append(path));
            StatusArea::showMessage("Adding \"%s\" file to \"%s\" playlist",
                                    fileName, plsModel->playlist());
            break;

        case Utils::FileType::Playlist:
            m_xmmsClient->playlistAddPlaylistFile(plsModel->playlist(),
                                                  std::string("file://").append(path));
            StatusArea::showMessage("Adding \"%s\" playlist to \"%s\" playlist",
                                    fileName, plsModel->playlist());
            break;

        case Utils::FileType::Unknown:
            StatusArea::showMessage("Unknown file type!");
            break;
    }
}
Esempio n. 5
0
bool
PlaylistManager::show( const Tomahawk::playlist_ptr& playlist )
{
    PlaylistView* view;
    if ( !m_playlistViews.contains( playlist ) )
    {
        view = new PlaylistView();
        PlaylistModel* model = new PlaylistModel();
        view->setModel( model );
        view->setFrameShape( QFrame::NoFrame );
        view->setAttribute( Qt::WA_MacShowFocusRect, 0 );
        model->loadPlaylist( playlist );
        playlist->resolve();

        m_playlistViews.insert( playlist, view );
    }
    else
    {
        view = m_playlistViews.value( playlist );
    }
    
    setPage( view );
    TomahawkSettings::instance()->appendRecentlyPlayedPlaylist( playlist );
    emit numSourcesChanged( SourceList::instance()->count() );

    return true;
}
Esempio n. 6
0
QueueView::QueueView( AnimatedSplitter* parent )
    : AnimatedWidget( parent )
    , ui( new Ui::QueueView )
    , m_dragTimer( 0 )
{
    ui->setupUi( this );
    TomahawkUtils::unmarginLayout( layout() );
    setContentsMargins( 0, 0, 0, 0 );

    setHiddenSize( QSize( 0, 22 ) );

    ui->queue->setProxyModel( new QueueProxyModel( ui->queue ) );
    ui->queue->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Ignored );

    PlaylistModel* queueModel = new PlaylistModel( this );
    queueModel->setStyle( PlaylistModel::Short );
    queueModel->finishLoading();
    ui->queue->setPlaylistModel( queueModel );
    queueModel->setReadOnly( false );

//    ui->queue->setEmptyTip( tr( "The queue is currently empty. Drop something to enqueue it!" ) );
    ui->queue->setEmptyTip( QString() );

    connect( queueModel, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( updateLabel() ) );
    connect( ui->toggleButton, SIGNAL( clicked() ), SLOT( show() ) );
    connect( this, SIGNAL( animationFinished() ), SLOT( onAnimationFinished() ) );

    ui->toggleButton->installEventFilter( this );
    ui->toggleButton->setCursor( Qt::PointingHandCursor );
}
Esempio n. 7
0
void PlaylistView::addUrl(const std::string& url)
{
    PlaylistModel *plsModel = static_cast<PlaylistModel*>(model());
    m_xmmsClient->playlistAddUrl(plsModel->playlist(), url);

    // FIXME: Url may be too long to display
    StatusArea::showMessage("Adding \"%s\" to \"%s\" playlist", url, plsModel->playlist());
}
Esempio n. 8
0
PlaylistView*
ViewManager::createPageForPlaylist( const playlist_ptr& pl )
{
    PlaylistView* view = new PlaylistView();
    PlaylistModel* model = new PlaylistModel();
    view->setPlaylistModel( model );
    model->loadPlaylist( pl );
    pl->resolve();

    m_playlistViews.insert( pl, view );
    return view;
}
Esempio n. 9
0
PlaylistView*
ViewManager::createPageForPlaylist( const playlist_ptr& pl )
{
    PlaylistView* view = new PlaylistView();
    PlaylistModel* model = new PlaylistModel();
    view->setPlaylistModel( model );
    model->loadPlaylist( pl );
    view->setFrameShape( QFrame::NoFrame );
    view->setAttribute( Qt::WA_MacShowFocusRect, 0 );
    pl->resolve();

    m_playlistViews.insert( pl, view );
    return view;
}
Esempio n. 10
0
PlaylistViewPage*
ViewManager::createPageForPlaylist( const playlist_ptr& playlist )
{
    PlaylistViewPage* view = new PlaylistViewPage();
    PlaylistModel* model = new PlaylistModel();

    // We need to set the model on the view before loading the playlist, so spinners & co are connected
    view->view()->trackView()->setPlayableModel( model );

    model->loadPlaylist( playlist );
    playlist->resolve();

    return view;
}
Esempio n. 11
0
PlaylistViewPage*
ViewManager::createPageForList( const QString& title, const QList< query_ptr >& queries )
{
    PlaylistViewPage* view = new PlaylistViewPage();
    PlaylistModel* model = new PlaylistModel();

    view->setTemporaryPage( true );

    // We need to set the model on the view before loading the playlist, so spinners & co are connected
    view->view()->trackView()->setPlayableModel( model );

    model->setTitle( title );
    model->appendQueries( queries );

    return view;
}
Esempio n. 12
0
FlexibleView*
ViewManager::createPageForPlaylist( const playlist_ptr& playlist )
{
    FlexibleView* view = new FlexibleView();
    PlaylistModel* model = new PlaylistModel();

    PlaylistView* pv = new PlaylistView();
    pv->setPlaylistModel( model );
    view->setDetailedView( pv );
    view->setPixmap( pv->pixmap() );

    model->loadPlaylist( playlist );
    view->setPlayableModel( model );
    playlist->resolve();

    return view;
}
Esempio n. 13
0
void PlaylistView::openContainingFolder()
{
    PlaylistModel *playlistModel = dynamic_cast<PlaylistModel *>(this->model());
    if (playlistModel == nullptr)
    {
        return;
    }

    QModelIndex i = this->currentIndex();
    if (i.isValid())
    {
        int row = i.row();
        const Song *s = playlistModel->getPlaylist()->getSong(row);

        QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(::mydirname(s->Filename))));
    }

}
Esempio n. 14
0
void PlaylistView::removeSelectedSongs()
{
    PlaylistModel *plsModel = static_cast<PlaylistModel*>(model());
    if (plsModel->itemsCount() && !isCurrentItemHidden()) {
        //   Actually we don't have to make copy of selectedItems, since removeEntry
        // doesn't modify it immediately, but this is not obvious and may lead to
        // problems in the future.
        const std::vector<int> selectedSongs = selectedItems();
        if (!selectedSongs.empty()) {
            assert(std::is_sorted(selectedSongs.begin(), selectedSongs.end()));
            std::for_each(selectedSongs.rbegin(), selectedSongs.rend(), [&](int item){
                m_xmmsClient->playlistRemoveEntry(plsModel->playlist(), item);
            });
        } else {
            m_xmmsClient->playlistRemoveEntry(plsModel->playlist(), currentItem());
        }
        showCurrentItem();
    }
}
Esempio n. 15
0
FlexibleView*
ViewManager::createPageForPlaylist( const playlist_ptr& playlist )
{
    FlexibleView* view = new FlexibleView();
    PlaylistModel* model = new PlaylistModel();

    PlaylistView* pv = new PlaylistView();
    view->setDetailedView( pv );
    view->setPixmap( pv->pixmap() );

    // We need to set the model on the view before loading the playlist, so spinners & co are connected
    view->setPlaylistModel( model );
    pv->setPlaylistModel( model );

    model->loadPlaylist( playlist );
    playlist->resolve();

    return view;
}
Esempio n. 16
0
void PlaylistView::showInspector()
{
    PlaylistModel *playlistModel = dynamic_cast<PlaylistModel *>(this->model());
    if (playlistModel == nullptr)
    {
        return;
    }

    QModelIndex i = this->currentIndex();
    if (i.isValid())
    {
        int row = i.row();
        const Song *s = playlistModel->getPlaylist()->getSong(row);

        SongInspector *insp = new SongInspector(s, this);
        insp->setAttribute(Qt::WA_DeleteOnClose);
        insp->show();
    }
}
Esempio n. 17
0
playlist_ptr
ViewManager::playlistForPage( ViewPage* page ) const
{
    playlist_ptr p;

    PlaylistViewPage* fv = dynamic_cast< PlaylistViewPage* >( page );
    if ( fv && fv->view()->trackView()->model() )
    {
        PlaylistModel* m = dynamic_cast< PlaylistModel* >( fv->view()->trackView()->model() );
        if ( m && m->playlist() )
        {
            p = m->playlist();
        }
    }
    else if ( dynamic_cast< DynamicWidget* >( page ) )
        p = dynamic_cast< DynamicWidget* >( page )->playlist();

    return p;
}
Esempio n. 18
0
FlexibleView*
ViewManager::createPageForList( const QString& title, const QList< query_ptr >& queries )
{
    FlexibleView* view = new FlexibleView();
    PlaylistModel* model = new PlaylistModel();

    PlaylistView* pv = new PlaylistView();
    view->setDetailedView( pv );
    view->setPixmap( pv->pixmap() );
    view->setTemporaryPage( true );

    // We need to set the model on the view before loading the playlist, so spinners & co are connected
    view->setPlaylistModel( model );
    pv->setPlaylistModel( model );

    model->setTitle( title );
    model->appendQueries( queries );

    return view;
}
Esempio n. 19
0
void PlaylistView::moveSelectedSongs()
{
    PlaylistModel *plsModel = static_cast<PlaylistModel*>(model());
    const std::vector<int> selectedSongs  = selectedItems();
    assert(std::is_sorted(selectedSongs.begin(), selectedSongs.end()));
    
    if (isCurrentItemHidden() || selectedSongs.empty())
        return;
    
    const int moveTo = currentItem();
    auto it = std::lower_bound(selectedSongs.begin(), selectedSongs.end(), moveTo);
    
    int to = moveTo;
    for (size_t i = it - selectedSongs.begin(); i < selectedSongs.size(); ++i, ++to) {
        m_xmmsClient->playlistMoveEntry(plsModel->playlist(), selectedSongs[i], to);
    }
    
    to = it == selectedSongs.end() ? moveTo : moveTo - 1;
    for (ptrdiff_t i = it - selectedSongs.begin() - 1; i >= 0; --i, --to) {
        m_xmmsClient->playlistMoveEntry(plsModel->playlist(), selectedSongs[i], to);
    }
}
Esempio n. 20
0
void PlaylistView::addPath(const std::string& path)
{
    // TODO: Introduce FileInfo class instead of using glib functions,
    // maybe simple stat call wrapper
    if (!g_file_test(path.c_str(), G_FILE_TEST_EXISTS)) {
        StatusArea::showMessage("File doesn't exist!");
        return;
    }

    if (g_file_test(path.c_str(), G_FILE_TEST_IS_REGULAR)) {
        addFile(path);
    } else if (g_file_test(path.c_str(), G_FILE_TEST_IS_DIR)) {
        PlaylistModel *plsModel = static_cast<PlaylistModel*>(model());
        m_xmmsClient->playlistAddRecursive(plsModel->playlist(),
                                           std::string("file://").append(path));
        // FIXME: Path may be too long to display
        StatusArea::showMessage("Adding \"%s\" directory to \"%s\" playlist",
                                path, plsModel->playlist());
    } else {
        StatusArea::showMessage("File is neither a directory nor regular file!");
    }
}
Esempio n. 21
0
void PlaylistView::unselectSongsByRegExp()
{
    // The same story here...
    auto resultCallback = [this](const std::string& pattern, LineEdit::Result result)
    {
        if (result == LineEdit::Result::Accepted) {
            GRegex *regex = g_regex_new(pattern.c_str(), G_REGEX_OPTIMIZE,
                                        (GRegexMatchFlags)0, nullptr);
            if (!regex)
                return;

            PlaylistModel *plsModel = static_cast<PlaylistModel*>(model());
            PlaylistItemDelegate *delegate = static_cast<PlaylistItemDelegate*>(itemDelegate());

            unselectItems([plsModel, delegate, regex](int item){
                return delegate->matchFormattedString(plsModel->song(item), regex);
            });
            g_regex_unref(regex);
            StatusArea::showMessage("%d items selected", selectedItems().size());
        }
    };
    StatusArea::askQuestion("Unselect items: ", resultCallback, ".*");
}
Esempio n. 22
0
void PlaylistView::moveItems(int steps)
{
    PlaylistModel *playlistModel = dynamic_cast<PlaylistModel *>(this->model());
    if (playlistModel == nullptr)
    {
        return;
    }

    QItemSelection indexList = this->selectionModel()->selection();
    std::sort(indexList.begin(), indexList.end(), steps > 0 ? sortQItemSelectionDesc : sortQItemSelectionAsc);

    for (QItemSelection::const_iterator i = indexList.cbegin(); i != indexList.cend(); ++i)
    {
        int top = i->top();
        int btm = i->bottom();
        int count = abs(top - btm);

        int srcRow = min(top, btm);
        int destRow = srcRow + steps;

        QModelIndex newIdx = steps > 0 ? playlistModel->index(destRow + count, 0) : playlistModel->index(srcRow - 1, 0);
        QModelIndex oldIdx = steps > 0 ? playlistModel->index(srcRow, 0) : playlistModel->index(srcRow + count, 0);
        if (newIdx.isValid())
        {
            this->selectionModel()->select(newIdx, QItemSelectionModel::SelectionFlag::Select | QItemSelectionModel::SelectionFlag::Rows);
            this->selectionModel()->select(oldIdx, QItemSelectionModel::SelectionFlag::Deselect | QItemSelectionModel::SelectionFlag::Rows);


            playlistModel->moveRows(playlistModel->index(0, 0),
                                    srcRow,
                                    count,
                                    playlistModel->index(playlistModel->rowCount(QModelIndex()) - 1,
                                                         playlistModel->columnCount(QModelIndex()) - 1),
                                    destRow);
        }
    }
}
Esempio n. 23
0
void
WhatsHotWidget::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
{
    if ( requestData.caller != s_whatsHotIdentifier )
        return;

    if ( output.isNull() )
    {
        tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Info came back empty";
        return;
    }

    if ( !output.canConvert< QVariantMap >() )
    {
        tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "WhatsHot: Could not parse output into a map";
        return;
    }

    QVariantMap returnedData = output.toMap();
    switch ( requestData.type )
    {
        case InfoSystem::InfoChartCapabilities:
        {
            setViewData( returnedData );
        }
        case InfoSystem::InfoChart:
        {
            if ( returnedData.contains( "chart_error" ) )
            {
                tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Info came back with error!";

                Tomahawk::InfoSystem::InfoStringHash criteria;
                criteria.insert( "chart_refetch", returnedData[ "chart_source" ].value< QString >() );

                Tomahawk::InfoSystem::InfoRequestData requestData;
                requestData.caller = s_whatsHotIdentifier;
                requestData.customData = QVariantMap();
                requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( criteria );
                requestData.type = Tomahawk::InfoSystem::InfoChartCapabilities;
                requestData.timeoutMillis = 20000;
                requestData.allSources = false;
                Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );

                tDebug( LOGVERBOSE ) << "WhatsHot: re-requesting InfoChartCapabilities";
                break;
            }

            if ( !returnedData.contains( "type" ) )
                break;

            const QString type = returnedData[ "type" ].toString();
            if ( !returnedData.contains( type ) )
                break;

            const QString chartId = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >().value( "chart_id" );

            m_queuedFetches.remove( chartId );

            ChartDataLoader* loader = new ChartDataLoader();
            loader->setProperty( "chartid", chartId );
            loader->moveToThread( m_workerThread );

            if ( type == "artists" )
            {
                loader->setType( ChartDataLoader::Artist );
                loader->setData( returnedData[ "artists" ].value< QStringList >() );

                connect( loader, SIGNAL( artists( Tomahawk::ChartDataLoader*, QList< Tomahawk::artist_ptr > ) ), SLOT( chartArtistsLoaded( Tomahawk::ChartDataLoader*, QList< Tomahawk::artist_ptr > ) ) );

                TreeModel* artistsModel = new TreeModel( ui->artistsViewLeft );
                artistsModel->setMode( InfoSystemMode );
                artistsModel->startLoading();

                m_artistModels[ chartId ] = artistsModel;

                if ( m_queueItemToShow == chartId )
                    setLeftViewArtists( artistsModel );
            }
            else if ( type == "albums" )
            {
                loader->setType( ChartDataLoader::Album );
                loader->setData( returnedData[ "albums" ].value< QList< Tomahawk::InfoSystem::InfoStringHash > >() );

                connect( loader, SIGNAL( albums( Tomahawk::ChartDataLoader*, QList< Tomahawk::album_ptr > ) ), SLOT( chartAlbumsLoaded( Tomahawk::ChartDataLoader*, QList< Tomahawk::album_ptr > ) ) );

                PlayableModel* albumModel = new PlayableModel( ui->albumsView );
                albumModel->startLoading();

                m_albumModels[ chartId ] = albumModel;

                if ( m_queueItemToShow == chartId )
                    setLeftViewAlbums( albumModel );
            }
            else if ( type == "tracks" )
            {
                loader->setType( ChartDataLoader::Track );
                loader->setData( returnedData[ "tracks" ].value< QList< Tomahawk::InfoSystem::InfoStringHash > >() );

                connect( loader, SIGNAL( tracks( Tomahawk::ChartDataLoader*, QList< Tomahawk::query_ptr > ) ), SLOT( chartTracksLoaded( Tomahawk::ChartDataLoader*, QList< Tomahawk::query_ptr > ) ) );

                PlaylistModel* trackModel = new PlaylistModel( ui->tracksViewLeft );
                trackModel->startLoading();

                m_trackModels[ chartId ] = trackModel;

                if ( m_queueItemToShow == chartId )
                    setLeftViewTracks( trackModel );

            }

            QMetaObject::invokeMethod( loader, "go", Qt::QueuedConnection );
            break;
        }

        default:
            return;
    }
}
Esempio n. 24
0
void PlaylistView::keyPressEvent(QKeyEvent *event)
{
    PlaylistModel *playlistModel = dynamic_cast<PlaylistModel *>(this->model());
    if (playlistModel == nullptr)
    {
        return;
    }
    
    QModelIndex bot = playlistModel->index(playlistModel->rowCount(QModelIndex()) - 1, 0);
    QModelIndex top = playlistModel->index(0, 0);

    int key = event->key();
    switch (key)
    {
        case Qt::Key_Delete:
        {
            QItemSelection indexList = this->selectionModel()->selection();

            int lastCount = 0;
            for (QItemSelection::const_iterator i = indexList.cbegin(); i != indexList.cend(); ++i)
            {
                int btm = i->bottom();
                int top = i->top();

                if (btm < 0 || top < 0)
                {
                    break;
                }

                lastCount = abs(top - btm) + 1;
                playlistModel->removeRows(min(btm, top), lastCount);
            }
        }
        break;

        case Qt::Key_W:
            this->moveItems(-1);
            break;

        case Qt::Key_S:
            this->moveItems(1);
            break;

        case Qt::Key_Home:
        case Qt::Key_End:
            if ((event->modifiers() & Qt::ShiftModifier) == Qt::ShiftModifier)
            {
                QModelIndex cur = this->currentIndex();
                
                QItemSelectionRange aboveCur(top, cur);
                
                QItemSelection selection;
                selection.append(aboveCur);
                this->selectionModel()->select(selection,
                                               ((key == Qt::Key_Home) ? QItemSelectionModel::Select : QItemSelectionModel::Deselect) | QItemSelectionModel::Rows);
                selection.clear();
                
                QItemSelectionRange belowCur(cur, bot);
                selection.append(belowCur);
                this->selectionModel()->select(selection,
                                               ((key == Qt::Key_Home) ? QItemSelectionModel::Deselect : QItemSelectionModel::Select) | QItemSelectionModel::Rows);
                
                // make sure the current index is selected
                this->selectionModel()->select(this->currentIndex(),
                                               QItemSelectionModel::Select | QItemSelectionModel::Rows);
                
                break;
            }
            else if ((event->modifiers() & Qt::NoModifier) == Qt::NoModifier)
            {
                this->setCurrentIndex((key == Qt::Key_Home) ? top : bot);
                break;
            }
            else
            {
                [[fallthrough]];
            }

        default:
            QTableView::keyPressEvent(event);
            break;
    }
}
Esempio n. 25
0
void PlaylistView::setPlaylist(const std::string& playlist)
{
    PlaylistModel *plsModel = static_cast<PlaylistModel*>(model());
    plsModel->setPlaylist(playlist);
}
int FilterPlaylistModel::currentIndex() const
{
    PlaylistModel *playlistmodel = static_cast<PlaylistModel*>(sourceModel());
    return mapFromSource(sourceModel()->index(playlistmodel->currentIndex(), 0)).row();
}
Esempio n. 27
0
void PlaylistView::setLazyLoadPlaylist(bool enable)
{
    PlaylistModel *plsModel = static_cast<PlaylistModel*>(model());
    plsModel->setLazyLoadPlaylist(enable);
}
void FilterPlaylistModel::playFromSourceModel(int indexInFilterModel)
{
    PlaylistModel *playlistmodel = static_cast<PlaylistModel*>(sourceModel());
    playlistmodel->play(mapToSource(index(indexInFilterModel, 0)).row());
}
Esempio n. 29
0
void PlaylistView::onItemEntered(int item)
{
    PlaylistModel *plsModel = static_cast<PlaylistModel*>(model());
    m_xmmsClient->playlistPlayItem(plsModel->playlist(), item);
}
Esempio n. 30
0
void PlaylistView::keyPressedEvent(const KeyEvent& keyEvent)
{
    PlaylistModel *plsModel = static_cast<PlaylistModel*>(model());

    switch (keyEvent.key()) {
        case Hotkeys::PlaylistView::RemoveEntry:
            removeSelectedSongs();
            break;

        case Hotkeys::PlaylistView::ClearPlaylist:
            m_xmmsClient->playlistClear(plsModel->playlist());
            break;

        case Hotkeys::PlaylistView::ShufflePlaylist:
            m_xmmsClient->playlistShuffle(plsModel->playlist());
            break;

        case Hotkeys::PlaylistView::GoToCurrentlyPlayingSong:
            setCurrentItem(plsModel->currentSongItem());
            break;

        case Hotkeys::PlaylistView::MoveSelectedSongs:
            moveSelectedSongs();
            break;
            
        case Hotkeys::PlaylistView::AddFileOrDirectory:
        {
            auto resultCallback = [this](const std::string& path, LineEdit::Result result)
            {
                if (result == LineEdit::Result::Accepted)
                    addPath(path);
            };
            StatusArea::askQuestion("Add path: ", resultCallback);
            break;
        }

        case Hotkeys::PlaylistView::AddUrl:
        {
            auto resultCallback = [this](const std::string& url, LineEdit::Result result)
            {
                if (result == LineEdit::Result::Accepted)
                    addUrl(url);
            };
            StatusArea::askQuestion("Add url: ", resultCallback);
            break;
        }
        
        case Hotkeys::PlaylistView::ShowSongInfo:
            if (plsModel->itemsCount() && !isCurrentItemHidden()) {
                int id = plsModel->song(currentItem()).id();
                if (id > 0)
                    showSongInfo(id);
            }
            break;
            
        case '+': // Select be regexp
            selectSongsByRegExp();
            break;

        case '\\': // Unselect be regexp
            unselectSongsByRegExp();
            break;

        default: ListViewAppIntegrated::keyPressedEvent(keyEvent);
    }
}