diff --git a/mainwindow.cpp b/mainwindow.cpp
index 6d90ca898..66198b6d8 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -923,3 +923,7 @@ void MainWindow::on_actionNest_triggered() {
}
}
}
+
+void MainWindow::on_actionToggle_Show_All_triggered() {
+ if (sequence != NULL) panel_timeline->toggle_show_all();
+}
diff --git a/mainwindow.h b/mainwindow.h
index 513de35bd..da61a9aa9 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -199,6 +199,8 @@ private slots:
void on_actionNest_triggered();
+ void on_actionToggle_Show_All_triggered();
+
private:
Ui::MainWindow *ui;
void setup_layout();
diff --git a/mainwindow.ui b/mainwindow.ui
index 1b6a5ec1e..506187947 100644
--- a/mainwindow.ui
+++ b/mainwindow.ui
@@ -137,6 +137,7 @@
+
@@ -848,6 +849,14 @@
Nest
+
+
+ Toggle Show All
+
+
+ \
+
+
diff --git a/panels/timeline.cpp b/panels/timeline.cpp
index 1d69d48ed..183539296 100644
--- a/panels/timeline.cpp
+++ b/panels/timeline.cpp
@@ -64,7 +64,8 @@ Timeline::Timeline(QWidget *parent) :
transition_tool_clip(-1),
transition_tool_init(false),
transition_tool_proc(false),
- move_insert(false)
+ move_insert(false),
+ showing_all(false)
{
default_track_height = (QGuiApplication::primaryScreen()->logicalDotsPerInch() / 96) * TRACK_DEFAULT_HEIGHT;
@@ -145,6 +146,16 @@ void Timeline::next_cut() {
if (seek_enabled) panel_sequence_viewer->seek(n_cut);
}
+void Timeline::toggle_show_all() {
+ showing_all = !showing_all;
+ if (showing_all) {
+ old_zoom = zoom;
+ set_zoom_value((double) (ui->timeline_area->width() - 200) / (double) sequence->getEndFrame());
+ } else {
+ set_zoom_value(old_zoom);
+ }
+}
+
int Timeline::get_track_height_size(bool video) {
if (video) {
return video_track_heights.size();
@@ -345,14 +356,19 @@ int lerp(int a, int b, double t) {
return ((1.0 - t) * a) + (t * b);
}
-void Timeline::set_zoom(bool in) {
- zoom *= (in) ? 2 : 0.5;
+void Timeline::set_zoom_value(double v) {
+ zoom = v;
ui->headers->update_zoom(zoom);
repaint_timeline();
- // TODO find a way to gradually move towards target_scroll instead of just setting it?
- int target_scroll = getScreenPointFromFrame(zoom, sequence->playhead)-(ui->editAreas->width()>>1);
- ui->horizontalScrollBar->setValue(target_scroll);
+ // TODO find a way to gradually move towards target_scroll instead of just setting it?
+ int target_scroll = getScreenPointFromFrame(zoom, sequence->playhead)-(ui->editAreas->width()>>1);
+ ui->horizontalScrollBar->setValue(target_scroll);
+}
+
+void Timeline::set_zoom(bool in) {
+ showing_all = false;
+ set_zoom_value(zoom * ((in) ? 2 : 0.5));
}
void Timeline::decheck_tool_buttons(QObject* sender) {
diff --git a/panels/timeline.h b/panels/timeline.h
index 77a980c3e..3528c3e0e 100644
--- a/panels/timeline.h
+++ b/panels/timeline.h
@@ -97,6 +97,7 @@ public:
void delete_in_out(bool ripple);
void previous_cut();
void next_cut();
+ void toggle_show_all();
int getTimelineScreenPointFromFrame(long frame);
long getTimelineFrameFromScreenPoint(int x);
@@ -116,6 +117,8 @@ public:
long drag_frame_start;
int drag_track_start;
void update_effect_controls();
+ bool showing_all;
+ double old_zoom;
QVector video_track_heights;
QVector audio_track_heights;
@@ -216,6 +219,7 @@ private slots:
void transition_menu_select(QAction*);
private:
+ void set_zoom_value(double v);
QVector tool_buttons;
void decheck_tool_buttons(QObject* sender);
void set_tool(int tool);
diff --git a/panels/viewer.cpp b/panels/viewer.cpp
index dadbb17a9..f704256a8 100644
--- a/panels/viewer.cpp
+++ b/panels/viewer.cpp
@@ -35,7 +35,8 @@ Viewer::Viewer(QWidget *parent) :
seq(NULL),
playing(false),
created_sequence(false),
- cue_recording_internal(false)
+ cue_recording_internal(false),
+ just_played(false)
{
ui->setupUi(this);
ui->headers->viewer = this;
@@ -283,17 +284,26 @@ void Viewer::play() {
return;
}
playhead_start = seq->playhead;
- start_msecs = QDateTime::currentMSecsSinceEpoch();
playing = true;
+ just_played = true;
set_playpause_icon(false);
- playback_updater.start();
+ start_msecs = QDateTime::currentMSecsSinceEpoch();
timer_update();
- audio_thread->notifyReceiver();
+ }
+}
+
+void Viewer::play_wake() {
+ if (just_played) {
+ start_msecs = QDateTime::currentMSecsSinceEpoch();
+ playback_updater.start();
+ audio_thread->notifyReceiver();
+ just_played = false;
}
}
void Viewer::pause() {
playing = false;
+ just_played = false;
set_playpause_icon(true);
playback_updater.stop();
@@ -394,8 +404,10 @@ void Viewer::set_media(int type, void* media) {
seq->name = footage->name;
seq->using_workarea = footage->using_inout;
- seq->workarea_in = footage->in;
- seq->workarea_out = footage->out;
+ if (footage->using_inout) {
+ seq->workarea_in = footage->in;
+ seq->workarea_out = footage->out;
+ }
seq->frame_rate = 30;
diff --git a/panels/viewer.h b/panels/viewer.h
index da294f8ce..61625ed02 100644
--- a/panels/viewer.h
+++ b/panels/viewer.h
@@ -50,6 +50,7 @@ public:
long playhead_start;
qint64 start_msecs;
QTimer playback_updater;
+ bool just_played;
void cue_recording(long start, long end, int track);
void uncue_recording();
@@ -69,6 +70,7 @@ public:
Ui::Viewer *ui;
public slots:
+ void play_wake();
private slots:
void on_pushButton_clicked();
diff --git a/playback/cacher.cpp b/playback/cacher.cpp
index d8a0d3530..82228bd3e 100644
--- a/playback/cacher.cpp
+++ b/playback/cacher.cpp
@@ -9,6 +9,8 @@
#include "panels/timeline.h"
#include "panels/project.h"
#include "playback/audio.h"
+#include "panels/panels.h"
+#include "panels/viewer.h"
#include "debug.h"
extern "C" {
@@ -37,8 +39,6 @@ double bytes_to_seconds(int nb_bytes, int nb_channels, int sample_rate) {
}
void apply_audio_effects(Clip* c, double timecode_start, AVFrame* frame, int nb_bytes, QVector nests) {
- dout << c->name << timecode_start;
-
// perform all aud io effects
double timecode_end;
timecode_end = timecode_start + bytes_to_seconds(nb_bytes, frame->channels, frame->sample_rate);
@@ -306,8 +306,8 @@ void cache_audio_worker(Clip* c, bool scrubbing, QVector& nests) {
}
}
- int offset = (audio_ibuffer_read + AUDIO_BUFFER_PADDING) - c->audio_buffer_write;
- if (offset > 0) {
+ int offset = audio_ibuffer_read - c->audio_buffer_write;
+ if (offset > 0) {
c->audio_buffer_write += offset;
c->frame_sample_index += offset;
}
@@ -341,7 +341,9 @@ void cache_audio_worker(Clip* c, bool scrubbing, QVector& nests) {
apply_audio_effects(c, bytes_to_seconds(frame->pts, frame->channels, frame->sample_rate), frame, nb_bytes, nests);
c->frame->pts += nb_bytes;
c->frame_sample_index = 0;
- if (c->audio_buffer_write == 0) c->audio_buffer_write = get_buffer_offset_from_frame(sequence, qMax(timeline_in, c->audio_target_frame));
+ if (c->audio_buffer_write == 0) {
+ c->audio_buffer_write = get_buffer_offset_from_frame(sequence, qMax(timeline_in, c->audio_target_frame));
+ }
int offset = audio_ibuffer_read - c->audio_buffer_write;
if (offset > 0) {
c->audio_buffer_write += offset;
@@ -361,6 +363,10 @@ void cache_audio_worker(Clip* c, bool scrubbing, QVector& nests) {
long buffer_timeline_out = get_buffer_offset_from_frame(sequence, timeline_out);
audio_write_lock.lock();
+ dout << "starting fsi:" << c->frame_sample_index << "abw:" << c->audio_buffer_write;
+
+
+
while (c->frame_sample_index < nb_bytes
&& c->audio_buffer_write < audio_ibuffer_read+(audio_ibuffer_size>>1)
&& c->audio_buffer_write < buffer_timeline_out) {
@@ -403,6 +409,9 @@ void cache_audio_worker(Clip* c, bool scrubbing, QVector& nests) {
break;
}
}
+
+ QMetaObject::invokeMethod(panel_footage_viewer, "play_wake", Qt::QueuedConnection);
+ QMetaObject::invokeMethod(panel_sequence_viewer, "play_wake", Qt::QueuedConnection);
}
void cache_video_worker(Clip* c, long playhead) {
diff --git a/ui/sourcetable.cpp b/ui/sourcetable.cpp
index b2324bbcd..dc184da98 100644
--- a/ui/sourcetable.cpp
+++ b/ui/sourcetable.cpp
@@ -16,6 +16,9 @@
#include
#include
#include
+#include
+#include
+#include
SourceTable::SourceTable(QWidget* parent) : QTreeWidget(parent) {
editing_item = NULL;
@@ -29,6 +32,8 @@ SourceTable::SourceTable(QWidget* parent) : QTreeWidget(parent) {
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu()));
}
+
+
void SourceTable::show_context_menu() {
QMenu menu(this);
@@ -45,6 +50,15 @@ void SourceTable::show_context_menu() {
if (type == MEDIA_TYPE_FOOTAGE) {
QAction* replace_action = menu.addAction("Replace/Relink Media");
connect(replace_action, SIGNAL(triggered(bool)), panel_project, SLOT(replace_selected_file()));
+
+#if defined(Q_OS_WIN)
+ QAction* reveal_in_explorer = menu.addAction("Reveal in Explorer");
+#elif defined(Q_OS_MAC)
+ QAction* reveal_in_explorer = menu.addAction("Reveal in Finder");
+#else
+ QAction* reveal_in_explorer = menu.addAction("Reveal in File Manager");
+#endif
+ connect(reveal_in_explorer, SIGNAL(triggered(bool)), this, SLOT(reveal_in_browser()));
}
if (type != MEDIA_TYPE_FOLDER) {
QAction* replace_clip_media = menu.addAction("Replace Clips Using This Media");
@@ -114,6 +128,29 @@ void SourceTable::create_seq_from_selected() {
}
}
+void SourceTable::reveal_in_browser() {
+ Media* m = get_footage_from_tree(selectedItems().at(0));
+
+#if defined(Q_OS_WIN)
+ QStringList args;
+ args << "/select," << QDir::toNativeSeparators(m->url);
+ QProcess::startDetached("explorer", args);
+#elif defined(Q_OS_MAC)
+ QStringList args;
+ args << "-e";
+ args << "tell application \"Finder\"";
+ args << "-e";
+ args << "activate";
+ args << "-e";
+ args << "select POSIX file \""+m->url+"\"";
+ args << "-e";
+ args << "end tell";
+ QProcess::startDetached("osascript", args);
+#else
+ QDesktopServices::openUrl(QUrl::fromLocalFile(m->url.left(m->url.lastIndexOf('/'))));
+#endif
+}
+
void SourceTable::item_renamed(QTreeWidgetItem* item) {
if (editing_item == item) {
MediaRename* mr = new MediaRename();
diff --git a/ui/sourcetable.h b/ui/sourcetable.h
index 13b55e109..77b9a590b 100644
--- a/ui/sourcetable.h
+++ b/ui/sourcetable.h
@@ -29,6 +29,7 @@ private slots:
void item_renamed(QTreeWidgetItem *item);
void show_context_menu();
void create_seq_from_selected();
+ void reveal_in_browser();
};
#endif // SOURCETABLE_H
diff --git a/ui/timelineheader.cpp b/ui/timelineheader.cpp
index 8ad183855..fc3877828 100644
--- a/ui/timelineheader.cpp
+++ b/ui/timelineheader.cpp
@@ -6,10 +6,10 @@
#include "project/undo.h"
#include "panels/viewer.h"
#include "io/config.h"
+#include "debug.h"
#include
#include
-#include
#include
#include
@@ -82,6 +82,9 @@ void TimelineHeader::set_out_point(long new_out) {
} else if (new_in > new_out) {
new_in = 0;
}
+
+ dout << new_in << new_out;
+
undo_stack.push(new SetTimelineInOutCommand(viewer->seq, true, new_in, new_out));
update_parents();
}
diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp
index 7c6e012e4..2f86b7e9b 100644
--- a/ui/timelinewidget.cpp
+++ b/ui/timelinewidget.cpp
@@ -1488,7 +1488,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos) {
} else {
s.out = s.old_out + frame_diff;
}
- } else {
+ } else if (clips_are_movable) {
for (int i=0;iselections.size();i++) {
Selection& s = sequence->selections[i];
s.in = s.old_in + frame_diff;
diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp
index ff0f3590e..71c3bd953 100644
--- a/ui/viewerwidget.cpp
+++ b/ui/viewerwidget.cpp
@@ -235,6 +235,8 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio)
}
}
+ int audio_track_count = 0;
+
QVector current_clips;
for (int i=0;iclips.size();i++) {
@@ -258,6 +260,7 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio)
open_clip(c, !rendering);
}
clip_is_active = true;
+ if (c->track >= 0) audio_track_count++;
} else if (c->open) {
close_clip(c);
}
@@ -486,6 +489,10 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio)
}
}
+ if (audio_track_count == 0) {
+ viewer->play_wake();
+ }
+
glPopMatrix();
if (!nests.isEmpty() && nests.last()->fbo != NULL) {