Ignore:
Timestamp:
Aug 31, 2016, 5:31:04 PM (9 years ago)
Author:
Silvan Scherrer
Message:

smplayer: update trunk to version 16.8.0

Location:
smplayer/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • smplayer/trunk

  • smplayer/trunk/src/playlist.cpp

    r176 r181  
    1919#include "playlist.h"
    2020
     21#include <QTableView>
     22#include <QStandardItemModel>
     23#include <QSortFilterProxyModel>
     24#include <QStyledItemDelegate>
    2125#include <QToolBar>
    2226#include <QFile>
     
    2630#include <QMessageBox>
    2731#include <QPushButton>
    28 #include <QRegExp>
    2932#include <QMenu>
    3033#include <QDateTime>
     
    4447#include <QDebug>
    4548
    46 #include "mytablewidget.h"
     49#if QT_VERSION >= 0x050000
     50#include "myscroller.h"
     51#endif
     52
    4753#include "myaction.h"
     54#include "mylineedit.h"
    4855#include "filedialog.h"
    4956#include "helper.h"
     
    5259#include "multilineinputdialog.h"
    5360#include "version.h"
    54 #include "global.h"
    55 #include "core.h"
    5661#include "extensions.h"
    5762#include "guiconfig.h"
    5863
    59 #include <stdlib.h>
     64#ifdef PLAYLIST_DOWNLOAD
     65#include "inputurl.h"
     66#include "youtube/loadpage.h"
     67#include "urlhistory.h"
     68#include <QNetworkAccessManager>
     69#include <QTemporaryFile>
     70#include <QClipboard>
     71#include <QMovie>
     72#endif
    6073
    6174#if USE_INFOPROVIDER
     
    6578#define DRAG_ITEMS 0
    6679#define PL_ALLOW_DUPLICATES 1
    67 
    68 #define COL_PLAY 0
     80#define SIMULATE_FILE_DELETION 0
     81#define USE_ITEM_DELEGATE 0
     82
     83#define COL_NUM 0
    6984#define COL_NAME 1
    7085#define COL_TIME 2
    71 
    72 using namespace Global;
    73 
    74 
    75 Playlist::Playlist( Core *c, QWidget * parent, Qt::WindowFlags f)
    76         : QWidget(parent,f)
     86#define COL_FILENAME 3
     87
     88#if USE_ITEM_DELEGATE
     89class PlaylistDelegate : public QStyledItemDelegate {
     90public:
     91        PlaylistDelegate(QObject * parent = 0) : QStyledItemDelegate(parent) {};
     92        virtual void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const {
     93                QStyleOptionViewItem opt = option;
     94                initStyleOption(&opt, index);
     95                if (index.column() == COL_NAME) {
     96                        bool played = index.data(PLItem::Role_Played).toBool();
     97                        bool current = index.data(PLItem::Role_Current).toBool();
     98                        if (current) opt.font.setBold(true);
     99                        else
     100                        if (played) opt.font.setItalic(true);
     101                }
     102                else
     103                if (index.column() == COL_FILENAME) {
     104                        opt.textElideMode = Qt::ElideMiddle;
     105                }
     106                QStyledItemDelegate::paint(painter, opt, index);
     107        }
     108};
     109#endif
     110
     111/* ----------------------------------------------------------- */
     112
     113
     114PLItem::PLItem() : QStandardItem() {
     115        col_num = new QStandardItem();
     116        col_duration = new QStandardItem();
     117        col_filename = new QStandardItem();
     118
     119        setDuration(0);
     120        setPlayed(false);
     121        setCurrent(false);
     122
     123        col_num->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
     124}
     125
     126PLItem::PLItem(const QString filename, const QString name, double duration) : QStandardItem() {
     127        col_num = new QStandardItem();
     128        col_duration = new QStandardItem();
     129        col_filename = new QStandardItem();
     130
     131        setFilename(filename);
     132        setName(name);
     133        setDuration(duration);
     134        setPlayed(false);
     135        setCurrent(false);
     136
     137        col_num->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
     138}
     139
     140PLItem::~PLItem() {
     141}
     142
     143void PLItem::setFilename(const QString filename) {
     144        col_filename->setText(filename);
     145        col_filename->setToolTip(filename);
     146        col_filename->setData(filename);
     147
     148        if (!filename.contains("://") && filename.count() > 50) {
     149                QStringList parts = filename.split(QDir::separator());
     150                //if (!parts.isEmpty() && parts[0].isEmpty()) parts[0] = "/";
     151                //qDebug() << "PLItem::setFilename: parts count:" << parts.count() << "parts:" << parts;
     152                if (parts.count() >= 2) {
     153                        QString s = parts[parts.count()-2] + QDir::separator() + parts[parts.count()-1];
     154                        if (parts.count() > 2) s = QString("...") + QDir::separator() + s;
     155                        col_filename->setText(s);
     156                }
     157        }
     158}
     159
     160void PLItem::setName(const QString name) {
     161        setText(name);
     162        setData(name);
     163        setToolTip(name);
     164}
     165
     166void PLItem::setDuration(double duration) {
     167        col_duration->setData(duration);
     168        col_duration->setText(Helper::formatTime(duration));
     169}
     170
     171void PLItem::setPlayed(bool played) {
     172        setData(played, Role_Played);
     173#if !USE_ITEM_DELEGATE
     174        QFont f = font();
     175        f.setItalic(played);
     176        setFont(f);
     177#endif
     178}
     179
     180void PLItem::setPosition(int position) {
     181        //col_num->setText(QString("%1").arg(position, 4, 10, QChar('0')));
     182        col_num->setText(QString::number(position));
     183        col_num->setData(position);
     184}
     185
     186void PLItem::setCurrent(bool b) {
     187        setData(b, Role_Current);
     188#if !USE_ITEM_DELEGATE
     189        QFont f = font();
     190        f.setBold(b);
     191        f.setItalic(b ? false : played());
     192        setFont(f);
     193#endif
     194}
     195
     196QString PLItem::filename() {
     197        return col_filename->data().toString();
     198}
     199
     200QString PLItem::name() {
     201        return text();
     202}
     203
     204double PLItem::duration() {
     205        return col_duration->data().toDouble();
     206}
     207
     208bool PLItem::played() {
     209        return data(Role_Played).toBool();
     210}
     211
     212int PLItem::position() {
     213        return col_num->data().toInt();
     214}
     215
     216bool PLItem::isCurrent() {
     217        return data(Role_Current).toBool();
     218}
     219
     220QList<QStandardItem *> PLItem::items() {
     221        QList<QStandardItem *> l;
     222        l << col_num << this << col_duration << col_filename;
     223        return l;
     224}
     225
     226
     227/* ----------------------------------------------------------- */
     228
     229
     230Playlist::Playlist(QWidget * parent, Qt::WindowFlags f)
     231        : QWidget(parent,f)
     232        , set(0)
     233        , modified(false)
     234        , recursive_add_directory(false)
     235        , automatically_get_info(false)
     236        , save_playlist_in_config(true)
     237        , play_files_from_start(true)
     238        , row_spacing(-1) // Default height
     239        , automatically_play_next(true)
     240        , ignore_player_errors(false)
     241        , change_name(true)
     242        , save_dirs(true)
    77243{
    78         save_playlist_in_config = true;
    79         recursive_add_directory = false;
    80         automatically_get_info = false;
    81         play_files_from_start = true;
    82 
    83         automatically_play_next = true;
    84         ignore_player_errors = false;
    85 
    86         row_spacing = -1; // Default height
    87 
    88         modified = false;
    89 
    90         core = c;
    91     playlist_path = "";
    92     latest_dir = "";
     244        playlist_path = "";
     245        latest_dir = "";
    93246
    94247        createTable();
     
    96249        createToolbar();
    97250
    98         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)) );
    101         connect( core, SIGNAL(mediaLoaded()), this, SLOT(getMediaInfo()) );
    102 
    103251        QVBoxLayout *layout = new QVBoxLayout;
    104         layout->addWidget( listView );
    105         layout->addWidget( toolbar );
     252        layout->addWidget(listView);
     253        layout->addWidget(toolbar);
     254#ifdef PLAYLIST_DOUBLE_TOOLBAR
     255        layout->addWidget(toolbar2);
     256#endif
    106257        setLayout(layout);
    107258
    108     clear();
     259        clear();
    109260
    110261        retranslateStrings();
     
    123274
    124275        // Random seed
    125         QTime t;
    126         t.start();
    127         srand( t.hour() * 3600 + t.minute() * 60 + t.second() );
    128 
    129         loadSettings();
    130 
    131         // Ugly hack to avoid to play next item automatically
    132         if (!automatically_play_next) {
    133                 disconnect( core, SIGNAL(mediaFinished()), this, SLOT(playNext()) );
    134         }
     276        QTime now = QTime::currentTime();
     277        qsrand(now.msec());
     278
     279        //loadSettings();
    135280
    136281        // Save config every 5 minutes.
    137282        save_timer = new QTimer(this);
    138283        connect( save_timer, SIGNAL(timeout()), this, SLOT(maybeSaveSettings()) );
    139         save_timer->start( 5 * 60000 );
     284        save_timer->start( 5 * 60000 );
     285
     286#ifdef PLAYLIST_DOWNLOAD
     287        downloader = new LoadPage(new QNetworkAccessManager(this), this);
     288        downloader->setUserAgent("SMPlayer");
     289        connect(downloader, SIGNAL(pageLoaded(QByteArray)), this, SLOT(playlistDownloaded(QByteArray)));
     290        connect(downloader, SIGNAL(errorOcurred(int, QString)), this, SLOT(errorOcurred(int, QString)));
     291
     292        history_urls = new URLHistory;
     293        history_urls->addUrl("http://smplayer.info/onlinetv.php");
     294#endif
    140295}
    141296
    142297Playlist::~Playlist() {
    143298        saveSettings();
    144 }
     299        if (set) delete set;
     300
     301#ifdef PLAYLIST_DOWNLOAD
     302        delete history_urls;
     303#endif
     304}
     305
     306void Playlist::setConfigPath(const QString & config_path) {
     307        qDebug() << "Playlist::setConfigPath:" << config_path;
     308
     309        if (set) {
     310                delete set;
     311                set = 0;
     312        }
     313
     314        if (!config_path.isEmpty()) {
     315                QString inifile = config_path + "/playlist.ini";
     316                qDebug() << "Playlist::setConfigPath: ini file:" << inifile;
     317                set = new QSettings(inifile, QSettings::IniFormat);
     318                loadSettings();
     319        }
     320}
     321
    145322
    146323void Playlist::setModified(bool mod) {
     
    152329
    153330void Playlist::createTable() {
    154         listView = new MyTableWidget( 0, COL_TIME + 1, this);
     331        table = new QStandardItemModel(this);
     332        table->setColumnCount(COL_FILENAME + 1);
     333        //table->setSortRole(Qt::UserRole + 1);
     334
     335        proxy = new QSortFilterProxyModel(this);
     336        proxy->setSourceModel(table);
     337        proxy->setSortRole(Qt::UserRole + 1);
     338        proxy->setFilterRole(Qt::UserRole + 1);
     339        proxy->setFilterKeyColumn(-1); // All columns
     340
     341#if USE_ITEM_DELEGATE
     342        PlaylistDelegate * pl_delegate = new PlaylistDelegate(this);
     343#endif
     344
     345        listView = new QTableView(this);
     346        listView->setModel(proxy);
     347
     348#if USE_ITEM_DELEGATE
     349        listView->setItemDelegateForColumn(COL_NAME, pl_delegate);
     350        //listView->setItemDelegateForColumn(COL_FILENAME, pl_delegate);
     351#endif
     352
    155353        listView->setObjectName("playlist_table");
    156354        listView->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
     
    159357        listView->setContextMenuPolicy( Qt::CustomContextMenu );
    160358        listView->setShowGrid(false);
    161         listView->setSortingEnabled(false);
    162         //listView->setAlternatingRowColors(true);
     359        listView->setSortingEnabled(true);
     360#if !USE_ITEM_DELEGATE
     361        listView->setAlternatingRowColors(true);
     362#endif
     363        listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
     364
     365        listView->verticalHeader()->hide();
    163366
    164367#if QT_VERSION >= 0x050000
     368        MyScroller::setScroller(listView->viewport());
     369
    165370        listView->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
    166         listView->horizontalHeader()->setSectionResizeMode(COL_NAME, QHeaderView::Stretch);
     371//      listView->horizontalHeader()->setSectionResizeMode(COL_NAME, QHeaderView::Stretch);
    167372#else
    168373        listView->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
    169         listView->horizontalHeader()->setResizeMode(COL_NAME, QHeaderView::Stretch);
    170 #endif
     374//      listView->horizontalHeader()->setResizeMode(COL_NAME, QHeaderView::Stretch);
     375//      listView->horizontalHeader()->setResizeMode(COL_FILENAME, QHeaderView::Interactive);
     376#endif
     377        listView->horizontalHeader()->setStretchLastSection(true);
     378
    171379        /*
    172380        listView->horizontalHeader()->setResizeMode(COL_TIME, QHeaderView::ResizeToContents);
    173381        listView->horizontalHeader()->setResizeMode(COL_PLAY, QHeaderView::ResizeToContents);
    174382        */
    175         listView->setIconSize( Images::icon("ok").size() );
     383        //listView->setIconSize( Images::icon("ok").size() );
    176384
    177385#if DRAG_ITEMS
     
    183391#endif
    184392
    185         connect( listView, SIGNAL(cellActivated(int,int)),
    186              this, SLOT(itemDoubleClicked(int)) );
    187 
    188         // EDIT BY NEO -->
    189         connect( listView->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(sortBy(int)));
    190         // <--
     393        connect(listView, SIGNAL(activated(const QModelIndex &)),
     394            this, SLOT(itemActivated(const QModelIndex &)) );
    191395}
    192396
     
    195399        connect( openAct, SIGNAL(triggered()), this, SLOT(load()) );
    196400
     401#ifdef PLAYLIST_DOWNLOAD
     402        openUrlAct = new MyAction(this, "pl_open_url", false);
     403        connect( openUrlAct, SIGNAL(triggered()), this, SLOT(openUrl()) );
     404#endif
     405
    197406        saveAct = new MyAction(this, "pl_save", false);
    198407        connect( saveAct, SIGNAL(triggered()), this, SLOT(save()) );
     
    250459        toolbar = new QToolBar(this);
    251460        toolbar->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
     461        //toolbar->setIconSize(QSize(48,48));
     462
     463#ifdef PLAYLIST_DOUBLE_TOOLBAR
     464        toolbar2 = new QToolBar(this);
     465        toolbar2->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
     466#endif
    252467
    253468        toolbar->addAction(openAct);
     469#ifdef PLAYLIST_DOWNLOAD
     470        toolbar->addAction(openUrlAct);
     471#endif
    254472        toolbar->addAction(saveAct);;
    255473        toolbar->addSeparator();
     
    273491        remove_button->setPopupMode(QToolButton::InstantPopup);
    274492
     493        filter_edit = new MyLineEdit(this);
     494        connect(filter_edit, SIGNAL(textChanged(const QString &)), this, SLOT(filterEditChanged(const QString &)));
     495
     496#ifdef PLAYLIST_DOWNLOAD
     497        QLabel * loading_label = new QLabel(this);
     498        animation = new QMovie();
     499        animation->setFileName(Images::file("pl_loading.gif"));
     500        loading_label->setMovie(animation);
     501#endif
     502
    275503        toolbar->addWidget(add_button);
    276504        toolbar->addWidget(remove_button);
     
    278506        toolbar->addSeparator();
    279507        toolbar->addAction(playAct);
    280         toolbar->addSeparator();
    281508        toolbar->addAction(prevAct);
    282509        toolbar->addAction(nextAct);
     510#ifdef PLAYLIST_DOUBLE_TOOLBAR
     511        toolbar2->addAction(moveUpAct);
     512        toolbar2->addAction(moveDownAct);
     513        toolbar2->addAction(repeatAct);
     514        toolbar2->addAction(shuffleAct);
     515        toolbar2->addSeparator();
     516        toolbar2->addWidget(filter_edit);
     517        #ifdef PLAYLIST_DOWNLOAD
     518        loading_label_action = toolbar2->addWidget(loading_label);
     519        #endif
     520#else
    283521        toolbar->addSeparator();
    284522        toolbar->addAction(repeatAct);
     
    287525        toolbar->addAction(moveUpAct);
    288526        toolbar->addAction(moveDownAct);
     527        toolbar->addSeparator();
     528        toolbar->addWidget(filter_edit);
     529        #ifdef PLAYLIST_DOWNLOAD
     530        loading_label_action = toolbar->addWidget(loading_label);
     531        #endif
     532#endif
     533
     534#ifdef PLAYLIST_DOWNLOAD
     535        loading_label_action->setVisible(false);
     536#endif
    289537
    290538        // Popup menu
     
    300548
    301549void Playlist::retranslateStrings() {
    302         listView->setHorizontalHeaderLabels( QStringList() << "   " <<
    303         tr("Name") << tr("Length") );
     550        table->setHorizontalHeaderLabels(QStringList() << " " << tr("Name") << tr("Length") << tr("Filename / URL") );
    304551
    305552        openAct->change( Images::icon("open"), tr("&Load") );
     553#ifdef PLAYLIST_DOWNLOAD
     554        openUrlAct->change( Images::icon("url"), tr("&Open URL") );
     555        openUrlAct->setToolTip(tr("Download playlist from URL"));
     556#endif
    306557        saveAct->change( Images::icon("save"), tr("&Save") );
    307558
     
    342593        remove_button->setToolTip( tr("Remove...") );
    343594
     595        // Filter edit
     596#if QT_VERSION >= 0x040700
     597        filter_edit->setPlaceholderText(tr("Search"));
     598#endif
     599
    344600        // Icon
    345601        setWindowIcon( Images::icon("logo", 64) );
     
    350606        qDebug("Playlist::list");
    351607
    352         PlaylistItemList::iterator it;
    353         for ( it = pl.begin(); it != pl.end(); ++it ) {
    354                 qDebug( "filename: '%s', name: '%s' duration: %f",
    355                (*it).filename().toUtf8().data(), (*it).name().toUtf8().data(),
    356                (*it).duration() );
    357         }
    358 }
    359 
    360 
    361 QString Playlist::print(QString seperator){
    362         qDebug("Playlist::print");
    363         QString output = "";
    364 
    365         PlaylistItemList::iterator it;
    366         for ( it = pl.begin(); it != pl.end(); ++it ) {
    367                 output += it->filename() + seperator + it->name() + seperator + QString::number(it->duration()) + "\r\n";
    368         }
    369 
    370         return output;
    371 }
    372 
    373 void Playlist::updateView() {
    374         qDebug("Playlist::updateView");
    375 
    376         listView->setRowCount( pl.count() );
    377 
    378         //QString number;
    379         QString name;
    380         QString time;
    381 
    382         for (int n=0; n < pl.count(); n++) {
    383                 name = pl[n].name();
    384                 if (name.isEmpty()) name = pl[n].filename();
    385                 time = Helper::formatTime( (int) pl[n].duration() );
    386                
    387                 //listView->setText(n, COL_POS, number);
    388                 qDebug("Playlist::updateView: name: '%s'", name.toUtf8().data());
    389                 listView->setText(n, COL_NAME, name);
    390                 listView->setText(n, COL_TIME, time);
    391 
    392                 if (pl[n].played()) {
    393                         listView->setIcon(n, COL_PLAY, Images::icon("ok") );
    394                 } else {
    395                         listView->setIcon(n, COL_PLAY, QPixmap() );
    396                 }
    397 
    398                 if (row_spacing > -1) listView->setRowHeight(n, listView->font().pointSize() + row_spacing);
    399         }
    400         //listView->resizeColumnsToContents();
    401         listView->resizeColumnToContents(COL_PLAY);
    402         listView->resizeColumnToContents(COL_TIME);
    403 
    404         setCurrentItem(current_item);
    405 
    406         //adjustSize();
     608        for (int n = 0; n < count(); n++) {
     609                PLItem * i = itemData(n);
     610                qDebug() << "Playlist::list: filename:" << i->filename() << "name:" << i->name() << "duration:" << i->duration();
     611        }
     612}
     613
     614void Playlist::setFilter(const QString & filter) {
     615        proxy->setFilterWildcard(filter);
     616}
     617
     618void Playlist::filterEditChanged(const QString & text) {
     619        qDebug() << "Playlist::filterEditChanged:" << text;
     620        setFilter(text);
    407621}
    408622
    409623void Playlist::setCurrentItem(int current) {
    410         QIcon play_icon;
    411         play_icon = Images::icon("play");
    412 
    413         int old_current = current_item;
    414         current_item = current;
    415 
    416         if ((current_item > -1) && (current_item < pl.count())) {
    417                 pl[current_item].setPlayed(true);
    418         }
    419 
    420         if ( (old_current >= 0) && (old_current < listView->rowCount()) ) {
    421                 listView->setIcon(old_current, COL_PLAY, QPixmap() );
    422         }
    423 
    424         if ( (current_item >= 0) && (current_item < listView->rowCount()) ) {
    425                 listView->setIcon(current_item, COL_PLAY, play_icon );
    426         }
    427         //if (current_item >= 0) listView->selectRow(current_item);
    428         if (current_item >= 0) {
    429                 listView->clearSelection();
    430                 listView->setCurrentCell( current_item, 0);
    431         }
     624        QModelIndex index = proxy->index(current, 0);
     625        QModelIndex s_index = proxy->mapToSource(index);
     626
     627        //qDebug() << "Playlist::setCurrentItem: index:" << index.row() << "s_index:" << s_index.row();
     628
     629        int s_current = s_index.row();
     630
     631        PLItem * item = 0;
     632        for (int n = 0; n < count(); n++) {
     633                item = itemData(n);
     634                if (n == s_current) {
     635                        item->setPlayed(true);
     636                }
     637                item->setCurrent( (n == s_current) );
     638        }
     639
     640        listView->clearSelection();
     641        listView->selectionModel()->setCurrentIndex(listView->model()->index(current, 0), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
     642}
     643
     644int Playlist::findCurrentItem() {
     645        //qDebug("Playlist::findCurrentItem");
     646
     647        static int last_current = -1;
     648
     649        // Check if the last found current is still the current item to save time
     650        PLItem * i = itemFromProxy(last_current);
     651        if (i && i->isCurrent()) {
     652                //qDebug() << "Playlist::findCurrentItem: return last_current:" << last_current;
     653                return last_current;
     654        }
     655
     656        for (int n = 0; n < proxy->rowCount(); n++) {
     657                if (itemFromProxy(n)->isCurrent()) {
     658                        last_current = n;
     659                        return n;
     660                }
     661        }
     662
     663        return -1;
    432664}
    433665
    434666void Playlist::clear() {
    435         pl.clear();
    436 
    437         listView->clearContents();
    438         listView->setRowCount(0);
    439 
     667        table->setRowCount(0);
    440668        setCurrentItem(0);
    441 
    442         setModified( false );
    443 }
    444 
    445 void Playlist::remove(int i){
    446         if(i > -1 && i < pl.count()){
    447                 pl.removeAt(i);
    448                 if(current_item == i && i == (pl.count() - 1))
    449                         setCurrentItem(i - 1);
    450                 setModified(false);
    451                 updateView();
    452         } //end if
     669        setModified(false);
    453670}
    454671
    455672int Playlist::count() {
    456         return pl.count();
     673        return table->rowCount();
    457674}
    458675
    459676bool Playlist::isEmpty() {
    460         return pl.isEmpty();
    461 }
     677        return (table->rowCount() > 0);
     678}
     679
     680bool Playlist::existsItem(int row) {
     681        return (row > -1 && row < table->rowCount());
     682}
     683
     684PLItem * Playlist::itemData(int row) {
     685        QStandardItem * i = table->item(row, COL_NAME);
     686        return static_cast<PLItem*>(i);
     687}
     688
     689PLItem * Playlist::itemFromProxy(int row) {
     690        QModelIndex index = proxy->index(row, 0);
     691        QModelIndex s_index = proxy->mapToSource(index);
     692        //qDebug() << "Playlist::itemFromProxy: index is valid:" << index.isValid() << "s_index is valid:" << s_index.isValid();
     693        if (index.isValid() && s_index.isValid()) {
     694                return itemData(s_index.row());
     695        } else {
     696                return 0;
     697        }
     698}
     699
     700/*
     701void Playlist::changeItem(int row, const QString & filename, const QString name, double duration, bool played, int pos) {
     702        PLItem * i = itemData(row);
     703
     704        int position = row + 1;
     705        if (pos != -1) position = pos;
     706        i->setPosition(position);
     707
     708        i->setFilename(filename);
     709        i->setName(name);
     710        i->setDuration(duration);
     711        i->setPlayed(played);
     712}
     713*/
    462714
    463715void Playlist::addItem(QString filename, QString name, double duration) {
    464         qDebug("Playlist::addItem: '%s'", filename.toUtf8().data());
     716        //qDebug() << "Playlist::addItem:" << filename;
    465717
    466718        #if defined(Q_OS_WIN) || defined(Q_OS_OS2)
     
    468720        #endif
    469721
     722                if (name.isEmpty()) {
     723                        QFileInfo fi(filename);
     724                        // Let's see if it looks like a file (no dvd://1 or something)
     725                        if (filename.indexOf(QRegExp("^.*://.*")) == -1) {
     726                                // Local file
     727                                name = fi.fileName();
     728                        } else {
     729                                // Stream
     730                                name = filename;
     731                        }
     732                }
     733
     734        PLItem * i = new PLItem(filename, name, duration);
     735        i->setPosition(count()+1);
     736        table->appendRow(i->items());
     737
     738        if (findCurrentItem() == -1) setCurrentItem(0);
     739
     740/*
    470741#if !PL_ALLOW_DUPLICATES
    471742        // Test if already is in the list
     
    506777        }
    507778#endif
    508 }
    509 
    510 // EDIT BY NEO -->
    511 void Playlist::sortBy(int section) {
    512         qDebug("Playlist::sortBy");
    513 
    514         sortBy(section, false, 0);
    515 }
    516 
    517 void Playlist::sortBy(int section, bool revert, int count) {
    518     // Bubble sort
    519     bool swaped = false;
    520 
    521     for ( int n = 0; n < (pl.count() - count); n++) {
    522 
    523       int last = n - 1;
    524       int current = n;
    525 
    526       // Revert the sort
    527       if (revert) {
    528           last = n;
    529           current = n - 1;
    530       }
    531 
    532       if (n > 0) {
    533           int compare = 0;
    534 
    535           if (section == 0) {
    536               // Sort by played
    537               bool lastItem = pl[last].played();
    538               bool currentItem = pl[current].played();
    539 
    540               if (!lastItem && currentItem) {
    541                   compare = 1;
    542               } else if (lastItem && currentItem) {
    543                   if (last == current_item) {
    544                      compare = 1;
    545                  } else {
    546                      compare = -1;
    547                  }
    548               } else {
    549                   compare = -1;
    550               }
    551           }
    552           else if (section == 1) {
    553               // Sort alphabetically
    554               QString lastItem = pl[last].name();
    555               QString currentItem = pl[current].name();
    556               compare = lastItem.compare(currentItem);
    557           } else if (section == 2) {
    558               // Sort by duration
    559               double lastItem = pl[last].duration();
    560               double currentItem = pl[current].duration();
    561 
    562               if (lastItem == currentItem) {
    563                   compare = 0;
    564               } else if (lastItem > currentItem) {
    565                   compare = 1;
    566               } else {
    567                   compare = -1;
    568               }
    569           }
    570 
    571           // Swap items
    572           if(compare > 0) {
    573               swapItems(n, n - 1);
    574 
    575               if (current_item == (n - 1)) {
    576                   current_item = n;
    577               } else if (current_item == n) {
    578                   current_item = n - 1;
    579               }
    580 
    581               listView->clearSelection();
    582               listView->setCurrentCell(n - 1, 0);
    583 
    584               swaped = true;
    585           }
    586       }
    587     }
    588 
    589     if ((count == 0) && !swaped && !revert) {
    590         // Revert sort
    591         sortBy(section, true, 0);
    592     }else if(swaped) {
    593         // Sort until there is nothing to sort
    594         sortBy(section, revert, ++count);
    595     } else {
    596         updateView();
    597     }
    598 }
    599 // <--
    600 
    601 void Playlist::load_m3u(QString file) {
    602         qDebug("Playlist::load_m3u");
    603 
    604         bool utf8 = (QFileInfo(file).suffix().toLower() == "m3u8");
     779*/
     780}
     781
     782
     783void Playlist::load_m3u(QString file, M3UFormat format) {
     784        bool utf8 = false;
     785        if (format == DetectFormat) {
     786                utf8 = (QFileInfo(file).suffix().toLower() == "m3u8");
     787        } else {
     788                utf8 = (format == M3U8);
     789        }
     790
     791        qDebug() << "Playlist::load_m3u: utf8:" << utf8;
    605792
    606793        QRegExp m3u_id("^#EXTM3U|^#M3U");
     
    634821                        }
    635822                        else
     823                        /*
    636824                        if (info.indexIn(line)!=-1) {
    637825                                duration = info.cap(1).toDouble();
     
    639827                                qDebug("Playlist::load_m3u: name: '%s', duration: %f", name.toUtf8().data(), duration );
    640828                        }
     829                        */
     830                        if (line.startsWith("#EXTINF:")) {
     831                                QStringList fields = line.mid(8).split(",");
     832                                //qDebug() << "Playlist::load_m3u: fields:" << fields;
     833                                if (fields.count() >= 1) duration = fields[0].toDouble();
     834                                if (fields.count() >= 2) name = fields[1];
     835                        }
    641836                        else
    642837                        if (line.startsWith("#")) {
     
    660855                }
    661856                f.close();
    662                 list();
    663                 updateView();
     857                //list();
    664858
    665859                setModified( false );
     
    710904        set.endGroup();
    711905
    712         list();
    713         updateView();
     906        //list();
    714907
    715908        setModified( false );
     
    754947                }
    755948
    756                 list();
    757                 updateView();
     949                //list();
    758950                setModified( false );
    759951                startPlay();
     
    762954
    763955bool Playlist::save_m3u(QString file) {
    764         qDebug("Playlist::save_m3u: '%s'", file.toUtf8().data());
     956        qDebug() << "Playlist::save_m3u:" << file;
    765957
    766958        QString dir_path = QFileInfo(file).path();
     
    771963        #endif
    772964
    773         qDebug(" * dirPath: '%s'", dir_path.toUtf8().data());
     965        qDebug() << "Playlist::save_m3u: dir_path:" << dir_path;
    774966
    775967        bool utf8 = (QFileInfo(file).suffix().toLower() == "m3u8");
    776968
    777969        QFile f( file );
    778     if ( f.open( QIODevice::WriteOnly ) ) {
    779         QTextStream stream( &f );
    780 
    781                 if (utf8) 
     970        if ( f.open( QIODevice::WriteOnly ) ) {
     971                QTextStream stream( &f );
     972
     973                if (utf8)
    782974                        stream.setCodec("UTF-8");
    783975                else
     
    789981                stream << "# Playlist created by SMPlayer " << Version::printable() << " \n";
    790982
    791                 PlaylistItemList::iterator it;
    792                 for ( it = pl.begin(); it != pl.end(); ++it ) {
    793                         filename = (*it).filename();
     983                for (int n = 0; n < count(); n++) {
     984                        PLItem * i = itemData(n);
     985                        filename = i->filename();
    794986                        #if defined(Q_OS_WIN) || defined(Q_OS_OS2)
    795987                        filename = Helper::changeSlashes(filename);
    796988                        #endif
    797989                        stream << "#EXTINF:";
    798                         stream << (*it).duration() << ",";
    799                         stream << (*it).name() << "\n";
     990                        stream << i->duration() << ",";
     991                        stream << i->name() << "\n";
    800992                        // Try to save the filename as relative instead of absolute
    801993                        if (filename.startsWith( dir_path )) {
     
    804996                        stream << filename << "\n";
    805997                }
    806         f.close();
     998                f.close();
    807999
    8081000                setModified( false );
    8091001                return true;
    810     } else {
     1002        } else {
    8111003                return false;
    8121004        }
     
    8151007
    8161008bool Playlist::save_pls(QString file) {
    817         qDebug("Playlist::save_pls: '%s'", file.toUtf8().data());
     1009        qDebug() << "Playlist::save_pls:" << file;
    8181010
    8191011        QString dir_path = QFileInfo(file).path();
     
    8241016        #endif
    8251017
    826         qDebug(" * dirPath: '%s'", dir_path.toUtf8().data());
     1018        qDebug() << "Playlist::save_pls: dir_path:" << dir_path;
    8271019
    8281020        QSettings set(file, QSettings::IniFormat);
    8291021        set.beginGroup( "playlist");
    830        
     1022
    8311023        QString filename;
    8321024
    833         PlaylistItemList::iterator it;
    834         for ( int n=0; n < pl.count(); n++ ) {
    835                 filename = pl[n].filename();
     1025        for (int n = 0; n < count(); n++) {
     1026                PLItem * i = itemData(n);
     1027                filename = i->filename();
    8361028                #if defined(Q_OS_WIN) || defined(Q_OS_OS2)
    8371029                filename = Helper::changeSlashes(filename);
     
    8441036
    8451037                set.setValue("File"+QString::number(n+1), filename);
    846                 set.setValue("Title"+QString::number(n+1), pl[n].name());
    847                 set.setValue("Length"+QString::number(n+1), (int) pl[n].duration());
    848         }
    849 
    850         set.setValue("NumberOfEntries", pl.count());
     1038                set.setValue("Title"+QString::number(n+1), i->name());
     1039                set.setValue("Length"+QString::number(n+1), (int) i->duration());
     1040        }
     1041
     1042        set.setValue("NumberOfEntries", count());
    8511043        set.setValue("Version", 2);
    8521044
     
    8731065                stream << "\t<trackList>\n";
    8741066
    875                 for ( int n=0; n < pl.count(); n++ ) {
    876                         QString location = pl[n].filename();
     1067                for (int n = 0; n < count(); n++) {
     1068                        PLItem * i = itemData(n);
     1069                        QString location = i->filename();
    8771070                        qDebug() << "Playlist::saveXSPF:" << location;
    878        
     1071
    8791072                        bool is_local = QFile::exists(location);
    8801073                       
     
    8981091                        }
    8991092
    900                         QString title = pl[n].name();
    901                         int duration = pl[n].duration() * 1000;
     1093                        QString title = i->name();
     1094                        int duration = i->duration() * 1000;
    9021095
    9031096                        #if QT_VERSION >= 0x050000
     
    9491142                                load_m3u(s);
    9501143                        }
     1144                        //listView->resizeColumnsToContents();
    9511145                }
    9521146        }
     
    10141208
    10151209void Playlist::playCurrent() {
    1016         int current = listView->currentRow();
     1210        int current = listView->currentIndex().row();
    10171211        if (current > -1) {
    10181212                playItem(current);
     
    10201214}
    10211215
    1022 void Playlist::itemDoubleClicked(int row) {
    1023         qDebug("Playlist::itemDoubleClicked: row: %d", row );
    1024         playItem(row);
     1216void Playlist::itemActivated(const QModelIndex & index ) {
     1217        qDebug() << "Playlist::itemActivated: row:" << index.row();
     1218        playItem(index.row());
    10251219}
    10261220
     
    10431237
    10441238void Playlist::playItem( int n ) {
    1045         qDebug("Playlist::playItem: %d (count:%d)", n, pl.count());
    1046 
    1047         if ( (n >= pl.count()) || (n < 0) ) {
     1239        qDebug("Playlist::playItem: %d (count: %d)", n, proxy->rowCount());
     1240
     1241        if ( (n >= proxy->rowCount()) || (n < 0) ) {
    10481242                qDebug("Playlist::playItem: out of range");
    10491243                emit playlistEnded();
     
    10511245        }
    10521246
    1053         qDebug(" playlist_path: '%s'", playlist_path.toUtf8().data() );
    1054 
    1055         QString filename = pl[n].filename();
    1056         QString filename_with_path = playlist_path + "/" + filename;
    1057 
     1247        QString filename = itemFromProxy(n)->filename();
    10581248        if (!filename.isEmpty()) {
    1059                 //pl[n].setPlayed(true);
    10601249                setCurrentItem(n);
    1061                 if (play_files_from_start)
    1062                         core->open(filename, 0);
    1063                 else
    1064                         core->open(filename);
    1065         }
    1066 
     1250                if (play_files_from_start) {
     1251                        emit requestToPlayFile(filename, 0);
     1252                } else {
     1253                        emit requestToPlayFile(filename);
     1254                }
     1255        }
    10671256}
    10681257
     
    10811270                        }
    10821271                }
    1083                 playItem( chosen_item );
     1272                playItem(chosen_item);
    10841273        } else {
    1085                 bool finished_list = (current_item+1 >= pl.count());
     1274                int current = findCurrentItem();
     1275                bool finished_list = (current + 1 >= proxy->rowCount());
    10861276                if (finished_list) clearPlayedTag();
    10871277
    1088                 if ( (repeatAct->isChecked()) && (finished_list) ) {
     1278                if (repeatAct->isChecked() && finished_list) {
    10891279                        playItem(0);
    10901280                } else {
    1091                         playItem( current_item+1 );
     1281                        playItem(current + 1);
    10921282                }
    10931283        }
     
    10961286void Playlist::playPrev() {
    10971287        qDebug("Playlist::playPrev");
    1098         if (current_item > 0) {
    1099                 playItem( current_item-1 );
     1288        int current = findCurrentItem() - 1;
     1289        if (current >= 0) {
     1290                playItem(current);
    11001291        } else {
    1101                 if (pl.count() > 1) playItem( pl.count() -1 );
     1292                if (proxy->rowCount() > 1) playItem(proxy->rowCount() - 1);
    11021293        }
    11031294}
     
    11051296
    11061297void Playlist::resumePlay() {
    1107         if (pl.count() > 0) {
    1108                 if (current_item < 0) current_item = 0;
    1109                 playItem(current_item);
    1110         }
    1111 }
    1112 
    1113 void Playlist::getMediaInfo() {
     1298        qDebug("Playlist::resumePlay");
     1299
     1300        if (count() > 0) {
     1301                int current = findCurrentItem();
     1302                if (current < 0) current = 0;
     1303                playItem(current);
     1304        }
     1305}
     1306
     1307void Playlist::getMediaInfo(const MediaData & mdat) {
    11141308        qDebug("Playlist::getMediaInfo");
    11151309
    1116         QString filename = core->mdat.filename;
    1117         double duration = core->mdat.duration;
    1118         QString artist = core->mdat.clip_artist;
    1119 
    1120         QString name = core->mdat.clip_name;
    1121         if (name.isEmpty()) name = core->mdat.stream_title;
     1310        QString filename = mdat.filename;
     1311        double duration = mdat.duration;
     1312        QString artist = mdat.clip_artist;
    11221313
    11231314        #if defined(Q_OS_WIN) || defined(Q_OS_OS2)
     
    11251316        #endif
    11261317
    1127         if (name.isEmpty()) {
    1128                 QFileInfo fi(filename);
    1129                 if (fi.exists()) {
    1130                         // Local file
    1131                         name = fi.fileName();
    1132                 } else {
    1133                         // Stream
    1134                         name = filename;
    1135                 }
    1136         }
    1137         if (!artist.isEmpty()) name = artist + " - " + name;
    1138 
    1139         for (int n = 0; n < pl.count(); n++) {
    1140                 if (pl[n].filename() == filename) {
     1318        QString name;
     1319        if (change_name) {
     1320                name = mdat.clip_name;
     1321                if (name.isEmpty()) name = mdat.stream_title;
     1322
     1323                if (name.isEmpty()) {
     1324                        QFileInfo fi(filename);
     1325                        if (fi.exists()) {
     1326                                // Local file
     1327                                name = fi.fileName();
     1328                        } else {
     1329                                // Stream
     1330                                name = filename;
     1331                        }
     1332                }
     1333                if (!artist.isEmpty()) name = artist + " - " + name;
     1334        }
     1335
     1336        for (int n = 0; n < count(); n++) {
     1337                PLItem * i = itemData(n);
     1338                if (i->filename() == filename) {
    11411339                        // Found item
    1142                         if (pl[n].duration() < 1) {
    1143                                 if (!name.isEmpty()) {
    1144                                         pl[n].setName(name);
     1340                        bool modified_name = !(i->filename().endsWith(i->name()));
     1341                        if (i->duration() < 1) {
     1342                                if (!modified_name && !name.isEmpty()) {
     1343                                        i->setName(name);
    11451344                                }
    1146                                 pl[n].setDuration(duration);
     1345                                i->setDuration(duration);
    11471346                        }
    11481347                        else
    11491348                        // Edited name (sets duration to 1)
    1150                         if (pl[n].duration() == 1) {
    1151                                 pl[n].setDuration(duration);
    1152                         }
    1153                 }
    1154         }
    1155 
    1156         updateView();
     1349                        if (i->duration() == 1) {
     1350                                i->setDuration(duration);
     1351                        }
     1352                }
     1353        }
    11571354}
    11581355
     
    11601357void Playlist::addCurrentFile() {
    11611358        qDebug("Playlist::addCurrentFile");
    1162         if (!core->mdat.filename.isEmpty()) {
    1163                 addItem( core->mdat.filename, "", 0 );
    1164                 getMediaInfo();
    1165         }
     1359        emit requestToAddCurrentFile();
    11661360}
    11671361
     
    11801374        qDebug("Playlist::addFiles");
    11811375
    1182 #if USE_INFOPROVIDER
     1376        #if USE_INFOPROVIDER
    11831377        bool get_info = (auto_get_info == GetInfo);
    11841378        if (auto_get_info == UserDefined) {
     
    11881382        MediaData data;
    11891383        setCursor(Qt::WaitCursor);
    1190 #endif
     1384        #endif
    11911385
    11921386        QString initial_file;
    1193         if (pl.count() == 1) initial_file = pl[0].filename();
     1387        if (count() == 1) initial_file = itemData(0)->filename();
    11941388        int new_current_item = -1;
    11951389
     
    11971391                QString name = "";
    11981392                double duration = 0;
    1199 #if USE_INFOPROVIDER
     1393                #if USE_INFOPROVIDER
    12001394                if ( (get_info) && (QFile::exists(files[n])) ) {
    12011395                        data = InfoProvider::getInfo(files[n]);
    12021396                        name = data.displayName();
    12031397                        duration = data.duration;
    1204                         //updateView();
    12051398                        //qApp->processEvents();
    12061399                }
    1207 #endif
     1400                #endif
    12081401
    12091402                //qDebug() << "Playlist::addFiles: comparing:" << initial_file << "with" << files[n];
    12101403
    12111404                if (!initial_file.isEmpty() && files[n] == initial_file) {
    1212                         PlaylistItem first_item = pl.takeFirst();
    1213                         name = first_item.name();
    1214                         duration = first_item.duration();
     1405                        PLItem * first_item = itemData(0);
     1406                        name = first_item->name();
     1407                        duration = first_item->duration();
     1408                        table->removeRow(0);
    12151409                        new_current_item = n;
    12161410                }
     
    12211415                }
    12221416        }
    1223 #if USE_INFOPROVIDER
     1417        #if USE_INFOPROVIDER
    12241418        unsetCursor();
    1225 #endif
     1419        #endif
    12261420
    12271421        if (new_current_item != -1) setCurrentItem(new_current_item);
    1228         updateView();
    1229 
    1230         qDebug( "Playlist::addFiles: latest_dir: '%s'", latest_dir.toUtf8().constData() );
     1422
     1423        qDebug() << "Playlist::addFiles: latest_dir:" << latest_dir;
    12311424}
    12321425
     
    12531446                        if (!u.isEmpty()) addItem( u, "", 0 );
    12541447                }
    1255                 updateView();
    12561448        }
    12571449}
     
    12671459
    12681460        QString filename;
    1269     QStringList::Iterator it = dir_list.begin();
    1270     while( it != dir_list.end() ) {
     1461        QStringList::Iterator it = dir_list.begin();
     1462        while( it != dir_list.end() ) {
    12711463                filename = dir;
    12721464                if (filename.right(1)!="/") filename += "/";
     
    13011493        qDebug("Playlist::removeSelected");
    13021494
    1303         int first_selected = -1;
    1304         int number_previous_item = 0;
    1305 
    1306         for (int n=0; n < listView->rowCount(); n++) {
    1307                 if (listView->isSelected(n, 0)) {
    1308                         qDebug(" row %d selected", n);
    1309                         pl[n].setMarkForDeletion(true);
    1310                         number_previous_item++;
    1311                         if (first_selected == -1) first_selected = n;
    1312                 }
    1313         }
    1314 
    1315         PlaylistItemList::iterator it;
    1316         for ( it = pl.begin(); it != pl.end(); ++it ) {
    1317                 if ( (*it).markedForDeletion() ) {
    1318                         qDebug("Remove '%s'", (*it).filename().toUtf8().data());
    1319                         it = pl.erase(it);
    1320                         it--;
    1321                         setModified( true );
    1322                 }
    1323         }
    1324 
    1325 
    1326     if (first_selected < current_item) {
    1327         current_item -= number_previous_item;
    1328     }
     1495        QModelIndexList indexes = listView->selectionModel()->selectedRows();
     1496        int count = indexes.count();
     1497
     1498        for (int n = count; n > 0; n--) {
     1499                QModelIndex s_index = proxy->mapToSource(indexes.at(n-1));
     1500                table->removeRow(s_index.row());
     1501                setModified(true);
     1502        }
    13291503
    13301504        if (isEmpty()) setModified(false);
    1331         updateView();
    1332 
    1333         if (first_selected >= listView->rowCount())
    1334                 first_selected = listView->rowCount() - 1;
    1335 
    1336         if ( ( first_selected > -1) && ( first_selected < listView->rowCount() ) ) {
    1337                 listView->clearSelection();
    1338                 listView->setCurrentCell( first_selected, 0);
    1339                 //listView->selectRow( first_selected );
     1505
     1506        if (findCurrentItem() == -1) {
     1507                int current = indexes.at(0).row() - 1;
     1508                if (current < 0) current = 0;
     1509                setCurrentItem(current);
    13401510        }
    13411511}
    13421512
    13431513void Playlist::removeAll() {
    1344         /*
    1345         pl.clear();
    1346         updateView();
    1347         setModified( false );
    1348         */
    13491514        clear();
    13501515}
    13511516
    13521517void Playlist::clearPlayedTag() {
    1353         for (int n = 0; n < pl.count(); n++) {
    1354                 pl[n].setPlayed(false);
    1355         }
    1356         updateView();
     1518        for (int n = 0; n < count(); n++) {
     1519                itemData(n)->setPlayed(false);
     1520        }
    13571521}
    13581522
     
    13601524        qDebug( "Playlist::chooseRandomItem");
    13611525
    1362         QList <int> fi; //List of not played items (free items)
    1363         for (int n = 0; n < pl.count(); n++) {
    1364                 if (!pl[n].played()) fi.append(n);
     1526        QList<int> fi; //List of not played items (free items)
     1527        for (int n = 0; n < proxy->rowCount(); n++) {
     1528                if (!itemFromProxy(n)->played()) fi.append(n);
    13651529        }
    13661530
     
    13741538        }
    13751539
    1376         int selected = (int) ((double) fi.count() * rand()/(RAND_MAX+1.0));
     1540        int selected = (qrand() % fi.count());
    13771541        qDebug("Playlist::chooseRandomItem: selected item: %d (%d)", selected, fi[selected]);
    13781542        return fi[selected];
    13791543}
    13801544
    1381 void Playlist::swapItems(int item1, int item2 ) {
    1382         PlaylistItem it1 = pl[item1];
    1383         pl[item1] = pl[item2];
    1384         pl[item2] = it1;
    1385         setModified( true );
    1386 }
    1387 
    1388 
    13891545void Playlist::upItem() {
    1390         qDebug("Playlist::upItem");
    1391 
    1392         int current = listView->currentRow();
    1393         qDebug(" currentRow: %d", current );
    1394 
    1395         moveItemUp(current);
    1396 
     1546        QModelIndex index = listView->currentIndex();
     1547        QModelIndex s_index = proxy->mapToSource(index);
     1548
     1549        QModelIndex prev = listView->model()->index(index.row()-1, 0);
     1550        QModelIndex s_prev = proxy->mapToSource(prev);
     1551
     1552        qDebug() << "Playlist::upItem: row:" << index.row() << "source row:" << s_index.row();
     1553        qDebug() << "Playlist::upItem: previous row:" << prev.row() << "previous source row:" << s_prev.row();
     1554
     1555        if (s_index.isValid() && s_prev.isValid()) {
     1556                int row = s_index.row();
     1557                int prev_row = s_prev.row();
     1558
     1559                int pos_num_current = itemData(row)->position();
     1560                int pos_num_prev = itemData(prev_row)->position();
     1561
     1562                qDebug() << "Playlist::upItem: pos_num_current:" << pos_num_current << "pos_num_prev:" << pos_num_prev;
     1563
     1564                itemData(row)->setPosition(pos_num_prev);
     1565                itemData(prev_row)->setPosition(pos_num_current);
     1566
     1567                QList<QStandardItem*> cells = table->takeRow(row);
     1568                table->insertRow(s_prev.row(), cells);
     1569                listView->selectionModel()->setCurrentIndex(listView->model()->index(index.row()-1, 0), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
     1570        }
    13971571}
    13981572
     
    14001574        qDebug("Playlist::downItem");
    14011575
    1402         int current = listView->currentRow();
    1403         qDebug(" currentRow: %d", current );
    1404 
    1405         moveItemDown(current);
    1406 }
    1407 
    1408 void Playlist::moveItemUp(int current){
    1409         qDebug("Playlist::moveItemUp");
    1410 
    1411         if (current >= 1) {
    1412                 swapItems( current, current-1 );
    1413                 if (current_item == (current-1)) current_item = current;
    1414                 else
    1415                 if (current_item == current) current_item = current-1;
    1416                 updateView();
    1417                 listView->clearSelection();
    1418                 listView->setCurrentCell( current-1, 0);
    1419         }
    1420 }
    1421 void Playlist::moveItemDown(int current ){
    1422         qDebug("Playlist::moveItemDown");
    1423 
    1424         if ( (current > -1) && (current < (pl.count()-1)) ) {
    1425                 swapItems( current, current+1 );
    1426                 if (current_item == (current+1)) current_item = current;
    1427                 else
    1428                 if (current_item == current) current_item = current+1;
    1429                 updateView();
    1430                 listView->clearSelection();
    1431                 listView->setCurrentCell( current+1, 0);
     1576        QModelIndex index = listView->currentIndex();
     1577        QModelIndex s_index = proxy->mapToSource(index);
     1578
     1579        QModelIndex next = listView->model()->index(index.row()+1, 0);
     1580        QModelIndex s_next = proxy->mapToSource(next);
     1581
     1582        qDebug() << "Playlist::downItem: row:" << index.row() << "source row:" << s_index.row();
     1583        qDebug() << "Playlist::downItem: next row:" << next.row() << "next source row:" << s_next.row();
     1584
     1585        if (s_index.isValid() && s_next.isValid()) {
     1586                int row = s_index.row();
     1587                int next_row = s_next.row();
     1588
     1589                int pos_num_current = itemData(row)->position();
     1590                int pos_num_next = itemData(next_row)->position();
     1591
     1592                qDebug() << "Playlist::downItem: pos_num_current:" << pos_num_current << "pos_num_next:" << pos_num_next;
     1593
     1594                itemData(row)->setPosition(pos_num_next);
     1595                itemData(next_row)->setPosition(pos_num_current);
     1596
     1597                QList<QStandardItem*> cells = table->takeRow(row);
     1598                table->insertRow(s_next.row(), cells);
     1599                listView->selectionModel()->setCurrentIndex(listView->model()->index(index.row()+1, 0), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
    14321600        }
    14331601}
    14341602
    14351603void Playlist::editCurrentItem() {
    1436         int current = listView->currentRow();
     1604        QModelIndex v_index = listView->currentIndex();
     1605        QModelIndex s_index = proxy->mapToSource(v_index);
     1606        qDebug() << "Playlist::editCurrentItem: row:" << v_index.row() << "source row:" << s_index.row();
     1607        int current = s_index.row();
    14371608        if (current > -1) editItem(current);
    14381609}
    14391610
    1440 void Playlist::editItem(int item) {
    1441         QString current_name = pl[item].name();
    1442         if (current_name.isEmpty()) current_name = pl[item].filename();
     1611void Playlist::editItem(int row) {
     1612        qDebug() << "Playlist::editItem:" << row;
     1613
     1614        PLItem * i = itemData(row);
     1615        QString current_name = i->name();
     1616        if (current_name.isEmpty()) current_name = i->filename();
    14431617
    14441618        bool ok;
    14451619        QString text = QInputDialog::getText( this,
    1446             tr("Edit name"), 
    1447             tr("Type the name that will be displayed in the playlist for this file:"), 
     1620            tr("Edit name"),
     1621            tr("Type the name that will be displayed in the playlist for this file:"),
    14481622            QLineEdit::Normal,
    14491623            current_name, &ok );
    14501624    if ( ok && !text.isEmpty() ) {
    1451         // user entered something and pressed OK
    1452                 pl[item].setName(text);
     1625                // user entered something and pressed OK
     1626                i->setName(text);
    14531627
    14541628                // If duration == 0 the name will be overwritten!
    1455                 if (pl[item].duration()<1) pl[item].setDuration(1);
    1456                 updateView();
     1629                if (i->duration() < 1) i->setDuration(1);
    14571630
    14581631                setModified( true );
    1459     }
     1632        }
    14601633}
    14611634
     
    14631636        qDebug("Playlist::deleteSelectedFileFromDisk");
    14641637
    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));
     1638        QModelIndex index = listView->currentIndex();
     1639        if (!index.isValid()) return;
     1640
     1641        QModelIndex s_index = proxy->mapToSource(index);
     1642
     1643        qDebug() << "Playlist::deleteSelectedFileFromDisk: row:" << index.row() << "source row:" << s_index.row();
     1644        int current = s_index.row();
     1645
     1646        // Select only the current row
     1647        listView->selectionModel()->setCurrentIndex(listView->model()->index(index.row(), 0), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
     1648
     1649        QString filename = itemData(current)->filename();
     1650        qDebug() << "Playlist::deleteSelectedFileFromDisk: current file:" << filename;
     1651
     1652        QFileInfo fi(filename);
     1653        if (fi.exists() && fi.isFile() && fi.isWritable()) {
     1654                // Ask the user for confirmation
     1655                int res = QMessageBox::question(this, tr("Confirm deletion"),
     1656                                        tr("You're about to DELETE the file '%1' from your drive.").arg(filename) + "<br>"+
     1657                                        tr("This action cannot be undone. Are you sure you want to proceed?"),
     1658                                        QMessageBox::Yes, QMessageBox::No);
     1659
     1660                if (res == QMessageBox::Yes) {
     1661                        // Delete file
     1662                        #if SIMULATE_FILE_DELETION
     1663                        bool success = true;
     1664                        #else
     1665                        bool success = QFile::remove(filename);
     1666                        #endif
     1667
     1668                        if (success) {
     1669                                // Remove item from the playlist
     1670                                table->removeRow(current);
     1671                                if (findCurrentItem() == -1) {
     1672                                        if (current > 0) setCurrentItem(current-1); else setCurrentItem(0);
    14931673                                }
    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                 }
     1674                        } else {
     1675                                QMessageBox::warning(this, tr("Deletion failed"),
     1676                                        tr("It wasn't possible to delete '%1'").arg(filename));
     1677                        }
     1678                }
     1679        } else {
     1680                qDebug("Playlist::deleteSelectedFileFromDisk: file doesn't exists, it's not a file or it's not writable");
     1681                QMessageBox::information(this, tr("Error deleting the file"),
     1682                        tr("It's not possible to delete '%1' from the filesystem.").arg(filename));
    15001683        }
    15011684}
     
    15891772        qDebug("Playlist::saveSettings");
    15901773
    1591         QSettings * set = settings;
    1592 
    1593         set->beginGroup( "directories");
    1594         bool save_dirs = set->value("save_dirs", false).toBool();
    1595         set->endGroup();
     1774        if (!set) return;
    15961775
    15971776        set->beginGroup( "playlist");
     
    16061785        set->setValue( "automatically_play_next", automatically_play_next );
    16071786        set->setValue( "ignore_player_errors", ignore_player_errors );
     1787        set->setValue( "change_name", change_name );
    16081788
    16091789        set->setValue( "row_spacing", row_spacing );
     
    16121792        set->setValue( "size", size() );
    16131793#endif
    1614         if (save_dirs) {
    1615                 set->setValue( "latest_dir", latest_dir );
    1616         } else {
    1617                 set->setValue( "latest_dir", "" );
    1618         }
    1619 
     1794        set->setValue(QString("header_state/%1").arg(Helper::qtVersion()), listView->horizontalHeader()->saveState());
     1795
     1796        set->setValue( "sort_column", proxy->sortColumn() );
     1797        set->setValue( "sort_order", proxy->sortOrder() );
     1798        set->setValue( "filter_case_sensivity", proxy->filterCaseSensitivity() );
     1799        set->setValue( "filter", filter_edit->text() );
     1800        set->setValue( "sort_case_sensivity", proxy->sortCaseSensitivity() );
     1801
     1802        set->endGroup();
     1803
     1804        set->beginGroup( "directories");
     1805        set->setValue("save_dirs", save_dirs);
     1806        set->setValue("latest_dir", save_dirs ? latest_dir : "" );
    16201807        set->endGroup();
    16211808
    16221809        if (save_playlist_in_config) {
    16231810                //Save current list
    1624                 set->beginGroup( "playlist_contents");
    1625 
    1626                 set->setValue( "count", (int) pl.count() );
    1627                 for ( int n=0; n < pl.count(); n++ ) {
    1628                         set->setValue( QString("item_%1_filename").arg(n), pl[n].filename() );
    1629                         set->setValue( QString("item_%1_duration").arg(n), pl[n].duration() );
    1630                         set->setValue( QString("item_%1_name").arg(n), pl[n].name() );
    1631                 }
    1632                 set->setValue( "current_item", current_item );
     1811                set->beginGroup("playlist_contents");
     1812                set->beginWriteArray("items");
     1813                //set->setValue( "count", count() );
     1814                for (int n = 0; n < count(); n++ ) {
     1815                        set->setArrayIndex(n);
     1816                        PLItem * i = itemData(n);
     1817                        set->setValue( QString("item_%1_filename").arg(n), i->filename() );
     1818                        set->setValue( QString("item_%1_duration").arg(n), i->duration() );
     1819                        set->setValue( QString("item_%1_name").arg(n), i->name() );
     1820                }
     1821                set->endArray();
     1822                set->setValue( "current_item", findCurrentItem() );
    16331823                set->setValue( "modified", modified );
    16341824
    16351825                set->endGroup();
    16361826        }
     1827
     1828#ifdef PLAYLIST_DOWNLOAD
     1829        set->beginGroup("history");
     1830        set->setValue("max_items", history_urls->maxItems());
     1831        set->setValue("urls", history_urls->toStringList());
     1832        set->endGroup();
     1833#endif
     1834
     1835        if (set->contains("playlist/change_title")) set->remove("playlist/change_title");
    16371836}
    16381837
     
    16401839        qDebug("Playlist::loadSettings");
    16411840
    1642         QSettings * set = settings;
     1841        if (!set) return;
    16431842
    16441843        set->beginGroup( "playlist");
     
    16531852        automatically_play_next = set->value( "automatically_play_next", automatically_play_next ).toBool();
    16541853        ignore_player_errors = set->value( "ignore_player_errors", ignore_player_errors ).toBool();
     1854        change_name = set->value( "change_name", change_name ).toBool();
    16551855
    16561856        row_spacing = set->value( "row_spacing", row_spacing ).toInt();
     
    16591859        resize( set->value("size", size()).toSize() );
    16601860#endif
    1661 
    1662         latest_dir = set->value( "latest_dir", latest_dir ).toString();
    1663 
     1861        listView->horizontalHeader()->restoreState(set->value(QString("header_state/%1").arg(Helper::qtVersion()), QByteArray()).toByteArray());
     1862
     1863        int sort_column = set->value("sort_column", COL_NUM).toInt();
     1864        int sort_order = set->value("sort_order", Qt::AscendingOrder).toInt();
     1865        int filter_case_sensivity = set->value("filter_case_sensivity", Qt::CaseInsensitive).toInt();
     1866        QString filter = set->value( "filter").toString();
     1867        int sort_case_sensivity = set->value("sort_case_sensivity", Qt::CaseInsensitive).toInt();
     1868
     1869        set->endGroup();
     1870
     1871        set->beginGroup( "directories");
     1872        save_dirs = set->value("save_dirs", save_dirs).toBool();
     1873        if (save_dirs) {
     1874                latest_dir = set->value("latest_dir", latest_dir).toString();
     1875        }
    16641876        set->endGroup();
    16651877
    16661878        if (save_playlist_in_config) {
    16671879                //Load latest list
    1668                 set->beginGroup( "playlist_contents");
    1669 
    1670                 int count = set->value( "count", 0 ).toInt();
     1880                set->beginGroup("playlist_contents");
     1881                int count = set->beginReadArray("items");
     1882
    16711883                QString filename, name;
    16721884                double duration;
    1673                 for ( int n=0; n < count; n++ ) {
     1885                for (int n = 0; n < count; n++) {
     1886                        set->setArrayIndex(n);
    16741887                        filename = set->value( QString("item_%1_filename").arg(n), "" ).toString();
    16751888                        duration = set->value( QString("item_%1_duration").arg(n), -1 ).toDouble();
     
    16771890                        addItem( filename, name, duration );
    16781891                }
     1892                set->endArray();
    16791893                setCurrentItem( set->value( "current_item", -1 ).toInt() );
    16801894                setModified( set->value( "modified", false ).toBool() );
    1681                 updateView();
    16821895
    16831896                set->endGroup();
    1684         }
     1897                //listView->resizeColumnsToContents();
     1898        }
     1899
     1900#ifdef PLAYLIST_DOWNLOAD
     1901        set->beginGroup("history");
     1902        history_urls->setMaxItems(set->value("max_items", 50).toInt());
     1903        history_urls->fromStringList( set->value("urls", history_urls->toStringList()).toStringList() );
     1904        set->endGroup();
     1905#endif
     1906
     1907        proxy->setFilterCaseSensitivity( (Qt::CaseSensitivity) filter_case_sensivity);
     1908        proxy->setSortCaseSensitivity( (Qt::CaseSensitivity) sort_case_sensivity);
     1909        proxy->sort(sort_column, (Qt::SortOrder) sort_order);
     1910        filter_edit->setText(filter);
    16851911}
    16861912
    16871913QString Playlist::lastDir() {
    16881914        QString last_dir = latest_dir;
    1689         if (last_dir.isEmpty()) last_dir = pref->latest_dir;
    16901915        return last_dir;
    16911916}
     1917
     1918#ifdef PLAYLIST_DOWNLOAD
     1919void Playlist::openUrl() {
     1920        qDebug("Playlist::openUrl");
     1921
     1922        InputURL d(this);
     1923
     1924        // Get url from clipboard
     1925        QString clipboard_text = QApplication::clipboard()->text();
     1926        if (!clipboard_text.isEmpty() && clipboard_text.contains("://")) {
     1927                d.setURL(clipboard_text);
     1928        }
     1929
     1930        for (int n = 0; n < history_urls->count(); n++) {
     1931                d.setURL(history_urls->url(n));
     1932        }
     1933
     1934        if (d.exec() == QDialog::Accepted ) {
     1935                QString url = d.url();
     1936                if (!url.isEmpty()) {
     1937                        history_urls->addUrl(url);
     1938                        openUrl(url);
     1939                }
     1940        }
     1941}
     1942
     1943void Playlist::openUrl(const QString & url) {
     1944        qDebug() << "Playlist::openUrl:" << url;
     1945        downloader->fetchPage(url);
     1946
     1947        showLoadingAnimation(true);
     1948}
     1949
     1950void Playlist::playlistDownloaded(QByteArray data) {
     1951        qDebug("Playlist::playlistDownloaded");
     1952        // Save to a temporary file
     1953        QTemporaryFile tf;
     1954        tf.open();
     1955        tf.write(data);
     1956        tf.close();
     1957        QString tfile = tf.fileName();
     1958        qDebug() << "Playlist::playlistDownloaded: tfile:" << tfile;
     1959
     1960        if (data.contains("#EXTM3U")) {
     1961                load_m3u(tfile, M3U8);
     1962        }
     1963        else
     1964        if (data.contains("[playlist]")) {
     1965                load_pls(tfile);
     1966        }
     1967        else
     1968        if (data.contains("xspf.org")) {
     1969                loadXSPF(tfile);
     1970        }
     1971        else {
     1972                QMessageBox::warning(this, "SMPlayer", tr("It's not possible to load this playlist") +": "+ tr("Unrecognized format."));
     1973        }
     1974
     1975        showLoadingAnimation(false);
     1976}
     1977
     1978void Playlist::errorOcurred(int error_number, QString error_str) {
     1979        showLoadingAnimation(false);
     1980
     1981        qDebug() << "Playlist::errorOcurred:" << error_number << ":" << error_str;
     1982        QMessageBox::warning(this, "SMPlayer", error_str);
     1983}
     1984
     1985void Playlist::showLoadingAnimation(bool b) {
     1986        if (b) animation->start(); else animation->stop();
     1987        loading_label_action->setVisible(b);
     1988}
     1989
     1990void Playlist::setMaxItemsUrlHistory(int max_items) {
     1991        history_urls->setMaxItems(max_items);
     1992}
     1993
     1994int Playlist::maxItemsUrlHistory() {
     1995        return history_urls->maxItems();
     1996}
     1997#endif
    16921998
    16931999// Language change stuff
Note: See TracChangeset for help on using the changeset viewer.