From ed051c6ed3bf047538f279da0b6b7ad8bd380038 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Wed, 4 Jan 2012 01:06:47 +0100 Subject: [PATCH] progress on online resources, archive.org now basically works --- src/utils/abstractservice.cpp | 1 + src/utils/abstractservice.h | 8 +- src/utils/archiveorg.cpp | 83 ++++++++---- src/utils/archiveorg.h | 2 + src/utils/freesound.cpp | 55 ++++++-- src/utils/openclipart.cpp | 3 +- src/utils/resourcewidget.cpp | 88 ++++++++----- src/utils/resourcewidget.h | 5 +- src/widgets/freesound_ui.ui | 236 ++++++++++++++-------------------- 9 files changed, 269 insertions(+), 212 deletions(-) diff --git a/src/utils/abstractservice.cpp b/src/utils/abstractservice.cpp index 9692eeac..47a919d7 100644 --- a/src/utils/abstractservice.cpp +++ b/src/utils/abstractservice.cpp @@ -28,6 +28,7 @@ AbstractService::AbstractService(QListWidget *listWidget, QObject * parent) : QObject(parent), hasPreview(false), hasMetadata(false), + inlineDownload(false), serviceType(NOSERVICE), m_listWidget(listWidget) { diff --git a/src/utils/abstractservice.h b/src/utils/abstractservice.h index 5b03c640..7f7c4ed0 100644 --- a/src/utils/abstractservice.h +++ b/src/utils/abstractservice.h @@ -41,7 +41,6 @@ const int descriptionRole = Qt::UserRole + 11; enum SERVICETYPE { NOSERVICE = 0, FREESOUND = 1, OPENCLIPART = 2, ARCHIVEORG = 3 }; struct OnlineItemInfo { - QString imagePreview; QString itemPreview; QString itemName; QString itemDownload; @@ -69,6 +68,8 @@ public: bool hasPreview; /** @brief Does this service provide meta info about the item. */ bool hasMetadata; + /** @brief Should we show the "import" button or does this service provide download urls in info browser. */ + bool inlineDownload; /** @brief The type for this service. */ SERVICETYPE serviceType; @@ -84,7 +85,12 @@ protected: signals: void searchInfo(const QString &); void maxPages(int); + /** @brief Emit meta info for current item in formatted html. */ + void gotMetaInfo(const QString); + /** @brief Emit some extra meta info (description, license). */ void gotMetaInfo(QMap info); + /** @brief We have an url for current item's preview thumbnail. */ + void gotThumb(const QString url); }; diff --git a/src/utils/archiveorg.cpp b/src/utils/archiveorg.cpp index af4a9778..de4bb332 100644 --- a/src/utils/archiveorg.cpp +++ b/src/utils/archiveorg.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "kdenlivesettings.h" @@ -40,8 +41,9 @@ ArchiveOrg::ArchiveOrg(QListWidget *listWidget, QObject *parent) : m_previewProcess(new QProcess) { serviceType = ARCHIVEORG; - hasPreview = true; + hasPreview = false; hasMetadata = true; + inlineDownload = true; //connect(m_previewProcess, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(slotPreviewStatusChanged(QProcess::ProcessState))); } @@ -55,7 +57,8 @@ void ArchiveOrg::slotStartSearch(const QString searchText, int page) m_listWidget->clear(); QString uri = "http://www.archive.org/advancedsearch.php?q="; uri.append(searchText); - uri.append("%20AND%20mediatype:MovingImage"); + uri.append("%20AND%20mediatype:movies");//MovingImage"); + uri.append("&fl%5B%5D=creator&fl%5B%5D=description&fl%5B%5D=identifier&fl%5B%5D=licenseurl&fl%5B%5D=title"); uri.append("&rows=30"); if (page > 1) uri.append("&page=" + QString::number(page)); uri.append("&output=json"); //&callback=callback&save=yes#raw"); @@ -96,7 +99,12 @@ void ArchiveOrg::slotShowResults(KJob* job) if (soundmap.contains("title")) { QListWidgetItem *item = new QListWidgetItem(soundmap.value("title").toString(), m_listWidget); item->setData(descriptionRole, soundmap.value("description").toString()); - item->setData(idRole, soundmap.value("identifier").toString()); + item->setData(idRole, soundmap.value("identifier").toString()); + QString author = soundmap.value("creator").toString(); + item->setData(authorRole, author); + if (author.startsWith("http")) item->setData(authorUrl, author); + item->setData(infoUrl, "http://archive.org/details/" + soundmap.value("identifier").toString()); + item->setData(downloadRole, "http://archive.org/download/" + soundmap.value("identifier").toString()); item->setData(licenseRole, soundmap.value("licenseurl").toString()); } } @@ -126,47 +134,51 @@ OnlineItemInfo ArchiveOrg::displayItemDetails(QListWidgetItem *item) info.infoUrl = item->data(infoUrl).toString(); info.author = item->data(authorRole).toString(); info.authorUrl = item->data(authorUrl).toString(); - m_metaInfo.insert(i18n("Duration"), item->data(durationRole).toString()); info.license = item->data(licenseRole).toString(); info.description = item->data(descriptionRole).toString(); - QString extraInfoUrl = item->data(infoData).toString(); + m_metaInfo.insert("url", info.itemDownload); + + QString extraInfoUrl = item->data(downloadRole).toString(); if (!extraInfoUrl.isEmpty()) { KJob* resolveJob = KIO::storedGet( KUrl(extraInfoUrl), KIO::NoReload, KIO::HideProgressInfo ); connect( resolveJob, SIGNAL( result( KJob* ) ), this, SLOT( slotParseResults( KJob* ) ) ); } - info.imagePreview = item->data(imageRole).toString(); return info; } void ArchiveOrg::slotParseResults(KJob* job) { -#ifdef USE_QJSON KIO::StoredTransferJob* storedQueryJob = static_cast( job ); - QJson::Parser parser; - bool ok; - QVariant data = parser.parse(storedQueryJob->data(), &ok); - if (data.canConvert(QVariant::Map)) { - QMap infos = data.toMap(); - //if (m_currentId != infos.value("id").toInt()) return; - if (infos.contains("samplerate")) - m_metaInfo.insert(i18n("Samplerate"), QString::number(infos.value("samplerate").toDouble())); - if (infos.contains("channels")) - m_metaInfo.insert(i18n("Channels"), QString::number(infos.value("channels").toInt())); - if (infos.contains("filesize")) { - KIO::filesize_t fSize = infos.value("filesize").toDouble(); - m_metaInfo.insert(i18n("File size"), KIO::convertSize(fSize)); - } - if (infos.contains("description")) { - m_metaInfo.insert("description", infos.value("description").toString()); + QDomDocument doc; + doc.setContent(storedQueryJob->data()); + QDomNodeList links = doc.elementsByTagName("a"); + QString html = QString(""; + QString link; + int ct = 0; + m_thumbsPath.clear(); + for (int i = 0; i < links.count(); i++) { + QString href = links.at(i).toElement().attribute("href"); + if (href.endsWith(".thumbs/")) { + // sub folder contains image thumbs, display one. + m_thumbsPath = m_metaInfo.value("url") + "/" + href; + KJob* thumbJob = KIO::storedGet( KUrl(m_thumbsPath), KIO::NoReload, KIO::HideProgressInfo ); + connect( thumbJob, SIGNAL( result( KJob* ) ), this, SLOT( slotParseThumbs( KJob* ) ) ); } - if (infos.contains("license")) { - m_metaInfo.insert("license", infos.value("license").toString()); + else if (!href.contains('/') && !href.endsWith(".xml")) { + link = m_metaInfo.value("url") + "/" + href; + ct++; + if (ct %2 == 0) { + html += ""; + } + else html += ""; + html += "").arg(link + "_preview").arg(link); } } - emit gotMetaInfo(m_metaInfo); -#endif + html += "
" + KUrl(link).fileName() + QString("previewdownload
"; + emit gotMetaInfo(html); } @@ -202,3 +214,20 @@ QString ArchiveOrg::getDefaultDownloadName(QListWidgetItem *item) if (!item) return QString(); return item->text(); } + +void ArchiveOrg::slotParseThumbs(KJob* job) +{ + KIO::StoredTransferJob* storedQueryJob = static_cast( job ); + QDomDocument doc; + doc.setContent(storedQueryJob->data()); + QDomNodeList links = doc.elementsByTagName("a"); + if (links.isEmpty()) return; + for (int i = 0; i < links.count(); i++) { + QString href = links.at(i).toElement().attribute("href"); + if (!href.contains('/') && i >= links.count() / 2) { + QString thumbUrl = m_thumbsPath + href; + emit gotThumb(thumbUrl); + break; + } + } +} diff --git a/src/utils/archiveorg.h b/src/utils/archiveorg.h index 95c9dc4e..51c558f0 100644 --- a/src/utils/archiveorg.h +++ b/src/utils/archiveorg.h @@ -49,10 +49,12 @@ public slots: private slots: void slotShowResults(KJob* job); void slotParseResults(KJob* job); + void slotParseThumbs(KJob* job); private: QMap m_metaInfo; QProcess *m_previewProcess; + QString m_thumbsPath; signals: void addClip(KUrl, const QString &); diff --git a/src/utils/freesound.cpp b/src/utils/freesound.cpp index 11637b2e..5cbdf878 100644 --- a/src/utils/freesound.cpp +++ b/src/utils/freesound.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "kdenlivesettings.h" @@ -42,7 +43,6 @@ FreeSound::FreeSound(QListWidget *listWidget, QObject *parent) : serviceType = FREESOUND; hasPreview = true; hasMetadata = true; - //connect(m_previewProcess, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(slotPreviewStatusChanged(QProcess::ProcessState))); } FreeSound::~FreeSound() @@ -143,7 +143,7 @@ OnlineItemInfo FreeSound::displayItemDetails(QListWidgetItem *item) KJob* resolveJob = KIO::storedGet( KUrl(extraInfoUrl), KIO::NoReload, KIO::HideProgressInfo ); connect( resolveJob, SIGNAL( result( KJob* ) ), this, SLOT( slotParseResults( KJob* ) ) ); } - info.imagePreview = item->data(imageRole).toString(); + emit gotThumb(item->data(imageRole).toString()); return info; } @@ -154,25 +154,60 @@ void FreeSound::slotParseResults(KJob* job) KIO::StoredTransferJob* storedQueryJob = static_cast( job ); QJson::Parser parser; bool ok; + int ct = 0; + QString html = QString("").arg(qApp->palette().alternateBase().color().name()); + QVariant data = parser.parse(storedQueryJob->data(), &ok); if (data.canConvert(QVariant::Map)) { QMap infos = data.toMap(); //if (m_currentId != infos.value("id").toInt()) return; - if (infos.contains("samplerate")) - m_metaInfo.insert(i18n("Samplerate"), QString::number(infos.value("samplerate").toDouble())); - if (infos.contains("channels")) - m_metaInfo.insert(i18n("Channels"), QString::number(infos.value("channels").toInt())); + + html += ""; + + if (m_metaInfo.contains(i18n("Duration"))) { + ct++; + if (ct %2 == 0) { + html += ""; + } + else html += ""; + html += ""; + m_metaInfo.remove(i18n("Duration")); + } + + if (infos.contains("samplerate")) { + ct++; + if (ct %2 == 0) { + html += ""; + } + else html += ""; + html += ""; + } + if (infos.contains("channels")) { + ct++; + if (ct %2 == 0) { + html += ""; + } + else html += ""; + html += ""; + } if (infos.contains("filesize")) { + ct++; + if (ct %2 == 0) { + html += ""; + } + else html += ""; KIO::filesize_t fSize = infos.value("filesize").toDouble(); - m_metaInfo.insert(i18n("File size"), KIO::convertSize(fSize)); - } - if (infos.contains("description")) { - m_metaInfo.insert("description", infos.value("description").toString()); + html += ""; } if (infos.contains("license")) { m_metaInfo.insert("license", infos.value("license").toString()); } + html +="
" + i18n("Duration") + "" + m_metaInfo.value(i18n("Duration")) + "
" + i18n("Samplerate") + "" + QString::number(infos.value("samplerate").toDouble()) + "
" + i18n("Channels") + "" + QString::number(infos.value("channels").toInt()) + "
" + i18n("File size") + "" + KIO::convertSize(fSize) + "
"; + if (infos.contains("description")) { + html += "" + infos.value("description").toString() + ""; + } } + emit gotMetaInfo(html); emit gotMetaInfo(m_metaInfo); #endif } diff --git a/src/utils/openclipart.cpp b/src/utils/openclipart.cpp index 2340d99d..f0cf579c 100644 --- a/src/utils/openclipart.cpp +++ b/src/utils/openclipart.cpp @@ -68,6 +68,7 @@ void OpenClipArt::slotShowResults(KJob* job) QListWidgetItem *item = new QListWidgetItem(title.firstChild().nodeValue(), m_listWidget); QDomElement thumb = currentClip.firstChildElement("media:thumbnail"); item->setData(imageRole, thumb.attribute("url")); + emit gotThumb(thumb.attribute("url")); QDomElement enclosure = currentClip.firstChildElement("enclosure"); item->setData(downloadRole, enclosure.attribute("url")); QDomElement link = currentClip.firstChildElement("link"); @@ -101,7 +102,7 @@ OnlineItemInfo OpenClipArt::displayItemDetails(QListWidgetItem *item) info.authorUrl = item->data(authorUrl).toString(); info.license = item->data(licenseRole).toString(); info.description = item->data(descriptionRole).toString(); - info.imagePreview = item->data(imageRole).toString(); + emit gotThumb(item->data(imageRole).toString()); return info; } diff --git a/src/utils/resourcewidget.cpp b/src/utils/resourcewidget.cpp index 80a663d1..60b210ec 100644 --- a/src/utils/resourcewidget.cpp +++ b/src/utils/resourcewidget.cpp @@ -65,17 +65,16 @@ ResourceWidget::ResourceWidget(const QString & folder, QWidget * parent) : #endif service_list->addItem(i18n("Open Clip Art Graphic Library"), OPENCLIPART); setWindowTitle(i18n("Search Online Resources")); - info_widget->setStyleSheet(QString("QTreeWidget { background-color: transparent;}")); - item_description->setStyleSheet(QString("KTextBrowser { background-color: transparent;}")); + info_browser->setStyleSheet(QString("QTextBrowser { background-color: transparent;}")); connect(button_search, SIGNAL(clicked()), this, SLOT(slotStartSearch())); connect(search_results, SIGNAL(currentRowChanged(int)), this, SLOT(slotUpdateCurrentSound())); connect(button_preview, SIGNAL(clicked()), this, SLOT(slotPlaySound())); - connect(button_import, SIGNAL(clicked()), this, SLOT(slotSaveSound())); + connect(button_import, SIGNAL(clicked()), this, SLOT(slotSaveItem())); connect(sound_author, SIGNAL(leftClickedUrl(const QString &)), this, SLOT(slotOpenUrl(const QString &))); connect(item_license, SIGNAL(leftClickedUrl(const QString &)), this, SLOT(slotOpenUrl(const QString &))); connect(sound_name, SIGNAL(leftClickedUrl(const QString &)), this, SLOT(slotOpenUrl(const QString &))); connect(service_list, SIGNAL(currentIndexChanged(int)), this, SLOT(slotChangeService())); - sound_image->setFixedWidth(180); + item_image->setFixedWidth(180); if (Solid::Networking::status() == Solid::Networking::Unconnected) { slotOffline(); } @@ -84,6 +83,8 @@ ResourceWidget::ResourceWidget(const QString & folder, QWidget * parent) : connect(page_next, SIGNAL(clicked()), this, SLOT(slotNextPage())); connect(page_prev, SIGNAL(clicked()), this, SLOT(slotPreviousPage())); connect(page_number, SIGNAL(valueChanged(int)), this, SLOT(slotStartSearch(int))); + connect(info_browser, SIGNAL(anchorClicked(const QUrl &)), this, SLOT(slotOpenLink(const QUrl &))); + sound_box->setEnabled(false); search_text->setFocus(); #ifdef USE_NEPOMUK @@ -109,9 +110,9 @@ void ResourceWidget::slotStartSearch(int page) void ResourceWidget::slotUpdateCurrentSound() { + item_image->setEnabled(false); if (!sound_autoplay->isChecked()) m_currentService->stopItemPreview(NULL); - info_widget->clear(); - item_description->clear(); + info_browser->clear(); item_license->clear(); QListWidgetItem *item = search_results->currentItem(); if (!item) { @@ -126,48 +127,41 @@ void ResourceWidget::slotUpdateCurrentSound() sound_name->setUrl(m_currentInfo.infoUrl); sound_author->setText(m_currentInfo.author); sound_author->setUrl(m_currentInfo.authorUrl); - item_description->setHtml(m_currentInfo.description); - + if (!m_currentInfo.description.isEmpty()) info_browser->setHtml("" + m_currentInfo.description + ""); + if (!m_currentInfo.license.isEmpty()) parseLicense(m_currentInfo.license); +} - KUrl img(m_currentInfo.imagePreview); + +void ResourceWidget::slotLoadThumb(const QString url) +{ + KUrl img(url); if (img.isEmpty()) return; if (KIO::NetAccess::exists(img, KIO::NetAccess::SourceSide, this)) { QString tmpFile; if (KIO::NetAccess::download(img, tmpFile, this)) { QPixmap pix(tmpFile); - int newHeight = pix.height() * sound_image->width() / pix.width(); + int newHeight = pix.height() * item_image->width() / pix.width(); if (newHeight > 200) { - sound_image->setScaledContents(false); - //sound_image->setFixedHeight(sound_image->width()); + item_image->setScaledContents(false); + //item_image->setFixedHeight(item_image->width()); } else { - sound_image->setScaledContents(true); - sound_image->setFixedHeight(newHeight); + item_image->setScaledContents(true); + item_image->setFixedHeight(newHeight); } - sound_image->setPixmap(pix); + item_image->setPixmap(pix); KIO::NetAccess::removeTempFile(tmpFile); } } + item_image->setEnabled(true); } void ResourceWidget::slotDisplayMetaInfo(QMap metaInfo) { - if (metaInfo.contains("description")) { - item_description->setHtml(metaInfo.value("description")); - metaInfo.remove("description"); - } if (metaInfo.contains("license")) { parseLicense(metaInfo.value("license")); - metaInfo.remove("license"); - } - QMap::const_iterator i = metaInfo.constBegin(); - while (i != metaInfo.constEnd()) { - new QTreeWidgetItem(info_widget, QStringList() << i.key() << i.value()); - ++i; } - info_widget->resizeColumnToContents(0); - info_widget->resizeColumnToContents(1); } @@ -199,15 +193,23 @@ void ResourceWidget::slotPreviewStatusChanged(QProcess::ProcessState state) button_preview->setText(i18n("Stop"));*/ } -void ResourceWidget::slotSaveSound() +void ResourceWidget::slotSaveItem(const QString originalUrl) { //if (m_currentUrl.isEmpty()) return; QListWidgetItem *item = search_results->currentItem(); if (!item) return; QString path = m_folder; + QString ext; if (!path.endsWith('/')) path.append('/'); - path.append(m_currentService->getDefaultDownloadName(item)); - QString ext = m_currentService->getExtension(search_results->currentItem()); + if (!originalUrl.isEmpty()) { + path.append(KUrl(originalUrl).fileName()); + ext = "*." + KUrl(originalUrl).fileName().section(".", -1); + m_currentInfo.itemDownload = originalUrl; + } + else { + path.append(m_currentService->getDefaultDownloadName(item)); + ext = m_currentService->getExtension(search_results->currentItem()); + } QString saveUrl = KFileDialog::getSaveFileName(KUrl(path), ext); if (saveUrl.isEmpty()) return; if (KIO::NetAccess::download(KUrl(m_currentInfo.itemDownload), saveUrl, this)) { @@ -247,15 +249,18 @@ void ResourceWidget::slotChangeService() else if (service == ARCHIVEORG) { m_currentService = new ArchiveOrg(search_results); } - + + connect(m_currentService, SIGNAL(gotMetaInfo(const QString)), this, SLOT(slotGotMetaInfo(const QString))); connect(m_currentService, SIGNAL(gotMetaInfo(QMap )), this, SLOT(slotDisplayMetaInfo(QMap ))); connect(m_currentService, SIGNAL(maxPages(int)), page_number, SLOT(setMaximum(int))); connect(m_currentService, SIGNAL(searchInfo(QString)), search_info, SLOT(setText(QString))); + connect(m_currentService, SIGNAL(gotThumb(const QString)), this, SLOT(slotLoadThumb(const QString))); button_preview->setVisible(m_currentService->hasPreview); + button_import->setVisible(!m_currentService->inlineDownload); sound_autoplay->setVisible(m_currentService->hasPreview); search_info->setText(QString()); - info_widget->setVisible(m_currentService->hasMetadata); + info_browser->setVisible(m_currentService->hasMetadata); if (!search_text->text().isEmpty()) slotStartSearch(); } @@ -309,3 +314,22 @@ void ResourceWidget::parseLicense(const QString &licenseUrl) item_license->setUrl(licenseUrl); } +void ResourceWidget::slotGotMetaInfo(const QString info) +{ + info_browser->setHtml(info_browser->toHtml() + info); +} + + +void ResourceWidget::slotOpenLink(const QUrl &url) +{ + QString path = url.toEncoded(); + if (path.endsWith("_preview")) { + path.chop(8); + slotOpenUrl(path); + } + else { + // import file in Kdenlive + slotSaveItem(path); + } +} + diff --git a/src/utils/resourcewidget.h b/src/utils/resourcewidget.h index 001b01f7..f4a19c15 100644 --- a/src/utils/resourcewidget.h +++ b/src/utils/resourcewidget.h @@ -47,13 +47,16 @@ private slots: void slotForcePlaySound(bool play); void slotPreviewStatusChanged(QProcess::ProcessState state); void slotDisplayMetaInfo(QMap metaInfo); - void slotSaveSound(); + void slotSaveItem(const QString originalUrl = QString()); void slotOpenUrl(const QString &url); void slotChangeService(); void slotOnline(); void slotOffline(); void slotNextPage(); void slotPreviousPage(); + void slotGotMetaInfo(const QString info); + void slotOpenLink(const QUrl &url); + void slotLoadThumb(const QString url); private: QString m_folder; diff --git a/src/widgets/freesound_ui.ui b/src/widgets/freesound_ui.ui index d4934c59..a61d5c57 100644 --- a/src/widgets/freesound_ui.ui +++ b/src/widgets/freesound_ui.ui @@ -52,7 +52,74 @@ - + + + + true + + + + + + + + 0 + 0 + + + + << + + + + + + + + 0 + 0 + + + + 1 + + + + + + + + 0 + 0 + + + + >> + + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + @@ -64,8 +131,8 @@ - - + + @@ -74,27 +141,14 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - - + Import - + @@ -110,7 +164,7 @@ - + @@ -120,157 +174,59 @@ - + Preview - - - - QFrame::NoFrame - - - true - - - QAbstractItemView::NoSelection - - - false - - - true - - - true - - - 2 - - - - 1 - - - - - 2 - - - - - + Auto play - - - - QFrame::NoFrame - - - true - - - - + License - + + + + + + 0 + 0 + + + + QFrame::NoFrame + + + false + + + false + + + - - - - true - - - - - - - - 0 - 0 - - - - << - - - - - - - - 0 - 0 - - - - 1 - - - - - - - - 0 - 0 - - - - >> - - - - - - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Close - - - - - - - KTextBrowser - QTextBrowser -
ktextbrowser.h
-
KLineEdit QLineEdit -- 2.39.5