⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qmplaylist.cpp

📁 可以播放MP3,wma等文件格式的播放器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/* qmplaylist.cpp * * $Id: qmplaylist.cpp,v 1.106.2.3 2002/10/11 06:39:03 kyllingstad Exp $ * * Apollo sound player: http://www.apolloplayer.org * Copyright(C) 2000-2002 Apollo Team.  See CREDITS file. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. * * The GNU General Public License is also available online at: * * http://www.gnu.org/copyleft/gpl.html */#include "qmplaylist.h"#include "message.h"#include "qmconfig.h"#include "qmdiritem.h"#include "qmplaylistformat.h"#include "qmpropertydialog.h"#include "qmsonginfopropertypage.h"#include "qmsongitem.h"#include "util.h"#include "qcstring.h"#include <algorithm>#include <iostream>#include <time.h>#include <cassert>#include <qdom.h>#include <qfile.h>#include <qfiledialog.h>#include <qfileinfo.h>#include <qmessagebox.h>#include <qstringlist.h>#include <qtextstream.h>int QmPlayList::s_PlayListCounter = 0;/* Disables false warning in Visual Studio about dynamic_cast */#ifdef _WS_WIN_#pragma warning(disable: 4541)#endif/*!  \file qmplaylist.cpp  \brief The playlist widget.  Duh. *//*!  \class QmPlayList qmplaylist.h  \brief Represents the playlist.  This widget is the playlist in Apollo.  It provides functionality  for loading and saving the playlist, as well as traversing and modifying  it.  In order to understand the class, a few definitions need to be pointed  out:  <ul>  <li> Selected - An item that is selected is drawn with a filled background.  Any number of items can be selected, including none.  Notice that if a folder  is selected, all its children are implicitly selected too.  This is not shown  visually.  See selectedItems() for more information. </li>  <li> Current - The text of the current item, if any, is drawn in a  different color than the other items.  The current item represents the  playing item, or the item that is paused or will be played if `Play' is  clicked. If there's no songs to be played, there won't be current  item. </li>  <li> Bad - Any number of items can be marked as bad.  A bad item cannot  be played expect for one case: A playing item can be marked as bad while  being played.  Playing will not stop. </li> </ul>  Some methods, such as nextSong, and prevSong, are not const because there  is no const QListView iterator.*//*! \fn void QmPlayList::disableNext()  Emitted when there's no songs below the current item, this allows  clients of this class to disable the next button.*//*! \fn void QmPlayList::enableNext()  Emitted when there are one or more songs below the current item, this allows  clients of this class to enable the next button.*//*! \fn void QmPlayList::disablePrev()  Emitted when there's no songs above the current item, this allows  clients of this class to disable the previous button.*//*! \fn void QmPlayList::enablePrev()  Emitted when there's one or more songs above the current item, this allows  clients of this class to disable the previous button.*//*!  Constructs a playlist widget.*/// It is necessary to keep a 'play item' variable (see above) so we can// remove its playing status when another item is selected.// currentItem() cannot be used as it will already be updated with// the new song.QmPlayList::QmPlayList(    QWidget *parent,    const char *name)    : QmListView(parent, name),      m_Dirty(false),      m_SongIndex(),      m_SongIndexDirty(true),	  m_DeletingItems(false),      m_PlayLength(0),      m_PlayLengthNotCounted(0),	  m_pCurrentSong(0),      m_Filename(""),	  m_pSongInfoPage(0),	  m_pPropertyDlg(0){	setMultiSelection(true);	setSelectionMode(Extended);	setAcceptDrops(true);	setDragAutoScroll(true);    setMinimumWidth(m_LengthWidth);    setHScrollBarMode(AlwaysOff);	reorganizable(true);    m_pMenu = new QPopupMenu(this);	connect(this, SIGNAL(mouseButtonClicked(int, QListViewItem*, const QPoint &, int)),			this, SLOT(mouseClick(int, QListViewItem*, const QPoint &, int)));	connect(this, SIGNAL(selectionChanged()),			this, SLOT(newSelection()));	connect(&m_Delay, SIGNAL(timeout()),            this, SLOT(newSelectionHandler()));}/*! */QmPlayList::~QmPlayList(){}/*!  Initialize the popup menu */voidQmPlayList::initMenu(){    m_ContinueHereId = m_pMenu->insertItem(        tr("Continue Here"),        this,        SLOT(continueHere()));    m_PlayFirstId = m_pMenu->insertItem(        tr("Play First (mid click)"),        QmMainWindow::mainwin,        SLOT(addToPlayFirst()));    m_FlattenId = m_pMenu->insertItem(        tr("Flatten"),        this,        SLOT(flatten()));     m_ReGroupId = m_pMenu->insertItem(         tr("Regroup"),         this,         SLOT(reGroup()));	m_pMenu->insertSeparator();    m_pMenu->insertItem(        tr("Expand First"),        this,        SLOT(expandFirstLevel()));    m_pMenu->insertItem(        tr("Expand All"),        this,        SLOT(expandAll()));    m_pMenu->insertItem(        tr("Collapse All"),        this,        SLOT(collapseAll()));	m_pMenu->insertSeparator();    m_pMenu->insertItem(        tr("Update song info for all songs"),        this,        SLOT(readSongInfo()));    m_GenerateId = m_pMenu->insertItem(        tr("Generate a playlist for each artist"),        this,        SLOT(generatePlayListForEachArtistAndAlbum(int)));    m_pMenu->setItemParameter(m_GenerateId, 0);        m_GenerateTreeId = m_pMenu->insertItem(        tr("Generate a playlist for each artist - and playlist tree"),        this,        SLOT(generatePlayListForEachArtistAndAlbum(int)));    m_pMenu->setItemParameter(m_GenerateTreeId, 1);	m_pMenu->insertItem(        "Clear",        this,        SLOT(clear()));	m_pMenu->insertSeparator();	m_pMenu->insertItem(        tr("Properties..."),        this,        SLOT(showItemProperties()));}/*!  Adds the playlist \a filename to the list.  The placement of the inserted  playlist is related to \a reference.  If \a reference is null, \a filename  will be appended if \a below is true or prepended if \a below is false.  If \a reference is not null, \a filename will be placed below \a reference  if \a below is true or above if \a below is false.  \return True if successful, false otherwise. */boolQmPlayList::add(	const QString & /*filename*/,	QListViewItem * /*reference*/,	bool /*below*/){	// This function will be used for drag'n drop but is more general than	// the current add() and is therefore meant to replace that one.    	return false;}/*!  \returns the total play length of the list in seconds.*/longQmPlayList::playLength() {	updateSongIndex();    return m_PlayLength;}/*!  \returns the number of songs in the list with unknown length.  Songs  that haven't been played yet and doesn't have the lenght info in the  playlist.  (Consider adding a "stat all songs" option in the menu.) */intQmPlayList::playLengthNotCounted() {	updateSongIndex();    return m_PlayLengthNotCounted;}/*!  \returns number of songs in the playlist.*/int QmPlayList::noSongs() {	updateSongIndex();    return m_SongIndex.size();}/*!  Increases the global counter.  The counter is used for sorting the songs  in the playlist.  \return The previous counter value, i.e. before it was increased.*/intQmPlayList::count(){    return s_PlayListCounter++;}/*!  Wraps around to the beginning if \param wrap is true.  \return The first non-bad song following the current song, or 0.  \sa prevSong(bool)*/QmSongItem*QmPlayList::nextSong(bool wrap) {	updateSongIndex();	if (m_SongIndex.empty())		return 0;		SongIndexIterator current = m_pCurrentSong ? std::find(m_SongIndex.begin(), m_SongIndex.end(), m_pCurrentSong) : m_SongIndex.begin();	if (current == m_SongIndex.end())		current = m_SongIndex.begin();	if (*current == m_SongIndex.back())		return wrap ? m_SongIndex.front() : 0;	++current;	return *current;}/*!  Wraps around to the end if \param wrap is true.  \return The first non-bad song preceding the current song, or 0.  \sa nextSong(bool)*/QmSongItem*QmPlayList::prevSong(bool wrap) {	updateSongIndex();	if (m_SongIndex.empty())		return 0;		SongIndexIterator current = m_pCurrentSong ? std::find(m_SongIndex.begin(), m_SongIndex.end(), m_pCurrentSong) : m_SongIndex.begin();	if (current == m_SongIndex.end())		current = m_SongIndex.begin();	if (*current == m_SongIndex.front())		return wrap ? m_SongIndex.back() : 0;	--current;	return *current;}/*!  Wraps around to the beginning if \param wrap is true.  \return The first non-bad song following the current song, or 0.  \sa prevSong(QmSongItem*, bool)*/QmSongItem*QmPlayList::nextSong(	QmSongItem *curSong,	bool wrap) {    if (isEmpty())		return 0;		SongIndexIterator current = m_pCurrentSong ? std::find(m_SongIndex.begin(), m_SongIndex.end(), curSong) : m_SongIndex.begin();	if (current == m_SongIndex.end())		current = m_SongIndex.begin();		if (*current == m_SongIndex.back())		return wrap ? m_SongIndex.front() : 0;	++current;	return *current;}/*!  Searches for a song with the given filepath.    \return the song if it's found, otherwize 0 */QmSongItem* QmPlayList::findSong(    const QString &filePath) {	updateSongIndex();	for (int i=m_SongIndex.size()-1; i>=0; --i)		if (filePath == m_SongIndex[i]->filePath()) 			return m_SongIndex[i];    return 0;}           /*!  Wraps around to the end if \param wrap is true.  \return The first non-bad song preceding the \param curSong song, or 0.  \sa nextSong(QmSongItem*, bool)*/QmSongItem*QmPlayList::prevSong(	QmSongItem *curSong,	bool wrap) {	updateSongIndex();	SongIndexIterator current = m_pCurrentSong ? std::find(m_SongIndex.begin(), m_SongIndex.end(), curSong) : m_SongIndex.begin();	if (current == m_SongIndex.end())		current = m_SongIndex.begin();	if (*current == m_SongIndex.front())		return wrap ? m_SongIndex.back() : 0;	--current;	return *current;}/*!  \return A random song.*/QmSongItem*QmPlayList::randomSong() {	updateSongIndex();    return m_SongIndex[static_cast<int>(m_SongIndex.size()*(double)rand()/RAND_MAX)];}/*!  If \a item is a non-bad song item, give it playing status and remove the playing  status from the song currently having it, if any.  If \a item is marked as  a bad song or is not a song, this function will do nothing.  This function also emits enableNext(), disableNext(), enablePrev() and  disablePrev() signals when appropriate.*/voidQmPlayList::setCurrent(	QmSongItem *song){    CHECK_PTR(song);	// rk: log this    if(song->isBad())        return;	if(m_pCurrentSong)		m_pCurrentSong->setPlaying(false);	// rk: disableNext() and enableNext() are currently not connected	updateSongIndex();		SongIndexIterator cur = std::find(m_SongIndex.begin(), m_SongIndex.end(), song);	assert(cur != m_SongIndex.end());	if (*cur == m_SongIndex.back() && !QmMainWindow::mainwin->loopMode())		emit disableNext();	else		emit enableNext();	if(cur == m_SongIndex.begin() && !QmMainWindow::mainwin->loopMode())		emit disablePrev();	else		emit enablePrev();		song->setPlaying(true);	m_pCurrentSong = song;    ensureItemVisible(song);}/*!  \return The current song, or 0 if there is no non-bad songs.  \todo I don't like this function.  The only reason for its existance is to save the  name of the playing item when quitting.*/QmSongItem*QmPlayList::currentSong() {	updateSongIndex();	if (m_pCurrentSong == 0)	{		if (m_SongIndex.empty())			return 0;		else			setCurrent(m_SongIndex.front());	}		return m_pCurrentSong;}/*!  \returns Song with index \a index, or playing song if \a index is -1 (default).  0 if no song playing or invalid index.*/QmSongItem*QmPlayList::song(    int index){	if (index == -1)		return m_pCurrentSong;		updateSongIndex();	return index >= static_cast<int>(m_SongIndex.size()) || index<0 ? 0 : m_SongIndex[index];}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -