Changeset 181 for smplayer/trunk/src/playlist.cpp
- Timestamp:
- Aug 31, 2016, 5:31:04 PM (9 years ago)
- Location:
- smplayer/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
smplayer/trunk
- Property svn:mergeinfo changed
/smplayer/vendor/current merged: 179
- Property svn:mergeinfo changed
-
smplayer/trunk/src/playlist.cpp
r176 r181 19 19 #include "playlist.h" 20 20 21 #include <QTableView> 22 #include <QStandardItemModel> 23 #include <QSortFilterProxyModel> 24 #include <QStyledItemDelegate> 21 25 #include <QToolBar> 22 26 #include <QFile> … … 26 30 #include <QMessageBox> 27 31 #include <QPushButton> 28 #include <QRegExp>29 32 #include <QMenu> 30 33 #include <QDateTime> … … 44 47 #include <QDebug> 45 48 46 #include "mytablewidget.h" 49 #if QT_VERSION >= 0x050000 50 #include "myscroller.h" 51 #endif 52 47 53 #include "myaction.h" 54 #include "mylineedit.h" 48 55 #include "filedialog.h" 49 56 #include "helper.h" … … 52 59 #include "multilineinputdialog.h" 53 60 #include "version.h" 54 #include "global.h"55 #include "core.h"56 61 #include "extensions.h" 57 62 #include "guiconfig.h" 58 63 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 60 73 61 74 #if USE_INFOPROVIDER … … 65 78 #define DRAG_ITEMS 0 66 79 #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 69 84 #define COL_NAME 1 70 85 #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 89 class PlaylistDelegate : public QStyledItemDelegate { 90 public: 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 114 PLItem::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 126 PLItem::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 140 PLItem::~PLItem() { 141 } 142 143 void 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 160 void PLItem::setName(const QString name) { 161 setText(name); 162 setData(name); 163 setToolTip(name); 164 } 165 166 void PLItem::setDuration(double duration) { 167 col_duration->setData(duration); 168 col_duration->setText(Helper::formatTime(duration)); 169 } 170 171 void 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 180 void 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 186 void 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 196 QString PLItem::filename() { 197 return col_filename->data().toString(); 198 } 199 200 QString PLItem::name() { 201 return text(); 202 } 203 204 double PLItem::duration() { 205 return col_duration->data().toDouble(); 206 } 207 208 bool PLItem::played() { 209 return data(Role_Played).toBool(); 210 } 211 212 int PLItem::position() { 213 return col_num->data().toInt(); 214 } 215 216 bool PLItem::isCurrent() { 217 return data(Role_Current).toBool(); 218 } 219 220 QList<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 230 Playlist::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) 77 243 { 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 = ""; 93 246 94 247 createTable(); … … 96 249 createToolbar(); 97 250 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 103 251 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 106 257 setLayout(layout); 107 258 108 259 clear(); 109 260 110 261 retranslateStrings(); … … 123 274 124 275 // 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(); 135 280 136 281 // Save config every 5 minutes. 137 282 save_timer = new QTimer(this); 138 283 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 140 295 } 141 296 142 297 Playlist::~Playlist() { 143 298 saveSettings(); 144 } 299 if (set) delete set; 300 301 #ifdef PLAYLIST_DOWNLOAD 302 delete history_urls; 303 #endif 304 } 305 306 void 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 145 322 146 323 void Playlist::setModified(bool mod) { … … 152 329 153 330 void 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 155 353 listView->setObjectName("playlist_table"); 156 354 listView->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); … … 159 357 listView->setContextMenuPolicy( Qt::CustomContextMenu ); 160 358 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(); 163 366 164 367 #if QT_VERSION >= 0x050000 368 MyScroller::setScroller(listView->viewport()); 369 165 370 listView->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); 166 listView->horizontalHeader()->setSectionResizeMode(COL_NAME, QHeaderView::Stretch);371 // listView->horizontalHeader()->setSectionResizeMode(COL_NAME, QHeaderView::Stretch); 167 372 #else 168 373 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 171 379 /* 172 380 listView->horizontalHeader()->setResizeMode(COL_TIME, QHeaderView::ResizeToContents); 173 381 listView->horizontalHeader()->setResizeMode(COL_PLAY, QHeaderView::ResizeToContents); 174 382 */ 175 listView->setIconSize( Images::icon("ok").size() );383 //listView->setIconSize( Images::icon("ok").size() ); 176 384 177 385 #if DRAG_ITEMS … … 183 391 #endif 184 392 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 &)) ); 191 395 } 192 396 … … 195 399 connect( openAct, SIGNAL(triggered()), this, SLOT(load()) ); 196 400 401 #ifdef PLAYLIST_DOWNLOAD 402 openUrlAct = new MyAction(this, "pl_open_url", false); 403 connect( openUrlAct, SIGNAL(triggered()), this, SLOT(openUrl()) ); 404 #endif 405 197 406 saveAct = new MyAction(this, "pl_save", false); 198 407 connect( saveAct, SIGNAL(triggered()), this, SLOT(save()) ); … … 250 459 toolbar = new QToolBar(this); 251 460 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 252 467 253 468 toolbar->addAction(openAct); 469 #ifdef PLAYLIST_DOWNLOAD 470 toolbar->addAction(openUrlAct); 471 #endif 254 472 toolbar->addAction(saveAct);; 255 473 toolbar->addSeparator(); … … 273 491 remove_button->setPopupMode(QToolButton::InstantPopup); 274 492 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 275 503 toolbar->addWidget(add_button); 276 504 toolbar->addWidget(remove_button); … … 278 506 toolbar->addSeparator(); 279 507 toolbar->addAction(playAct); 280 toolbar->addSeparator();281 508 toolbar->addAction(prevAct); 282 509 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 283 521 toolbar->addSeparator(); 284 522 toolbar->addAction(repeatAct); … … 287 525 toolbar->addAction(moveUpAct); 288 526 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 289 537 290 538 // Popup menu … … 300 548 301 549 void Playlist::retranslateStrings() { 302 listView->setHorizontalHeaderLabels( QStringList() << " " << 303 tr("Name") << tr("Length") ); 550 table->setHorizontalHeaderLabels(QStringList() << " " << tr("Name") << tr("Length") << tr("Filename / URL") ); 304 551 305 552 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 306 557 saveAct->change( Images::icon("save"), tr("&Save") ); 307 558 … … 342 593 remove_button->setToolTip( tr("Remove...") ); 343 594 595 // Filter edit 596 #if QT_VERSION >= 0x040700 597 filter_edit->setPlaceholderText(tr("Search")); 598 #endif 599 344 600 // Icon 345 601 setWindowIcon( Images::icon("logo", 64) ); … … 350 606 qDebug("Playlist::list"); 351 607 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 614 void Playlist::setFilter(const QString & filter) { 615 proxy->setFilterWildcard(filter); 616 } 617 618 void Playlist::filterEditChanged(const QString & text) { 619 qDebug() << "Playlist::filterEditChanged:" << text; 620 setFilter(text); 407 621 } 408 622 409 623 void 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 644 int 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; 432 664 } 433 665 434 666 void Playlist::clear() { 435 pl.clear(); 436 437 listView->clearContents(); 438 listView->setRowCount(0); 439 667 table->setRowCount(0); 440 668 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); 453 670 } 454 671 455 672 int Playlist::count() { 456 return pl.count();673 return table->rowCount(); 457 674 } 458 675 459 676 bool Playlist::isEmpty() { 460 return pl.isEmpty(); 461 } 677 return (table->rowCount() > 0); 678 } 679 680 bool Playlist::existsItem(int row) { 681 return (row > -1 && row < table->rowCount()); 682 } 683 684 PLItem * Playlist::itemData(int row) { 685 QStandardItem * i = table->item(row, COL_NAME); 686 return static_cast<PLItem*>(i); 687 } 688 689 PLItem * 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 /* 701 void 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 */ 462 714 463 715 void Playlist::addItem(QString filename, QString name, double duration) { 464 qDebug("Playlist::addItem: '%s'", filename.toUtf8().data());716 //qDebug() << "Playlist::addItem:" << filename; 465 717 466 718 #if defined(Q_OS_WIN) || defined(Q_OS_OS2) … … 468 720 #endif 469 721 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 /* 470 741 #if !PL_ALLOW_DUPLICATES 471 742 // Test if already is in the list … … 506 777 } 507 778 #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 783 void 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; 605 792 606 793 QRegExp m3u_id("^#EXTM3U|^#M3U"); … … 634 821 } 635 822 else 823 /* 636 824 if (info.indexIn(line)!=-1) { 637 825 duration = info.cap(1).toDouble(); … … 639 827 qDebug("Playlist::load_m3u: name: '%s', duration: %f", name.toUtf8().data(), duration ); 640 828 } 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 } 641 836 else 642 837 if (line.startsWith("#")) { … … 660 855 } 661 856 f.close(); 662 list(); 663 updateView(); 857 //list(); 664 858 665 859 setModified( false ); … … 710 904 set.endGroup(); 711 905 712 list(); 713 updateView(); 906 //list(); 714 907 715 908 setModified( false ); … … 754 947 } 755 948 756 list(); 757 updateView(); 949 //list(); 758 950 setModified( false ); 759 951 startPlay(); … … 762 954 763 955 bool Playlist::save_m3u(QString file) { 764 qDebug( "Playlist::save_m3u: '%s'", file.toUtf8().data());956 qDebug() << "Playlist::save_m3u:" << file; 765 957 766 958 QString dir_path = QFileInfo(file).path(); … … 771 963 #endif 772 964 773 qDebug( " * dirPath: '%s'", dir_path.toUtf8().data());965 qDebug() << "Playlist::save_m3u: dir_path:" << dir_path; 774 966 775 967 bool utf8 = (QFileInfo(file).suffix().toLower() == "m3u8"); 776 968 777 969 QFile f( file ); 778 779 780 781 if (utf8) 970 if ( f.open( QIODevice::WriteOnly ) ) { 971 QTextStream stream( &f ); 972 973 if (utf8) 782 974 stream.setCodec("UTF-8"); 783 975 else … … 789 981 stream << "# Playlist created by SMPlayer " << Version::printable() << " \n"; 790 982 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(); 794 986 #if defined(Q_OS_WIN) || defined(Q_OS_OS2) 795 987 filename = Helper::changeSlashes(filename); 796 988 #endif 797 989 stream << "#EXTINF:"; 798 stream << (*it).duration() << ",";799 stream << (*it).name() << "\n";990 stream << i->duration() << ","; 991 stream << i->name() << "\n"; 800 992 // Try to save the filename as relative instead of absolute 801 993 if (filename.startsWith( dir_path )) { … … 804 996 stream << filename << "\n"; 805 997 } 806 998 f.close(); 807 999 808 1000 setModified( false ); 809 1001 return true; 810 1002 } else { 811 1003 return false; 812 1004 } … … 815 1007 816 1008 bool Playlist::save_pls(QString file) { 817 qDebug( "Playlist::save_pls: '%s'", file.toUtf8().data());1009 qDebug() << "Playlist::save_pls:" << file; 818 1010 819 1011 QString dir_path = QFileInfo(file).path(); … … 824 1016 #endif 825 1017 826 qDebug( " * dirPath: '%s'", dir_path.toUtf8().data());1018 qDebug() << "Playlist::save_pls: dir_path:" << dir_path; 827 1019 828 1020 QSettings set(file, QSettings::IniFormat); 829 1021 set.beginGroup( "playlist"); 830 1022 831 1023 QString filename; 832 1024 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(); 836 1028 #if defined(Q_OS_WIN) || defined(Q_OS_OS2) 837 1029 filename = Helper::changeSlashes(filename); … … 844 1036 845 1037 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()); 851 1043 set.setValue("Version", 2); 852 1044 … … 873 1065 stream << "\t<trackList>\n"; 874 1066 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(); 877 1070 qDebug() << "Playlist::saveXSPF:" << location; 878 1071 879 1072 bool is_local = QFile::exists(location); 880 1073 … … 898 1091 } 899 1092 900 QString title = pl[n].name();901 int duration = pl[n].duration() * 1000;1093 QString title = i->name(); 1094 int duration = i->duration() * 1000; 902 1095 903 1096 #if QT_VERSION >= 0x050000 … … 949 1142 load_m3u(s); 950 1143 } 1144 //listView->resizeColumnsToContents(); 951 1145 } 952 1146 } … … 1014 1208 1015 1209 void Playlist::playCurrent() { 1016 int current = listView->current Row();1210 int current = listView->currentIndex().row(); 1017 1211 if (current > -1) { 1018 1212 playItem(current); … … 1020 1214 } 1021 1215 1022 void Playlist::item DoubleClicked(int row) {1023 qDebug( "Playlist::itemDoubleClicked: row: %d", row);1024 playItem( row);1216 void Playlist::itemActivated(const QModelIndex & index ) { 1217 qDebug() << "Playlist::itemActivated: row:" << index.row(); 1218 playItem(index.row()); 1025 1219 } 1026 1220 … … 1043 1237 1044 1238 void Playlist::playItem( int n ) { 1045 qDebug("Playlist::playItem: %d (count: %d)", n, pl.count());1046 1047 if ( (n >= p l.count()) || (n < 0) ) {1239 qDebug("Playlist::playItem: %d (count: %d)", n, proxy->rowCount()); 1240 1241 if ( (n >= proxy->rowCount()) || (n < 0) ) { 1048 1242 qDebug("Playlist::playItem: out of range"); 1049 1243 emit playlistEnded(); … … 1051 1245 } 1052 1246 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(); 1058 1248 if (!filename.isEmpty()) { 1059 //pl[n].setPlayed(true);1060 1249 setCurrentItem(n); 1061 if (play_files_from_start) 1062 core->open(filename, 0);1063 else1064 core->open(filename);1065 }1066 1250 if (play_files_from_start) { 1251 emit requestToPlayFile(filename, 0); 1252 } else { 1253 emit requestToPlayFile(filename); 1254 } 1255 } 1067 1256 } 1068 1257 … … 1081 1270 } 1082 1271 } 1083 playItem( chosen_item);1272 playItem(chosen_item); 1084 1273 } else { 1085 bool finished_list = (current_item+1 >= pl.count()); 1274 int current = findCurrentItem(); 1275 bool finished_list = (current + 1 >= proxy->rowCount()); 1086 1276 if (finished_list) clearPlayedTag(); 1087 1277 1088 if ( (repeatAct->isChecked()) && (finished_list)) {1278 if (repeatAct->isChecked() && finished_list) { 1089 1279 playItem(0); 1090 1280 } else { 1091 playItem( current_item+1);1281 playItem(current + 1); 1092 1282 } 1093 1283 } … … 1096 1286 void Playlist::playPrev() { 1097 1287 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); 1100 1291 } else { 1101 if (p l.count() > 1) playItem( pl.count() -1);1292 if (proxy->rowCount() > 1) playItem(proxy->rowCount() - 1); 1102 1293 } 1103 1294 } … … 1105 1296 1106 1297 void 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 1307 void Playlist::getMediaInfo(const MediaData & mdat) { 1114 1308 qDebug("Playlist::getMediaInfo"); 1115 1309 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; 1122 1313 1123 1314 #if defined(Q_OS_WIN) || defined(Q_OS_OS2) … … 1125 1316 #endif 1126 1317 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) { 1141 1339 // 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); 1145 1344 } 1146 pl[n].setDuration(duration);1345 i->setDuration(duration); 1147 1346 } 1148 1347 else 1149 1348 // 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 } 1157 1354 } 1158 1355 … … 1160 1357 void Playlist::addCurrentFile() { 1161 1358 qDebug("Playlist::addCurrentFile"); 1162 if (!core->mdat.filename.isEmpty()) { 1163 addItem( core->mdat.filename, "", 0 ); 1164 getMediaInfo(); 1165 } 1359 emit requestToAddCurrentFile(); 1166 1360 } 1167 1361 … … 1180 1374 qDebug("Playlist::addFiles"); 1181 1375 1182 #if USE_INFOPROVIDER1376 #if USE_INFOPROVIDER 1183 1377 bool get_info = (auto_get_info == GetInfo); 1184 1378 if (auto_get_info == UserDefined) { … … 1188 1382 MediaData data; 1189 1383 setCursor(Qt::WaitCursor); 1190 #endif1384 #endif 1191 1385 1192 1386 QString initial_file; 1193 if ( pl.count() == 1) initial_file = pl[0].filename();1387 if (count() == 1) initial_file = itemData(0)->filename(); 1194 1388 int new_current_item = -1; 1195 1389 … … 1197 1391 QString name = ""; 1198 1392 double duration = 0; 1199 #if USE_INFOPROVIDER1393 #if USE_INFOPROVIDER 1200 1394 if ( (get_info) && (QFile::exists(files[n])) ) { 1201 1395 data = InfoProvider::getInfo(files[n]); 1202 1396 name = data.displayName(); 1203 1397 duration = data.duration; 1204 //updateView();1205 1398 //qApp->processEvents(); 1206 1399 } 1207 #endif1400 #endif 1208 1401 1209 1402 //qDebug() << "Playlist::addFiles: comparing:" << initial_file << "with" << files[n]; 1210 1403 1211 1404 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); 1215 1409 new_current_item = n; 1216 1410 } … … 1221 1415 } 1222 1416 } 1223 #if USE_INFOPROVIDER1417 #if USE_INFOPROVIDER 1224 1418 unsetCursor(); 1225 #endif1419 #endif 1226 1420 1227 1421 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; 1231 1424 } 1232 1425 … … 1253 1446 if (!u.isEmpty()) addItem( u, "", 0 ); 1254 1447 } 1255 updateView();1256 1448 } 1257 1449 } … … 1267 1459 1268 1460 QString filename; 1269 1270 1461 QStringList::Iterator it = dir_list.begin(); 1462 while( it != dir_list.end() ) { 1271 1463 filename = dir; 1272 1464 if (filename.right(1)!="/") filename += "/"; … … 1301 1493 qDebug("Playlist::removeSelected"); 1302 1494 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 } 1329 1503 1330 1504 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); 1340 1510 } 1341 1511 } 1342 1512 1343 1513 void Playlist::removeAll() { 1344 /*1345 pl.clear();1346 updateView();1347 setModified( false );1348 */1349 1514 clear(); 1350 1515 } 1351 1516 1352 1517 void 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 } 1357 1521 } 1358 1522 … … 1360 1524 qDebug( "Playlist::chooseRandomItem"); 1361 1525 1362 QList 1363 for (int n = 0; n < p l.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); 1365 1529 } 1366 1530 … … 1374 1538 } 1375 1539 1376 int selected = ( int) ((double) fi.count() * rand()/(RAND_MAX+1.0));1540 int selected = (qrand() % fi.count()); 1377 1541 qDebug("Playlist::chooseRandomItem: selected item: %d (%d)", selected, fi[selected]); 1378 1542 return fi[selected]; 1379 1543 } 1380 1544 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 1389 1545 void 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 } 1397 1571 } 1398 1572 … … 1400 1574 qDebug("Playlist::downItem"); 1401 1575 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); 1432 1600 } 1433 1601 } 1434 1602 1435 1603 void 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(); 1437 1608 if (current > -1) editItem(current); 1438 1609 } 1439 1610 1440 void Playlist::editItem(int item) { 1441 QString current_name = pl[item].name(); 1442 if (current_name.isEmpty()) current_name = pl[item].filename(); 1611 void 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(); 1443 1617 1444 1618 bool ok; 1445 1619 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:"), 1448 1622 QLineEdit::Normal, 1449 1623 current_name, &ok ); 1450 1624 if ( ok && !text.isEmpty() ) { 1451 1452 pl[item].setName(text);1625 // user entered something and pressed OK 1626 i->setName(text); 1453 1627 1454 1628 // 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); 1457 1630 1458 1631 setModified( true ); 1459 } 1632 } 1460 1633 } 1461 1634 … … 1463 1636 qDebug("Playlist::deleteSelectedFileFromDisk"); 1464 1637 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); 1493 1673 } 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)); 1500 1683 } 1501 1684 } … … 1589 1772 qDebug("Playlist::saveSettings"); 1590 1773 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; 1596 1775 1597 1776 set->beginGroup( "playlist"); … … 1606 1785 set->setValue( "automatically_play_next", automatically_play_next ); 1607 1786 set->setValue( "ignore_player_errors", ignore_player_errors ); 1787 set->setValue( "change_name", change_name ); 1608 1788 1609 1789 set->setValue( "row_spacing", row_spacing ); … … 1612 1792 set->setValue( "size", size() ); 1613 1793 #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 : "" ); 1620 1807 set->endGroup(); 1621 1808 1622 1809 if (save_playlist_in_config) { 1623 1810 //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() ); 1633 1823 set->setValue( "modified", modified ); 1634 1824 1635 1825 set->endGroup(); 1636 1826 } 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"); 1637 1836 } 1638 1837 … … 1640 1839 qDebug("Playlist::loadSettings"); 1641 1840 1642 QSettings * set = settings;1841 if (!set) return; 1643 1842 1644 1843 set->beginGroup( "playlist"); … … 1653 1852 automatically_play_next = set->value( "automatically_play_next", automatically_play_next ).toBool(); 1654 1853 ignore_player_errors = set->value( "ignore_player_errors", ignore_player_errors ).toBool(); 1854 change_name = set->value( "change_name", change_name ).toBool(); 1655 1855 1656 1856 row_spacing = set->value( "row_spacing", row_spacing ).toInt(); … … 1659 1859 resize( set->value("size", size()).toSize() ); 1660 1860 #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 } 1664 1876 set->endGroup(); 1665 1877 1666 1878 if (save_playlist_in_config) { 1667 1879 //Load latest list 1668 set->beginGroup( 1669 1670 int count = set->value( "count", 0 ).toInt(); 1880 set->beginGroup("playlist_contents"); 1881 int count = set->beginReadArray("items"); 1882 1671 1883 QString filename, name; 1672 1884 double duration; 1673 for ( int n=0; n < count; n++ ) { 1885 for (int n = 0; n < count; n++) { 1886 set->setArrayIndex(n); 1674 1887 filename = set->value( QString("item_%1_filename").arg(n), "" ).toString(); 1675 1888 duration = set->value( QString("item_%1_duration").arg(n), -1 ).toDouble(); … … 1677 1890 addItem( filename, name, duration ); 1678 1891 } 1892 set->endArray(); 1679 1893 setCurrentItem( set->value( "current_item", -1 ).toInt() ); 1680 1894 setModified( set->value( "modified", false ).toBool() ); 1681 updateView();1682 1895 1683 1896 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); 1685 1911 } 1686 1912 1687 1913 QString Playlist::lastDir() { 1688 1914 QString last_dir = latest_dir; 1689 if (last_dir.isEmpty()) last_dir = pref->latest_dir;1690 1915 return last_dir; 1691 1916 } 1917 1918 #ifdef PLAYLIST_DOWNLOAD 1919 void 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 1943 void Playlist::openUrl(const QString & url) { 1944 qDebug() << "Playlist::openUrl:" << url; 1945 downloader->fetchPage(url); 1946 1947 showLoadingAnimation(true); 1948 } 1949 1950 void 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 1978 void 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 1985 void Playlist::showLoadingAnimation(bool b) { 1986 if (b) animation->start(); else animation->stop(); 1987 loading_label_action->setVisible(b); 1988 } 1989 1990 void Playlist::setMaxItemsUrlHistory(int max_items) { 1991 history_urls->setMaxItems(max_items); 1992 } 1993 1994 int Playlist::maxItemsUrlHistory() { 1995 return history_urls->maxItems(); 1996 } 1997 #endif 1692 1998 1693 1999 // Language change stuff
Note:
See TracChangeset
for help on using the changeset viewer.