/*************************************************************************** * Copyright (C) 2006 by Ilya Kotov * * forkotov02@hotmail.ru * * * * 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. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include "dock.h" #include "fileloader.h" #include "playlist.h" #include "skin.h" #include "listwidget.h" #include "button.h" #include "playlistitem.h" #include "playlistmodel.h" #include "playlisttitlebar.h" #include "playlistslider.h" #include "pixmapwidget.h" #include "symboldisplay.h" #include "playlistcontrol.h" #include "keyboardmanager.h" #include PlayList::PlayList ( QWidget *parent ) : QWidget ( parent ) { setWindowFlags ( Qt::Dialog | Qt::FramelessWindowHint ); m_update = FALSE; m_resize = FALSE; m_anchor_row = -1; createMenus(); resize ( 275,116 ); setMinimumSize ( 275,116 ); setBaseSize ( 275,116 ); m_listWidget = new ListWidget ( this ); m_listWidget->show(); m_listWidget->setGeometry ( 12,20,243,58 ); m_plslider = new PlayListSlider ( this ); m_plslider->show(); setSizeIncrement ( 25,29 ); m_skin = Skin::getPointer(); m_buttonAdd = new Button ( this,Skin::PL_BT_ADD,Skin::PL_BT_ADD ); m_buttonAdd->move ( 11,86 ); m_buttonSub = new Button ( this,Skin::PL_BT_SUB,Skin::PL_BT_SUB ); m_buttonSub->move ( 40,86 ); m_selectButton = new Button ( this,Skin::PL_BT_SEL,Skin::PL_BT_SEL ); m_selectButton->move ( 70,86 ); m_sortButton= new Button ( this,Skin::PL_BT_SORT,Skin::PL_BT_SORT ); m_sortButton->move ( 99,86 ); m_playlistButton = new Button ( this,Skin::PL_BT_LST,Skin::PL_BT_LST ); m_pl_control = new PlaylistControl ( this ); m_pl_control->move ( 0,0 ); m_pl_control->show(); m_length_totalLength = new SymbolDisplay ( this,14 ); m_length_totalLength->setAlignment ( Qt::AlignLeft ); m_length_totalLength -> show(); m_current_time = new SymbolDisplay ( this,6 ); m_current_time->show(); m_keyboardManager = new KeyboardManager ( this ); connect ( m_listWidget, SIGNAL ( selectionChanged() ), parent, SLOT ( replay() ) ); connect ( m_plslider, SIGNAL ( sliderMoved ( int ) ), m_listWidget, SLOT ( scroll ( int ) ) ); connect ( m_listWidget, SIGNAL ( positionChanged ( int, int ) ), m_plslider, SLOT ( setPos ( int, int ) ) ); connect ( m_skin, SIGNAL ( skinChanged() ), this, SLOT ( update() ) ); connect ( m_buttonAdd, SIGNAL ( clicked() ), SLOT ( showAddMenu() ) ); connect ( m_buttonSub, SIGNAL ( clicked() ), SLOT ( showSubMenu() ) ); connect ( m_selectButton, SIGNAL ( clicked() ), SLOT ( showSelectMenu() ) ); connect ( m_sortButton, SIGNAL ( clicked() ), SLOT ( showSortMenu() ) ); connect ( m_playlistButton, SIGNAL ( clicked() ), SLOT ( showPlaylistMenu() ) ); connect ( m_pl_control, SIGNAL ( nextClicked() ), SIGNAL ( next() ) ); connect ( m_pl_control, SIGNAL ( previousClicked() ), SIGNAL ( prev() ) ); connect ( m_pl_control, SIGNAL ( playClicked() ), SIGNAL ( play() ) ); connect ( m_pl_control, SIGNAL ( pauseClicked() ), SIGNAL ( pause() ) ); connect ( m_pl_control, SIGNAL ( stopClicked() ), SIGNAL ( stop() ) ); connect ( m_pl_control, SIGNAL ( ejectClicked() ), SIGNAL ( eject() ) ); m_titleBar = new PlayListTitleBar ( this ); m_titleBar->move ( 0,0 ); readSettings(); } PlayList::~PlayList() {} void PlayList::createMenus() { m_addMenu = new QMenu ( this ); m_subMenu = new QMenu ( this ); m_selectMenu = new QMenu ( this ); m_sortMenu = new QMenu ( this ); m_playlistMenu = new QMenu ( this ); } void PlayList::createActions() { //add menu QAction *addFileAct = new QAction ( tr ( "&Add File" ),this ); addFileAct->setShortcut ( tr ( "F" ) ); m_addMenu->addAction ( addFileAct ); connect ( addFileAct, SIGNAL ( triggered() ), parent(), SLOT ( addFile () ) ); m_actions << addFileAct; QAction *addDirAct = new QAction ( tr ( "&Add Directory" ),this ); addDirAct->setShortcut ( tr ( "D" ) ); m_addMenu->addAction ( addDirAct ); connect ( addDirAct, SIGNAL ( triggered() ), parent(), SLOT ( addDir () ) ); m_actions << addDirAct; QAction *addUrlAct = new QAction ( tr ( "&Add Url" ),this ); addUrlAct->setShortcut ( tr ( "U" ) ); m_addMenu->addAction ( addUrlAct ); connect ( addUrlAct, SIGNAL ( triggered() ), parent(), SLOT ( addUrl () ) ); m_actions << addUrlAct; //remove menu QAction *remSelAct = new QAction ( tr ( "&Remove Selected" ),this ); remSelAct->setShortcut ( tr ( "Del" ) ); m_subMenu->addAction ( remSelAct ); connect ( remSelAct, SIGNAL ( triggered() ), m_playListModel, SLOT ( removeSelected () ) ); this->addAction ( remSelAct ); QAction *remAllAct = new QAction ( tr ( "&Remove All" ),this ); //remAllAct->setShortcut(tr("D")); FIXME: add correct shortcat m_subMenu->addAction ( remAllAct ); connect ( remAllAct, SIGNAL ( triggered() ), m_playListModel, SLOT ( clear () ) ); m_actions << remAllAct; QAction *remUnselAct = new QAction ( tr ( "&Remove Unselected" ),this ); m_subMenu->addAction ( remUnselAct ); connect ( remUnselAct, SIGNAL ( triggered() ), m_playListModel, SLOT ( removeUnselected () ) ); //listwidget menu QAction *detailsAct = new QAction ( tr ( "&View Track Details" ),this ); detailsAct->setShortcut ( tr ( "Alt+I" ) ); m_listWidget->menu()->addAction ( detailsAct ); connect ( detailsAct, SIGNAL ( triggered() ), m_playListModel, SLOT ( showDetails () ) ); // sort menu m_sortMenu->addAction ( detailsAct ); m_sortMenu->addSeparator(); QMenu* sort_mode_menu = new QMenu ( tr ( "Sort List" ),m_sortMenu ); QSignalMapper* signalMapper = new QSignalMapper ( this ); QAction* titleAct = sort_mode_menu->addAction ( tr ( "By Title" ) ); connect ( titleAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); signalMapper->setMapping ( titleAct, PlayListModel::TITLE ); QAction* nameAct = sort_mode_menu->addAction ( tr ( "By Filename" ) ); connect ( nameAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); signalMapper->setMapping ( nameAct, PlayListModel::FILENAME ); QAction* pathnameAct = sort_mode_menu->addAction ( tr ( "By Path + Filename" ) ); connect ( pathnameAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); signalMapper->setMapping ( pathnameAct, PlayListModel::PATH_AND_FILENAME ); QAction* dateAct = sort_mode_menu->addAction ( tr ( "By Date" ) ); connect ( dateAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); signalMapper->setMapping ( dateAct, PlayListModel::DATE ); QAction* trackAct = sort_mode_menu->addAction ( tr ( "By Track Number" ) ); connect ( trackAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); signalMapper->setMapping ( trackAct, PlayListModel::TRACK ); connect ( signalMapper, SIGNAL ( mapped ( int ) ), m_playListModel, SLOT ( sort ( int ) ) ); m_sortMenu->addMenu ( sort_mode_menu ); sort_mode_menu = new QMenu ( tr ( "Sort Selection" ),m_sortMenu ); signalMapper = new QSignalMapper ( this ); titleAct = sort_mode_menu->addAction ( tr ( "By Title" ) ); connect ( titleAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); signalMapper->setMapping ( titleAct, PlayListModel::TITLE ); nameAct = sort_mode_menu->addAction ( tr ( "By Filename" ) ); connect ( nameAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); signalMapper->setMapping ( nameAct, PlayListModel::FILENAME ); pathnameAct = sort_mode_menu->addAction ( tr ( "By Path + Filename" ) ); connect ( pathnameAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); signalMapper->setMapping ( pathnameAct, PlayListModel::PATH_AND_FILENAME ); dateAct = sort_mode_menu->addAction ( tr ( "By Date" ) ); connect ( dateAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); signalMapper->setMapping ( dateAct, PlayListModel::DATE ); trackAct = sort_mode_menu->addAction ( tr ( "By Track Number" ) ); connect ( trackAct, SIGNAL ( triggered ( bool ) ), signalMapper, SLOT ( map() ) ); signalMapper->setMapping ( trackAct, PlayListModel::TRACK ); connect ( signalMapper, SIGNAL ( mapped ( int ) ), m_playListModel, SLOT ( sortSelection ( int ) ) ); m_sortMenu->addMenu ( sort_mode_menu ); m_sortMenu->addSeparator(); m_sortMenu->addAction ( tr ( "Randomize List" ),m_playListModel,SLOT ( randomizeList() ) ); m_sortMenu->addAction ( tr ( "Reverse List" ),m_playListModel,SLOT ( reverseList() ) ); m_listWidget->menu()->addSeparator(); m_listWidget->menu()->addActions (m_subMenu->actions()); m_listWidget->menu()->addSeparator(); m_listWidget->menu()->addAction(tr("&Queue"),m_playListModel, SLOT(addToQueue()), tr("Q")); m_actions << m_listWidget->menu()->actions(); //select menu QAction *invSelAct = new QAction ( tr ( "Invert Selection" ),this ); m_selectMenu->addAction ( invSelAct ); connect ( invSelAct, SIGNAL ( triggered() ), m_playListModel, SLOT ( invertSelection () ) ); m_selectMenu->addSeparator(); QAction *selNoneAct = new QAction ( tr ( "&Select None" ),this ); //selNoneAct->setShortcut(tr("Ctrl+Shift+A")); m_selectMenu->addAction ( selNoneAct ); connect ( selNoneAct, SIGNAL ( triggered() ), m_playListModel, SLOT ( clearSelection () ) ); this->addAction ( selNoneAct ); QAction *selAllAct = new QAction ( tr ( "&Select All" ),this ); selAllAct->setShortcut ( tr ( "Ctrl+A" ) ); m_selectMenu->addAction ( selAllAct ); connect ( selAllAct, SIGNAL ( triggered() ), m_playListModel, SLOT ( selectAll () ) ); this->addAction ( selAllAct ); // Playlist Menu QAction *newListAct = new QAction ( tr ( "&New List" ),this ); newListAct->setShortcut ( tr ( "Shift+N" ) ); m_actions << newListAct; m_playlistMenu->addAction ( newListAct ); connect ( newListAct, SIGNAL ( triggered() ), this, SIGNAL ( newPlaylist() ) ); m_playlistMenu->addSeparator(); QAction *loadListAct = new QAction ( tr ( "&Load List" ),this ); loadListAct->setShortcut ( tr ( "O" ) ); m_playlistMenu->addAction ( loadListAct ); connect ( loadListAct, SIGNAL ( triggered() ), this, SIGNAL ( loadPlaylist() ) ); QAction *saveListAct = new QAction ( tr ( "&Save List" ),this ); saveListAct->setShortcut ( tr ( "Shift+S" ) ); m_playlistMenu->addAction ( saveListAct ); connect ( saveListAct, SIGNAL ( triggered() ), this, SIGNAL ( savePlaylist() ) ); this->addActions ( m_playlistMenu->actions() ); Dock::getPointer()->addActions ( m_actions ); } void PlayList::closeEvent (QCloseEvent *e) { if(e->spontaneous ()) emit closed(); writeSettings(); } void PlayList::paintEvent ( QPaintEvent * ) { int m_sx = ( width()-275 ) /25; int m_sy = ( height()-116 ) /29; drawPixmap ( m_sx, m_sy ); } void PlayList::drawPixmap ( int sx, int sy ) { QPainter paint; paint.begin ( this ); paint.drawPixmap ( 0,20,m_skin->getPlPart ( Skin::PL_LFILL ) ); for ( int i = 1; igetPlPart ( Skin::PL_LFILL ) ); } paint.drawPixmap ( 0,78+29*sy,m_skin->getPlPart ( Skin::PL_LSBAR ) ); for ( int i = 0; igetPlPart ( Skin::PL_SFILL1 ) ); } paint.drawPixmap ( 125+sx*25,78+sy*29,m_skin->getPlPart ( Skin::PL_RSBAR ) ); paint.end(); } void PlayList::resizeEvent ( QResizeEvent *e ) { int sx = ( e->size().width()-275 ) /25; int sy = ( e->size().height()-116 ) /29; if (sx < 0 || sy < 0) return; m_titleBar->resize ( 275+25*sx,20 ); m_plslider->resize ( 20,58+sy*29 ); m_listWidget->resize ( 243+25*sx,58+29*sy ); m_buttonAdd->move ( 11,86+29*sy ); m_buttonSub->move ( 40,86+29*sy ); m_selectButton->move ( 70,86+29*sy ); m_sortButton->move ( 99,86+29*sy ); m_pl_control->move ( 128+sx*25,100+29*sy ); m_playlistButton->move ( 228+sx*25,86+29*sy ); m_length_totalLength -> move ( 131+sx*25,88+29*sy ); m_current_time->move ( 190+sx*25,101+29*sy ); m_plslider->move ( 255+sx*25,20 ); } void PlayList::mousePressEvent ( QMouseEvent *e ) { m_pos = e->pos (); if ( ( m_pos.x() > width()-25 ) && ( m_pos.y() > height()-25 ) ) { m_resize = TRUE; setCursor ( Qt::SizeFDiagCursor ); } else m_resize = FALSE; } void PlayList::mouseMoveEvent ( QMouseEvent *e ) { if ( m_resize ) { resize ( e->x() +25, e->y() +25 ); //usleep(32000); } } void PlayList::mouseReleaseEvent ( QMouseEvent * ) { setCursor ( Qt::ArrowCursor ); /*if (m_resize) m_listWidget->updateList();*/ m_resize = FALSE; Dock::getPointer()->updateDock(); } void PlayList::setModel ( PlayListModel *model ) { m_playListModel = model; m_listWidget->setModel (model); m_keyboardManager->setModel (model); m_titleBar->setModel (model); createActions(); } void PlayList::changeEvent ( QEvent * event ) { if ( event->type() == QEvent::ActivationChange ) { m_titleBar->setActive ( isActiveWindow() ); } } void PlayList::readSettings() { if ( m_update ) { m_listWidget->readSettings(); m_titleBar->readSettings(); } else { QSettings settings (QDir::homePath() +"/.qmmp/qmmprc", QSettings::IniFormat); settings.beginGroup ( "PlayList" ); //position move ( settings.value ("pos", QPoint ( 100, 332 ) ).toPoint()); settings.endGroup(); m_update = TRUE; } } void PlayList::writeSettings() { QSettings settings ( QDir::homePath() +"/.qmmp/qmmprc", QSettings::IniFormat ); settings.beginGroup ( "PlayList" ); //position settings.setValue ( "pos", this->pos() ); settings.endGroup(); } void PlayList::showAddMenu() { m_addMenu->exec ( m_buttonAdd->mapToGlobal ( QPoint ( 0,0 ) ) ); } void PlayList::showSubMenu() { m_subMenu->exec ( m_buttonSub->mapToGlobal ( QPoint ( 0,0 ) ) ); } void PlayList::showSelectMenu() { m_selectMenu->exec ( m_selectButton->mapToGlobal ( QPoint ( 0,0 ) ) ); } void PlayList::showSortMenu() { m_sortMenu->exec ( m_sortButton->mapToGlobal ( QPoint ( 0,0 ) ) ); } QString PlayList::formatTime ( int sec ) { int minutes = sec / 60; int seconds = sec % 60; QString str_minutes = QString::number ( minutes ); QString str_seconds = QString::number ( seconds ); if ( minutes < 10 ) str_minutes.prepend ( "0" ); if ( seconds < 10 ) str_seconds.prepend ( "0" ); return str_minutes + ":" + str_seconds; } void PlayList::setInfo (const OutputState &st,int length_current, int length_total) { if (st.type() == OutputState::Info) { m_current_time->display ( formatTime ( st.elapsedSeconds() ) ); m_current_time->update(); QString str_length = formatTime ( length_current ) + "/" + formatTime ( length_total ); m_length_totalLength->display ( str_length ); m_length_totalLength->update(); } else if (st.type() == OutputState::Playing) { m_listWidget->updateList(); //removes progress message from TextScroller } } PlayListItem *PlayList::currentItem() { if ( m_playListModel ) return m_playListModel->currentItem(); else return 0; } void PlayList::showPlaylistMenu() { m_playlistMenu->exec ( m_playlistButton->mapToGlobal ( QPoint ( 0,0 ) ) ); } void PlayList::keyPressEvent ( QKeyEvent *ke ) { if ( m_keyboardManager->handleKeyPress ( ke ) ) update(); }