]> git.sesse.net Git - kdenlive/blob - src/utils/resourcewidget.cpp
Fix compilation with KDE < 4.6 (Nepomuk):
[kdenlive] / src / utils / resourcewidget.cpp
1 /***************************************************************************
2  *   Copyright (C) 2011 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
3  *                                                                         *
4  *                                                                         *
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.                                   *
9  *                                                                         *
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.                          *
14  *                                                                         *
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  ***************************************************************************/
20
21
22 #include "resourcewidget.h"
23 #include "freesound.h"
24 #include "openclipart.h"
25
26 #include <QPushButton>
27 #include <QSpinBox>
28 #include <QListWidget>
29 #include <QDomDocument>
30
31 #include <KDebug>
32 #include "kdenlivesettings.h"
33 #include <KGlobalSettings>
34 #include <KMessageBox>
35 #include <KFileDialog>
36 #include <kio/job.h>
37 #include <KIO/NetAccess>
38 #include <Solid/Networking>
39 #include <KRun>
40
41 #ifdef USE_NEPOMUK AND KDE_IS_VERSION(4,6,0)
42 #include <Nepomuk/Variant>
43 #include <Nepomuk/Resource>
44 #include <Nepomuk/ResourceManager>
45 #include <Soprano/Vocabulary/NAO>
46 #include <Nepomuk/Vocabulary/NIE>
47 #include <Nepomuk/Vocabulary/NDO>
48 #endif
49
50 ResourceWidget::ResourceWidget(const QString & folder, QWidget * parent) :
51         QDialog(parent),
52         m_folder(folder),
53         m_currentService(NULL)
54 {
55     setFont(KGlobalSettings::toolBarFont());
56     setupUi(this);
57     setAttribute(Qt::WA_DeleteOnClose);
58 #ifdef USE_QJSON
59     service_list->addItem(i18n("Freesound Audio Library"), FREESOUND);
60 #endif
61     service_list->addItem(i18n("Open Clip Art Graphic Library"), OPENCLIPART);
62     setWindowTitle(i18n("Search Online Resources"));
63     info_widget->setStyleSheet(QString("QTreeWidget { background-color: transparent;}"));
64     item_description->setStyleSheet(QString("KTextBrowser { background-color: transparent;}"));
65     connect(button_search, SIGNAL(clicked()), this, SLOT(slotStartSearch()));
66     connect(search_results, SIGNAL(currentRowChanged(int)), this, SLOT(slotUpdateCurrentSound()));
67     connect(button_preview, SIGNAL(clicked()), this, SLOT(slotPlaySound()));
68     connect(button_import, SIGNAL(clicked()), this, SLOT(slotSaveSound()));
69     connect(sound_author, SIGNAL(leftClickedUrl(const QString &)), this, SLOT(slotOpenUrl(const QString &)));
70     connect(item_license, SIGNAL(leftClickedUrl(const QString &)), this, SLOT(slotOpenUrl(const QString &)));
71     connect(sound_name, SIGNAL(leftClickedUrl(const QString &)), this, SLOT(slotOpenUrl(const QString &)));
72     connect(service_list, SIGNAL(currentIndexChanged(int)), this, SLOT(slotChangeService()));
73     sound_image->setFixedWidth(180);
74     if (Solid::Networking::status() == Solid::Networking::Unconnected) {
75         slotOffline();
76     }
77     connect(Solid::Networking::notifier(), SIGNAL(shouldConnect()), this, SLOT(slotOnline()));
78     connect(Solid::Networking::notifier(), SIGNAL(shouldDisconnect()), this, SLOT(slotOffline()));
79     connect(page_next, SIGNAL(clicked()), this, SLOT(slotNextPage()));
80     connect(page_prev, SIGNAL(clicked()), this, SLOT(slotPreviousPage()));
81     connect(page_number, SIGNAL(valueChanged(int)), this, SLOT(slotStartSearch(int)));
82     sound_box->setEnabled(false);
83     search_text->setFocus();
84 #ifdef USE_NEPOMUK AND KDE_IS_VERSION(4,6,0)    
85     Nepomuk::ResourceManager::instance()->init();
86 #endif
87     slotChangeService();
88 }
89
90 ResourceWidget::~ResourceWidget()
91 {
92     if (m_currentService) delete m_currentService;
93 }
94
95 void ResourceWidget::slotStartSearch(int page)
96 {
97     /*m_currentPreview.clear();
98     m_currentUrl.clear();*/
99     page_number->blockSignals(true);
100     page_number->setValue(page);
101     page_number->blockSignals(false);
102     m_currentService->slotStartSearch(search_text->text(), page);
103     /*QString uri;
104     if (m_service == FREESOUND) {
105         uri = "http://www.freesound.org/api/sounds/search/?q=";
106         uri.append(search_text->text());
107         if (page > 1) uri.append("&p=" + QString::number(page));
108         uri.append("&api_key=a1772c8236e945a4bee30a64058dabf8");
109     }
110     else if (m_service == OPENCLIPART) {
111         uri = "http://openclipart.org/api/search/?query=";
112         uri.append(search_text->text());
113         if (page > 1) uri.append("&page=" + QString::number(page));
114     }*/
115 }
116
117 void ResourceWidget::slotUpdateCurrentSound()
118 {
119     if (!sound_autoplay->isChecked()) m_currentService->stopItemPreview(NULL);
120     info_widget->clear();
121     item_description->clear();
122     item_license->clear();
123     QListWidgetItem *item = search_results->currentItem();
124     if (!item) {
125         sound_box->setEnabled(false);
126         return;
127     }
128     m_currentInfo = m_currentService->displayItemDetails(item);
129     /*m_currentPreview = item->data(previewRole).toString();
130     m_currentUrl = item->data(downloadRole).toString();
131     m_currentId = item->data(idRole).toInt();*/
132     
133     if (sound_autoplay->isChecked()) m_currentService->startItemPreview(item);
134     sound_box->setEnabled(true);
135     sound_name->setText(item->text());
136     sound_name->setUrl(m_currentInfo.infoUrl);
137     sound_author->setText(m_currentInfo.author);
138     sound_author->setUrl(m_currentInfo.authorUrl);
139     item_description->setHtml(m_currentInfo.description);
140     
141
142     KUrl img(m_currentInfo.imagePreview);
143     if (img.isEmpty()) return;
144     if (KIO::NetAccess::exists(img, KIO::NetAccess::SourceSide, this)) {
145         QString tmpFile;
146         if (KIO::NetAccess::download(img, tmpFile, this)) {
147             QPixmap pix(tmpFile);
148             int newHeight = pix.height() * sound_image->width() / pix.width();
149             if (newHeight > 200) {
150                 sound_image->setScaledContents(false);
151                 //sound_image->setFixedHeight(sound_image->width());
152             }
153             else {
154                 sound_image->setScaledContents(true);
155                 sound_image->setFixedHeight(newHeight);
156             }
157             sound_image->setPixmap(pix);
158             KIO::NetAccess::removeTempFile(tmpFile);
159         }
160     }
161 }
162
163
164 void ResourceWidget::slotDisplayMetaInfo(QMap <QString, QString> metaInfo)
165 {
166     if (metaInfo.contains("description")) {
167         item_description->setHtml(metaInfo.value("description"));
168         metaInfo.remove("description");
169     }
170     if (metaInfo.contains("license")) {
171         parseLicense(metaInfo.value("license"));
172         metaInfo.remove("license");
173     }
174     QMap<QString, QString>::const_iterator i = metaInfo.constBegin();
175     while (i != metaInfo.constEnd()) {
176         new QTreeWidgetItem(info_widget, QStringList() << i.key() << i.value());
177         ++i;
178     }
179     info_widget->resizeColumnToContents(0);
180     info_widget->resizeColumnToContents(1);
181 }
182
183
184 void ResourceWidget::slotPlaySound()
185 {
186     if (!m_currentService) return;
187     bool started = m_currentService->startItemPreview(search_results->currentItem());
188     if (started) button_preview->setText(i18n("Preview"));
189     else button_preview->setText(i18n("Stop"));
190 }
191
192
193 void ResourceWidget::slotForcePlaySound(bool play)
194 {
195     /*
196     if (m_service != FREESOUND) return;
197     m_previewProcess->close();
198     if (m_currentPreview.isEmpty()) return;
199     if (play)
200         m_previewProcess->start("ffplay", QStringList() << m_currentPreview << "-nodisp");
201     */
202 }
203
204 void ResourceWidget::slotPreviewStatusChanged(QProcess::ProcessState state)
205 {
206     /*if (state == QProcess::NotRunning)
207         button_preview->setText(i18n("Preview"));
208     else 
209         button_preview->setText(i18n("Stop"));*/
210 }
211
212 void ResourceWidget::slotSaveSound()
213 {
214     //if (m_currentUrl.isEmpty()) return;
215     QListWidgetItem *item = search_results->currentItem();
216     if (!item) return;
217     QString path = m_folder;
218     if (!path.endsWith('/')) path.append('/');
219     path.append(m_currentService->getDefaultDownloadName(item));
220     QString ext = m_currentService->getExtension(search_results->currentItem());
221     QString saveUrl = KFileDialog::getSaveFileName(KUrl(path), ext);
222     if (saveUrl.isEmpty()) return;
223     if (KIO::NetAccess::download(KUrl(m_currentInfo.itemDownload), saveUrl, this)) {
224         const KUrl filePath = KUrl(saveUrl);
225 #ifdef USE_NEPOMUK AND KDE_IS_VERSION(4,6,0)
226         Nepomuk::Resource res( filePath );
227         res.setProperty( Nepomuk::Vocabulary::NIE::license(), (Nepomuk::Variant) item_license->text() );
228         res.setProperty( Nepomuk::Vocabulary::NIE::licenseType(), (Nepomuk::Variant) item_license->url() );
229         res.setProperty( Nepomuk::Vocabulary::NDO::copiedFrom(), sound_name->url() );
230         //res.setDescription(item_description->toPlainText());
231         //res.setProperty( Soprano::Vocabulary::NAO::description(), 
232 #endif
233         emit addClip(KUrl(saveUrl), QString());//, sound_name->url());
234     }
235 }
236
237 void ResourceWidget::slotOpenUrl(const QString &url)
238 {
239     new KRun(KUrl(url), this);
240 }
241
242 void ResourceWidget::slotChangeService()
243 {
244     if (m_currentService) {
245         delete m_currentService;
246         m_currentService = NULL;
247     }
248     SERVICETYPE service = (SERVICETYPE) service_list->itemData(service_list->currentIndex()).toInt();
249     if (service == FREESOUND) {
250         m_currentService = new FreeSound(search_results);
251     }
252     else if (service == OPENCLIPART) {
253         m_currentService = new OpenClipArt(search_results);
254     }
255     connect(m_currentService, SIGNAL(gotMetaInfo(QMap <QString, QString>)), this, SLOT(slotDisplayMetaInfo(QMap <QString, QString>)));
256     connect(m_currentService, SIGNAL(maxPages(int)), page_number, SLOT(setMaximum(int)));
257     connect(m_currentService, SIGNAL(searchInfo(QString)), search_info, SLOT(setText(QString)));
258     
259     button_preview->setVisible(m_currentService->hasPreview);
260     sound_autoplay->setVisible(m_currentService->hasPreview);
261     search_info->setText(QString());
262     info_widget->setVisible(m_currentService->hasMetadata);
263     if (!search_text->text().isEmpty()) slotStartSearch();
264 }
265
266 void ResourceWidget::slotOnline()
267 {
268     button_search->setEnabled(true);
269     search_info->setText(QString());
270 }
271
272 void ResourceWidget::slotOffline()
273 {
274     button_search->setEnabled(false);
275     search_info->setText(i18n("You need to be online\n for searching"));
276 }
277
278 void ResourceWidget::slotNextPage()
279 {
280     int ix = page_number->value();
281     if (search_results->count() > 0) page_number->setValue(ix + 1);
282 }
283
284 void ResourceWidget::slotPreviousPage()
285 {
286     int ix = page_number->value();
287     if (ix > 1) page_number->setValue(ix - 1);
288 }
289
290 void ResourceWidget::parseLicense(const QString &licenseUrl)
291 {
292     QString licenseName;
293     if (licenseUrl.contains("/sampling+/"))
294         licenseName = "Sampling+";
295     else if (licenseUrl.contains("/by/"))
296         licenseName = "Attribution";
297     else if (licenseUrl.contains("/by-nd/"))
298         licenseName = "Attribution-NoDerivs";
299     else if (licenseUrl.contains("/by-nc-sa/"))
300         licenseName = "Attribution-NonCommercial-ShareAlike";
301     else if (licenseUrl.contains("/by-sa/"))
302         licenseName = "Attribution-ShareAlike";
303     else if (licenseUrl.contains("/by-nc/"))
304         licenseName = "Attribution-NonCommercial";
305     else if (licenseUrl.contains("/by-nc-nd/"))
306         licenseName = "Attribution-NonCommercial-NoDerivs";
307     else if (licenseUrl.contains("/publicdomain/zero/"))
308         licenseName = "Creative Commons 0";
309     else if (licenseUrl.endsWith("/publicdomain"))
310         licenseName = "Public Domain";
311     item_license->setText(i18n("License: %1", licenseName));
312     item_license->setUrl(licenseUrl);
313 }
314