Began refactoring settings handling.
[vlc-remote] / 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 #include "configdialog.h"
22 #include "aboutdialog.h"
23 #include "vlcbrowseelement.h"
24 #include "appsettings.h"
25
26 BrowseMainWindow::BrowseMainWindow(QWidget *parent) :
27         QMainWindow(parent),
28         ui(new Ui::BrowseMainWindow)
29 {
30
31     ui->setupUi(this);
32     mCurrentDir = "~/"; //AppSettings::getHomeDirectory().path; // This works on win as well as linux, would guess mac too.
33     setWindowTitle("Vlc remote");
34
35
36     mNetManager = new QNetworkAccessManager(this);
37
38     mContents = new QList<VlcBrowseElement>();
39
40     ui->listWidget->setTextElideMode(Qt::ElideMiddle);
41     ui->listWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
42
43     ui->playButton->setIcon(QIcon::fromTheme("camera_playback"));
44     ui->addButton->setIcon(QIcon::fromTheme("general_add"));
45     ui->browseButton->setIcon(QIcon::fromTheme("filemanager_media_folder"));
46     ui->browseButton->setDisabled(true);
47     ui->playButton->setDisabled(true);
48     ui->addButton->setDisabled(true);
49
50     connect(ui->browseButton,SIGNAL(clicked()),this,SLOT(onBrowse()));
51     connect(ui->addButton,SIGNAL(clicked()),this,SLOT(onAddToPlaylist()));
52     connect(ui->playButton,SIGNAL(clicked()),this,SLOT(onPlay()));
53     connect(ui->listWidget, SIGNAL(itemSelectionChanged()), this, SLOT(onListSelectionChanged()));
54
55     connect(ui->actionGoHome, SIGNAL(triggered()), this, SLOT(showHomeFolder()));
56     connect(ui->actionSetHome, SIGNAL(triggered()), this, SLOT(setHomeFolder()));
57     connect(ui->actionViewFavourites, SIGNAL(triggered()), this, SLOT(showFavourites()));
58     connect(ui->actionSetFavourite, SIGNAL(triggered()), this, SLOT(setFavourite()));
59
60     init();
61
62
63 }
64 void BrowseMainWindow::init()  // THIS METHOD IS CALLED WHEN CONFIG CHANGED...
65 {
66     mIp = AppSettings::getCurrentIp(); // AccountDialog::currentIp();
67     setHomeDirectory();
68 }
69 void BrowseMainWindow::setHomeDirectory()
70 {
71     mCurrentDir = AppSettings::getHomeDirectory().path;
72 }
73 void BrowseMainWindow::showCurrentDirectory()  // THIS METHOD IS CALLED WHEN WINDOW IS OPENED...
74 {
75     browseDirectory(mCurrentDir);
76 }
77
78 BrowseMainWindow::~BrowseMainWindow()
79 {
80     delete ui;
81 }
82
83 void BrowseMainWindow::changeEvent(QEvent *e)
84 {
85     QMainWindow::changeEvent(e);
86     switch (e->type()) {
87     case QEvent::LanguageChange:
88         ui->retranslateUi(this);
89         break;
90     default:
91         break;
92     }
93 }
94
95 void BrowseMainWindow::showHomeFolder() {
96     browseDirectory(AppSettings::getHomeDirectory().path);
97 }
98 void BrowseMainWindow::setHomeFolder() {
99     if (0 < mCurrentDir.length()) {
100         VlcDirectory dir;
101         dir.name = "Home";
102         dir.path = mCurrentDir;
103         AppSettings::setHomeDirectory(dir);
104     }
105 }
106 void BrowseMainWindow::showFavourites() {}
107 void BrowseMainWindow::setFavourite() {}
108
109 void BrowseMainWindow::onListSelectionChanged() {
110     QList<QListWidgetItem *> items = ui->listWidget->selectedItems();
111     if (0 < items.count()) {
112         mCurrentElement = getElementFromText(items.at(0)->text());
113         // are we up dir?
114         if (0 == QString::compare("..", mCurrentElement.name)) {
115             ui->browseButton->setDisabled(true);
116             ui->playButton->setDisabled(true);
117             ui->addButton->setDisabled(true);
118             mCurrentDir = mCurrentElement.path;
119             browseDirectory(mCurrentDir);
120         }
121         else {
122             // can we browse?
123             if (0 == QString::compare("directory", mCurrentElement.type)) {
124                 ui->browseButton->setDisabled(false);
125             }
126             else {
127                 ui->browseButton->setDisabled(true);
128             }
129             // can we play?
130             ui->playButton->setDisabled(false);
131             // can we playlist?
132             ui->addButton->setDisabled(false);
133         }
134     }
135 }
136
137 VlcBrowseElement BrowseMainWindow::getElementFromText(QString text) {
138     for (int idx = 0; idx < mContents->count(); ++idx) {
139         if (0 == QString::compare(text, mContents->at(idx).name)) {
140             return mContents->at(idx);
141         }
142     }
143     return *(new VlcBrowseElement());
144 }
145
146 void BrowseMainWindow::onBrowse() {
147     // check for directory
148     if (0 == QString::compare("directory", mCurrentElement.type)) {
149         // call browseDirectory
150         mCurrentDir = mCurrentElement.path;
151         browseDirectory(mCurrentDir);
152     }
153     else {
154         ui->browseButton->setDisabled(true);
155     }
156 }
157
158 void BrowseMainWindow::onAddToPlaylist() {
159     QUrl url = QUrl("http://"+mIp+"/requests/status.xml?command=in_enqueue");
160     url.addEncodedQueryItem(QByteArray("input"), QUrl::toPercentEncoding(mCurrentElement.path.replace("\\", "\\\\")));
161     mNetManager->get(QNetworkRequest(url));
162     //mNetManager->get(QNetworkRequest(QUrl("http://"+mIp+"/requests/status.xml?command=in_enqueue&input=" + mCurrentElement.path.replace("\\", "\\\\"))));
163 }
164
165 void BrowseMainWindow::onPlay() {
166     QUrl url = QUrl("http://"+mIp+"/requests/status.xml?command=in_play");
167     url.addEncodedQueryItem(QByteArray("input"), QUrl::toPercentEncoding(mCurrentElement.path.replace("\\", "\\\\")));
168     mNetManager->get(QNetworkRequest(url));
169     //mNetManager->get(QNetworkRequest(QUrl("http://"+mIp+"/requests/status.xml?command=in_play&input=" + mCurrentElement.path.replace("\\", "\\\\"))));
170 }
171
172 void BrowseMainWindow::browseDirectory(QString dir) {
173     mContents->clear();
174     ui->listWidget->clear();
175     mResponse.clear();
176     QUrl url = QUrl("http://"+mIp+"/requests/browse.xml");
177     url.addEncodedQueryItem(QByteArray("dir"), QUrl::toPercentEncoding(dir));
178     QNetworkReply * reply = mNetManager->get(QNetworkRequest(url));
179     //QNetworkReply * reply =  mNetManager->get(QNetworkRequest(QUrl("http://"+mIp+"/requests/browse.xml?dir=" + dir.replace("&", "%26").replace("\\", "\\\\"))));
180     connect(reply,SIGNAL(readyRead()),this,SLOT(readReady()));
181     connect(mNetManager,SIGNAL(finished(QNetworkReply *)),this,SLOT(finished(QNetworkReply *)));
182 }
183 void BrowseMainWindow::readReady() {
184     QNetworkReply * reply = qobject_cast<QNetworkReply*>(sender());
185     // append to buffer
186     mResponse += reply->readAll();
187 }
188 void BrowseMainWindow::finished(QNetworkReply * reply) {
189     // now we can call parseXmlDirectory to process the full buffers
190     this->parseXmlDirectory();
191     // only interested in finished signals
192     disconnect(mNetManager,SIGNAL(finished(QNetworkReply *)),this,SLOT(finished(QNetworkReply *)));
193 }
194 void BrowseMainWindow::parseXmlDirectory() {
195     QDomDocument doc;
196     doc.setContent(this->mResponse);
197     QDomElement docElem = doc.documentElement();
198     QDomNodeList elements = docElem.elementsByTagName("element");
199     // we can sort by folders then files alphabetically by running to lists and appending them at the end
200     // vlc alpha sorts everything in the incoming stream, we just need to seperate files from folders.
201     QList<VlcBrowseElement>* files = new QList<VlcBrowseElement>();
202     if (0 < elements.count()) {
203         int idx = 0;
204         do {
205             QDomNode node = elements.at(idx);
206             VlcBrowseElement* dir = new VlcBrowseElement();
207             dir->type = node.attributes().namedItem("type").nodeValue();
208             dir->size = node.attributes().namedItem("size").nodeValue().toInt();
209             dir->date = QDate::fromString(node.attributes().namedItem("date").nodeValue());
210             dir->path = node.attributes().namedItem("path").nodeValue();
211             dir->name = node.attributes().namedItem("name").nodeValue();
212             dir->extension = getExtension(dir->path, node.attributes().namedItem("extension").nodeValue());
213             ++idx;
214             if (0 != QString::compare("directory", dir->type)) {
215                 files->append(*dir);
216             }
217             else if (0 == QString::compare("..", dir->name)) {
218                 this->mContents->prepend(*dir);
219             }
220             else {
221                 this->mContents->append(*dir);
222             }
223             delete dir;
224         } while (idx < elements.count());
225         if (0 < files->count()) {
226             mContents->append(*files);
227         }
228     }
229     delete files;
230     mResponse.clear();
231
232     // Update UI
233     this->updateList();
234 }
235
236 QString BrowseMainWindow::getExtension(QString path, QString extension) {
237     // return extension if exists
238     if (!extension.isNull() && !extension.isEmpty()) return extension;
239     // return blank if no path
240     if (path.isNull() || path.isEmpty()) return "";
241     // otherwise extract the extension
242     int dot_pos = path.lastIndexOf('.');
243     if (0 < dot_pos) {
244         return path.right(path.length() - (dot_pos + 1));
245     }
246     else { // no dot
247         return "";
248     }
249 }
250
251 void BrowseMainWindow::writeFile(QString path, QByteArray text) {
252     QFile file(path);
253     if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
254         return;
255
256     QTextStream out(&file);
257     out << text;
258 }
259
260 void BrowseMainWindow::updateList() {
261     int ct = this->mContents->count();
262     if (0 < ct) {
263         QIcon icon_up     = QIcon::fromTheme("filemanager_folder_up");
264         QIcon icon_folder = QIcon::fromTheme("general_folder");
265         QIcon icon_audio  = QIcon::fromTheme("general_audio_file");
266         QIcon icon_video  = QIcon::fromTheme("general_video_file");
267         QIcon icon_image  = QIcon::fromTheme("general_image");
268         QIcon icon_flash  = QIcon::fromTheme("filemanager_flash_file");
269         for (int idx = 0; idx < ct; ++idx) {
270             VlcBrowseElement dir = mContents->at(idx);
271             QListWidgetItem* item;
272             bool item_good = false;
273             if (0 == QString::compare("directory", dir.type)) {
274                 if (0 == QString::compare("..", dir.name)) {
275                     item = new QListWidgetItem(icon_up, dir.name, ui->listWidget, 0);
276                     item_good = true;
277                 }
278                 else {
279                     item = new QListWidgetItem(icon_folder, dir.name, ui->listWidget, 0);
280                     item_good = true;
281                 }
282             }
283             else if (0 == QString::compare("file", dir.type)) {
284                 if ( 0 == QString::compare(dir.extension, "jpg")  ||
285                      0 == QString::compare(dir.extension, "jpeg") ||
286                      0 == QString::compare(dir.extension, "gif")  ||
287                      0 == QString::compare(dir.extension, "png")  ||
288                      0 == QString::compare(dir.extension, "bmp")  ) {
289                     item_good = true;
290                     item = new QListWidgetItem(icon_image, dir.name, ui->listWidget, 0); // .jpg, .jpeg, .gif, .png, .bmp
291                 }
292                 else if ( 0 == QString::compare(dir.extension, "mp3")  ||
293                           0 == QString::compare(dir.extension, "m4a")  ||
294                           0 == QString::compare(dir.extension, "ogg")  ||
295                           0 == QString::compare(dir.extension, "oga")  ||
296                           0 == QString::compare(dir.extension, "wav")  ||
297                           0 == QString::compare(dir.extension, "flac")  ) {
298                     item_good = true;
299                     item = new QListWidgetItem(icon_audio, dir.name, ui->listWidget, 0); // .mp3, .m4a, .ogg, .oga, .wav, .flac
300                 }
301                 else if ( 0 == QString::compare(dir.extension, "avi")  ||
302                           0 == QString::compare(dir.extension, "mpeg") ||
303                           0 == QString::compare(dir.extension, "mpg")  ||
304                           0 == QString::compare(dir.extension, "mov")  ||
305                           0 == QString::compare(dir.extension, "mp4")  ||
306                           0 == QString::compare(dir.extension, "wmv")  ||
307                           0 == QString::compare(dir.extension, "mkv")  ||
308                           0 == QString::compare(dir.extension, "ogv")  ) {
309                     item_good = true;
310                     item = new QListWidgetItem(icon_video, dir.name, ui->listWidget, 0); // .avi, .mpg, .mpeg, .mov, .mp4, .wmv, .mkv, .ogv
311                 }
312                 else if ( 0 == QString::compare(dir.extension, "flv")  ) {
313                     item_good = true;
314                     item = new QListWidgetItem(icon_flash, dir.name, ui->listWidget, 0); // .flv
315                 }
316                 else {
317                     if (dir.name.startsWith("Flash")) {
318                         item_good = true;
319                         item = new QListWidgetItem(icon_flash, dir.name, ui->listWidget, 0);
320                     }
321                     else {
322                         item_good = false;
323                     }
324                 }
325             }
326             if (item_good) {
327                 ui->listWidget->addItem(item);
328             }
329             // other types ignored
330         }
331     }
332 }
333
334