751770a7b32e70d0209650182266f5a8f2a1a045
[vlc-remote] / src / browsemainwindow.cpp
1 /*   VLC-REMOTE for MAEMO 5
2 *   Copyright (C) 2010 Schutz Sacha <istdasklar@gmail.com>, Dru Moore <usr@dru-id.co.uk>, Yann Nave <yannux@onbebop.net>
3 *   This program is free software; you can redistribute it and/or modify
4 *   it under the terms of the GNU General Public License version 2,
5 *   or (at your option) any later version, as published by the Free
6 *   Software Foundation
7 *
8 *   This program is distributed in the hope that it will be useful,
9 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 *   GNU General Public License for more details
12 *
13 *   You should have received a copy of the GNU General Public
14 *   License along with this program; if not, write to the
15 *   Free Software Foundation, Inc.,
16 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 */
18 #include "browsemainwindow.h"
19 #include "ui_browsemainwindow.h"
20 #include <QSettings>
21 #if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
22 #include <QMaemo5InformationBox>
23 #endif
24 #include "configdialog.h"
25 #include "aboutdialog.h"
26 #include "vlcbrowseelement.h"
27 #include "appsettings.h"
28
29 BrowseMainWindow::BrowseMainWindow(QWidget *parent) :
30         QMainWindow(parent),
31         ui(new Ui::BrowseMainWindow)
32 {
33
34     ui->setupUi(this);
35     mCurrentDir = "~/"; //AppSettings::getHomeDirectory().path; // This works on win as well as linux, would guess mac too.
36     setWindowTitle("Vlc remote");
37
38
39     mNetManager = new QNetworkAccessManager(this);
40
41     mContents = new QList<VlcBrowseElement>();
42
43     ui->listWidget->setTextElideMode(Qt::ElideMiddle);
44     ui->listWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
45
46     ui->playButton->setIcon(QIcon::fromTheme("camera_playback"));
47     ui->addButton->setIcon(QIcon::fromTheme("general_add"));
48     ui->browseButton->setIcon(QIcon::fromTheme("filemanager_media_folder"));
49     ui->browseButton->setDisabled(true);
50     ui->playButton->setDisabled(true);
51     ui->addButton->setDisabled(true);
52
53     connect(ui->listWidget,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(onBrowse()));
54     connect(ui->browseButton,SIGNAL(clicked()),this,SLOT(onBrowse()));
55     connect(ui->addButton,SIGNAL(clicked()),this,SLOT(onAddToPlaylist()));
56     connect(ui->playButton,SIGNAL(clicked()),this,SLOT(onPlay()));
57     connect(ui->listWidget, SIGNAL(itemSelectionChanged()), this, SLOT(onListSelectionChanged()));
58
59     connect(ui->actionGoUserHome, SIGNAL(triggered()), this, SLOT(showUserHomeFolder()));
60     connect(ui->actionGoHome, SIGNAL(triggered()), this, SLOT(showHomeFolder()));
61     connect(ui->actionSetHome, SIGNAL(triggered()), this, SLOT(setHomeFolder()));
62     connect(ui->actionViewFavourites, SIGNAL(triggered()), this, SLOT(showFavourites()));
63     connect(ui->actionSetFavourite, SIGNAL(triggered()), this, SLOT(setFavourite()));
64
65     init();
66
67
68 }
69 void BrowseMainWindow::init()  // THIS METHOD IS CALLED WHEN CONFIG CHANGED...
70 {
71     mIp = AppSettings::getCurrentIp(); // AccountDialog::currentIp();
72     setHomeDirectory();
73 }
74 void BrowseMainWindow::setHomeDirectory()
75 {
76     mCurrentDir = AppSettings::getHomeDirectory().path;
77 }
78 void BrowseMainWindow::showCurrentDirectory()  // THIS METHOD IS CALLED WHEN WINDOW IS OPENED...
79 {
80     browseDirectory(mCurrentDir);
81 }
82
83 BrowseMainWindow::~BrowseMainWindow()
84 {
85     delete ui;
86 }
87
88 void BrowseMainWindow::changeEvent(QEvent *e)
89 {
90     QMainWindow::changeEvent(e);
91     switch (e->type()) {
92     case QEvent::LanguageChange:
93         ui->retranslateUi(this);
94         break;
95     default:
96         break;
97     }
98 }
99
100 void BrowseMainWindow::showHomeFolder() {
101     browseDirectory(AppSettings::getHomeDirectory().path);
102 }
103 void BrowseMainWindow::showUserHomeFolder() {
104     browseDirectory("~/");
105 }
106 void BrowseMainWindow::setHomeFolder() {
107     if (0 < mCurrentElement.name.length() && (0 == QString::compare("directory", mCurrentElement.type) || 0 == QString::compare("dir", mCurrentElement.type))) {
108         VlcDirectory dir;
109         dir.name = mCurrentElement.name;
110         dir.path = mCurrentElement.path;
111         AppSettings::setHomeDirectory(dir);
112     }
113     else if (0 < mCurrentDir.length()) {
114         VlcDirectory dir;
115         QString name = mCurrentDir;
116         int idx = mCurrentDir.lastIndexOf('/');
117         if (0 > idx) idx = mCurrentDir.lastIndexOf('\\');
118         if (0 < idx) {
119             name = mCurrentDir.right(mCurrentDir.length() - (idx + 1));
120         }
121         dir.name = name;
122         dir.path = mCurrentDir;
123         AppSettings::setHomeDirectory(dir);
124     }
125 }
126 void BrowseMainWindow::showFavourites() {
127     emit showFavouritesWindow();
128 #if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
129     this->hide();
130 #endif
131 }
132 void BrowseMainWindow::setFavourite() {
133     if (0 < mCurrentElement.name.length() && (0 == QString::compare("directory", mCurrentElement.type) || 0 == QString::compare("dir", mCurrentElement.type))) {
134         VlcDirectory dir;
135         dir.name = mCurrentElement.name;
136         dir.path = mCurrentElement.path;
137         AppSettings::addFavourite(dir);
138     }
139     else if (0 < mCurrentDir.length()) {
140         VlcDirectory dir;
141         QString name = mCurrentDir;
142         int idx = mCurrentDir.lastIndexOf('/');
143         if (0 > idx) idx = mCurrentDir.lastIndexOf('\\');
144         if (0 < idx) {
145             name = mCurrentDir.right(mCurrentDir.length() - (idx + 1));
146         }
147         dir.name = name;
148         dir.path = mCurrentDir;
149         AppSettings::addFavourite(dir);
150     }
151 }
152
153 void BrowseMainWindow::onListSelectionChanged() {
154     QList<QListWidgetItem *> items = ui->listWidget->selectedItems();
155     if (0 < items.count()) {
156         mCurrentElement = getElementFromText(items.at(0)->text());
157         // are we up dir?
158         if (0 == QString::compare("..", mCurrentElement.name)) {
159             ui->browseButton->setDisabled(true);
160             ui->playButton->setDisabled(true);
161             ui->addButton->setDisabled(true);
162             mCurrentDir = mCurrentElement.path;
163             browseDirectory(mCurrentDir);
164         }
165         else {
166             // can we browse?
167             if (0 == QString::compare("directory", mCurrentElement.type) || 0 == QString::compare("dir", mCurrentElement.type)) {
168                 ui->browseButton->setDisabled(false);
169             }
170             else {
171                 ui->browseButton->setDisabled(true);
172             }
173             // can we play?
174             ui->playButton->setDisabled(false);
175             // can we playlist?
176             ui->addButton->setDisabled(false);
177         }
178     }
179 }
180
181 VlcBrowseElement BrowseMainWindow::getElementFromText(QString text) {
182     for (int idx = 0; idx < mContents->count(); ++idx) {
183         if (0 == QString::compare(text, mContents->at(idx).name)) {
184             return mContents->at(idx);
185         }
186     }
187     return *(new VlcBrowseElement());
188 }
189
190 void BrowseMainWindow::onBrowse() {
191     // check for directory
192     if (0 == QString::compare("directory", mCurrentElement.type) || 0 == QString::compare("dir", mCurrentElement.type)) {
193         // call browseDirectory
194         mCurrentDir = mCurrentElement.path;
195         browseDirectory(mCurrentDir);
196     }
197     else {
198         ui->browseButton->setDisabled(true);
199     }
200 }
201
202 void BrowseMainWindow::onAddToPlaylist() {
203     QUrl url = QUrl("http://"+mIp+"/requests/status.xml?command=in_enqueue");
204     url.addEncodedQueryItem(QByteArray("input"), QUrl::toPercentEncoding(mCurrentElement.path.replace("\\", "\\\\").replace("'", "\\'")));
205     mNetManager->get(QNetworkRequest(url));
206 }
207
208 void BrowseMainWindow::onPlay() {
209     QUrl url = QUrl("http://"+mIp+"/requests/status.xml?command=in_play");
210     url.addEncodedQueryItem(QByteArray("input"), QUrl::toPercentEncoding(mCurrentElement.path.replace("\\", "\\\\").replace("'", "\\'")));
211     mNetManager->get(QNetworkRequest(url));
212 }
213
214 void BrowseMainWindow::browseDirectory(QString dir) {
215     mResponse.clear();
216     QUrl url = QUrl("http://"+mIp+"/requests/browse.xml");
217     url.addEncodedQueryItem(QByteArray("dir"), QUrl::toPercentEncoding(dir));
218     QNetworkReply * reply = mNetManager->get(QNetworkRequest(url));
219 #if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
220     this->setAttribute(Qt::WA_Maemo5ShowProgressIndicator, true);
221 #endif
222     connect(reply,SIGNAL(readyRead()),this,SLOT(readReady()));
223     connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(error(QNetworkReply::NetworkError)));
224     connect(mNetManager,SIGNAL(finished(QNetworkReply *)),this,SLOT(finished(QNetworkReply *)));
225 }
226 void BrowseMainWindow::error(QNetworkReply::NetworkError code) {
227 #if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
228     this->setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false);
229 #endif
230     qDebug() << code;
231 }
232 void BrowseMainWindow::readReady() {
233     QNetworkReply * reply = qobject_cast<QNetworkReply*>(sender());
234     // append to buffer
235     mResponse += reply->readAll();
236 }
237 void BrowseMainWindow::finished(QNetworkReply * reply) {
238     // now we can call parseXmlDirectory to process the full buffers
239     this->parseXmlDirectory();
240     // only interested in finished signals
241     disconnect(mNetManager,SIGNAL(finished(QNetworkReply *)),this,SLOT(finished(QNetworkReply *)));
242 #if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
243     this->setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false);
244 #endif
245     delete reply;
246 }
247 void BrowseMainWindow::parseXmlDirectory() {
248     QDomDocument doc;
249     doc.setContent(this->mResponse);
250     QDomElement docElem = doc.documentElement();
251     QDomNodeList elements = docElem.elementsByTagName("element");
252     // we can sort by folders then files alphabetically by running to lists and appending them at the end
253     // vlc alpha sorts everything in the incoming stream, we just need to seperate files from folders.
254     if (0 < elements.count()) {
255         QList<VlcBrowseElement>* files = new QList<VlcBrowseElement>();
256         int idx = 0;
257         mContents->clear();
258         do {
259             QDomNode node = elements.at(idx);
260             VlcBrowseElement* dir = new VlcBrowseElement();
261             dir->type = node.attributes().namedItem("type").nodeValue();
262             dir->size = node.attributes().namedItem("size").nodeValue().toInt();
263             dir->date = QDate::fromString(node.attributes().namedItem("date").nodeValue());
264             dir->path = node.attributes().namedItem("path").nodeValue();
265             dir->name = node.attributes().namedItem("name").nodeValue();
266             dir->extension = getExtension(dir->path, node.attributes().namedItem("extension").nodeValue());
267             ++idx;
268             if (0 != QString::compare("directory", dir->type) && 0 != QString::compare("dir", dir->type)) {
269                 files->append(*dir);
270             }
271             else if (0 == QString::compare("..", dir->name)) {
272                 this->mContents->prepend(*dir);
273             }
274             else {
275                 this->mContents->append(*dir);
276             }
277             delete dir;
278         } while (idx < elements.count());
279         if (0 < files->count()) {
280             mContents->append(*files);
281         }
282         delete files;
283         // Update UI
284         this->updateList();
285     }
286     else {
287         // alert user of error / empty directory
288         qDebug() << "can't browse dir: " << mCurrentDir;
289 #if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
290         QMaemo5InformationBox::information(this, tr("Directory could not be browsed!"), QMaemo5InformationBox::DefaultTimeout);
291 #endif
292     }
293     mResponse.clear();
294
295 }
296
297 QString BrowseMainWindow::getExtension(QString path, QString extension) {
298     // return extension if exists
299     if (!extension.isNull() && !extension.isEmpty()) return extension;
300     // return blank if no path
301     if (path.isNull() || path.isEmpty()) return "";
302     // otherwise extract the extension
303     int dot_pos = path.lastIndexOf('.');
304     if (0 < dot_pos) {
305         return path.right(path.length() - (dot_pos + 1));
306     }
307     else { // no dot
308         return "";
309     }
310 }
311
312 void BrowseMainWindow::updateList() {
313     ui->listWidget->clear();
314     int ct = this->mContents->count();
315     if (0 < ct) {
316         QIcon icon_up     = QIcon::fromTheme("filemanager_folder_up");
317         QIcon icon_folder = QIcon::fromTheme("general_folder");
318         QIcon icon_audio  = QIcon::fromTheme("general_audio_file");
319         QIcon icon_video  = QIcon::fromTheme("general_video_file");
320         QIcon icon_image  = QIcon::fromTheme("general_image");
321         QIcon icon_flash  = QIcon::fromTheme("filemanager_flash_file");
322         QIcon icon_real   = QIcon::fromTheme("filemanager_real_music");
323         QIcon icon_playl  = QIcon::fromTheme("filemanager_playlist");
324         QIcon icon_unknown= QIcon::fromTheme("filemanager_unknown_file");
325         for (int idx = 0; idx < ct; ++idx) {
326             VlcBrowseElement dir = mContents->at(idx);
327             QListWidgetItem* item;
328             bool item_good = false;
329             if (0 == QString::compare("directory", dir.type) || 0 == QString::compare("dir", dir.type)) {
330                 if (0 == QString::compare("..", dir.name)) {
331                     item = new QListWidgetItem(icon_up, dir.name, ui->listWidget, 0);
332                     item_good = true;
333                 }
334                 else {
335                     item = new QListWidgetItem(icon_folder, dir.name, ui->listWidget, 0);
336                     item_good = true;
337                 }
338             }
339             else if (0 == QString::compare("file", dir.type)) {
340                 if ( 0 == QString::compare(dir.extension, "jpg")  ||
341                      0 == QString::compare(dir.extension, "jpeg") ||
342                      0 == QString::compare(dir.extension, "gif")  ||
343                      0 == QString::compare(dir.extension, "png")  ||
344                      0 == QString::compare(dir.extension, "bmp")  ) {
345                     item_good = true;
346                     item = new QListWidgetItem(icon_image, dir.name, ui->listWidget, 0); // .jpg, .jpeg, .gif, .png, .bmp
347                 }
348                 else if ( 0 == QString::compare(dir.extension, "mp3")  ||
349                           0 == QString::compare(dir.extension, "m4a")  ||
350                           0 == QString::compare(dir.extension, "ogg")  ||
351                           0 == QString::compare(dir.extension, "oga")  ||
352                           0 == QString::compare(dir.extension, "wav")  ||
353                           0 == QString::compare(dir.extension, "flac")  ) {
354                     item_good = true;
355                     item = new QListWidgetItem(icon_audio, dir.name, ui->listWidget, 0); // .mp3, .m4a, .ogg, .oga, .wav, .flac
356                 }
357                 else if ( 0 == QString::compare(dir.extension, "m3u")  ||
358                           0 == QString::compare(dir.extension, "wpl")  ||
359                           0 == QString::compare(dir.extension, "pls")  ||
360                           0 == QString::compare(dir.extension, "asx")  ||
361                           0 == QString::compare(dir.extension, "xspf") ||
362                           0 == QString::compare(dir.extension, "cmml")  ) {
363                     item_good = true;
364                     item = new QListWidgetItem(icon_playl, dir.name, ui->listWidget, 0); // .m3u, .wpl, .pls, .asx, .xspf, .cmml
365                 }
366                 else if ( 0 == QString::compare(dir.extension, "avi")  ||
367                           0 == QString::compare(dir.extension, "mpeg") ||
368                           0 == QString::compare(dir.extension, "mpg")  ||
369                           0 == QString::compare(dir.extension, "mov")  ||
370                           0 == QString::compare(dir.extension, "mp4")  ||
371                           0 == QString::compare(dir.extension, "m4v")  ||
372                           0 == QString::compare(dir.extension, "wmv")  ||
373                           0 == QString::compare(dir.extension, "mkv")  ||
374                           0 == QString::compare(dir.extension, "ogv")  ) {
375                     item_good = true;
376                     item = new QListWidgetItem(icon_video, dir.name, ui->listWidget, 0); // .avi, .mpg, .mpeg, .mov, .mp4, .m4v, .wmv, .mkv, .ogv
377                 }
378                 else if ( 0 == QString::compare(dir.extension, "rm")  ||
379                           0 == QString::compare(dir.extension, "ra")  ||
380                           0 == QString::compare(dir.extension, "ram")  ) {
381                     item = new QListWidgetItem(icon_real, dir.name, ui->listWidget, 0); // .ram, 'rm, 'ra
382                 }
383                 else if ( 0 == QString::compare(dir.extension, "flv")  ) {
384                     item_good = true;
385                     item = new QListWidgetItem(icon_flash, dir.name, ui->listWidget, 0); // .flv
386                 }
387                 else {
388                     if (dir.name.startsWith("Flash")) {
389                         item_good = true;
390                         item = new QListWidgetItem(icon_flash, dir.name, ui->listWidget, 0);
391                     }
392                     else {
393                         if (AppSettings::getShowUnknownFileTypes()) {
394                             item_good = true;
395                             item = new QListWidgetItem(icon_unknown, dir.name, ui->listWidget, 0);
396                         }
397                         else {
398                             item_good = false;
399                         }
400                     }
401                 }
402             }
403             if (item_good) {
404                 ui->listWidget->addItem(item);
405             }
406             // other types ignored
407         }
408     }
409 }
410
411