diff --git a/io/config.h b/io/config.h
index 5259971a5..ea0745650 100644
--- a/io/config.h
+++ b/io/config.h
@@ -9,6 +9,7 @@
#define TIMECODE_DROP 0
#define TIMECODE_NONDROP 1
#define TIMECODE_FRAMES 2
+#define TIMECODE_MILLISECONDS 3
#define RECORD_MODE_MONO 1
#define RECORD_MODE_STEREO 2
diff --git a/mainwindow.cpp b/mainwindow.cpp
index cb8c525e9..612c4996c 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -646,6 +646,7 @@ void MainWindow::viewMenu_About_To_Be_Shown() {
ui->actionFrames->setChecked(config.timecode_view == TIMECODE_FRAMES);
ui->actionDrop_Frame->setChecked(config.timecode_view == TIMECODE_DROP);
ui->actionNon_Drop_Frame->setChecked(config.timecode_view == TIMECODE_NONDROP);
+ ui->actionMilliseconds->setChecked(config.timecode_view == TIMECODE_MILLISECONDS);
ui->actionOff->setChecked(!config.show_title_safe_area);
ui->actionDefault->setChecked(config.show_title_safe_area && !config.use_custom_title_safe_ratio);
@@ -1012,3 +1013,8 @@ void MainWindow::on_actionPage_Autoscroll_triggered() {
void MainWindow::on_actionSmooth_Auto_scroll_triggered() {
config.autoscroll = AUTOSCROLL_SMOOTH_SCROLL;
}
+
+void MainWindow::on_actionMilliseconds_triggered() {
+ config.timecode_view = TIMECODE_MILLISECONDS;
+ update_ui(false);
+}
diff --git a/mainwindow.h b/mainwindow.h
index d4f4052c1..6d9cec2c4 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -211,6 +211,8 @@ private slots:
void on_actionSmooth_Auto_scroll_triggered();
+ void on_actionMilliseconds_triggered();
+
private:
Ui::MainWindow *ui;
void setup_layout(bool reset);
diff --git a/mainwindow.ui b/mainwindow.ui
index 66260f4ce..b444a2a49 100644
--- a/mainwindow.ui
+++ b/mainwindow.ui
@@ -33,7 +33,7 @@
0
0
653
- 19
+ 25
@@ -916,6 +917,14 @@
Smooth Auto-scroll
+
+
+ true
+
+
+ Milliseconds
+
+
diff --git a/panels/viewer.cpp b/panels/viewer.cpp
index 02fec95ac..d6d14380d 100644
--- a/panels/viewer.cpp
+++ b/panels/viewer.cpp
@@ -108,19 +108,37 @@ void Viewer::assert_audio_device() {
long timecode_to_frame(const QString& s, int view, double frame_rate) {
QList list = s.split(QRegExp("[:;]"));
- if (view == TIMECODE_FRAMES || list.size() == 1) {
+ if (view == TIMECODE_FRAMES || (list.size() == 1 && view != TIMECODE_MILLISECONDS)) {
return s.toLong();
}
int frRound = qRound(frame_rate);
- int hours = ((list.size() > 0) ? list.at(0).toInt() : 0) * frRound * 3600;
- int minutes = ((list.size() > 1) ? list.at(1).toInt() : 0) * frRound * 60;
- int seconds = ((list.size() > 2) ? list.at(2).toInt() : 0) * frRound;
- int frames = (list.size() > 3) ? list.at(3).toInt() : 0;
+ int hours, minutes, seconds, frames;
+
+ if (view == TIMECODE_MILLISECONDS) {
+ long milliseconds = s.toLong();
+
+ hours = milliseconds/3600000;
+ milliseconds -= (hours*3600000);
+ minutes = milliseconds/60000;
+ milliseconds -= (minutes*60000);
+ seconds = milliseconds/1000;
+ milliseconds -= (seconds*1000);
+ frames = qRound64((milliseconds*0.001)*frame_rate);
+
+ seconds = qRound64(seconds * frame_rate);
+ minutes = qRound64(minutes * frame_rate * 60);
+ hours = qRound64(hours * frame_rate * 3600);
+ } else {
+ hours = ((list.size() > 0) ? list.at(0).toInt() : 0) * frRound * 3600;
+ minutes = ((list.size() > 1) ? list.at(1).toInt() : 0) * frRound * 60;
+ seconds = ((list.size() > 2) ? list.at(2).toInt() : 0) * frRound;
+ frames = (list.size() > 3) ? list.at(3).toInt() : 0;
+ }
int f = (frames + seconds + minutes + hours);
- if (view == TIMECODE_DROP && frame_rate_is_droppable(frame_rate)) {
+ if ((view == TIMECODE_DROP || view == TIMECODE_MILLISECONDS) && frame_rate_is_droppable(frame_rate)) {
// return drop
int d;
int m;
@@ -155,7 +173,7 @@ QString frame_to_timecode(long f, int view, double frame_rate) {
int frames = 0;
QString token = ":";
- if (view == TIMECODE_DROP && frame_rate_is_droppable(frame_rate)) {
+ if ((view == TIMECODE_DROP || view == TIMECODE_MILLISECONDS) && frame_rate_is_droppable(frame_rate)) {
//CONVERT A FRAME NUMBER TO DROP FRAME TIMECODE
//Code by David Heidelberger, adapted from Andrew Duncan, further adapted for Olive by Olive Team
//Given an int called framenumber and a double called framerate
@@ -165,7 +183,7 @@ QString frame_to_timecode(long f, int view, double frame_rate) {
int m;
int dropFrames = round(frame_rate * .066666); //Number of frames to drop on the minute marks is the nearest integer to 6% of the framerate
- int framesPerHour = round(frame_rate*60*60); //Number of frames in an hour
+ int framesPerHour = round(frame_rate*60*60); //Number of frqRound64ames in an hour
int framesPer24Hours = framesPerHour*24; //Number of frames in a day - timecode rolls over after 24 hours
int framesPer10Minutes = round(frame_rate * 60 * 10); //Number of frames per ten minutes
int framesPerMinute = (round(frame_rate)*60)- dropFrames; //Number of frames per minute is the round of the framerate * 60 minus the number of dropped frames
@@ -199,6 +217,9 @@ QString frame_to_timecode(long f, int view, double frame_rate) {
secs = f/int_fps % 60;
frames = f%int_fps;
}
+ if (view == TIMECODE_MILLISECONDS) {
+ return QString::number((hours*3600000)+(mins*60000)+(secs*1000)+qCeil(frames*1000/frame_rate));
+ }
return QString(QString::number(hours).rightJustified(2, '0') +
":" + QString::number(mins).rightJustified(2, '0') +
":" + QString::number(secs).rightJustified(2, '0') +
diff --git a/project/effectrow.cpp b/project/effectrow.cpp
index 2ce7244c7..fba1cfbe8 100644
--- a/project/effectrow.cpp
+++ b/project/effectrow.cpp
@@ -72,8 +72,10 @@ bool EffectRow::isKeyframing() {
}
void EffectRow::setKeyframing(bool b) {
- keyframing = b;
- keyframe_enable->setChecked(b);
+ if (parent_effect->meta->type != EFFECT_TYPE_TRANSITION) {
+ keyframing = b;
+ keyframe_enable->setChecked(b);
+ }
}
void EffectRow::set_keyframe_enabled(bool enabled) {