]> git.sesse.net Git - kdenlive/commitdiff
progress on online resources, archive.org now basically works
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Wed, 4 Jan 2012 00:06:47 +0000 (01:06 +0100)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Wed, 4 Jan 2012 00:06:47 +0000 (01:06 +0100)
src/utils/abstractservice.cpp
src/utils/abstractservice.h
src/utils/archiveorg.cpp
src/utils/archiveorg.h
src/utils/freesound.cpp
src/utils/openclipart.cpp
src/utils/resourcewidget.cpp
src/utils/resourcewidget.h
src/widgets/freesound_ui.ui

index 9692eeac4c06a9e802e200e7d0d1852ff2a5729f..47a919d77de73c288d959deff30353af30436425 100644 (file)
@@ -28,6 +28,7 @@ AbstractService::AbstractService(QListWidget *listWidget, QObject * parent) :
         QObject(parent),
         hasPreview(false),
         hasMetadata(false),
+        inlineDownload(false),
         serviceType(NOSERVICE),
         m_listWidget(listWidget)
 {
index 5b03c6404c243fd010ad570e239d173b251e3dd8..7f7c4ed09fa8ca9686187c866a66fc0d7232f8f4 100644 (file)
@@ -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 <QString, QString> info);
+    /** @brief We have an url for current item's preview thumbnail. */
+    void gotThumb(const QString url);
 };
 
 
index af4a9778e4f23421b4fde5d4b47c586d73fd3bc4..de4bb332413001129859b29e1db2eb298e94f074 100644 (file)
@@ -25,6 +25,7 @@
 #include <QSpinBox>
 #include <QListWidget>
 #include <QDomDocument>
+#include <QApplication>
 
 #include <KDebug>
 #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<KIO::StoredTransferJob*>( job );
-    QJson::Parser parser;
-    bool ok;
-    QVariant data = parser.parse(storedQueryJob->data(), &ok);
-    if (data.canConvert(QVariant::Map)) {
-        QMap <QString, QVariant> 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("<style type=\"text/css\">tr.cellone {background-color: %1;}").arg(qApp->palette().alternateBase().color().name());
+    html += "</style><table width=\"100%\" cellspacing=\"0\" cellpadding=\"2\">";
+    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 += "<tr class=\"cellone\">";
+            }
+            else html += "<tr>";
+            html += "<td>" + KUrl(link).fileName() + QString("</td><td><a href=\"%1\">preview</a></td><td><a href=\"%2\">download</a></td></tr>").arg(link + "_preview").arg(link);
         }
     }
-    emit gotMetaInfo(m_metaInfo);
-#endif    
+    html += "</table>";
+    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<KIO::StoredTransferJob*>( 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;
+        }
+    }
+}
index 95c9dc4e22f95ad78b326c445e3b268c20453bf7..51c558f066a9186ba87b6c8c7389ab6c0b5b41da 100644 (file)
@@ -49,10 +49,12 @@ public slots:
 private slots:
     void slotShowResults(KJob* job);
     void slotParseResults(KJob* job);
+    void slotParseThumbs(KJob* job);
     
 private:
     QMap <QString, QString> m_metaInfo;
     QProcess *m_previewProcess;
+    QString m_thumbsPath;
 
 signals:
     void addClip(KUrl, const QString &);
index 11637b2e6cc8e80f74d8da7dc354b53efcbc9374..5cbdf8784688ab287837f99f5a1ed419e70ca40f 100644 (file)
@@ -25,6 +25,7 @@
 #include <QSpinBox>
 #include <QListWidget>
 #include <QDomDocument>
+#include <QApplication>
 
 #include <KDebug>
 #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<KIO::StoredTransferJob*>( job );
     QJson::Parser parser;
     bool ok;
+    int ct = 0;
+    QString html = QString("<style type=\"text/css\">tr.cellone {background-color: %1;}</style>").arg(qApp->palette().alternateBase().color().name());
+    
     QVariant data = parser.parse(storedQueryJob->data(), &ok);
     if (data.canConvert(QVariant::Map)) {
         QMap <QString, QVariant> 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 += "<table width=\"100%\" cellspacing=\"0\" cellpadding=\"2\">";
+    
+        if (m_metaInfo.contains(i18n("Duration"))) {
+            ct++;
+            if (ct %2 == 0) {
+                html += "<tr class=\"cellone\">";
+            }
+            else html += "<tr>";
+            html += "<td>" + i18n("Duration") + "</td><td>" + m_metaInfo.value(i18n("Duration")) + "</td></tr>";
+            m_metaInfo.remove(i18n("Duration"));
+        }
+        
+        if (infos.contains("samplerate")) {
+            ct++;
+            if (ct %2 == 0) {
+                html += "<tr class=\"cellone\">";
+            }
+            else html += "<tr>";
+            html += "<td>" + i18n("Samplerate") + "</td><td>" + QString::number(infos.value("samplerate").toDouble()) + "</td></tr>";
+        }
+        if (infos.contains("channels")) {
+            ct++;
+            if (ct %2 == 0) {
+                html += "<tr class=\"cellone\">";
+            }
+            else html += "<tr>";
+            html += "<td>" + i18n("Channels") + "</td><td>" + QString::number(infos.value("channels").toInt()) + "</td></tr>";
+        }
         if (infos.contains("filesize")) {
+            ct++;
+            if (ct %2 == 0) {
+                html += "<tr class=\"cellone\">";
+            }
+            else html += "<tr>";
             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 += "<td>" + i18n("File size") + "</td><td>" + KIO::convertSize(fSize) + "</td></tr>";
         }
         if (infos.contains("license")) {
             m_metaInfo.insert("license", infos.value("license").toString());
         }
+        html +="</table>";
+        if (infos.contains("description")) {
+            html += "<em>" + infos.value("description").toString() + "</em>";
+        }
     }
+    emit gotMetaInfo(html);
     emit gotMetaInfo(m_metaInfo);
 #endif    
 }
index 2340d99d94e72816fe51009db8bb7915e795828f..f0cf579cbf86e3584d3c77de52328ead0deae05e 100644 (file)
@@ -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;
 }
 
index 80a663d10bd138795df91cae332cf10e0849e48a..60b210ecb57c21c19c9a0e778d168cc60e59179f 100644 (file)
@@ -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("<em>" + m_currentInfo.description + "</em>");
+    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 <QString, QString> 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<QString, QString>::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 <QString, QString>)), this, SLOT(slotDisplayMetaInfo(QMap <QString, QString>)));
     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);
+    }
+}
+
index 001b01f79afb57e047a34a3b6461466f2d8e7854..f4a19c158386ec17bfeb4a3eb80a12525db3d286 100644 (file)
@@ -47,13 +47,16 @@ private slots:
     void slotForcePlaySound(bool play);
     void slotPreviewStatusChanged(QProcess::ProcessState state);
     void slotDisplayMetaInfo(QMap <QString, QString> 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;
index d4934c59dc876e5870d96c0513082d6959111644..a61d5c57cc0485a0bbd231b9c3434547b84073cf 100644 (file)
      </property>
     </widget>
    </item>
-   <item row="1" column="4" rowspan="2">
+   <item row="2" column="0" colspan="4">
+    <widget class="QListWidget" name="search_results">
+     <property name="alternatingRowColors">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="0">
+    <widget class="QPushButton" name="page_prev">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="text">
+      <string>&lt;&lt;</string>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="1" colspan="2">
+    <widget class="QSpinBox" name="page_number">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="minimum">
+      <number>1</number>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="3">
+    <widget class="QPushButton" name="page_next">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="text">
+      <string>&gt;&gt;</string>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="0" colspan="5">
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="QLabel" name="search_info">
+       <property name="text">
+        <string/>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="ButtonBox">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Close</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="1" column="4" rowspan="3">
     <widget class="QGroupBox" name="sound_box">
      <property name="sizePolicy">
       <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
       <string/>
      </property>
      <layout class="QGridLayout" name="gridLayout">
-      <item row="1" column="0" colspan="4">
-       <widget class="QLabel" name="sound_image">
+      <item row="1" column="0" colspan="3">
+       <widget class="QLabel" name="item_image">
         <property name="text">
          <string/>
         </property>
         </property>
        </widget>
       </item>
-      <item row="7" column="2">
-       <spacer name="verticalSpacer">
-        <property name="orientation">
-         <enum>Qt::Vertical</enum>
-        </property>
-        <property name="sizeHint" stdset="0">
-         <size>
-          <width>20</width>
-          <height>40</height>
-         </size>
-        </property>
-       </spacer>
-      </item>
-      <item row="13" column="1" colspan="3">
+      <item row="10" column="1" colspan="2">
        <widget class="QPushButton" name="button_import">
         <property name="text">
          <string>Import</string>
         </property>
        </widget>
       </item>
-      <item row="4" column="0" colspan="4">
+      <item row="4" column="0" colspan="3">
        <widget class="KUrlLabel" name="sound_author">
         <property name="minimumSize">
          <size>
         </property>
        </widget>
       </item>
-      <item row="0" column="0" colspan="4">
+      <item row="0" column="0" colspan="3">
        <widget class="KUrlLabel" name="sound_name">
         <property name="text">
          <string/>
         </property>
        </widget>
       </item>
-      <item row="13" column="0">
+      <item row="10" column="0">
        <widget class="QPushButton" name="button_preview">
         <property name="text">
          <string>Preview</string>
         </property>
        </widget>
       </item>
-      <item row="8" column="0" colspan="4">
-       <widget class="QTreeWidget" name="info_widget">
-        <property name="frameShape">
-         <enum>QFrame::NoFrame</enum>
-        </property>
-        <property name="alternatingRowColors">
-         <bool>true</bool>
-        </property>
-        <property name="selectionMode">
-         <enum>QAbstractItemView::NoSelection</enum>
-        </property>
-        <property name="rootIsDecorated">
-         <bool>false</bool>
-        </property>
-        <property name="allColumnsShowFocus">
-         <bool>true</bool>
-        </property>
-        <property name="headerHidden">
-         <bool>true</bool>
-        </property>
-        <property name="columnCount">
-         <number>2</number>
-        </property>
-        <column>
-         <property name="text">
-          <string notr="true">1</string>
-         </property>
-        </column>
-        <column>
-         <property name="text">
-          <string notr="true">2</string>
-         </property>
-        </column>
-       </widget>
-      </item>
-      <item row="12" column="0">
+      <item row="9" column="0">
        <widget class="QCheckBox" name="sound_autoplay">
         <property name="text">
          <string>Auto play</string>
         </property>
        </widget>
       </item>
-      <item row="9" column="0" colspan="4">
-       <widget class="KTextBrowser" name="item_description">
-        <property name="frameShape">
-         <enum>QFrame::NoFrame</enum>
-        </property>
-        <property name="openExternalLinks">
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-      <item row="11" column="0">
+      <item row="8" column="0">
        <widget class="QLabel" name="label">
         <property name="text">
          <string>License</string>
         </property>
        </widget>
       </item>
-      <item row="11" column="1" colspan="3">
+      <item row="8" column="1" colspan="2">
        <widget class="KUrlLabel" name="item_license">
         <property name="text">
          <string/>
         </property>
        </widget>
       </item>
+      <item row="5" column="0" colspan="3">
+       <widget class="QTextBrowser" name="info_browser">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="frameShape">
+         <enum>QFrame::NoFrame</enum>
+        </property>
+        <property name="openExternalLinks">
+         <bool>false</bool>
+        </property>
+        <property name="openLinks">
+         <bool>false</bool>
+        </property>
+       </widget>
+      </item>
      </layout>
     </widget>
    </item>
-   <item row="2" column="0" colspan="4">
-    <widget class="QListWidget" name="search_results">
-     <property name="alternatingRowColors">
-      <bool>true</bool>
-     </property>
-    </widget>
-   </item>
-   <item row="3" column="0">
-    <widget class="QPushButton" name="page_prev">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="text">
-      <string>&lt;&lt;</string>
-     </property>
-    </widget>
-   </item>
-   <item row="3" column="1" colspan="2">
-    <widget class="QSpinBox" name="page_number">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="minimum">
-      <number>1</number>
-     </property>
-    </widget>
-   </item>
-   <item row="3" column="3">
-    <widget class="QPushButton" name="page_next">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="text">
-      <string>&gt;&gt;</string>
-     </property>
-    </widget>
-   </item>
-   <item row="4" column="0" colspan="5">
-    <layout class="QHBoxLayout" name="horizontalLayout_2">
-     <item>
-      <widget class="QLabel" name="search_info">
-       <property name="text">
-        <string/>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QDialogButtonBox" name="ButtonBox">
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="standardButtons">
-        <set>QDialogButtonBox::Close</set>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
   </layout>
  </widget>
  <customwidgets>
-  <customwidget>
-   <class>KTextBrowser</class>
-   <extends>QTextBrowser</extends>
-   <header>ktextbrowser.h</header>
-  </customwidget>
   <customwidget>
    <class>KLineEdit</class>
    <extends>QLineEdit</extends>