add_subdirectory(colorscopes)
add_subdirectory(commands)
add_subdirectory(projecttree)
+add_subdirectory(utils)
add_subdirectory(databackup)
add_subdirectory(kiss_fft)
add_subdirectory(mimetypes)
widgets/dvdwizardvob_ui.ui
widgets/effectlist_ui.ui
widgets/effectstack_ui.ui
+ widgets/freesound_ui.ui
widgets/geometryval_ui.ui
widgets/geometrywidget_ui.ui
widgets/histogram_ui.ui
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<gui name="kdenlive" version="66">
+<gui name="kdenlive" version="67">
<ToolBar name="extraToolBar" >
<text>Extra Toolbar</text>
<Action name="project_render" />
<Action name="add_text_clip" />
<Action name="add_text_template_clip" />
<Action name="add_folder" />
+ <Action name="download_audio" />
<Menu name="extract_audio" ><text>Extract Audio</text>
</Menu>
<Menu name="stabilize" ><text>Stabilize</text>
#include "audioscopes/spectrogram.h"
#include "archivewidget.h"
#include "databackup/backupwidget.h"
+#include "utils/freesound.h"
#include <KApplication>
QAction *addFolderButton = new KAction(KIcon("folder-new"), i18n("Create Folder"), this);
collection.addAction("add_folder", addFolderButton);
connect(addFolderButton , SIGNAL(triggered()), m_projectList, SLOT(slotAddFolder()));
+
+ QAction *downloadAudio = new KAction(KIcon("download"), i18n("Download Audio"), this);
+ collection.addAction("download_audio", downloadAudio);
+ connect(downloadAudio , SIGNAL(triggered()), this, SLOT(slotDownloadAudio()));
QAction *clipProperties = new KAction(KIcon("document-edit"), i18n("Clip Properties"), this);
collection.addAction("clip_properties", clipProperties);
}
+void MainWindow::slotDownloadAudio()
+{
+ QString currentFolder;
+ if (m_activeDocument) currentFolder = m_activeDocument->projectFolder().path();
+ else currentFolder = KdenliveSettings::defaultprojectfolder();
+ FreeSound *d = new FreeSound(currentFolder);
+ connect(d, SIGNAL(addClip(KUrl)), this, SLOT(slotAddProjectClip(KUrl)));
+ d->show();
+}
+
#include "mainwindow.moc"
#ifdef DEBUG_MAINW
void slotDisableProxies();
void slotElapsedTime();
+ /** @brief Open the freesound audio search dialog. */
+ void slotDownloadAudio();
signals:
Q_SCRIPTABLE void abortRenderJob(const QString &url);
--- /dev/null
+set(kdenlive_SRCS
+ ${kdenlive_SRCS}
+ utils/freesound.cpp
+ PARENT_SCOPE
+)
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
+ * Copyright (C) 2011 by Marco Gittler (marco@gitma.de) *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+
+#include "freesound.h"
+
+#include <QPushButton>
+#include <QSpinBox>
+#include <QListWidget>
+
+#include <KDebug>
+#include "kdenlivesettings.h"
+#include <KGlobalSettings>
+#include <KMessageBox>
+#include <KFileDialog>
+#include <kio/job.h>
+#include <KIO/NetAccess>
+#include <KRun>
+
+#include <qjson/parser.h>
+
+const int imageRole = Qt::UserRole;
+const int urlRole = Qt::UserRole + 1;
+const int soundRole = Qt::UserRole + 2;
+const int durationRole = Qt::UserRole + 3;
+const int previewRole = Qt::UserRole + 4;
+const int authorRole = Qt::UserRole + 5;
+const int authorUrl = Qt::UserRole + 6;
+const int soundUrl = Qt::UserRole + 7;
+
+FreeSound::FreeSound(const QString & folder, QWidget * parent) :
+ QDialog(parent),
+ m_folder(folder)
+{
+ setFont(KGlobalSettings::toolBarFont());
+ setupUi(this);
+ setAttribute(Qt::WA_DeleteOnClose);
+ setWindowTitle(i18n("Search FreeSound Audio Library"));
+ 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(sound_author, SIGNAL(leftClickedUrl(const QString &)), this, SLOT(slotOpenUrl(const QString &)));
+ connect(sound_name, SIGNAL(leftClickedUrl(const QString &)), this, SLOT(slotOpenUrl(const QString &)));
+ m_previewProcess = new QProcess;
+ connect(m_previewProcess, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(slotPreviewStatusChanged(QProcess::ProcessState)));
+}
+
+FreeSound::~FreeSound()
+{
+ if (m_previewProcess) delete m_previewProcess;
+}
+
+void FreeSound::slotStartSearch()
+{
+ m_result.clear();
+ m_currentPreview.clear();
+ m_currentUrl.clear();
+ page_number->blockSignals(true);
+ page_number->setValue(0);
+ page_number->blockSignals(false);
+ QString uri = "http://www.freesound.org/api/sounds/search/?q=";
+ uri.append(search_text->text());
+ uri.append("&api_key=a1772c8236e945a4bee30a64058dabf8");
+ KIO::TransferJob *job = KIO::get(KUrl(uri));
+ connect (job, SIGNAL( data(KIO::Job *, const QByteArray & )), this, SLOT(slotDataIsHere(KIO::Job *,const QByteArray &)));
+ connect(job, SIGNAL(result(KJob*)), this, SLOT(slotShowResults()));
+}
+
+void FreeSound::slotDataIsHere(KIO::Job *,const QByteArray & data )
+{
+ //kDebug() << "data is here";
+ m_result.append(data);
+}
+
+void FreeSound::slotShowResults()
+{
+ QJson::Parser parser;
+ bool ok;
+ m_data = parser.parse(m_result, &ok);
+ QVariant sounds;
+ search_results->blockSignals(true);
+ search_results->clear();
+ if (m_data.canConvert(QVariant::Map)) {
+ QMap <QString, QVariant> map = m_data.toMap();
+ QMap<QString, QVariant>::const_iterator i = map.constBegin();
+ while (i != map.constEnd()) {
+ if (i.key() == "num_results") search_info->setText(i18np("Found %1 result", "Found %1 results", i.value().toInt()));
+ else if (i.key() == "num_pages") {
+ page_number->setMaximum(i.value().toInt());
+ }
+ else if (i.key() == "sounds") {
+ sounds = i.value();
+ if (sounds.canConvert(QVariant::List)) {
+ QList <QVariant> soundsList = sounds.toList();
+ for (int j = 0; j < soundsList.count(); j++) {
+ if (soundsList.at(j).canConvert(QVariant::Map)) {
+ QMap <QString, QVariant> soundmap = soundsList.at(j).toMap();
+ if (soundmap.contains("original_filename")) {
+ QListWidgetItem *item = new QListWidgetItem(soundmap.value("original_filename").toString(), search_results);
+ item->setData(imageRole, soundmap.value("waveform_m").toString());
+ item->setData(soundUrl, soundmap.value("url").toString());
+ item->setData(durationRole, soundmap.value("duration").toDouble());
+ item->setData(previewRole, soundmap.value("preview-hq-mp3").toString());
+ item->setData(soundRole, soundmap.value("serve").toString() + "?api_key=a1772c8236e945a4bee30a64058dabf8");
+ QVariant authorInfo = soundmap.value("user");
+ if (authorInfo.canConvert(QVariant::Map)) {
+ QMap <QString, QVariant> authorMap = authorInfo.toMap();
+ if (authorMap.contains("username")) {
+ item->setData(authorRole, authorMap.value("username").toString());
+ item->setData(authorUrl, authorMap.value("url").toString());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ++i;
+ }
+ }
+ search_results->blockSignals(false);
+ search_results->setCurrentRow(0);
+}
+
+void FreeSound::slotUpdateCurrentSound()
+{
+ m_currentPreview.clear();
+ m_currentUrl.clear();
+ QListWidgetItem *item = search_results->currentItem();
+ if (!item) {
+ sound_box->setEnabled(false);
+ return;
+ }
+ m_currentPreview = item->data(previewRole).toString();
+ m_currentUrl = item->data(soundRole).toString();
+ button_preview->setEnabled(!m_currentPreview.isEmpty());
+ sound_box->setEnabled(true);
+ sound_name->setText(item->text());
+ sound_name->setUrl(item->data(soundUrl).toString());
+ sound_author->setText(item->data(authorRole).toString());
+ sound_author->setUrl(item->data(authorUrl).toString());
+ sound_duration->setText(QString::number(item->data(durationRole).toDouble()));
+ KUrl img(item->data(imageRole).toString());
+ 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);
+ sound_image->setPixmap(pix);
+ KIO::NetAccess::removeTempFile(tmpFile);
+ }
+ }
+}
+
+
+void FreeSound::slotPlaySound()
+{
+ if (m_currentPreview.isEmpty()) return;
+ if (m_previewProcess && m_previewProcess->state() != QProcess::NotRunning) {
+ m_previewProcess->close();
+ return;
+ }
+ m_previewProcess->start("ffplay", QStringList() << m_currentPreview << "-nodisp");
+}
+
+void FreeSound::slotPreviewStatusChanged(QProcess::ProcessState state)
+{
+ if (state == QProcess::NotRunning)
+ button_preview->setText(i18n("Preview"));
+ else
+ button_preview->setText(i18n("Stop"));
+}
+
+void FreeSound::slotSaveSound()
+{
+ if (m_currentUrl.isEmpty()) return;
+ QString path = m_folder;
+ if (!path.endsWith('/')) path.append('/');
+ path.append(sound_name->text());
+ QString ext = "*." + sound_name->text().section('.', -1);
+ QString saveUrl = KFileDialog::getSaveFileName(KUrl(path), ext);
+ if (saveUrl.isEmpty()) return;
+ if (KIO::NetAccess::download(KUrl(m_currentUrl), saveUrl, this)) {
+ emit addClip(KUrl(saveUrl));
+ }
+}
+
+void FreeSound::slotOpenUrl(const QString &url)
+{
+ new KRun(KUrl(url), this);
+}
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
+ * Copyright (C) 2011 by Marco Gittler (marco@gitma.de) *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+
+#ifndef FREESOUND_H
+#define FREESOUND_H
+
+
+#include "ui_freesound_ui.h"
+
+#include <QDialog>
+#include <QProcess>
+#include <kio/jobclasses.h>
+
+
+
+class FreeSound : public QDialog, public Ui::FreeSound_UI
+{
+ Q_OBJECT
+
+public:
+ FreeSound(const QString & folder, QWidget * parent = 0);
+ ~FreeSound();
+
+
+private slots:
+ void slotStartSearch();
+ void slotDataIsHere(KIO::Job *,const QByteArray & data );
+ void slotShowResults();
+ void slotUpdateCurrentSound();
+ void slotPlaySound();
+ void slotPreviewStatusChanged(QProcess::ProcessState state);
+ void slotSaveSound();
+ void slotOpenUrl(const QString &url);
+
+private:
+ QString m_folder;
+ QByteArray m_result;
+ QVariant m_data;
+ QString m_currentPreview;
+ QString m_currentUrl;
+ QProcess *m_previewProcess;
+
+signals:
+ void addClip(KUrl);
+};
+
+
+#endif
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>FreeSound_UI</class>
+ <widget class="QDialog" name="FreeSound_UI">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>334</width>
+ <height>284</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0" colspan="2">
+ <widget class="KLineEdit" name="search_text"/>
+ </item>
+ <item row="0" column="2" colspan="2">
+ <widget class="QPushButton" name="button_search">
+ <property name="text">
+ <string>Search</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4" rowspan="2">
+ <widget class="QGroupBox" name="sound_box">
+ <property name="title">
+ <string/>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="0" colspan="4">
+ <widget class="QLabel" name="sound_image">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" colspan="4">
+ <widget class="QPushButton" name="button_preview">
+ <property name="text">
+ <string>Preview</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0" colspan="2">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Similar sounds</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="3">
+ <widget class="QComboBox" name="similar_list"/>
+ </item>
+ <item row="8" column="1">
+ <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="9" column="0" colspan="4">
+ <widget class="QPushButton" name="button_import">
+ <property name="text">
+ <string>Import</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="3">
+ <widget class="KUrlLabel" name="sound_author">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLabel" name="sound_duration">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Duration</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="2">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="0" colspan="4">
+ <widget class="KUrlLabel" name="sound_name">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="4">
+ <widget class="QListWidget" name="search_results">
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" 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><<</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" colspan="2">
+ <widget class="QSpinBox" name="page_number">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="2" 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>>></string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="4">
+ <widget class="QLabel" name="search_info">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="4">
+ <widget class="QDialogButtonBox" name="ButtonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>KLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>klineedit.h</header>
+ </customwidget>
+ <customwidget>
+ <class>KUrlLabel</class>
+ <extends>QLabel</extends>
+ <header>kurllabel.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>ButtonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>FreeSound_UI</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>ButtonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>FreeSound_UI</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>