implemented replacing media and importing folders
This commit is contained in:
+38
-9
@@ -12,6 +12,8 @@
|
||||
#include <QMimeData>
|
||||
#include <QHeaderView>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QFileInfo>
|
||||
#include <QDebug>
|
||||
|
||||
SourceTable::SourceTable(QWidget* parent) : QTreeWidget(parent) {
|
||||
@@ -35,23 +37,36 @@ void SourceTable::show_context_menu(const QPoint& pos) {
|
||||
if (selectedItems().size() == 1) {
|
||||
// replace footage
|
||||
if (get_type_from_tree(selectedItems().at(0)) == MEDIA_TYPE_FOOTAGE) {
|
||||
menu.addAction("Replace/Relink Media");
|
||||
QAction* replace_action = menu.addAction("Replace/Relink Media");
|
||||
connect(replace_action, SIGNAL(triggered(bool)), panel_project, SLOT(replace_media()));
|
||||
}
|
||||
menu.addAction("Replace Clips Using This Media");
|
||||
}
|
||||
|
||||
// duplicate item
|
||||
bool all_sequences = true;
|
||||
bool all_footage = true;
|
||||
for (int i=0;i<selectedItems().size();i++) {
|
||||
if (get_type_from_tree(selectedItems().at(i)) != MEDIA_TYPE_SEQUENCE) {
|
||||
all_sequences = false;
|
||||
break;
|
||||
all_sequences = false;
|
||||
}
|
||||
if (get_type_from_tree(selectedItems().at(i)) != MEDIA_TYPE_FOOTAGE) {
|
||||
all_footage = false;
|
||||
}
|
||||
}
|
||||
|
||||
// ONLY sequences are selected
|
||||
if (all_sequences) {
|
||||
// ONLY sequences are selected
|
||||
QAction* duplicate_action = menu.addAction("Duplicate");
|
||||
connect(duplicate_action, SIGNAL(triggered(bool)), panel_project, SLOT(duplicate_selected()));
|
||||
}
|
||||
}
|
||||
|
||||
// ONLY footage is selected
|
||||
if (all_footage) {
|
||||
QAction* delete_footage_from_sequences = menu.addAction("Delete All Clips Using This Media");
|
||||
connect(delete_footage_from_sequences, SIGNAL(triggered(bool)), panel_project, SLOT(delete_clips_using_selected_media()));
|
||||
}
|
||||
|
||||
// delete media
|
||||
QAction* delete_action = menu.addAction("Delete");
|
||||
@@ -127,22 +142,36 @@ void SourceTable::dragMoveEvent(QDragMoveEvent *event) {
|
||||
|
||||
void SourceTable::dropEvent(QDropEvent* event) {
|
||||
const QMimeData* mimeData = event->mimeData();
|
||||
QTreeWidgetItem* drop_item = itemAt(event->pos());
|
||||
if (mimeData->hasUrls()) {
|
||||
// drag files in from outside
|
||||
QList<QUrl> urls = mimeData->urls();
|
||||
if (!urls.isEmpty()) {
|
||||
if (!urls.isEmpty()) {
|
||||
QStringList paths;
|
||||
for (int i=0;i<urls.size();i++) {
|
||||
qDebug() << urls.at(i).toLocalFile();
|
||||
for (int i=0;i<urls.size();i++) {
|
||||
paths.append(urls.at(i).toLocalFile());
|
||||
}
|
||||
panel_project->process_file_list(paths);
|
||||
bool replace = false;
|
||||
if (urls.size() == 1
|
||||
&& drop_item != NULL
|
||||
&& get_type_from_tree(drop_item) == MEDIA_TYPE_FOOTAGE
|
||||
&& !QFileInfo(paths.at(0)).isDir()
|
||||
&& QMessageBox::question(this, "Replace Media", "You dropped a file onto '" + drop_item->text(0) + "'. Would you like to replace it with the dropped file?", QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes) {
|
||||
replace = true;
|
||||
panel_project->replace_media(drop_item, paths.at(0));
|
||||
}
|
||||
if (!replace) {
|
||||
QTreeWidgetItem* parent = NULL;
|
||||
if (drop_item != NULL && get_type_from_tree(drop_item) == MEDIA_TYPE_FOLDER) {
|
||||
parent = drop_item;
|
||||
}
|
||||
panel_project->process_file_list(NULL, paths, parent, NULL);
|
||||
}
|
||||
}
|
||||
event->acceptProposedAction();
|
||||
} else {
|
||||
// dragging files within project
|
||||
QVector<QTreeWidgetItem*> move_items;
|
||||
QTreeWidgetItem* drop_item = itemAt(event->pos());
|
||||
// if we dragged to the root OR dragged to a folder
|
||||
if (drop_item == NULL || (drop_item != NULL && get_type_from_tree(drop_item) == MEDIA_TYPE_FOLDER)) {
|
||||
QList<QTreeWidgetItem*> selected_items = selectedItems();
|
||||
|
||||
+46
-40
@@ -815,12 +815,12 @@ void TimelineWidget::update_ghosts(QPoint& mouse_pos) {
|
||||
validator = g.ghost_length + frame_diff;
|
||||
if (validator < 1) frame_diff += (1 - validator);
|
||||
|
||||
// prevent clip length exceeding media length
|
||||
if (c->media_type == MEDIA_TYPE_SEQUENCE
|
||||
// prevent clip length exceeding media length
|
||||
if (c->media_type == MEDIA_TYPE_SEQUENCE
|
||||
|| (c->media_type == MEDIA_TYPE_FOOTAGE && !static_cast<Media*>(c->media)->get_stream_from_file_index(c->media_stream)->infinite_length)) {
|
||||
validator = g.old_clip_in + g.ghost_length + frame_diff;
|
||||
if (validator > g.media_length) frame_diff -= validator - g.media_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ripple ops
|
||||
@@ -1433,30 +1433,22 @@ void TimelineWidget::redraw_clips() {
|
||||
}
|
||||
|
||||
if (clip->media_type == MEDIA_TYPE_FOOTAGE) {
|
||||
bool draw_checkerboard = false;
|
||||
QRect checkerboard_rect = clip_rect;
|
||||
Media* m = static_cast<Media*>(clip->media);
|
||||
MediaStream* ms = m->get_stream_from_file_index(clip->media_stream);
|
||||
if (ms == NULL) {
|
||||
// draw "error lines" if media stream is missing
|
||||
clip_painter.setPen(QPen(QColor(64, 64, 64), 2));
|
||||
int limit = clip_rect.width();
|
||||
int clip_height = clip_rect.bottom()-clip_rect.top();
|
||||
for (int j=-clip_height;j<limit;j+=15) {
|
||||
int lines_start_x = clip_rect.left()+j;
|
||||
int lines_start_y = clip_rect.bottom();
|
||||
int lines_end_x = lines_start_x + clip_height;
|
||||
int lines_end_y = clip_rect.top();
|
||||
if (lines_start_x < clip_rect.left()) {
|
||||
lines_start_y -= (clip_rect.left() - lines_start_x);
|
||||
lines_start_x = clip_rect.left();
|
||||
}
|
||||
if (lines_end_x > clip_rect.right()) {
|
||||
lines_end_y -= (clip_rect.right() - lines_end_x);
|
||||
lines_end_x = clip_rect.right();
|
||||
}
|
||||
clip_painter.drawLine(lines_start_x, lines_start_y, lines_end_x, lines_end_y);
|
||||
}
|
||||
draw_checkerboard = true;
|
||||
} else if (ms->preview_done) {
|
||||
// draw thumbnail/waveform
|
||||
long media_length = m->get_length_in_frames(clip->sequence->frame_rate);
|
||||
int waveform_limit = qMin(clip_rect.width(), panel_timeline->getScreenPointFromFrame(media_length - clip->clip_in));
|
||||
|
||||
if (waveform_limit < clip_rect.width()) {
|
||||
draw_checkerboard = true;
|
||||
checkerboard_rect.setLeft(clip_rect.left() + waveform_limit);
|
||||
}
|
||||
|
||||
if (clip->track < 0) {
|
||||
int thumb_y = clip_painter.fontMetrics().height()+CLIP_TEXT_PADDING+CLIP_TEXT_PADDING;
|
||||
int thumb_height = clip_rect.height()-thumb_y;
|
||||
@@ -1465,33 +1457,47 @@ void TimelineWidget::redraw_clips() {
|
||||
QRect thumb_rect(thumb_x, clip_rect.y()+thumb_y, thumb_width, thumb_height);
|
||||
clip_painter.drawImage(thumb_rect, ms->video_preview);
|
||||
}
|
||||
} else if (clip_rect.height() > TRACK_MIN_HEIGHT) {
|
||||
} else if (clip_rect.height() > TRACK_MIN_HEIGHT) {
|
||||
int divider = ms->audio_channels*2;
|
||||
|
||||
clip_painter.setPen(QColor(80, 80, 80));
|
||||
int channel_height = clip_rect.height()/ms->audio_channels;
|
||||
long media_length = m->get_length_in_frames(clip->sequence->frame_rate);
|
||||
for (int i=0;i<clip_rect.width();i++) {
|
||||
|
||||
for (int i=0;i<waveform_limit;i++) {
|
||||
int waveform_index = qFloor((((clip->clip_in + ((double) i/panel_timeline->zoom))/media_length) * ms->audio_preview.size())/divider)*divider;
|
||||
|
||||
for (int j=0;j<ms->audio_channels;j++) {
|
||||
int mid = clip_rect.top()+channel_height*j+(channel_height/2);
|
||||
int offset = waveform_index+(j*2);
|
||||
for (int j=0;j<ms->audio_channels;j++) {
|
||||
int mid = clip_rect.top()+channel_height*j+(channel_height/2);
|
||||
int offset = waveform_index+(j*2);
|
||||
|
||||
qint8 min = (double)ms->audio_preview.at(offset) / 128.0 * (channel_height/2);
|
||||
qint8 max = (double)ms->audio_preview.at(offset+1) / 128.0 * (channel_height/2);
|
||||
clip_painter.drawLine(clip_rect.left()+i, mid+min, clip_rect.left()+i, mid+max);
|
||||
|
||||
/*if (offset >= 0 && offset < ms->audio_preview.size()) {
|
||||
|
||||
} else {
|
||||
QMessageBox::critical(this, "AAAAAAAAAAAAA", "Here's that terrible, no-good bug again!!! I've stepped around it but plz report the following to Matt:\n\n" + QString::number(offset) + " vs " + QString::number(clip->media_stream->audio_preview.size()), QMessageBox::Ok);
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
qint8 min = (double)ms->audio_preview.at(offset) / 128.0 * (channel_height/2);
|
||||
qint8 max = (double)ms->audio_preview.at(offset+1) / 128.0 * (channel_height/2);
|
||||
clip_painter.drawLine(clip_rect.left()+i, mid+min, clip_rect.left()+i, mid+max);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (draw_checkerboard) {
|
||||
// draw "error lines" if media stream is missing
|
||||
clip_painter.setPen(QPen(QColor(64, 64, 64), 2));
|
||||
int limit = checkerboard_rect.width();
|
||||
int clip_height = checkerboard_rect.bottom()-checkerboard_rect.top();
|
||||
for (int j=-clip_height;j<limit;j+=15) {
|
||||
int lines_start_x = checkerboard_rect.left()+j;
|
||||
int lines_start_y = checkerboard_rect.bottom();
|
||||
int lines_end_x = lines_start_x + clip_height;
|
||||
int lines_end_y = checkerboard_rect.top();
|
||||
if (lines_start_x < checkerboard_rect.left()) {
|
||||
lines_start_y -= (checkerboard_rect.left() - lines_start_x);
|
||||
lines_start_x = checkerboard_rect.left();
|
||||
}
|
||||
if (lines_end_x > checkerboard_rect.right()) {
|
||||
lines_end_y -= (checkerboard_rect.right() - lines_end_x);
|
||||
lines_end_x = checkerboard_rect.right();
|
||||
}
|
||||
clip_painter.drawLine(lines_start_x, lines_start_y, lines_end_x, lines_end_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// top left bevel
|
||||
|
||||
+15
-12
@@ -110,19 +110,22 @@ void ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
|
||||
case MEDIA_TYPE_FOOTAGE:
|
||||
{
|
||||
Media* m = static_cast<Media*>(c->media);
|
||||
if (m->ready
|
||||
&& m->get_stream_from_file_index(c->media_stream) != NULL
|
||||
&& is_clip_active(c, playhead)) {
|
||||
// if thread is already working, we don't want to touch this,
|
||||
// but we also don't want to hang the UI thread
|
||||
if (!c->open) {
|
||||
open_clip(c, multithreaded);
|
||||
}
|
||||
if (m->ready) {
|
||||
if (m->get_stream_from_file_index(c->media_stream) != NULL
|
||||
&& is_clip_active(c, playhead)) {
|
||||
// if thread is already working, we don't want to touch this,
|
||||
// but we also don't want to hang the UI thread
|
||||
if (!c->open) {
|
||||
open_clip(c, multithreaded);
|
||||
}
|
||||
|
||||
clip_is_active = true;
|
||||
} else if (c->open) {
|
||||
close_clip(c);
|
||||
}
|
||||
clip_is_active = true;
|
||||
} else if (c->open) {
|
||||
close_clip(c);
|
||||
}
|
||||
} else {
|
||||
texture_failed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MEDIA_TYPE_SEQUENCE:
|
||||
|
||||
Reference in New Issue
Block a user