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