1 //===========================================
2 // Lumina-DE source code
3 // Copyright (c) 2015, Ken Moore
4 // Available under the 3-clause BSD license
5 // See the LICENSE file for full details
6 //===========================================
7 #include "PlayerWidget.h"
8 #include "ui_PlayerWidget.h"
9
10 #include <QDir>
11 #include <QUrl>
12 #include <QInputDialog>
13 #include <QFileDialog>
14 #include <LuminaXDG.h>
15 #include <QDebug>
16 #include <QDesktopWidget>
17
PlayerWidget(QWidget * parent)18 PlayerWidget::PlayerWidget(QWidget *parent) : QWidget(parent), ui(new Ui::PlayerWidget()){
19 ui->setupUi(this); //load the designer form
20 PLAYER = new QMediaPlayer(this);
21 PLAYER->setVolume(100);
22 PLAYER->setNotifyInterval(1000); //1 second interval (just needs to be a rough estimate)
23 PLAYLIST = new QMediaPlaylist(this);
24 PLAYLIST->setPlaybackMode(QMediaPlaylist::Sequential);
25 PLAYER->setPlaylist(PLAYLIST);
26
27 configMenu = new QMenu(this);
28 ui->tool_config->setMenu(configMenu);
29 addMenu = new QMenu(this);
30 ui->tool_add->setMenu(addMenu);
31
32 updatinglists = false; //start off as false
33
34 ui->combo_playlist->setContextMenuPolicy(Qt::NoContextMenu);
35
36 LoadIcons();
37 playerStateChanged(); //update button visibility
38 currentSongChanged();
39 //Connect all the signals/slots
40 //connect(infoTimer, SIGNAL(timeout()), this, SLOT(rotateTrackInfo()) );
41 connect(PLAYER, SIGNAL(positionChanged(qint64)),this, SLOT(updateProgress(qint64)) );
42 connect(PLAYER, SIGNAL(durationChanged(qint64)), this, SLOT(updateMaxProgress(qint64)) );
43 connect(PLAYLIST, SIGNAL(mediaChanged(int, int)), this, SLOT(playlistChanged()) );
44 connect(PLAYER, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(playerStateChanged()) );
45 connect(PLAYLIST, SIGNAL(currentMediaChanged(const QMediaContent&)), this, SLOT(currentSongChanged()) );
46 connect(ui->combo_playlist, SIGNAL(currentIndexChanged(int)), this, SLOT(userlistSelectionChanged()) );
47 connect(ui->tool_play, SIGNAL(clicked()), this, SLOT(playClicked()) );
48 connect(ui->tool_pause, SIGNAL(clicked()), this, SLOT(pauseClicked()) );
49 connect(ui->tool_stop, SIGNAL(clicked()), this, SLOT(stopClicked()) );
50 connect(ui->tool_next, SIGNAL(clicked()), this, SLOT(nextClicked()) );
51 connect(ui->tool_prev, SIGNAL(clicked()), this, SLOT(prevClicked()) );
52
53 }
54
~PlayerWidget()55 PlayerWidget::~PlayerWidget(){
56 //qDebug() << "Removing PlayerWidget";
57 }
58
LoadIcons()59 void PlayerWidget::LoadIcons(){
60 ui->tool_stop->setIcon( LXDG::findIcon("media-playback-stop","") );
61 ui->tool_play->setIcon( LXDG::findIcon("media-playback-start","") );
62 ui->tool_pause->setIcon( LXDG::findIcon("media-playback-pause","") );
63 ui->tool_next->setIcon( LXDG::findIcon("media-skip-forward","") );
64 ui->tool_prev->setIcon( LXDG::findIcon("media-skip-backward","") );
65 ui->tool_add->setIcon( LXDG::findIcon("list-add","") );
66 ui->tool_config->setIcon( LXDG::findIcon("configure","") );
67 //Now re-assemble the menus as well
68 configMenu->clear();
69 configMenu->addAction(LXDG::findIcon("media-eject",""), tr("Clear Playlist"), this, SLOT(ClearPlaylist()));
70 configMenu->addAction(LXDG::findIcon("roll",""), tr("Shuffle Playlist"), this, SLOT(ShufflePlaylist()));
71 addMenu->clear();
72 addMenu->addAction(LXDG::findIcon("document-new",""), tr("Add Files"), this, SLOT(AddFilesToPlaylist()));
73 addMenu->addAction(LXDG::findIcon("folder-new",""), tr("Add Directory"), this, SLOT(AddDirToPlaylist()));
74 addMenu->addAction(LXDG::findIcon("download",""), tr("Add URL"), this, SLOT(AddURLToPlaylist()));
75 }
76
playClicked()77 void PlayerWidget::playClicked(){
78 PLAYER->play();
79 }
80
pauseClicked()81 void PlayerWidget::pauseClicked(){
82 PLAYER->pause();
83 }
84
stopClicked()85 void PlayerWidget::stopClicked(){
86 PLAYER->stop();
87 }
88
nextClicked()89 void PlayerWidget::nextClicked(){
90 PLAYLIST->next();
91 }
92
prevClicked()93 void PlayerWidget::prevClicked(){
94 PLAYLIST->previous();
95 }
96
AddFilesToPlaylist()97 void PlayerWidget::AddFilesToPlaylist(){
98 //Prompt the user to select multimedia files
99 QFileDialog dlg(0, Qt::Dialog | Qt::WindowStaysOnTopHint );
100 dlg.setFileMode(QFileDialog::ExistingFiles);
101 dlg.setAcceptMode(QFileDialog::AcceptOpen);
102 dlg.setNameFilter( tr("Multimedia Files")+" ("+LXDG::findAVFileExtensions().join(" ")+")");
103 dlg.setWindowTitle(tr("Select Multimedia Files"));
104 dlg.setWindowIcon( LXDG::findIcon("file-open","") );
105 dlg.setDirectory(QDir::homePath()); //start in the home directory
106 //ensure it is centered on the current screen
107 QPoint center = QApplication::desktop()->screenGeometry(this).center();
108 dlg.move( center.x()-(dlg.width()/2), center.y()-(dlg.height()/2) );
109 dlg.show();
110 while( dlg.isVisible() ){
111 QApplication::processEvents();
112 }
113 QList<QUrl> files = dlg.selectedUrls();
114 if(files.isEmpty() || dlg.result()!=QDialog::Accepted){ return; } //cancelled
115 //Make this use show/processEvents later
116 //QList<QUrl> files = QFileDialog::getOpenFileUrls(0, tr("Select Multimedia Files"), QDir::homePath(), "Multimedia Files ("+LXDG::findAVFileExtensions().join(" ")+")");
117 QList<QMediaContent> urls;
118 for(int i=0; i<files.length(); i++){
119 urls << QMediaContent(files[i]);
120 }
121 PLAYLIST->addMedia(urls);
122 playlistChanged();
123 }
124
AddDirToPlaylist()125 void PlayerWidget::AddDirToPlaylist(){
126 QFileDialog dlg(0, Qt::Dialog | Qt::WindowStaysOnTopHint );
127 dlg.setFileMode(QFileDialog::Directory);
128 dlg.setOption(QFileDialog::ShowDirsOnly, true);
129 dlg.setAcceptMode(QFileDialog::AcceptOpen);
130 dlg.setWindowTitle(tr("Select Multimedia Directory"));
131 dlg.setWindowIcon( LXDG::findIcon("folder-open","") );
132 dlg.setDirectory(QDir::homePath()); //start in the home directory
133 //ensure it is centered on the current screen
134 QPoint center = QApplication::desktop()->screenGeometry(this).center();
135 dlg.move( center.x()-(dlg.width()/2), center.y()-(dlg.height()/2) );
136 dlg.show();
137 while( dlg.isVisible() ){
138 QApplication::processEvents();
139 }
140 if(dlg.result() != QDialog::Accepted){ return; } //cancelled
141 QStringList sel = dlg.selectedFiles();
142 if(sel.isEmpty()){ return; } //cancelled
143 QString dirpath = sel.first(); //QFileDialog::getExistingDirectory(0, tr("Select a Multimedia Directory"), QDir::homePath() );
144 if(dirpath.isEmpty()){ return; } //cancelled
145 QDir dir(dirpath);
146 QFileInfoList files = dir.entryInfoList(LXDG::findAVFileExtensions(), QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
147 if(files.isEmpty()){ return; } //nothing in this directory
148 QList<QMediaContent> urls;
149 for(int i=0; i<files.length(); i++){
150 urls << QMediaContent(QUrl::fromLocalFile(files[i].absoluteFilePath()) );
151 }
152 PLAYLIST->addMedia(urls);
153 playlistChanged();
154 }
155
AddURLToPlaylist()156 void PlayerWidget::AddURLToPlaylist(){
157 QInputDialog dlg(0, Qt::Dialog | Qt::WindowStaysOnTopHint );
158 dlg.setInputMode(QInputDialog::TextInput);
159 dlg.setLabelText(tr("Enter a valid URL for a multimedia file or stream:"));
160 dlg.setTextEchoMode(QLineEdit::Normal);
161 dlg.setWindowTitle(tr("Multimedia URL"));
162 dlg.setWindowIcon( LXDG::findIcon("download","") );
163 //ensure it is centered on the current screen
164 QPoint center = QApplication::desktop()->screenGeometry(this).center();
165 dlg.move( center.x()-(dlg.width()/2), center.y()-(dlg.height()/2) );
166 dlg.show();
167 while( dlg.isVisible() ){
168 QApplication::processEvents();
169 }
170 QString url = dlg.textValue();
171 if(url.isEmpty() || dlg.result()!=QDialog::Accepted){ return; } //cancelled
172
173 //QString url = QInputDialog::getText(0, tr("Multimedia URL"), tr("Enter a valid URL for a multimedia file or stream"), QLineEdit::Normal);
174 //if(url.isEmpty()){ return; }
175 QUrl newurl(url);
176 if(!newurl.isValid()){ return; } //invalid URL
177 PLAYLIST->addMedia(newurl);
178 playlistChanged();
179 }
180
ClearPlaylist()181 void PlayerWidget::ClearPlaylist(){
182 PLAYER->stop();
183 PLAYLIST->clear();
184 playlistChanged();
185 }
186
ShufflePlaylist()187 void PlayerWidget::ShufflePlaylist(){
188 PLAYLIST->shuffle();
189 }
190
191
userlistSelectionChanged()192 void PlayerWidget::userlistSelectionChanged(){ //front-end combobox was changed by the user
193 if(updatinglists){ return; }
194 PLAYLIST->setCurrentIndex( ui->combo_playlist->currentIndex() );
195 }
196
playerStateChanged()197 void PlayerWidget::playerStateChanged(){
198 switch( PLAYER->state() ){
199 case QMediaPlayer::StoppedState:
200 ui->tool_stop->setVisible(false);
201 ui->tool_play->setVisible(true);
202 ui->tool_pause->setVisible(false);
203 ui->progressBar->setVisible(false);
204 break;
205 case QMediaPlayer::PausedState:
206 ui->tool_stop->setVisible(true);
207 ui->tool_play->setVisible(true);
208 ui->tool_pause->setVisible(false);
209 ui->progressBar->setVisible(true);
210 break;
211 case QMediaPlayer::PlayingState:
212 ui->tool_stop->setVisible(true);
213 ui->tool_play->setVisible(false);
214 ui->tool_pause->setVisible(true);
215 ui->progressBar->setVisible(true);
216 break;
217 }
218
219 }
220
playlistChanged()221 void PlayerWidget::playlistChanged(){
222 updatinglists = true;
223 ui->combo_playlist->clear();
224 for(int i=0; i<PLAYLIST->mediaCount(); i++){
225 QUrl url = PLAYLIST->media(i).canonicalUrl();
226 if(url.isLocalFile()){
227 ui->combo_playlist->addItem(LXDG::findMimeIcon(url.fileName().section(".",-1)), url.fileName() );
228 }else{
229 ui->combo_playlist->addItem(LXDG::findIcon("download",""), url.toString() );
230 }
231 }
232 if(PLAYLIST->currentIndex()<0 && PLAYLIST->mediaCount()>0){ PLAYLIST->setCurrentIndex(0); }
233 ui->combo_playlist->setCurrentIndex(PLAYLIST->currentIndex());
234
235 updatinglists = false;
236 }
237
currentSongChanged()238 void PlayerWidget::currentSongChanged(){
239 if(PLAYLIST->currentIndex() != ui->combo_playlist->currentIndex()){
240 updatinglists = true;
241 ui->combo_playlist->setCurrentIndex(PLAYLIST->currentIndex());
242 updatinglists = false;
243 }
244 ui->tool_next->setEnabled( PLAYLIST->nextIndex() >= 0 );
245 ui->tool_prev->setEnabled( PLAYLIST->previousIndex() >= 0);
246 ui->label_num->setText( QString::number( PLAYLIST->currentIndex()+1)+"/"+QString::number(PLAYLIST->mediaCount()) );
247 ui->progressBar->setRange(0, PLAYER->duration() );
248 ui->progressBar->setValue(0);
249 }
250
updateProgress(qint64 val)251 void PlayerWidget::updateProgress(qint64 val){
252 //qDebug() << "Update Progress Bar:" << val;
253 ui->progressBar->setValue(val);
254 }
255
updateMaxProgress(qint64 val)256 void PlayerWidget::updateMaxProgress(qint64 val){
257 ui->progressBar->setRange(0,val);
258 }
259
260
AudioPlayerPlugin(QWidget * parent,QString ID)261 AudioPlayerPlugin::AudioPlayerPlugin(QWidget *parent, QString ID) : LDPlugin(parent, ID){
262 player = new PlayerWidget(this);
263 this->setLayout( new QVBoxLayout() );
264 this->layout()->setContentsMargins(0,0,0,0);
265 this->layout()->addWidget(player);
266
267 }
268
~AudioPlayerPlugin()269 AudioPlayerPlugin::~AudioPlayerPlugin(){
270 //qDebug() << "Remove AudioPlayerPlugin";
271 }
272