/***************************************************************************
* Copyright (C) 2006-2021 by Ilya Kotov *
* forkotov02@ya.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., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include <QPainter>
#include <QResizeEvent>
#include <QSettings>
#include <QMenu>
#include <QAction>
#include <QCloseEvent>
#include <QInputDialog>
#include <QScreen>
#include <algorithm>
#include <qmmpui/playlistitem.h>
#include <qmmpui/playlistmodel.h>
#include <qmmpui/playlistmanager.h>
#include <qmmpui/uihelper.h>
#include <qmmpui/qmmpuisettings.h>
#include <qmmp/soundcore.h>
#include "dock.h"
#include "skin.h"
#include "listwidget.h"
#include "button.h"
#include "playlisttitlebar.h"
#include "playlistslider.h"
#include "pixmapwidget.h"
#include "symboldisplay.h"
#include "playlistcontrol.h"
#include "keyboardmanager.h"
#include "playlistbrowser.h"
#include "playlistselector.h"
#include "windowsystem.h"
#include "actionmanager.h"
#include "playlistheader.h"
#include "playlist.h"
PlayList::PlayList (PlayListManager *manager, QWidget *parent)
: QWidget (parent)
{
setAttribute(Qt::WA_AlwaysShowToolTips,true);
setWindowTitle(tr("Playlist"));
m_pl_manager = manager;
m_ui_settings = QmmpUiSettings::instance();
m_skin = Skin::instance();
m_ratio = m_skin->ratio();
#ifdef QMMP_WS_X11
QString wm_name = WindowSystem::netWindowManagerName();
m_compiz = wm_name.contains("compiz", Qt::CaseInsensitive);
if(wm_name.contains("openbox", Qt::CaseInsensitive) || wm_name.contains("xfwm4", Qt::CaseInsensitive))
setWindowFlags (Qt::Drawer | Qt::FramelessWindowHint);
else if(wm_name.contains("metacity", Qt::CaseInsensitive) ||
wm_name.contains("kwin", Qt::CaseInsensitive))
setWindowFlags (Qt::Tool | Qt::FramelessWindowHint);
else
#endif
setWindowFlags (Qt::Dialog | Qt::FramelessWindowHint);
#ifdef QMMP_WS_X11
if(m_compiz)
{
setFixedSize(275*m_ratio, 116*m_ratio);
}
else
#endif
{
resize (275*m_ratio, 116*m_ratio);
setSizeIncrement (25*m_ratio, 29*m_ratio);
setMinimumSize(275*m_ratio, 116*m_ratio);
}
m_listWidget = new ListWidget (this);
m_plslider = new PlayListSlider (this);
m_buttonAdd = new Button (this,Skin::PL_BT_ADD,Skin::PL_BT_ADD, Skin::CUR_PNORMAL);
m_buttonSub = new Button (this,Skin::PL_BT_SUB,Skin::PL_BT_SUB, Skin::CUR_PNORMAL);
m_selectButton = new Button (this,Skin::PL_BT_SEL,Skin::PL_BT_SEL, Skin::CUR_PNORMAL);
m_sortButton= new Button (this,Skin::PL_BT_SORT,Skin::PL_BT_SORT, Skin::CUR_PNORMAL);
m_playlistButton = new Button (this,Skin::PL_BT_LST,Skin::PL_BT_LST, Skin::CUR_PNORMAL);
m_resizeWidget = new QWidget(this);
m_resizeWidget->resize(25,25);
m_resizeWidget->setCursor(m_skin->getCursor (Skin::CUR_PSIZE));
m_pl_control = new PlaylistControl (this);
m_length_totalLength = new SymbolDisplay (this,17);
m_length_totalLength->setAlignment (Qt::AlignLeft);
m_current_time = new SymbolDisplay (this,6);
m_keyboardManager = new KeyboardManager (m_listWidget);
connect(m_listWidget, SIGNAL(doubleClicked()), parent, SLOT(replay()));
connect(m_plslider, SIGNAL(sliderMoved(int)), m_listWidget, SLOT(setViewPosition(int)));
connect(m_listWidget, SIGNAL(positionChanged(int, int)), m_plslider,
SLOT(setPos (int, int)));
connect(m_skin, SIGNAL(skinChanged()), SLOT(updateSkin()));
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()));
connect(m_pl_manager, SIGNAL(selectedPlayListChanged(PlayListModel *, PlayListModel *)),
m_listWidget, SLOT(setModel(PlayListModel*, PlayListModel*)));
m_listWidget->setModel(m_pl_manager->selectedPlayList());
createMenus();
createActions();
readSettings();
m_titleBar = new PlayListTitleBar (this);
m_titleBar->setMinimumSize(0,0);
m_titleBar->move(0,0);
connect(m_pl_manager, SIGNAL(currentPlayListChanged(PlayListModel *, PlayListModel *)),
SLOT(onCurrentPlayListChanged(PlayListModel*,PlayListModel*)));
connect(m_pl_manager->currentPlayList(), SIGNAL(listChanged(int)), SLOT(onListChanged(int)));
m_titleBar->setModel(m_pl_manager->currentPlayList());
setCursor(m_skin->getCursor(Skin::CUR_PNORMAL));
updatePositions();
setTime(-1);
}
PlayList::~PlayList()
{
delete m_keyboardManager;
}
void PlayList::updatePositions()
{
int sx = (width()-275*m_ratio)/25;
int sy = (height()-116*m_ratio)/29;
if(sx < 0 || sy < 0 || m_shaded) //skip shaded mode
return;
m_titleBar->resize (275*m_ratio+25*sx, 20*m_ratio);
m_plslider->resize (20*m_ratio, 58*m_ratio+sy*29);
int pl_x = 12*m_ratio;
int pl_y = 20*m_ratio;
int pl_w = 243*m_ratio+25*sx;
int pl_h = 58*m_ratio+29*sy;
if(m_pl_selector)
{
m_pl_selector->resize(243*m_ratio+25*sx, m_pl_selector->height());
m_pl_selector->move(12*m_ratio, 20*m_ratio + 58*m_ratio+29*sy - m_pl_selector->height());
pl_h -= m_pl_selector->height();
}
m_listWidget->resize (pl_w, pl_h);
m_listWidget->move (pl_x, pl_y);
m_buttonAdd->move (11*m_ratio, 86*m_ratio+29*sy);
m_buttonSub->move (40*m_ratio, 86*m_ratio+29*sy);
m_selectButton->move (70*m_ratio, 86*m_ratio+29*sy);
m_sortButton->move (99*m_ratio, 86*m_ratio+29*sy);
m_pl_control->move (128*m_ratio+sx*25, 100*m_ratio+29*sy);
m_playlistButton->move (228*m_ratio+sx*25, 86*m_ratio+29*sy);
m_length_totalLength -> move (132*m_ratio+sx*25, 88*m_ratio+29*sy);
m_current_time->move (191*m_ratio+sx*25,101*m_ratio+29*sy);
m_plslider->move (255*m_ratio+sx*25,20*m_ratio);
m_resizeWidget->move(width() - 25, height() - 29);
}
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);
m_copySelectedMenu = new QMenu (tr("&Copy Selection To"), m_listWidget->menu());
m_copySelectedMenu->setIcon(QIcon::fromTheme("edit-copy"));
connect(m_copySelectedMenu, SIGNAL(aboutToShow()),
SLOT(generateCopySelectedMenu()));
connect(m_copySelectedMenu, SIGNAL(triggered(QAction *)),
SLOT(copySelectedMenuActionTriggered(QAction *)));
}
void PlayList::createActions()
{
//add menu
m_addMenu->addAction(SET_ACTION(ActionManager::PL_ADD_FILE, parent(), SLOT(addFile())));
m_addMenu->addAction(SET_ACTION(ActionManager::PL_ADD_DIRECTORY, parent(), SLOT(addDir())));
m_addMenu->addAction(SET_ACTION(ActionManager::PL_ADD_URL, parent(), SLOT(addUrl())));
UiHelper::instance()->registerMenu(UiHelper::ADD_MENU, m_addMenu, false);
//sub menu
m_subMenu->addAction(SET_ACTION(ActionManager::PL_REMOVE_SELECTED, m_pl_manager, SLOT(removeSelected())));
m_subMenu->addAction(SET_ACTION(ActionManager::PL_REMOVE_ALL, m_pl_manager, SLOT(clear())));
m_subMenu->addAction(SET_ACTION(ActionManager::PL_REMOVE_UNSELECTED, m_pl_manager,
SLOT(removeUnselected())));
m_subMenu->addSeparator();
m_subMenu->addAction(SET_ACTION(ActionManager::PL_REFRESH, m_pl_manager,
SLOT(refresh())));
m_subMenu->addAction(SET_ACTION(ActionManager::PL_REMOVE_INVALID, m_pl_manager,
SLOT(removeInvalidTracks())));
m_subMenu->addAction(SET_ACTION(ActionManager::PL_REMOVE_DUPLICATES, m_pl_manager,
SLOT(removeDuplicates())));
//sort menu
m_sortMenu->addAction(SET_ACTION(ActionManager::PL_SHOW_INFO, m_pl_manager, SLOT(showDetails ())));
m_sortMenu->addSeparator();
QMenu* sort_mode_menu = new QMenu (tr("Sort List"), this);
sort_mode_menu->setIcon(QIcon::fromTheme("view-sort-ascending"));
QAction *titleAct = sort_mode_menu->addAction(tr ("By Title"));
connect(titleAct, &QAction::triggered, [this]{ m_pl_manager->sort(PlayListModel::TITLE); } );
QAction *albumAct = sort_mode_menu->addAction(tr ("By Album"));
connect(albumAct, &QAction::triggered, [this]{ m_pl_manager->sort(PlayListModel::ALBUM); } );
QAction *artistAct = sort_mode_menu->addAction(tr ("By Artist"));
connect(artistAct, &QAction::triggered, [this]{ m_pl_manager->sort(PlayListModel::ARTIST); } );
QAction *albumArtistAct = sort_mode_menu->addAction(tr ("By Album Artist"));
connect(albumArtistAct, &QAction::triggered, [this]{ m_pl_manager->sort(PlayListModel::ALBUMARTIST); } );
QAction *nameAct = sort_mode_menu->addAction(tr ("By Filename"));
connect(nameAct, &QAction::triggered, [this]{ m_pl_manager->sort(PlayListModel::FILENAME); } );
QAction *pathnameAct = sort_mode_menu->addAction(tr ("By Path + Filename"));
connect(pathnameAct, &QAction::triggered, [this]{ m_pl_manager->sort(PlayListModel::PATH_AND_FILENAME); } );
QAction *dateAct = sort_mode_menu->addAction(tr ("By Date"));
connect(dateAct, &QAction::triggered, [this]{ m_pl_manager->sort(PlayListModel::DATE); } );
QAction *trackAct = sort_mode_menu->addAction(tr("By Track Number"));
connect(trackAct, &QAction::triggered, [this]{ m_pl_manager->sort(PlayListModel::TRACK); } );
QAction *discAct = sort_mode_menu->addAction(tr("By Disc Number"));
connect(discAct, &QAction::triggered, [this]{ m_pl_manager->sort(PlayListModel::DISCNUMBER); } );
QAction *fileCreationDateAct = sort_mode_menu->addAction(tr("By File Creation Date"));
connect(fileCreationDateAct, &QAction::triggered, [this]{ m_pl_manager->sort(PlayListModel::FILE_CREATION_DATE); } );
QAction *fileModificationDateAct = sort_mode_menu->addAction(tr("By File Modification Date"));
connect(fileModificationDateAct, &QAction::triggered, [this]{ m_pl_manager->sort(PlayListModel::FILE_MODIFICATION_DATE); } );
QAction *groupAct = sort_mode_menu->addAction(tr("By Group"));
connect(groupAct, &QAction::triggered, [this]{ m_pl_manager->sort(PlayListModel::GROUP); } );
m_sortMenu->addMenu (sort_mode_menu);
sort_mode_menu = new QMenu (tr("Sort Selection"), m_sortMenu);
sort_mode_menu->setIcon(QIcon::fromTheme("view-sort-ascending"));
titleAct = sort_mode_menu->addAction(tr ("By Title"));
connect(titleAct, &QAction::triggered, [this]{ m_pl_manager->sortSelection(PlayListModel::TITLE); });
albumAct = sort_mode_menu->addAction(tr ("By Album"));
connect(albumAct, &QAction::triggered, [this]{ m_pl_manager->sortSelection(PlayListModel::ALBUM); });
artistAct = sort_mode_menu->addAction(tr ("By Artist"));
connect(artistAct, &QAction::triggered, [this]{ m_pl_manager->sortSelection(PlayListModel::ARTIST); });
albumArtistAct = sort_mode_menu->addAction(tr ("By Album Artist"));
connect(albumArtistAct, &QAction::triggered, [this]{ m_pl_manager->sortSelection(PlayListModel::ALBUMARTIST); });
nameAct = sort_mode_menu->addAction(tr ("By Filename"));
connect(nameAct, &QAction::triggered, [this]{ m_pl_manager->sortSelection(PlayListModel::FILENAME); });
pathnameAct = sort_mode_menu->addAction(tr ("By Path + Filename"));
connect(pathnameAct, &QAction::triggered, [this]{ m_pl_manager->sortSelection(PlayListModel::PATH_AND_FILENAME); });
dateAct = sort_mode_menu->addAction(tr ("By Date"));
connect(dateAct, &QAction::triggered, [this]{ m_pl_manager->sortSelection(PlayListModel::DATE); });
trackAct = sort_mode_menu->addAction(tr ("By Track Number"));
connect(trackAct, &QAction::triggered, [this]{ m_pl_manager->sortSelection(PlayListModel::TRACK); });
discAct = sort_mode_menu->addAction(tr("By Disc Number"));
connect(discAct, &QAction::triggered, [this]{ m_pl_manager->sortSelection(PlayListModel::DISCNUMBER); });
fileCreationDateAct = sort_mode_menu->addAction(tr("By File Creation Date"));
connect(fileCreationDateAct, &QAction::triggered, [this]{ m_pl_manager->sortSelection(PlayListModel::FILE_CREATION_DATE); });
fileModificationDateAct = sort_mode_menu->addAction(tr("By File Modification Date"));
connect(fileModificationDateAct, &QAction::triggered, [this]{ m_pl_manager->sortSelection(PlayListModel::FILE_MODIFICATION_DATE ); });
m_sortMenu->addMenu (sort_mode_menu);
m_sortMenu->addSeparator();
m_sortMenu->addAction (QIcon::fromTheme("media-playlist-shuffle"), tr("Randomize List"),
m_pl_manager, SLOT(randomizeList()));
m_sortMenu->addAction (QIcon::fromTheme("view-sort-descending"), tr("Reverse List"),
m_pl_manager, SLOT(reverseList()));
//playlist context menu
m_listWidget->menu()->addAction(ActionManager::instance()->action(ActionManager::PL_SHOW_INFO));
m_listWidget->menu()->addSeparator();
m_listWidget->menu()->addActions (m_subMenu->actions().mid(0,3)); //use 3 first actions
m_listWidget->menu()->addMenu(UiHelper::instance()->createMenu(UiHelper::PLAYLIST_MENU,
tr("Actions"), true, this));
m_listWidget->menu()->addSeparator();
m_listWidget->menu()->addAction(SET_ACTION(ActionManager::PL_ENQUEUE, m_pl_manager, SLOT(addToQueue())));
//select menu
m_selectMenu->addAction(SET_ACTION(ActionManager::PL_INVERT_SELECTION, m_pl_manager,
SLOT(invertSelection ())));
m_selectMenu->addSeparator();
m_selectMenu->addAction(SET_ACTION(ActionManager::PL_CLEAR_SELECTION, m_pl_manager,
SLOT(clearSelection ())));
m_selectMenu->addAction(SET_ACTION(ActionManager::PL_SELECT_ALL, m_pl_manager, SLOT(selectAll())));
//Playlist Menu
m_playlistMenu->addAction(SET_ACTION(ActionManager::PL_NEW, m_pl_manager, SLOT(createPlayList())));
m_playlistMenu->addAction(SET_ACTION(ActionManager::PL_CLOSE, this, SLOT(deletePlaylist())));
m_playlistMenu->addAction(SET_ACTION(ActionManager::PL_RENAME, this, SLOT(renamePlaylist())));
m_playlistMenu->addSeparator();
m_playlistMenu->addAction(SET_ACTION(ActionManager::PL_LOAD, this, SIGNAL(loadPlaylist())));
m_playlistMenu->addAction(SET_ACTION(ActionManager::PL_SAVE, this, SIGNAL(savePlaylist())));
m_playlistMenu->addSeparator();
m_playlistMenu->addAction(SET_ACTION(ActionManager::PL_SELECT_NEXT, m_pl_manager,
SLOT(selectNextPlayList())));
m_playlistMenu->addAction(SET_ACTION(ActionManager::PL_SELECT_PREVIOUS, m_pl_manager,
SLOT(selectPreviousPlayList())));
m_playlistMenu->addAction(SET_ACTION(ActionManager::PL_SHOW_MANAGER, this, SLOT(showPlayLists())));
//actions
SET_ACTION(ActionManager::PL_GROUP_TRACKS, m_ui_settings, SLOT(setGroupsEnabled(bool)));
ACTION(ActionManager::PL_GROUP_TRACKS)->setChecked(m_ui_settings->isGroupsEnabled());
SET_ACTION(ActionManager::PL_SHOW_TABBAR, this, SLOT(readSettings()));
}
void PlayList::closeEvent (QCloseEvent *e)
{
if(e->spontaneous ())
parentWidget()->close();
}
void PlayList::paintEvent (QPaintEvent *)
{
int sx = (width()-275*m_ratio) /25;
int sy = (height()-116*m_ratio) /29;
QPainter paint(this);
drawPixmap (&paint, 0, 20*m_ratio, m_skin->getPlPart (Skin::PL_LFILL));
for (int i = 1; i<sy+2*m_ratio; i++)
{
drawPixmap (&paint, 0, 20*m_ratio+29*i, m_skin->getPlPart (Skin::PL_LFILL));
}
drawPixmap (&paint, 0, 78*m_ratio+29*sy, m_skin->getPlPart (Skin::PL_LSBAR));
for (int i = 0; i<sx; i++)
{
drawPixmap (&paint, 125*m_ratio+i*25,78*m_ratio+sy*29,m_skin->getPlPart (Skin::PL_SFILL1));
}
drawPixmap (&paint,125*m_ratio+sx*25,78*m_ratio+sy*29,m_skin->getPlPart (Skin::PL_RSBAR));
}
void PlayList::drawPixmap (QPainter *painter, int x, int y, const QPixmap &pix)
{
style()->drawItemPixmap(painter, QRect(x, y, pix.width(), pix.height()), Qt::AlignCenter, pix);
}
void PlayList::resizeEvent (QResizeEvent *)
{
updatePositions();
}
void PlayList::mousePressEvent (QMouseEvent *e)
{
Q_UNUSED(e);
if(m_resizeWidget->underMouse())
{
m_resize = true;
setCursor (m_skin->getCursor (Skin::CUR_PSIZE));
}
else
m_resize = false;
}
void PlayList::mouseMoveEvent (QMouseEvent *e)
{
if(m_resize)
{
int dx = m_ratio * 25;
int dy = m_ratio * 29;
int sx = ((e->x() - 275 * m_ratio) + 14) / dx;
int sy = ((e->y() - 116 * m_ratio) + 14) / dy;
sx = qMax(sx, 0);
sy = qMax(sy, 0);
#ifdef QMMP_WS_X11
if(m_compiz)
setFixedSize(275 * m_ratio + dx * sx, 116 * m_ratio + dy * sy);
else
#endif
resize(275 * m_ratio + dx * sx, 116 * m_ratio + dy * sy);
#ifdef QMMP_WS_X11
//avoid right corner moving during resize
if(layoutDirection() == Qt::RightToLeft)
WindowSystem::revertGravity(winId());
#endif
}
}
void PlayList::mouseReleaseEvent (QMouseEvent *)
{
setCursor (m_skin->getCursor (Skin::CUR_PNORMAL));
/*if(m_resize)
m_listWidget->updateList();*/
m_resize = false;
Dock::instance()->updateDock();
}
void PlayList::changeEvent (QEvent * event)
{
if(event->type() == QEvent::ActivationChange)
{
m_titleBar->setActive (isActiveWindow());
}
}
void PlayList::readSettings()
{
if(ACTION(ActionManager::PL_SHOW_TABBAR)->isChecked())
{
if(!m_pl_selector)
m_pl_selector = new PlayListSelector(m_pl_manager, this);
m_pl_selector->show();
m_listWidget->menu()->insertMenu(m_listWidget->menu()->actions().at(2),m_copySelectedMenu);
}
else
{
if(m_pl_selector)
{
m_pl_selector->deleteLater();
m_listWidget->menu()->removeAction(m_copySelectedMenu->menuAction());
}
m_pl_selector = nullptr;
}
if(m_update)
{
m_listWidget->readSettings();
m_titleBar->readSettings();
if(m_pl_selector)
m_pl_selector->readSettings();
updatePositions();
}
else
{
QScreen *primaryScreen = QGuiApplication::primaryScreen();
QRect availableGeometry = primaryScreen->availableGeometry();
QSettings settings (Qmmp::configFile(), QSettings::IniFormat);
QPoint pos = settings.value ("Skinned/pl_pos", QPoint (100, 332)).toPoint();
m_ratio = m_skin->ratio();
//TODO QGuiApplication::screenAt
const QList<QScreen *> screens = QGuiApplication::screens();
auto it = std::find_if(screens.cbegin(), screens.cend(), [pos](QScreen *screen){ return screen->availableGeometry().contains(pos); });
if(it != screens.cend())
availableGeometry = (*it)->availableGeometry();
pos.setX(qBound(availableGeometry.left(), pos.x(), availableGeometry.right() - m_ratio*275));
pos.setY(qBound(availableGeometry.top(), pos.y(), availableGeometry.bottom() - m_ratio*116));
move(pos); //position
m_update = true;
}
}
#ifdef QMMP_WS_X11
bool PlayList::event (QEvent *event)
{
if(event->type() == QEvent::WinIdChange ||
event->type() == QEvent::Show)
{
WindowSystem::ghostWindow(winId());
WindowSystem::setWinHint(winId(), "playlist", "Qmmp");
}
return QWidget::event(event);
}
#endif
void PlayList::writeSettings()
{
QSettings settings (Qmmp::configFile(), QSettings::IniFormat);
//position
settings.setValue ("Skinned/pl_pos", this->pos());
}
#ifdef QMMP_WS_X11
bool PlayList::useCompiz() const
{
return m_compiz;
}
#endif
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)
{
if(sec >= 3600)
sec /= 60;
return QString("%1:%2").arg(sec/60, 2, 10, QChar('0')).arg(sec%60, 2, 10, QChar('0'));
}
void PlayList::setTime(qint64 time)
{
if(time < 0)
m_current_time->display("--:--");
else
m_current_time->display(formatTime (time/1000));
m_current_time->update();
SoundCore *core = SoundCore::instance();
if(core)
{
QString str_length = formatTime(m_pl_manager->currentPlayList()->totalDuration() / 1000) + "/";
if(core->state() == Qmmp::Playing || core->state() == Qmmp::Paused)
str_length.append(formatTime(core->duration() / 1000));
else
str_length.append("--:--");
m_length_totalLength->display(str_length);
m_length_totalLength->update();
}
}
void PlayList::showPlaylistMenu()
{
m_playlistMenu->exec (m_playlistButton->mapToGlobal (QPoint (0,0)));
}
void PlayList::keyPressEvent (QKeyEvent *ke)
{
m_keyboardManager->handleKeyPress (ke);
}
void PlayList::updateSkin()
{
if(m_pl_selector)
m_pl_selector->readSettings();
setCursor(m_skin->getCursor(Skin::CUR_PNORMAL)); // TODO shaded
m_resizeWidget->setCursor(m_skin->getCursor (Skin::CUR_PSIZE));
m_ratio = m_skin->ratio();
setMinimalMode(m_shaded);
}
void PlayList::deletePlaylist()
{
m_pl_manager->removePlayList(m_pl_manager->selectedPlayList());
}
void PlayList::renamePlaylist()
{
bool ok = false;
QString name = QInputDialog::getText (this,
tr("Rename Playlist"), tr("Playlist name:"),
QLineEdit::Normal,
m_pl_manager->selectedPlayList()->name(), &ok);
if(ok)
m_pl_manager->selectedPlayList()->setName(name);
}
void PlayList::showPlayLists()
{
if(!m_pl_browser)
{
m_pl_browser = new PlayListBrowser(m_pl_manager, this);
m_pl_browser->show();
}
else
m_pl_browser->show();
}
void PlayList::generateCopySelectedMenu()
{
m_copySelectedMenu->clear();
QAction* action = m_copySelectedMenu->addAction (tr("&New PlayList"));
action->setIcon(QIcon::fromTheme("document-new"));
m_copySelectedMenu->addSeparator();
for(QString name : m_pl_manager->playListNames())
{
m_copySelectedMenu->addAction("&" + name.replace("&", "&&"));
}
}
void PlayList::copySelectedMenuActionTriggered(QAction *action)
{
PlayListModel *targetPlayList = nullptr;
QString actionText=action->text();
if(action == m_copySelectedMenu->actions().at(0))//actionText == tr ("&New PlayList"))
{
targetPlayList = m_pl_manager->createPlayList(m_pl_manager->selectedPlayList()->name());
}
else
{
actionText.remove(0,1).replace("&&", "&");
for(PlayListModel *model : m_pl_manager->playLists())
{
//if("&" + model->name().replace("&", "&&") == actionText)
if(model->name() == actionText)
{
targetPlayList = model;
break;
}
}
}
if(!targetPlayList)
{
qWarning("Error: Cannot find target playlist '%s'",qPrintable(actionText));
return;
}
QList <PlayListTrack *> theCopy;
for(PlayListTrack *track : m_pl_manager->selectedPlayList()->selectedTracks())
{
PlayListTrack *newItem = new PlayListTrack(*track);
theCopy << newItem;
}
targetPlayList->add(theCopy);
}
void PlayList::onCurrentPlayListChanged(PlayListModel *current, PlayListModel *previous)
{
m_titleBar->setModel(current);
connect(current, SIGNAL(listChanged(int)), SLOT(onListChanged(int)));
if(previous)
disconnect(current, SIGNAL(listChanged(int)), this, SLOT(onListChanged(int)));
}
void PlayList::onListChanged(int flags)
{
if(flags & PlayListModel::CURRENT || flags & PlayListModel::STRUCTURE)
setTime(-1);
}
void PlayList::setMinimalMode(bool b)
{
if(!m_shaded)
m_height = height();
m_shaded = b;
#ifdef QMMP_WS_X11
if(m_compiz)
{
if(m_shaded)
{
m_height = height();
setFixedSize(qMax(width(), 275 * m_ratio), 14*m_ratio);
}
else
{
setFixedSize(qMax(width(), 275 * m_ratio), qMax(m_height, 116*m_ratio));
}
}
else
#endif
{
if(m_shaded)
{
m_height = height();
setSizeIncrement (25*m_ratio, 1);
setMinimumSize (275*m_ratio, 14*m_ratio);
resize(width(), 14*m_ratio);
}
else
{
setMinimumSize(275*m_ratio, 116*m_ratio);
resize (width(), m_height);
setSizeIncrement (25*m_ratio, 29*m_ratio);
}
}
updatePositions();
update();
}