Commit 03d8d75d authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle

Merge branch '2012'

parents 2c02637c afe60bb7
Pipeline #40577 passed with stage
in 9 minutes and 49 seconds
......@@ -3,17 +3,9 @@
<mime-type type="application/x-kdenlive">
<comment>Kdenlive video project document</comment>
<comment xml:lang="ca">Document de projecte de vídeo del Kdenlive</comment>
<comment xml:lang="ca@valencia">Document de projecte de vídeo del Kdenlive</comment>
<comment xml:lang="en_GB">Kdenlive video project document</comment>
<comment xml:lang="eu">Kdenlive-ko bideo-proiektuaren dokumentua</comment>
<comment xml:lang="fr">Document de projet vidéo pour Kdenlive</comment>
<comment xml:lang="it">Progetto video di Kdenlive</comment>
<comment xml:lang="lt">Kdenlive video projekto dokumentas</comment>
<comment xml:lang="nl">Video projectdocument van Kdenlive</comment>
<comment xml:lang="nn">Kdenlive-videoprosjektdokument</comment>
<comment xml:lang="pt">Documento de projecto de vídeo do Kdenlive</comment>
<comment xml:lang="pt_BR">Documento de projeto de vídeo do Kdenlive</comment>
<comment xml:lang="sl">Dokument video projekta Kdenlive</comment>
<comment xml:lang="sv">Kdenlive-videoprojektdokument</comment>
<comment xml:lang="uk">документ відеопроєкту Kdenlive</comment>
<comment xml:lang="zh_CN">Kdenlive 视频项目文档</comment>
......@@ -23,16 +15,9 @@
<mime-type type="application/x-kdenlivetitle">
<comment>Kdenlive video title</comment>
<comment xml:lang="ca">Títol de vídeo del Kdenlive</comment>
<comment xml:lang="ca@valencia">Títol de vídeo del Kdenlive</comment>
<comment xml:lang="en_GB">Kdenlive video title</comment>
<comment xml:lang="eu">Kdenlive-ko bideo-izenburua</comment>
<comment xml:lang="fr">Titre de vidéo pour Kdenlive</comment>
<comment xml:lang="it">Titolo video di Kdenlive</comment>
<comment xml:lang="nl">Titel van Kdenlive-video</comment>
<comment xml:lang="nn">Kdenlive-videotittel</comment>
<comment xml:lang="pt">Título de vídeo do Kdenlive</comment>
<comment xml:lang="pt_BR">Título de vídeo do Kdenlive</comment>
<comment xml:lang="sl">Naslov videa Kdenlive</comment>
<comment xml:lang="sv">Kdenlive-video</comment>
<comment xml:lang="uk">заголовок відео Kdenlive</comment>
<comment xml:lang="zh_CN">Kdenlive 视频标题</comment>
......
......@@ -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,11 +66,8 @@ std::shared_ptr<SubtitleModel> SubtitleModel::getModel()
return pCore->projectManager()->getSubtitleModel();
}
void SubtitleModel::parseSubtitle()
{
qDebug()<<"Parsing started";
QString filePath; //"path_to_subtitle_file.srt";
m_subFilePath = filePath;
void SubtitleModel::importSubtitle(const QString filePath, int offset)
{
QString start,end,comment;
QString timeLine;
GenTime startPos, endPos;
......@@ -80,10 +79,10 @@ void SubtitleModel::parseSubtitle()
*/
if (filePath.isEmpty())
return;
GenTime subtitleOffset(offset, pCore->getCurrentFps());
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 +100,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;
......@@ -118,7 +120,7 @@ void SubtitleModel::parseSubtitle()
}
turn++;
} else {
addSubtitle(startPos,endPos,comment);
addSubtitle(startPos + subtitleOffset, endPos + subtitleOffset, comment);
//reinitialize
comment = timeLine = "";
turn = 0; r = 0;
......@@ -211,7 +213,7 @@ void SubtitleModel::parseSubtitle()
// Text
comment = dialogue[9]+ remainingStr;
//qDebug()<<"Start: "<< start << "End: "<<end << comment;
addSubtitle(startPos,endPos,comment);
addSubtitle(startPos + subtitleOffset, endPos + subtitleOffset, comment);
}
}
turn++;
......@@ -222,10 +224,21 @@ void SubtitleModel::parseSubtitle()
}
assFile.close();
}
toJson();
jsontoSubtitle(toJson());
}
void SubtitleModel::parseSubtitle(const QString subPath)
{
qDebug()<<"Parsing started";
if (!subPath.isEmpty()) {
m_subtitleFilter->set("av.filename", subPath.toUtf8().constData());
}
QString filePath = m_subtitleFilter->get("av.filename");
m_subFilePath = filePath;
importSubtitle(filePath);
//jsontoSubtitle(toJson());
}
GenTime SubtitleModel::stringtoTime(QString &str)
{
QStringList total,secs;
......@@ -470,9 +483,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 +572,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());
}
......
......@@ -95,16 +95,19 @@ public:
@param newPos is new start position of subtitle
*/
void moveSubtitle(GenTime oldPos, GenTime newPos);
/** @brief Function that imports a subtitle file */
void importSubtitle(const QString filePath, int offset = 0);
/** @brief Exports the subtitle model to json */
QString toJson();
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;
......
......@@ -81,8 +81,9 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, QString projectFolder, QUndoGroup *und
, m_modified(false)
, m_documentOpenStatus(CleanProject)
, m_projectFolder(std::move(projectFolder))
, m_guideModel(new MarkerListModel(m_commandStack, this))
, m_subtitleModel(nullptr)
{
m_guideModel.reset(new MarkerListModel(m_commandStack, this));
connect(m_guideModel.get(), &MarkerListModel::modelChanged, this, &KdenliveDoc::guidesChanged);
connect(this, SIGNAL(updateCompositionMode(int)), parent, SLOT(slotUpdateCompositeAction(int)));
bool success = false;
......@@ -759,6 +760,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 +1800,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 +1819,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) {
......
......@@ -85,6 +85,11 @@
<label>Default mix transition duration.</label>
<default>00:00:01:00</default>
</entry>
<entry name="subtitle_duration" type="String">
<label>Default subtitle duration.</label>
<default>00:00:05:00</default>
</entry>
<entry name="autoimagesequence" type="Bool">
<label>Automatically import image sequences.</label>
......
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
<kpartgui name="kdenlive" version="195" translationDomain="kdenlive">
<kpartgui name="kdenlive" version="196" translationDomain="kdenlive">
<MenuBar>
<Menu name="file" >
<Action name="file_save"/>
......@@ -30,6 +30,7 @@
<Menu name="subtitles" ><text>Subtitles</text>
<Action name="subtitle_tool" />
<Action name="add_subtitle" />
<Action name="import_subtitle" />
</Menu>
<Separator />
<Action name="bin_view_mode" />
......
......@@ -1127,7 +1127,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);
......@@ -1705,6 +1707,7 @@ void MainWindow::setupActions()
addAction(QStringLiteral("delete_all_guides"), i18n("Delete All Guides"), this, SLOT(slotDeleteAllGuides()),
QIcon::fromTheme(QStringLiteral("edit-delete")));
addAction(QStringLiteral("add_subtitle"), i18n("Add Subtitle"), this, SLOT(slotAddSubtitle()), QIcon::fromTheme(QStringLiteral("list-add")), Qt::SHIFT +Qt::Key_S);
addAction(QStringLiteral("import_subtitle"), i18n("Import Subtitle File"), this, SLOT(slotImportSubtitle()), QIcon::fromTheme(QStringLiteral("list-add")));
addAction(QStringLiteral("delete_subtitle_clip"), i18n("Delete Subtitle"), this, SLOT(slotDeleteItem()), QIcon::fromTheme(QStringLiteral("edit-delete")));
m_saveAction = KStandardAction::save(pCore->projectManager(), SLOT(saveFile()), actionCollection());
......@@ -4173,27 +4176,41 @@ void MainWindow::slotActivateTarget()
}
}
void MainWindow::slotEditSubtitle()
void MainWindow::resetSubtitles()
{
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();
// Hide subtitle track
m_buttonSubtitleEditTool->setChecked(false);
getMainTimeline()->showSubtitles = false;
}
void MainWindow::slotEditSubtitle(const QString subPath)
{
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();
}
void MainWindow::slotAddSubtitle()
{
if (!getMainTimeline()->showSubtitles) {
if (pCore->currentDoc()->getSubtitleModel() == nullptr || !getMainTimeline()->showSubtitles) {
slotEditSubtitle();
m_buttonSubtitleEditTool->setChecked(true);
}
getCurrentTimeline()->controller()->addSubtitle();
}
void MainWindow::slotImportSubtitle()
{
if (pCore->currentDoc()->getSubtitleModel() == nullptr || !getMainTimeline()->showSubtitles) {
slotEditSubtitle();
m_buttonSubtitleEditTool->setChecked(true);
}
getCurrentTimeline()->controller()->importSubtitle();
}
#ifdef DEBUG_MAINW
#undef DEBUG_MAINW
#endif
......@@ -141,6 +141,9 @@ public:
/** @brief Raise (show) the project bin*/
void raiseBin();
/** @brief Hide subtitle track */
void resetSubtitles();
protected:
/** @brief Closes the window.
* @return false if the user presses "Cancel" on a confirmation dialog or
......@@ -295,6 +298,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,9 +512,10 @@ private slots:
void slotActivateVideoTrackSequence();
/** @brief Select target for current track */
void slotActivateTarget();
void slotEditSubtitle();
/** @brief Add subtitle clip to timeline */
void slotAddSubtitle();
/** @brief Import a subtitle file */
void slotImportSubtitle();
signals:
Q_SCRIPTABLE void abortRenderJob(const QString &url);
......
......@@ -896,7 +896,32 @@ bool ArchiveWidget::processProjectFile()
// Make a copy of original project file for extra safety
QString backupPath = archive_url->url().toLocalFile() + QDir::separator() + m_name + QStringLiteral("-backup.kdenlive");
QFile source(pCore->currentDoc()->url().toLocalFile());
source.copy(backupPath);
if (!source.copy(backupPath)) {
// Error
KMessageBox::error(this, i18n("Cannot write to file %1", backupPath));
return false;
}
// Copy subtitle files if any
QString sub = pCore->currentDoc()->url().toLocalFile();
if (QFileInfo::exists(sub + QStringLiteral(".srt"))) {
QFile subFile(sub + QStringLiteral(".srt"));
backupPath = archive_url->url().toLocalFile() + QDir::separator() + QFileInfo(subFile).fileName();
if (!subFile.copy(backupPath)) {
// Error
KMessageBox::error(this, i18n("Cannot write to file %1", backupPath));
return false;
}
}
if (QFileInfo::exists(sub + QStringLiteral(".ass"))) {
QFile subFile(sub + QStringLiteral(".ass"));
backupPath = archive_url->url().toLocalFile() + QDir::separator() + QFileInfo(subFile).fileName();
if (!subFile.copy(backupPath)) {
// Error
KMessageBox::error(this, i18n("Cannot write to file %1", backupPath));
return false;
}
}
QString path = archive_url->url().toLocalFile() + QDir::separator() + m_name + QStringLiteral(".kdenlive");
QFile file(path);
......
......@@ -271,6 +271,7 @@ bool ProjectManager::closeCurrentDocument(bool saveChanges, bool quit)
disconnect(pCore->window()->getMainTimeline()->controller(), &TimelineController::durationChanged, this, &ProjectManager::adjustProjectDuration);
pCore->window()->getMainTimeline()->controller()->clipActions.clear();
pCore->window()->getMainTimeline()->controller()->prepareClose();
pCore->window()->resetSubtitles();
if (m_mainTimelineModel) {
m_mainTimelineModel->prepareClose();
}
......@@ -295,6 +296,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 +308,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 +1096,4 @@ void ProjectManager::addAudioTracks(int tracksCount)
std::shared_ptr<SubtitleModel> ProjectManager::getSubtitleModel()
{
return current()->getSubtitleModel();
}
\ No newline at end of file
}
......@@ -875,6 +875,11 @@ Rectangle {
onExited: {
scim = false
}
onDoubleClicked: {
if (root.showSubtitles && root.activeTool === 0 && mouse.y > ruler.height && mouse.y < (ruler.height + subtitleTrack.height)) {
timeline.addSubtitle((scrollView.contentX + mouseX) / timeline.scaleFactor)
}
}
onPositionChanged: {
if (pressed && ((mouse.buttons === Qt.MidButton) || (mouse.buttons === Qt.LeftButton && root.activeTool == 0 && (mouse.modifiers & Qt.ControlModifier) && !shiftPress))) {
// Pan view
......
......@@ -50,8 +50,10 @@
#include "timeline2/view/dialogs/trackdialog.h"
#include "transitions/transitionsrepository.hpp"
#include "audiomixer/mixermanager.hpp"
#include "ui_import_subtitle_ui.h"
#include <KColorScheme>
#include <KRecentDirs>
#include <QApplication>
#include <QClipboard>
#include <QQuickItem>
......@@ -3829,10 +3831,12 @@ void TimelineController::shiftSubtitle(int oldStartFrame, int newStartFrame, int
pCore->pushUndo(local_undo, local_redo, i18n("Move subtitle"));
}
void TimelineController::addSubtitle()
void TimelineController::addSubtitle(int startframe)
{
int startframe = pCore->getTimelinePosition();
int endframe = startframe + 50; //create basic subtitle clip of default width
if (startframe == -1) {
startframe = pCore->getTimelinePosition();
}
int endframe = startframe + pCore->getDurationFromString(KdenliveSettings::subtitle_duration());
auto subtitleModel = pCore->projectManager()->current()->getSubtitleModel();
Fun local_undo = [subtitleModel, startframe, endframe]() {
......@@ -3849,6 +3853,22 @@ void TimelineController::addSubtitle()
pCore->pushUndo(local_undo, local_redo, i18n("Add subtitle"));
}
void TimelineController::importSubtitle()
{
QPointer<QDialog> d = new QDialog;
Ui::ImportSub_UI view;
view.setupUi(d);
d->setWindowTitle(i18n("Import Subtitle"));
if (d->exec() == QDialog::Accepted && !view.subtitle_url->url().isEmpty()) {
auto subtitleModel = pCore->projectManager()->current()->getSubtitleModel();
int offset = 0;
if (view.cursor_pos->isChecked()) {
offset = pCore->getTimelinePosition();
}
subtitleModel->importSubtitle(view.subtitle_url->url().toLocalFile(), offset);
}
}
void TimelineController::deleteSubtitle(int startframe, int endframe, QString text)
{
auto subtitleModel = pCore->projectManager()->current()->getSubtitleModel();
......@@ -3865,5 +3885,4 @@ void TimelineController::deleteSubtitle(int startframe, int endframe, QString te
};
local_redo();
pCore->pushUndo(local_undo, local_redo, i18n("Delete subtitle"));
return;
}
......@@ -579,9 +579,11 @@ public:
/** @brief Shift subtitle clips without changing the clip duration */
Q_INVOKABLE void shiftSubtitle(int oldStartFrame, int newStartFrame, int endFrame=0, QString text = QString());
/** @brief Add subtitle clip at cursor's position in timeline */
Q_INVOKABLE void addSubtitle();
Q_INVOKABLE void addSubtitle(int startframe = -1);
/** @brief Delete subtitle clip with frame as start position*/
Q_INVOKABLE void deleteSubtitle(int frameframe, int endframe, QString Ctext);
/** @brief Import a subtitle file*/
void importSubtitle();
public slots:
void resetView();
......
......@@ -498,7 +498,7 @@ void TimelineWidget::connectSubtitleModel()
{
showSubtitles = !showSubtitles;
//qDebug()<<"null ptr NOT here at root context";
rootObject()->setProperty("showSubtitles",showSubtitles);
rootObject()->setProperty("showSubtitles", showSubtitles);
rootContext()->setContextProperty("subtitleModel", pCore->projectManager()->current()->getSubtitleModel().get());
}
}
\ No newline at end of file
}
......@@ -124,6 +124,16 @@
<item row="3" column="1">
<widget class="QLineEdit" name="kcfg_mix_duration"/>
</item>
<item row="3" column="3">
<widget class="QLineEdit" name="kcfg_subtitle_duration"/>
</item>
<item row="3" column="2">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Subtitles</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ImportSub_UI</class>
<widget class="QDialog" name="ImportSub_UI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>383</width>
<height>204</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="4" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">