1 /***************************************************************************
2 * Copyright (C) 2011 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
19 ***************************************************************************/
22 #include "freesound.h"
24 #include <QPushButton>
26 #include <QListWidget>
27 #include <QDomDocument>
28 #include <QApplication>
31 #include "kdenlivesettings.h"
36 #include <qjson/parser.h>
39 FreeSound::FreeSound(QListWidget *listWidget, QObject *parent) :
40 AbstractService(listWidget, parent),
41 m_previewProcess(new QProcess)
43 serviceType = FREESOUND;
48 FreeSound::~FreeSound()
50 if (m_previewProcess) delete m_previewProcess;
53 void FreeSound::slotStartSearch(const QString searchText, int page)
55 m_listWidget->clear();
56 QString uri = "http://www.freesound.org/api/sounds/search/?q=";
57 uri.append(searchText);
58 if (page > 1) uri.append("&p=" + QString::number(page));
59 uri.append("&api_key=a1772c8236e945a4bee30a64058dabf8");
61 KJob* resolveJob = KIO::storedGet( KUrl(uri), KIO::NoReload, KIO::HideProgressInfo );
62 connect( resolveJob, SIGNAL( result( KJob* ) ), this, SLOT( slotShowResults( KJob* ) ) );
66 void FreeSound::slotShowResults(KJob* job)
68 if (job->error() != 0 ) return;
69 m_listWidget->blockSignals(true);
70 KIO::StoredTransferJob* storedQueryJob = static_cast<KIO::StoredTransferJob*>( job );
74 //kDebug()<<"// GOT RESULT: "<<m_result;
75 QVariant data = parser.parse(storedQueryJob->data(), &ok);
77 if (data.canConvert(QVariant::Map)) {
78 QMap <QString, QVariant> map = data.toMap();
79 QMap<QString, QVariant>::const_iterator i = map.constBegin();
80 while (i != map.constEnd()) {
81 if (i.key() == "num_results") emit searchInfo(i18np("Found %1 result", "Found %1 results", i.value().toInt()));
82 else if (i.key() == "num_pages") {
83 emit maxPages(i.value().toInt());
85 else if (i.key() == "sounds") {
87 if (sounds.canConvert(QVariant::List)) {
88 QList <QVariant> soundsList = sounds.toList();
89 for (int j = 0; j < soundsList.count(); j++) {
90 if (soundsList.at(j).canConvert(QVariant::Map)) {
91 QMap <QString, QVariant> soundmap = soundsList.at(j).toMap();
92 if (soundmap.contains("original_filename")) {
93 QListWidgetItem *item = new QListWidgetItem(soundmap.value("original_filename").toString(), m_listWidget);
94 item->setData(imageRole, soundmap.value("waveform_m").toString());
95 item->setData(infoUrl, soundmap.value("url").toString());
96 item->setData(infoData, soundmap.value("ref").toString() + "?api_key=a1772c8236e945a4bee30a64058dabf8");
97 item->setData(durationRole, soundmap.value("duration").toDouble());
98 item->setData(idRole, soundmap.value("id").toInt());
99 item->setData(previewRole, soundmap.value("preview-hq-mp3").toString());
100 item->setData(downloadRole, soundmap.value("serve").toString() + "?api_key=a1772c8236e945a4bee30a64058dabf8");
101 QVariant authorInfo = soundmap.value("user");
102 if (authorInfo.canConvert(QVariant::Map)) {
103 QMap <QString, QVariant> authorMap = authorInfo.toMap();
104 if (authorMap.contains("username")) {
105 item->setData(authorRole, authorMap.value("username").toString());
106 item->setData(authorUrl, authorMap.value("url").toString());
118 m_listWidget->blockSignals(false);
119 m_listWidget->setCurrentRow(0);
124 OnlineItemInfo FreeSound::displayItemDetails(QListWidgetItem *item)
131 info.itemPreview = item->data(previewRole).toString();
132 info.itemDownload = item->data(downloadRole).toString();
133 info.itemId = item->data(idRole).toInt();
134 info.itemName = item->text();
135 info.infoUrl = item->data(infoUrl).toString();
136 info.author = item->data(authorRole).toString();
137 info.authorUrl = item->data(authorUrl).toString();
138 m_metaInfo.insert(i18n("Duration"), item->data(durationRole).toString());
139 info.license = item->data(licenseRole).toString();
140 info.description = item->data(descriptionRole).toString();
142 QString extraInfoUrl = item->data(infoData).toString();
143 if (!extraInfoUrl.isEmpty()) {
144 KJob* resolveJob = KIO::storedGet( KUrl(extraInfoUrl), KIO::NoReload, KIO::HideProgressInfo );
145 connect( resolveJob, SIGNAL( result( KJob* ) ), this, SLOT( slotParseResults( KJob* ) ) );
147 emit gotThumb(item->data(imageRole).toString());
152 void FreeSound::slotParseResults(KJob* job)
155 KIO::StoredTransferJob* storedQueryJob = static_cast<KIO::StoredTransferJob*>( job );
156 QJson::Parser parser;
159 QString html = QString("<style type=\"text/css\">tr.cellone {background-color: %1;}</style>").arg(qApp->palette().alternateBase().color().name());
161 QVariant data = parser.parse(storedQueryJob->data(), &ok);
162 if (data.canConvert(QVariant::Map)) {
163 QMap <QString, QVariant> infos = data.toMap();
164 //if (m_currentId != infos.value("id").toInt()) return;
166 html += "<table width=\"100%\" cellspacing=\"0\" cellpadding=\"2\">";
168 if (m_metaInfo.contains(i18n("Duration"))) {
171 html += "<tr class=\"cellone\">";
174 html += "<td>" + i18n("Duration") + "</td><td>" + m_metaInfo.value(i18n("Duration")) + "</td></tr>";
175 m_metaInfo.remove(i18n("Duration"));
178 if (infos.contains("samplerate")) {
181 html += "<tr class=\"cellone\">";
184 html += "<td>" + i18n("Samplerate") + "</td><td>" + QString::number(infos.value("samplerate").toDouble()) + "</td></tr>";
186 if (infos.contains("channels")) {
189 html += "<tr class=\"cellone\">";
192 html += "<td>" + i18n("Channels") + "</td><td>" + QString::number(infos.value("channels").toInt()) + "</td></tr>";
194 if (infos.contains("filesize")) {
197 html += "<tr class=\"cellone\">";
200 KIO::filesize_t fSize = infos.value("filesize").toDouble();
201 html += "<td>" + i18n("File size") + "</td><td>" + KIO::convertSize(fSize) + "</td></tr>";
203 if (infos.contains("license")) {
204 m_metaInfo.insert("license", infos.value("license").toString());
207 if (infos.contains("description")) {
208 m_metaInfo.insert("description", infos.value("description").toString());
211 emit gotMetaInfo(html);
212 emit gotMetaInfo(m_metaInfo);
217 bool FreeSound::startItemPreview(QListWidgetItem *item)
219 if (!item) return false;
220 QString url = item->data(previewRole).toString();
221 if (url.isEmpty()) return false;
222 if (m_previewProcess && m_previewProcess->state() != QProcess::NotRunning) {
223 m_previewProcess->close();
225 m_previewProcess->start("ffplay", QStringList() << url << "-nodisp");
230 void FreeSound::stopItemPreview(QListWidgetItem */*item*/)
232 if (m_previewProcess && m_previewProcess->state() != QProcess::NotRunning) {
233 m_previewProcess->close();
237 QString FreeSound::getExtension(QListWidgetItem *item)
239 if (!item) return QString();
240 return QString("*.") + item->text().section('.', -1);
244 QString FreeSound::getDefaultDownloadName(QListWidgetItem *item)
246 if (!item) return QString();