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