Ignore:
Timestamp:
May 3, 2016, 5:25:45 PM (9 years ago)
Author:
Silvan Scherrer
Message:

smplayer: update trunk to version 16.4

Location:
smplayer/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • smplayer/trunk

  • smplayer/trunk/src/playlist.cpp

    r170 r176  
    11/*  smplayer, GUI front-end for mplayer.
    2     Copyright (C) 2006-2014 Ricardo Villalba <rvm@users.sourceforge.net>
     2    Copyright (C) 2006-2016 Ricardo Villalba <rvm@users.sourceforge.net>
    33
    44    This program is free software; you can redistribute it and/or modify
     
    4141#include <QApplication>
    4242#include <QMimeData>
     43#include <QDomDocument>
     44#include <QDebug>
    4345
    4446#include "mytablewidget.h"
     
    6264
    6365#define DRAG_ITEMS 0
     66#define PL_ALLOW_DUPLICATES 1
    6467
    6568#define COL_PLAY 0
     
    7982
    8083        automatically_play_next = true;
     84        ignore_player_errors = false;
    8185
    8286        row_spacing = -1; // Default height
     
    9397
    9498        connect( core, SIGNAL(mediaFinished()), this, SLOT(playNext()), Qt::QueuedConnection );
     99        connect( core, SIGNAL(mplayerFailed(QProcess::ProcessError)), this, SLOT(playerFailed(QProcess::ProcessError)) );
     100        connect( core, SIGNAL(mplayerFinishedWithError(int)), this, SLOT(playerFinishedWithError(int)) );
    95101        connect( core, SIGNAL(mediaLoaded()), this, SLOT(getMediaInfo()) );
    96102
     
    236242        editAct = new MyAction(this, "pl_edit", false);
    237243        connect( editAct, SIGNAL(triggered()), this, SLOT(editCurrentItem()) );
     244
     245        deleteSelectedFileFromDiskAct = new MyAction(this, "pl_delete_from_disk");
     246        connect( deleteSelectedFileFromDiskAct, SIGNAL(triggered()), this, SLOT(deleteSelectedFileFromDisk()));
    238247}
    239248
     
    284293        popup->addAction(removeSelectedAct);
    285294        popup->addAction(editAct);
     295        popup->addAction(deleteSelectedFileFromDiskAct);
    286296
    287297        connect( listView, SIGNAL(customContextMenuRequested(const QPoint &)),
     
    320330        removeSelectedAct->change( tr("Remove &selected") );
    321331        removeAllAct->change( tr("Remove &all") );
     332
     333        deleteSelectedFileFromDiskAct->change( tr("&Delete file from disk") );
    322334
    323335        // Edit
     
    456468        #endif
    457469
     470#if !PL_ALLOW_DUPLICATES
    458471        // Test if already is in the list
    459472        bool exists = false;
     
    474487
    475488        if (!exists) {
     489#endif
    476490                if (name.isEmpty()) {
    477491                        QFileInfo fi(filename);
     
    487501                pl.append( PlaylistItem(filename, name, duration) );
    488502                //setModified( true ); // Better set the modified on a higher level
     503#if !PL_ALLOW_DUPLICATES
    489504        } else {
    490505                qDebug("Playlist::addItem: item not added, already in the list");
    491506        }
     507#endif
    492508}
    493509
     
    591607        QRegExp info("^#EXTINF:(.*),(.*)");
    592608
    593     QFile f( file );
    594     if ( f.open( QIODevice::ReadOnly ) ) {
     609        QFile f( file );
     610        if ( f.open( QIODevice::ReadOnly ) ) {
    595611                playlist_path = QFileInfo(file).path();
    596612
     
    600616                double duration=0;
    601617
    602         QTextStream stream( &f );
     618                QTextStream stream( &f );
    603619
    604620                if (utf8)
     
    607623                        stream.setCodec(QTextCodec::codecForLocale());
    608624
    609         QString line;
    610         while ( !stream.atEnd() ) {
    611             line = stream.readLine(); // line of text excluding '\n'
    612             qDebug( " * line: '%s'", line.toUtf8().data() );
     625                QString line;
     626                while ( !stream.atEnd() ) {
     627                        line = stream.readLine().trimmed();
     628                        if (line.isEmpty()) continue; // Ignore empty lines
     629
     630                        qDebug( "Playlist::load_m3u: line: '%s'", line.toUtf8().data() );
    613631                        if (m3u_id.indexIn(line)!=-1) {
    614632                                //#EXTM3U
     
    619637                                duration = info.cap(1).toDouble();
    620638                                name = info.cap(2);
    621                                 qDebug(" * name: '%s', duration: %f", name.toUtf8().data(), duration );
     639                                qDebug("Playlist::load_m3u: name: '%s', duration: %f", name.toUtf8().data(), duration );
    622640                        }
    623641                        else
     
    640658                                duration = 0;
    641659                        }
    642         }
    643         f.close();
     660                }
     661                f.close();
    644662                list();
    645663                updateView();
     
    698716
    699717        if (set.status() == QSettings::NoError) startPlay();
     718}
     719
     720void Playlist::loadXSPF(const QString & filename) {
     721        qDebug() << "Playlist::loadXSPF:" << filename;
     722
     723        QFile f(filename);
     724        if (!f.open(QIODevice::ReadOnly)) {
     725                return;
     726        }
     727
     728        QDomDocument dom_document;
     729        bool ok = dom_document.setContent(f.readAll());
     730        qDebug() << "Playlist::loadXSPF: success:" << ok;
     731        if (!ok) return;
     732
     733        QDomNode root = dom_document.documentElement();
     734        qDebug() << "Playlist::loadXSPF: tagname:" << root.toElement().tagName();
     735
     736        QDomNode child = root.firstChildElement("trackList");
     737        if (!child.isNull()) {
     738                clear();
     739
     740                qDebug() << "Playlist::loadXSPF: child:" << child.nodeName();
     741                QDomNode track = child.firstChildElement("track");
     742                while (!track.isNull()) {
     743                        QString location = QUrl::fromPercentEncoding(track.firstChildElement("location").text().toLatin1());
     744                        QString title = track.firstChildElement("title").text();
     745                        int duration = track.firstChildElement("duration").text().toInt();
     746
     747                        qDebug() << "Playlist::loadXSPF: location:" << location;
     748                        qDebug() << "Playlist::loadXSPF: title:" << title;
     749                        qDebug() << "Playlist::loadXSPF: duration:" << duration;
     750
     751                        addItem( location, title, (double) duration / 1000 );
     752
     753                        track = track.nextSiblingElement("track");
     754                }
     755
     756                list();
     757                updateView();
     758                setModified( false );
     759                startPlay();
     760        }
    700761}
    701762
     
    800861}
    801862
     863bool Playlist::saveXSPF(const QString & filename) {
     864        qDebug() << "Playlist::saveXSPF:" << filename;
     865
     866        QFile f(filename);
     867        if (f.open( QIODevice::WriteOnly)) {
     868                QTextStream stream(&f);
     869                stream.setCodec("UTF-8");
     870
     871                stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
     872                stream << "<playlist version=\"1\" xmlns=\"http://xspf.org/ns/0/\">\n";
     873                stream << "\t<trackList>\n";
     874
     875                for ( int n=0; n < pl.count(); n++ ) {
     876                        QString location = pl[n].filename();
     877                        qDebug() << "Playlist::saveXSPF:" << location;
     878       
     879                        bool is_local = QFile::exists(location);
     880                       
     881                        #ifdef Q_OS_WIN
     882                        if (is_local) {
     883                                location.replace("\\", "/");
     884                        }
     885                        #endif
     886                        //qDebug() << "Playlist::saveXSPF:" << location;
     887                       
     888                        QUrl url(location);
     889                        location = url.toEncoded();
     890                        //qDebug() << "Playlist::saveXSPF:" << location;
     891                       
     892                        if (!location.startsWith("file:") && is_local) {
     893                                #ifdef Q_OS_WIN
     894                                location = "file:///" + location;
     895                                #else
     896                                location = "file://" + location;
     897                                #endif
     898                        }
     899
     900                        QString title = pl[n].name();
     901                        int duration = pl[n].duration() * 1000;
     902
     903                        #if QT_VERSION >= 0x050000
     904                        location = location.toHtmlEscaped();
     905                        title = title.toHtmlEscaped();
     906                        #else
     907                        location = Qt::escape(location);
     908                        title = Qt::escape(title);
     909                        #endif
     910
     911                        stream << "\t\t<track>\n";
     912                        stream << "\t\t\t<location>" << location << "</location>\n";
     913                        stream << "\t\t\t<title>" << title << "</title>\n";
     914                        stream << "\t\t\t<duration>" << duration << "</duration>\n";
     915                        stream << "\t\t</track>\n";
     916                }
     917
     918                stream << "\t</trackList>\n";
     919                stream << "</playlist>\n";
     920
     921                setModified(false);
     922                return true;
     923        } else {
     924                return false;
     925        }
     926}
     927
    802928
    803929void Playlist::load() {
     
    807933                    this, tr("Choose a file"),
    808934                    lastDir(),
    809                     tr("Playlists") + e.playlist().forFilter());
     935                    tr("Playlists") + e.playlist().forFilter() + ";;" + tr("All files") +" (*)");
    810936
    811937                if (!s.isEmpty()) {
    812938                        latest_dir = QFileInfo(s).absolutePath();
    813939
    814                         if (QFileInfo(s).suffix().toLower() == "pls")
     940                        QString suffix = QFileInfo(s).suffix().toLower();
     941                        if (suffix == "pls") {
    815942                                load_pls(s);
     943                        }
    816944                        else
     945                        if (suffix == "xspf") {
     946                                loadXSPF(s);
     947                        }
     948                        else {
    817949                                load_m3u(s);
     950                        }
    818951                }
    819952        }
     
    825958                    this, tr("Choose a filename"),
    826959                    lastDir(),
    827                     tr("Playlists") + e.playlist().forFilter());
     960                    tr("Playlists") + e.playlist().forFilter() + ";;" + tr("All files") +" (*)");
    828961
    829962        if (!s.isEmpty()) {
     
    846979                latest_dir = QFileInfo(s).absolutePath();
    847980
    848                 if (QFileInfo(s).suffix().toLower() == "pls")
     981                QString suffix = QFileInfo(s).suffix().toLower();
     982                if (suffix  == "pls") {
    849983                        return save_pls(s);
     984                }
    850985                else
     986                if (suffix  == "xspf") {
     987                        return saveXSPF(s);
     988                }
     989                else {
    851990                        return save_m3u(s);
     991                }
    852992
    853993        } else {
     
    9331073                // Shuffle
    9341074                int chosen_item = chooseRandomItem();
     1075                qDebug("Playlist::playNext: chosen_item: %d", chosen_item);
    9351076                if (chosen_item == -1) {
    9361077                        clearPlayedTag();
    937                         if (repeatAct->isChecked()) chosen_item = chooseRandomItem();
     1078                        if (repeatAct->isChecked()) {
     1079                                chosen_item = chooseRandomItem();
     1080                                if (chosen_item == -1) chosen_item = 0;
     1081                        }
    9381082                }
    9391083                playItem( chosen_item );
     
    9681112
    9691113void Playlist::getMediaInfo() {
    970         qDebug("Playlist:: getMediaInfo");
     1114        qDebug("Playlist::getMediaInfo");
    9711115
    9721116        QString filename = core->mdat.filename;
     
    9931137        if (!artist.isEmpty()) name = artist + " - " + name;
    9941138
    995         int pos=0;
    996         PlaylistItemList::iterator it;
    997         for ( it = pl.begin(); it != pl.end(); ++it ) {
    998                 /* qDebug("Playlist:: getMediaInfo: f1: %s f2: %s", (*it).filename().toUtf8().constData(), filename.toUtf8().constData()); */
    999                 if ( (*it).filename() == filename ) {
    1000                         /* qDebug("Playlist:: getMediaInfo: duration: %f", (*it).duration()); */
    1001                         if ((*it).duration()<1) {
     1139        for (int n = 0; n < pl.count(); n++) {
     1140                if (pl[n].filename() == filename) {
     1141                        // Found item
     1142                        if (pl[n].duration() < 1) {
    10021143                                if (!name.isEmpty()) {
    1003                                         (*it).setName(name);
     1144                                        pl[n].setName(name);
    10041145                                }
    1005                                 (*it).setDuration(duration);
    1006                                 //setModified( true );
    1007                         }
    1008                         else
     1146                                pl[n].setDuration(duration);
     1147                        }
     1148                        else
    10091149                        // Edited name (sets duration to 1)
    1010                         if ((*it).duration()==1) {
    1011                                 (*it).setDuration(duration);
    1012                                 //setModified( true );
    1013                         }
    1014                         setCurrentItem(pos);
    1015                 }
    1016                 pos++;
    1017         }
     1150                        if (pl[n].duration() == 1) {
     1151                                pl[n].setDuration(duration);
     1152                        }
     1153                }
     1154        }
     1155
    10181156        updateView();
    10191157}
     
    10521190#endif
    10531191
    1054     QStringList::Iterator it = files.begin();
    1055     while( it != files.end() ) {
     1192        QString initial_file;
     1193        if (pl.count() == 1) initial_file = pl[0].filename();
     1194        int new_current_item = -1;
     1195
     1196        for (int n = 0; n < files.count(); n++) {
     1197                QString name = "";
     1198                double duration = 0;
    10561199#if USE_INFOPROVIDER
    1057                 if ( (get_info) && (QFile::exists((*it))) ) {
    1058                         data = InfoProvider::getInfo( (*it) );
    1059                         addItem( (*it), data.displayName(), data.duration );
     1200                if ( (get_info) && (QFile::exists(files[n])) ) {
     1201                        data = InfoProvider::getInfo(files[n]);
     1202                        name = data.displayName();
     1203                        duration = data.duration;
    10601204                        //updateView();
    10611205                        //qApp->processEvents();
    1062                 } else {
    1063                         addItem( (*it), "", 0 );
    1064                 }
    1065 #else
    1066         addItem( (*it), "", 0 );
     1206                }
    10671207#endif
    10681208
    1069                 if (QFile::exists(*it)) {
    1070                         latest_dir = QFileInfo((*it)).absolutePath();
    1071                 }
    1072 
    1073         ++it;
    1074     }
     1209                //qDebug() << "Playlist::addFiles: comparing:" << initial_file << "with" << files[n];
     1210
     1211                if (!initial_file.isEmpty() && files[n] == initial_file) {
     1212                        PlaylistItem first_item = pl.takeFirst();
     1213                        name = first_item.name();
     1214                        duration = first_item.duration();
     1215                        new_current_item = n;
     1216                }
     1217                addItem(files[n], name, duration);
     1218
     1219                if (QFile::exists(files[n])) {
     1220                        latest_dir = QFileInfo(files[n]).absolutePath();
     1221                }
     1222        }
    10751223#if USE_INFOPROVIDER
    10761224        unsetCursor();
    10771225#endif
     1226
     1227        if (new_current_item != -1) setCurrentItem(new_current_item);
    10781228        updateView();
    10791229
     
    12011351
    12021352void Playlist::clearPlayedTag() {
    1203         PlaylistItemList::iterator it;
    1204         for ( it = pl.begin(); it != pl.end(); ++it ) {
    1205                 (*it).setPlayed(false);
     1353        for (int n = 0; n < pl.count(); n++) {
     1354                pl[n].setPlayed(false);
    12061355        }
    12071356        updateView();
     
    12101359int Playlist::chooseRandomItem() {
    12111360        qDebug( "Playlist::chooseRandomItem");
     1361
    12121362        QList <int> fi; //List of not played items (free items)
    1213 
    1214         int n=0;
    1215         PlaylistItemList::iterator it;
    1216         for ( it = pl.begin(); it != pl.end(); ++it ) {
    1217                 if (! (*it).played() ) fi.append(n);
    1218                 n++;
    1219         }
    1220 
    1221         qDebug(" * free items: %d", fi.count() );
    1222 
    1223         if (fi.count()==0) return -1; // none free
    1224 
    1225         qDebug(" * items: ");
    1226         for (int i=0; i < fi.count(); i++) {
    1227                 qDebug("   * item: %d", fi[i]);
     1363        for (int n = 0; n < pl.count(); n++) {
     1364                if (!pl[n].played()) fi.append(n);
     1365        }
     1366
     1367        qDebug("Playlist::chooseRandomItem: free items: %d", fi.count() );
     1368
     1369        if (fi.count() == 0) return -1; // none free
     1370
     1371        qDebug("Playlist::chooseRandomItem: items: ");
     1372        for (int i = 0; i < fi.count(); i++) {
     1373                qDebug("Playlist::chooseRandomItem: * item: %d", fi[i]);
    12281374        }
    12291375
    12301376        int selected = (int) ((double) fi.count() * rand()/(RAND_MAX+1.0));
    1231         qDebug(" * selected item: %d (%d)", selected, fi[selected]);
     1377        qDebug("Playlist::chooseRandomItem: selected item: %d (%d)", selected, fi[selected]);
    12321378        return fi[selected];
    12331379}
     
    13121458                setModified( true );
    13131459    }
     1460}
     1461
     1462void Playlist::deleteSelectedFileFromDisk() {
     1463        qDebug("Playlist::deleteSelectedFileFromDisk");
     1464
     1465        int current = listView->currentRow();
     1466        if (current > -1) {
     1467                // If more that one row is selected, select only the current one
     1468                listView->clearSelection();
     1469                listView->setCurrentCell(current, 0);
     1470
     1471                QString filename = pl[current].filename();
     1472                qDebug() << "Playlist::deleteSelectedFileFromDisk: current file:" << filename;
     1473
     1474                QFileInfo fi(filename);
     1475                if (fi.exists() && fi.isFile() && fi.isWritable()) {
     1476                        // Ask the user for confirmation
     1477                        int res = QMessageBox::question(this, tr("Confirm deletion"),
     1478                                                tr("You're about to DELETE the file '%1' from your drive.").arg(filename) + "<br>"+
     1479                                                tr("This action cannot be undone. Are you sure you want to proceed?"),
     1480                                                QMessageBox::Yes, QMessageBox::No);
     1481
     1482                        if (res == QMessageBox::Yes) {
     1483                                // Delete file
     1484                                bool success = QFile::remove(filename);
     1485                                //bool success = false;
     1486
     1487                                if (success) {
     1488                                        // Remove item from the playlist
     1489                                        removeSelected();
     1490                                } else {
     1491                                        QMessageBox::warning(this, tr("Deletion failed"),
     1492                                                tr("It wasn't possible to delete '%1'").arg(filename));
     1493                                }
     1494                        }
     1495                } else {
     1496                        qDebug("Playlist::deleteSelectedFileFromDisk: file doesn't exists, it's not a file or it's not writable");
     1497                        QMessageBox::information(this, tr("Error deleting the file"),
     1498                                tr("It's not possible to delete '%1' from the filesystem.").arg(filename));
     1499                }
     1500        }
    13141501}
    13151502
     
    13781565}
    13791566
     1567void Playlist::playerFailed(QProcess::ProcessError e) {
     1568        qDebug("Playlist::playerFailed");
     1569        if (ignore_player_errors) {
     1570                if (e != QProcess::FailedToStart) {
     1571                        playNext();
     1572                }
     1573        }
     1574}
     1575
     1576void Playlist::playerFinishedWithError(int e) {
     1577        qDebug("Playlist::playerFinishedWithError: %d", e);
     1578        if (ignore_player_errors) {
     1579                playNext();
     1580        }
     1581}
    13801582
    13811583void Playlist::maybeSaveSettings() {
     
    14031605        set->setValue( "play_files_from_start", play_files_from_start );
    14041606        set->setValue( "automatically_play_next", automatically_play_next );
     1607        set->setValue( "ignore_player_errors", ignore_player_errors );
    14051608
    14061609        set->setValue( "row_spacing", row_spacing );
     
    14491652        play_files_from_start = set->value( "play_files_from_start", play_files_from_start ).toBool();
    14501653        automatically_play_next = set->value( "automatically_play_next", automatically_play_next ).toBool();
     1654        ignore_player_errors = set->value( "ignore_player_errors", ignore_player_errors ).toBool();
    14511655
    14521656        row_spacing = set->value( "row_spacing", row_spacing ).toInt();
Note: See TracChangeset for help on using the changeset viewer.