Correctly load / save subtitle file

parent f435261a
......@@ -23,6 +23,7 @@
#include "bin/bin.h"
#include "core.h"
#include "project/projectmanager.h"
#include "doc/kdenlivedoc.h"
#include "timeline2/model/snapmodel.hpp"
#include "profiles/profilemodel.hpp"
#include <mlt++/MltProperties.h>
......@@ -42,6 +43,7 @@ SubtitleModel::SubtitleModel(Mlt::Tractor *tractor, QObject *parent)
qDebug()<<"Filter!";
if (tractor != nullptr) {
qDebug()<<"Tractor!";
m_subtitleFilter->set("internal_added", 237);
m_tractor->attach(*m_subtitleFilter.get());
}
setup();
......@@ -64,10 +66,13 @@ std::shared_ptr<SubtitleModel> SubtitleModel::getModel()
return pCore->projectManager()->getSubtitleModel();
}
void SubtitleModel::parseSubtitle()
void SubtitleModel::parseSubtitle(const QString subPath)
{
qDebug()<<"Parsing started";
QString filePath; //"path_to_subtitle_file.srt";
if (!subPath.isEmpty()) {
m_subtitleFilter->set("av.filename", subPath.toUtf8().constData());
}
QString filePath = m_subtitleFilter->get("av.filename");
m_subFilePath = filePath;
QString start,end,comment;
QString timeLine;
......@@ -83,7 +88,7 @@ void SubtitleModel::parseSubtitle()
if (filePath.contains(".srt")) {
QFile srtFile(filePath);
if (!srtFile.exists() && !srtFile.open(QIODevice::ReadOnly)) {
if (!srtFile.exists() || !srtFile.open(QIODevice::ReadOnly)) {
qDebug() << " File not found " << filePath;
return;
}
......@@ -101,15 +106,18 @@ void SubtitleModel::parseSubtitle()
}
if (line.contains("-->")) {
timeLine += line;
QStringList srtTime;
srtTime = timeLine.split(' ');
QStringList srtTime = timeLine.split(' ');
if (srtTime.count() < 3) {
// invalid time
continue;
}
start = srtTime[0];
startPos= stringtoTime(start);
end = srtTime[2];
startPos = stringtoTime(start);
endPos = stringtoTime(end);
} else {
r++;
if (comment != "")
if (!comment.isEmpty())
comment += " ";
if (r == 1)
comment += line;
......@@ -222,8 +230,7 @@ void SubtitleModel::parseSubtitle()
}
assFile.close();
}
toJson();
jsontoSubtitle(toJson());
//jsontoSubtitle(toJson());
}
GenTime SubtitleModel::stringtoTime(QString &str)
......@@ -470,9 +477,12 @@ QString SubtitleModel::toJson()
return QString(jsonDoc.toJson());
}
void SubtitleModel::jsontoSubtitle(const QString &data)
void SubtitleModel::jsontoSubtitle(const QString &data, QString updatedFileName)
{
QString outFile = "path_to_temp_Subtitle.srt"; // use srt format as default unless file is imported (m_subFilePath)
QString outFile = updatedFileName.isEmpty() ? m_subtitleFilter->get("av.filename") : updatedFileName;
if (outFile.isEmpty()) {
outFile = pCore->currentDoc()->subTitlePath(); // use srt format as default unless file is imported (m_subFilePath)
}
if (!outFile.contains(".ass"))
qDebug()<< "srt file import"; // if imported file isn't .ass, it is .srt format
QFile outF(outFile);
......@@ -556,7 +566,7 @@ void SubtitleModel::jsontoSubtitle(const QString &data)
//qDebug() << "ADDING SUBTITLE to FILE AT START POS: " << startPos <<" END POS: "<<endPos;//<< ", FPS: " << pCore->getCurrentFps();
}
}
qDebug()<<"Setting subtitle filter";
qDebug()<<"Setting subtitle filter: "<<outFile;
m_subtitleFilter->set("av.filename", outFile.toUtf8().constData());
m_tractor->attach(*m_subtitleFilter.get());
}
......
......@@ -101,10 +101,10 @@ public:
public slots:
/** @brief Function that parses through a subtitle file */
void parseSubtitle();
void parseSubtitle(const QString subPath = QString());
/** @brief Import model to a temporary subtitle file to which the Subtitle effect is applied*/
void jsontoSubtitle(const QString &data);
void jsontoSubtitle(const QString &data, QString updatedFileName = QString());
private:
std::weak_ptr<DocUndoStack> m_undoStack;
......
......@@ -759,6 +759,26 @@ void KdenliveDoc::setUrl(const QUrl &url)
m_url = url;
}
void KdenliveDoc::updateSubtitle(QString newUrl)
{
if (m_subtitleModel) {
if (newUrl.isEmpty() && m_url.isValid()) {
newUrl = m_url.toLocalFile();
}
QString subPath;
if (newUrl.isEmpty()) {
subPath = subTitlePath();
} else {
// Update path of subtitle file
QString documentId = QDir::cleanPath(getDocumentProperty(QStringLiteral("documentid")));
QFileInfo info(newUrl);
subPath = info.dir().absoluteFilePath(QString("%1.srt").arg(info.fileName()));
}
qDebug()<<"===== SAVING SUBTITLE TO NEW ATH: "<<subPath;
m_subtitleModel->jsontoSubtitle(m_subtitleModel->toJson(), subPath);
}
}
void KdenliveDoc::slotModified()
{
setModified(!m_commandStack->isClean());
......@@ -1779,6 +1799,18 @@ std::shared_ptr<SubtitleModel> KdenliveDoc::getSubtitleModel() const
return m_subtitleModel;
}
QString KdenliveDoc::subTitlePath()
{
QString path;
QString documentId = QDir::cleanPath(getDocumentProperty(QStringLiteral("documentid")));
if (m_url.isValid()) {
return QFileInfo(m_url.toLocalFile()).dir().absoluteFilePath(QString("%1.srt").arg(m_url.fileName()));
} else {
path = QDir::temp().absoluteFilePath(QString("%1.srt").arg(documentId));
}
return path;
}
void KdenliveDoc::subtitlesChanged()
{
//m_subtitleModel->parseSubtitle();
......@@ -1786,15 +1818,15 @@ void KdenliveDoc::subtitlesChanged()
return;
}
void KdenliveDoc::initializeSubtitles(const std::shared_ptr<SubtitleModel> m_subtitle)
void KdenliveDoc::initializeSubtitles(const std::shared_ptr<SubtitleModel> m_subtitle, const QString subPath)
{
m_subtitleModel = m_subtitle;
connect(m_subtitleModel.get(), &SubtitleModel::modelChanged, this, &KdenliveDoc::subtitlesChanged);
m_subtitleModel->parseSubtitle();
m_subtitleModel->parseSubtitle(subPath);
//QMetaObject::invokeMethod(m_subtitle.get(), "parseSubtitle", Qt::QueuedConnection);
}
void KdenliveDoc::removeSubtitles()
{
m_subtitleModel->removeAllSubtitles();
}
\ No newline at end of file
}
......@@ -79,6 +79,8 @@ public:
const QString description() const;
void setUrl(const QUrl &url);
/** @brief Update path of subtitle url. */
void updateSubtitle(QString newUrl = QString());
/** @brief Defines whether the document needs to be saved. */
bool isModified() const;
......@@ -173,9 +175,11 @@ public:
/** @brief Returns a pointer to the subtitle model */
std::shared_ptr<SubtitleModel> getSubtitleModel() const;
/** @brief Initialize and connect subtitle model */
void initializeSubtitles(const std::shared_ptr<SubtitleModel> m_subtitle);
void initializeSubtitles(const std::shared_ptr<SubtitleModel> m_subtitle, const QString subPath = QString());
/** @brief Delete all subtitles from subtitle model */
void removeSubtitles();
/** @brief Returns a path for current document's subtitle file */
QString subTitlePath();
private:
QUrl m_url;
......@@ -276,4 +280,4 @@ signals:
void updateCompositionMode(int);
};
#endif
\ No newline at end of file
#endif
......@@ -21,6 +21,7 @@
#include "effectstackmodel.hpp"
#include "assets/keyframes/model/keyframemodellist.hpp"
#include "core.h"
#include "mainwindow.h"
#include "doc/docundostack.hpp"
#include "effectgroupmodel.hpp"
#include "effectitemmodel.hpp"
......@@ -921,6 +922,11 @@ void EffectStackModel::importEffects(const std::weak_ptr<Mlt::Service> &service,
if (auto ms = m_masterService.lock()) {
ms->attach(*filter.get());
}
if (m_ownerId.first == ObjectType::Master && filter->get("mlt_service") == QLatin1String("avfilter.subtitles")) {
// A subtitle filter, update project
QString subFile(filter->get("av.filename"));
pCore->window()->slotEditSubtitle(subFile);
}
continue;
}
if (filter->get("kdenlive_id") == nullptr) {
......
......@@ -1123,7 +1123,9 @@ void MainWindow::setupActions()
m_buttonSubtitleEditTool->setCheckable(true);
m_buttonSubtitleEditTool->setChecked(false);
addAction(QStringLiteral("subtitle_tool"), m_buttonSubtitleEditTool);
connect(m_buttonSubtitleEditTool, &QAction::triggered, this, &MainWindow::slotEditSubtitle);
connect(m_buttonSubtitleEditTool, &QAction::triggered, [this]() {
slotEditSubtitle();
});
// create tools buttons
m_buttonSelectTool = new QAction(QIcon::fromTheme(QStringLiteral("cursor-arrow")), i18n("Selection tool"), this);
......@@ -4168,14 +4170,12 @@ void MainWindow::slotActivateTarget()
}
}
void MainWindow::slotEditSubtitle()
void MainWindow::slotEditSubtitle(const QString subPath)
{
std::shared_ptr<SubtitleModel> m_subtitleModel;
if (!getMainTimeline()->showSubtitles) {
m_subtitleModel.reset(new SubtitleModel(getMainTimeline()->controller()->tractor(),this));
pCore->currentDoc()->initializeSubtitles(m_subtitleModel);
} else {
pCore->currentDoc()->removeSubtitles();
std::shared_ptr<SubtitleModel> subtitleModel = pCore->currentDoc()->getSubtitleModel();
if (subtitleModel == nullptr) {
subtitleModel.reset(new SubtitleModel(getMainTimeline()->controller()->tractor(),this));
pCore->currentDoc()->initializeSubtitles(subtitleModel, subPath);
}
getMainTimeline()->connectSubtitleModel();
}
......
......@@ -295,6 +295,7 @@ public slots:
void slotSwitchTimelineZone(bool toggled);
/** @brief Open the online services search dialog. */
void slotDownloadResources();
void slotEditSubtitle(const QString subPath = QString());
private slots:
/** @brief Shows the shortcut dialog. */
......@@ -508,7 +509,6 @@ private slots:
void slotActivateVideoTrackSequence();
/** @brief Select target for current track */
void slotActivateTarget();
void slotEditSubtitle();
void slotAddSubtitle();
signals:
......
......@@ -295,6 +295,9 @@ bool ProjectManager::saveFileAs(const QString &outputFileName, bool saveACopy)
// Sync document properties
prepareSave();
QString saveFolder = QFileInfo(outputFileName).absolutePath();
if (!saveACopy) {
m_project->updateSubtitle(outputFileName);
}
QString scene = projectSceneList(saveFolder);
if (!m_replacementPattern.isEmpty()) {
QMapIterator<QString, QString> i(m_replacementPattern);
......@@ -304,6 +307,7 @@ bool ProjectManager::saveFileAs(const QString &outputFileName, bool saveACopy)
}
}
if (!m_project->saveSceneList(outputFileName, scene)) {
m_project->updateSubtitle();
return false;
}
QUrl url = QUrl::fromLocalFile(outputFileName);
......@@ -1091,4 +1095,4 @@ void ProjectManager::addAudioTracks(int tracksCount)
std::shared_ptr<SubtitleModel> ProjectManager::getSubtitleModel()
{
return current()->getSubtitleModel();
}
\ No newline at end of file
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment