Commit 85435a3b authored by Gary Wang's avatar Gary Wang Committed by Jean-Baptiste Mardelle
Browse files

Guides Exporter: allow set a time offset for markers

parent 424f6aca
......@@ -11,6 +11,7 @@
#include "kdenlive_debug.h"
#include <KMessageWidget>
#include <QDateTimeEdit>
#include <QFontDatabase>
#include <QPushButton>
#include <QClipboard>
......@@ -48,17 +49,26 @@ ExportGuidesDialog::ExportGuidesDialog(const MarkerListModel *model, const GenTi
));
messageWidget->setVisible(false);
updateContentByModel(defaultFormat, markerTypeComboBox->currentIndex() - 1);
updateContentByModel();
QPushButton * btn = buttonBox->addButton(i18n("Copy to Clipboard"), QDialogButtonBox::ActionRole);
btn->setIcon(QIcon::fromTheme("edit-copy"));
connect(markerTypeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this](int newIndex) {
updateContentByModel(formatEdit->text(), newIndex - 1);
connect(markerTypeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this]() {
updateContentByModel();
});
connect(offsetTimeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this](int newIndex) {
offsetTime->setEnabled(newIndex != 0);
updateContentByModel();
});
connect(offsetTime, QOverload<const QTime &>::of(&QDateTimeEdit::timeChanged), this, [this]() {
updateContentByModel();
});
connect(formatEdit, &QLineEdit::textEdited, this, [this]() {
updateContentByModel(formatEdit->text(), markerTypeComboBox->currentIndex() - 1);
updateContentByModel();
});
connect(btn, &QAbstractButton::clicked, this, [this]() {
......@@ -73,7 +83,38 @@ ExportGuidesDialog::~ExportGuidesDialog()
{
}
void ExportGuidesDialog::updateContentByModel(const QString & format, int markerIndex) const
double ExportGuidesDialog::offsetTimeMs() const
{
switch (offsetTimeComboBox->currentIndex()) {
case 1: // Add
return offsetTime->time().msecsSinceStartOfDay();
case 2: // Subtract
return - offsetTime->time().msecsSinceStartOfDay();
case 0: // Disabled
default:
return 0;
}
}
void ExportGuidesDialog::updateContentByModel() const
{
updateContentByModel(formatEdit->text(), markerTypeComboBox->currentIndex() - 1, offsetTimeMs());
}
QString chapterTimeStringFromMs(double timeMs) {
bool negative = timeMs < 0;
int totalSec = qAbs(timeMs / 1000);
int hour = totalSec / 3600;
int min = totalSec % 3600 / 60;
int sec = totalSec % 3600 % 60;
if (hour == 0) {
return QString::asprintf("%s%d:%02d", negative ? "-" : "", min, sec);
} else {
return QString::asprintf("%s%d:%02d:%02d", negative ? "-" : "", hour, min, sec);
}
}
void ExportGuidesDialog::updateContentByModel(const QString & format, int markerIndex, double offset) const
{
QStringList chapterTexts;
QList<CommentedTime> markers(m_markerListModel->getAllMarkers(markerIndex));
......@@ -81,26 +122,27 @@ void ExportGuidesDialog::updateContentByModel(const QString & format, int marker
bool needShowInfoMsg = false;
const int markerCount = markers.length();
const double currentFps = pCore->getCurrentFps();
for (int i = 0; i < markers.length(); i++) {
const CommentedTime &currentMarker = markers.at(i);
const GenTime &nextGenTime = markerCount - 1 == i ? m_projectDuration : markers.at(i + 1).time();
QString line(format);
QTime currentTime = QTime(0,0).addMSecs(currentMarker.time().ms());
QTime nextTime = QTime(0,0).addMSecs(nextGenTime.ms());
double currentTimeMs = currentMarker.time().ms() + offset;
double nextTimeMs = nextGenTime.ms() + offset;
if (i == 0 && needCheck && currentTime.msec() != 0) {
if (i == 0 && needCheck && !qFuzzyCompare(currentTimeMs, 0)) {
needShowInfoMsg = true;
}
if (needCheck && currentTime.secsTo(nextTime) < 10) {
if (needCheck && (nextTimeMs / 1000 - currentTimeMs / 1000) < 10) {
needShowInfoMsg = true;
}
line.replace("{{index}}", QString::number(i + 1));
line.replace("{{timecode}}", currentTime.hour() <= 0 ? currentTime.toString("mm:ss") : currentTime.toString("h:mm:ss"));
line.replace("{{nexttimecode}}", nextTime.hour() <= 0 ? nextTime.toString("mm:ss") : nextTime.toString("h:mm:ss"));
line.replace("{{frame}}", QString::number(currentMarker.time().frames(pCore->getCurrentFps())));
line.replace("{{timecode}}", chapterTimeStringFromMs(currentTimeMs));
line.replace("{{nexttimecode}}", chapterTimeStringFromMs(nextTimeMs));
line.replace("{{frame}}", QString::number(currentMarker.time().frames(currentFps)));
line.replace("{{comment}}", currentMarker.comment());
chapterTexts.append(line);
}
......
......@@ -30,7 +30,9 @@ public:
~ExportGuidesDialog() override;
private:
void updateContentByModel(const QString &format, int markerIndex) const;
double offsetTimeMs() const;
void updateContentByModel() const;
void updateContentByModel(const QString &format, int markerIndex, double offset) const;
const MarkerListModel * m_markerListModel;
const GenTime m_projectDuration;
......
......@@ -14,17 +14,7 @@
<string>Marker</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="4" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QPlainTextEdit" name="generatedContent">
<property name="readOnly">
<bool>true</bool>
......@@ -34,8 +24,12 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="formatEdit"/>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Exported:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="markerTypeComboBox">
......@@ -66,29 +60,82 @@
</property>
</widget>
</item>
<item row="1" column="0">
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Format:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<item row="4" column="0" colspan="2">
<widget class="KMessageWidget" name="messageWidget" native="true">
<property name="closeButtonVisible" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="formatEdit"/>
</item>
<item row="5" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Exported:</string>
<string>Offset:</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="KMessageWidget" name="messageWidget">
<property name="closeButtonVisible" stdset="0">
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QComboBox" name="offsetTimeComboBox">
<item>
<property name="text">
<string>Disabled</string>
</property>
</item>
<item>
<property name="text">
<string>Add</string>
</property>
</item>
<item>
<property name="text">
<string>Subtract</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QTimeEdit" name="offsetTime">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</property>
<property name="displayFormat">
<string>h:mm:ss</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KMessageWidget</class>
<extends>QWidget</extends>
<header>kmessagewidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
......
  • @garywang Maybe we could put a link for the "guide Export" into the render widget?

    grafik

  • Author Contributor

    Maybe we could put a link for the "guide Export" into the render widget?

    @emohr Seems like a good idea, will send a MR later :)

  • Personally I am not sure if this is a good idea, at least as shown in the mockup. I have the feeling that this will overload the render widget especially if we are going to add more export option like eg. the one requested here #1434

    I would prefer to add a "Export" sub menu either to the "File" menu or the "Project" menu and put the export options there. If we really want to have it in the Render Dialog (which is still a "Render" dialog and not an "Export" dialog) we should have a small menu button somewhere and not big one with icon and text

  • My thought was: User is rendering and wants to export the guide as youtube marker as well: "Where can I find that possibility?".

    Maybe under "File" an "Export" sub menu for all kind of exports would be a good idea. Even the subtitle export we could put there as well.

  • I understand you idea and if we find a discreet to add it to the render dialog it is okay, I think, but we should overload the GUI. Putting it in the place you suggested is tricky on smaller screens since it blows the min width of the dialog… I have no good idea where else to put it yet.

  • Another place for a link to an "export collector" would be: more option -> instead of Export Metadata. In such an "export collector" under "File" we could put all possible exports together like: Export Metadata, Subtitles, Guides, …" and all existing exports would link/point to this collector.

  • Author Contributor

    I did think about it and now I think it might not be a good idea to put the "export guides" button here. Since this dialog is "Rendering" dialog and all what it does is things related to rendering. Maybe we can put an Export button next to the Render button on the toolbar so it can be more noticeable.

    mock up

Supports Markdown
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