-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial proof-of-concept for QML filter view and favorite filters
- Loading branch information
Showing
42 changed files
with
996 additions
and
498 deletions.
There are no files selected for viewing
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
/* | ||
* Copyright (c) 2014 Meltytech, LLC | ||
* Author: Brian Matherly <code@brianmatherly.com> | ||
* | ||
* 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 3 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, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
#include "filtercontroller.h" | ||
#include <QQmlEngine> | ||
#include <QDir> | ||
#include <QDebug> | ||
#include <QQmlComponent> | ||
#include <QtConcurrent/QtConcurrentRun> | ||
#include "mltcontroller.h" | ||
#include "settings.h" | ||
#include "qmltypes/qmlmetadata.h" | ||
#include "qmltypes/qmlutilities.h" | ||
#include "qmltypes/qmlfilter.h" | ||
|
||
FilterController::FilterController(QObject* parent) : QObject(parent), | ||
m_metadataModel(this), | ||
m_attachedModel(this), | ||
m_currentFilterIndex(-1) | ||
{ | ||
// Process filters in a separate thread and add them to the model asynchronously. | ||
connect(this, SIGNAL(newMetadataFound(QmlMetadata*)), this, SLOT(addMetadata(QmlMetadata*)), Qt::QueuedConnection); | ||
m_future = QtConcurrent::run(this, &FilterController::loadFilterMetadata); | ||
|
||
connect(&m_attachedModel, SIGNAL(changed()), this, SLOT(handleAttachedModelChange())); | ||
} | ||
|
||
void FilterController::loadFilterMetadata() { | ||
QQmlEngine engine; | ||
QDir dir = QmlUtilities::qmlDir(); | ||
dir.cd("filters"); | ||
foreach (QString dirName, dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Executable)) { | ||
QDir subdir = dir; | ||
subdir.cd(dirName); | ||
subdir.setFilter(QDir::Files | QDir::NoDotAndDotDot | QDir::Readable); | ||
subdir.setNameFilters(QStringList("meta*.qml")); | ||
foreach (QString fileName, subdir.entryList()) { | ||
qDebug() << "reading filter metadata" << dirName << fileName; | ||
QQmlComponent component(&engine, subdir.absoluteFilePath(fileName)); | ||
QmlMetadata *meta = qobject_cast<QmlMetadata*>(component.create()); | ||
if (meta && (meta->isAudio() || (meta->needsGPU() == Settings.playerGPU()))) { | ||
// Check if mlt_service is available. | ||
if (MLT.repository()->filters()->get_data(meta->mlt_service().toLatin1().constData())) { | ||
qDebug() << "added filter" << meta->name(); | ||
meta->loadSettings(); | ||
meta->setPath(subdir); | ||
meta->setParent(0); | ||
meta->moveToThread(this->thread()); | ||
emit newMetadataFound(meta); | ||
} | ||
} else if (!meta) { | ||
qWarning() << component.errorString(); | ||
} | ||
} | ||
}; | ||
} | ||
|
||
QmlMetadata *FilterController::metadataForService(Mlt::Service *service) | ||
{ | ||
m_future.waitForFinished(); | ||
QmlMetadata* meta = NULL; | ||
int rowCount = m_metadataModel.rowCount(); | ||
QString uniqueId = service->get("shotcut:filter"); | ||
|
||
// Fallback to mlt_service for legacy filters | ||
if (uniqueId.isEmpty()) { | ||
uniqueId = service->get("mlt_service"); | ||
} | ||
|
||
for (int i = 0; i < rowCount; i++) { | ||
QmlMetadata* tmpMeta = m_metadataModel.get(i); | ||
if (tmpMeta->uniqueId() == uniqueId) { | ||
meta = tmpMeta; | ||
break; | ||
} | ||
} | ||
|
||
return meta; | ||
} | ||
|
||
MetadataModel* FilterController::metadataModel() | ||
{ | ||
return &m_metadataModel; | ||
} | ||
|
||
AttachedFiltersModel* FilterController::attachedModel() | ||
{ | ||
return &m_attachedModel; | ||
} | ||
|
||
void FilterController::setProducer(Mlt::Producer *producer) | ||
{ | ||
m_currentFilter.reset(NULL); | ||
m_attachedModel.reset(producer); | ||
} | ||
|
||
void FilterController::attachFilter(int metadataIndex) | ||
{ | ||
QmlMetadata* meta = m_metadataModel.get(metadataIndex); | ||
QmlFilter* filter = NULL; | ||
if (meta) { | ||
filter = new QmlFilter(m_attachedModel, *meta, -1); | ||
m_currentFilterIndex = m_attachedModel.rowCount() - 1; | ||
} else { | ||
m_currentFilterIndex = -1; | ||
} | ||
emit currentFilterChanged(filter, meta); | ||
m_currentFilter.reset(filter); | ||
} | ||
|
||
void FilterController::removeFilter(int attachedIndex) | ||
{ | ||
QModelIndex index = m_attachedModel.index(attachedIndex); | ||
if (index.isValid()) { | ||
m_attachedModel.remove(index.row()); | ||
} | ||
} | ||
|
||
void FilterController::setCurrentFilter(int attachedIndex) | ||
{ | ||
if( attachedIndex == m_currentFilterIndex ) { | ||
return; | ||
} | ||
|
||
Mlt::Filter* mltFilter = m_attachedModel.filterForRow(attachedIndex); | ||
QmlMetadata* meta = NULL; | ||
QmlFilter* filter = NULL; | ||
|
||
if (mltFilter && mltFilter->is_valid()) { | ||
meta = metadataForService(mltFilter); | ||
if (meta) { | ||
filter = new QmlFilter(m_attachedModel, *meta, attachedIndex); | ||
} | ||
} | ||
|
||
if (meta) { | ||
m_currentFilterIndex = attachedIndex; | ||
} else { | ||
m_currentFilterIndex = -1; | ||
} | ||
|
||
emit currentFilterChanged(filter, meta); | ||
m_currentFilter.reset(filter); | ||
delete mltFilter; | ||
} | ||
|
||
void FilterController::setFadeInDuration(int duration) | ||
{ | ||
/* TODO: implement this | ||
if (m_quickObject && ui->listView->currentIndex().isValid()) { | ||
Mlt::Filter* filter = m_model.filterForRow(ui->listView->currentIndex().row()); | ||
if (filter && filter->is_valid() | ||
&& QString(filter->get("shotcut:filter")).startsWith("fadeIn")) { | ||
m_quickObject->setProperty("duration", duration); | ||
} | ||
delete filter; | ||
} | ||
*/ | ||
} | ||
|
||
void FilterController::setFadeOutDuration(int duration) | ||
{ | ||
/* TODO: implement this | ||
if (m_quickObject && ui->listView->currentIndex().isValid()) { | ||
Mlt::Filter* filter = m_model.filterForRow(ui->listView->currentIndex().row()); | ||
if (filter && filter->is_valid() | ||
&& QString(filter->get("shotcut:filter")).startsWith("fadeOut")) { | ||
m_quickObject->setProperty("duration", duration); | ||
} | ||
delete filter; | ||
} | ||
*/ | ||
} | ||
|
||
void FilterController::handleAttachedModelChange() | ||
{ | ||
MLT.refreshConsumer(); | ||
} | ||
|
||
void FilterController::addMetadata(QmlMetadata* meta) | ||
{ | ||
m_metadataModel.add(meta); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* Copyright (c) 2014 Meltytech, LLC | ||
* Author: Brian Matherly <code@brianmatherly.com> | ||
* | ||
* 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 3 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, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#ifndef FILTERCONTROLLER_H | ||
#define FILTERCONTROLLER_H | ||
|
||
#include <QObject> | ||
#include <QScopedPointer> | ||
#include <QFuture> | ||
#include "models/metadatamodel.h" | ||
#include "models/attachedfiltersmodel.h" | ||
#include "qmltypes/qmlmetadata.h" | ||
#include "qmltypes/qmlfilter.h" | ||
|
||
class FilterController : public QObject | ||
{ | ||
Q_OBJECT | ||
|
||
public: | ||
explicit FilterController(QObject* parent = 0); | ||
MetadataModel* metadataModel(); | ||
AttachedFiltersModel* attachedModel(); | ||
|
||
QmlMetadata* metadataForService(Mlt::Service *service); | ||
|
||
signals: | ||
void currentFilterChanged(QmlFilter* filter, QmlMetadata* meta); | ||
void newMetadataFound(QmlMetadata* meta); | ||
|
||
public slots: | ||
void setProducer(Mlt::Producer *producer = 0); | ||
void attachFilter(int metadataIndex); | ||
void removeFilter(int attachedIndex); | ||
void setCurrentFilter(int attachedIndex); | ||
void setFadeInDuration(int duration); | ||
void setFadeOutDuration(int duration); | ||
|
||
private slots: | ||
void handleAttachedModelChange(); | ||
void addMetadata(QmlMetadata*); | ||
|
||
private: | ||
void loadFilterMetadata(); | ||
|
||
QFuture<void> m_future; | ||
QScopedPointer<QmlFilter> m_currentFilter; | ||
MetadataModel m_metadataModel; | ||
AttachedFiltersModel m_attachedModel; | ||
int m_currentFilterIndex; | ||
}; | ||
|
||
#endif // FILTERCONTROLLER_H |
Oops, something went wrong.