ACTUALLY fixed urgent sequence deletion bug

This commit is contained in:
itsmattkc
2018-11-05 20:07:43 +11:00
parent e342294917
commit 72fe20d857
9 changed files with 70 additions and 27 deletions
+4 -1
View File
@@ -10,7 +10,7 @@ extern "C" {
#include "project/clip.h"
Media::Media() : ready(false), preview_gen(NULL) {
Media::Media() : ready(false), preview_gen(NULL), throbber(NULL) {
ready_lock.lock();
}
@@ -23,6 +23,9 @@ void Media::reset() {
preview_gen->cancel();
preview_gen->wait();
}
if (throbber != NULL) {
delete throbber;
}
for (int i=0;i<video_tracks.size();i++) {
delete video_tracks.at(i);
}
+2
View File
@@ -21,6 +21,7 @@
struct Sequence;
struct Clip;
class PreviewGenerator;
class MediaThrobber;
struct MediaStream {
int file_index;
@@ -53,6 +54,7 @@ struct Media {
bool ready;
PreviewGenerator* preview_gen;
MediaThrobber* throbber;
QMutex ready_lock;
bool using_inout;
+14 -9
View File
@@ -195,21 +195,26 @@ void PreviewGenerator::generate_waveform() {
codec_ctx[i] = NULL;
if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
AVCodec* codec = avcodec_find_decoder(fmt_ctx->streams[i]->codecpar->codec_id);
codec_ctx[i] = avcodec_alloc_context3(codec);
avcodec_parameters_to_context(codec_ctx[i], fmt_ctx->streams[i]->codecpar);
avcodec_open2(codec_ctx[i], codec, NULL);
if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && codec_ctx[i]->channel_layout == 0) {
codec_ctx[i]->channel_layout = av_get_default_channel_layout(fmt_ctx->streams[i]->codecpar->channels);
}
if (codec != NULL) {
codec_ctx[i] = avcodec_alloc_context3(codec);
avcodec_parameters_to_context(codec_ctx[i], fmt_ctx->streams[i]->codecpar);
avcodec_open2(codec_ctx[i], codec, NULL);
if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && codec_ctx[i]->channel_layout == 0) {
codec_ctx[i]->channel_layout = av_get_default_channel_layout(fmt_ctx->streams[i]->codecpar->channels);
}
}
}
}
}
AVPacket* packet = av_packet_alloc();
bool done = true;
bool end_of_file = false;
// get the ball rolling
av_read_frame(fmt_ctx, packet);
// get the ball rolling
do {
av_read_frame(fmt_ctx, packet);
} while (codec_ctx[packet->stream_index] == NULL);
avcodec_send_packet(codec_ctx[packet->stream_index], packet);
while (!end_of_file) {
+13 -8
View File
@@ -198,7 +198,8 @@ void Project::new_sequence(ComboAction *ca, Sequence *s, bool open, QTreeWidgetI
void Project::start_preview_generator(QTreeWidgetItem* item, Media* media, bool replacing) {
// set up throbber animation
MediaThrobber* throbber = new MediaThrobber(item);
MediaThrobber* throbber = new MediaThrobber(item);
item->setData(0, Qt::UserRole + 5, reinterpret_cast<quintptr>(throbber));
PreviewGenerator* pg = new PreviewGenerator(item, media, replacing);
media->preview_gen = pg;
@@ -212,6 +213,7 @@ QString Project::get_file_name_from_path(const QString& path) {
QTreeWidgetItem* Project::new_item() {
QTreeWidgetItem* item = new QTreeWidgetItem();
item->setData(0, Qt::UserRole + 5, NULL);
item->setFlags(item->flags() | Qt::ItemIsEditable);
return item;
}
@@ -425,7 +427,6 @@ void Project::process_file_list(bool recursive, QStringList& files, QTreeWidgetI
// check file extension (assume it's not a
int lastcharindex = file.lastIndexOf(".");
dout << "INFO:" << file << lastcharindex;
bool found = true;
if (lastcharindex != -1 && lastcharindex > file.lastIndexOf('/')) {
// image_sequence_formats
@@ -441,6 +442,8 @@ void Project::process_file_list(bool recursive, QStringList& files, QTreeWidgetI
lastcharindex = file.length();
}
if (lastcharindex == 0) lastcharindex++;
if (found && file[lastcharindex-1].isDigit()) {
bool is_img_sequence = false;
@@ -696,6 +699,7 @@ void Project::clear() {
while (ui->treeWidget->topLevelItemCount() > 0) {
QTreeWidgetItem* item = ui->treeWidget->topLevelItem(0);
if (get_type_from_tree(item) != MEDIA_TYPE_SEQUENCE) delete_media(item); // already deleted
if (item->data(0, Qt::UserRole + 5) != NULL) delete reinterpret_cast<MediaThrobber*>(item->data(0, Qt::UserRole + 5).value<quintptr>());
delete item;
}
}
@@ -1440,7 +1444,7 @@ QVector<Sequence*> Project::list_all_project_sequences() {
#define THROBBER_LIMIT 20
#define THROBBER_SIZE 50
MediaThrobber::MediaThrobber(QTreeWidgetItem* i) : pixmap(":/icons/throbber.png"), animation(0), item(i) {
MediaThrobber::MediaThrobber(QTreeWidgetItem *i) : pixmap(":/icons/throbber.png"), animation(0), item(i) {
// set up throbber
animation_update();
animator.setInterval(20);
@@ -1452,17 +1456,17 @@ void MediaThrobber::animation_update() {
if (animation == THROBBER_LIMIT) {
animation = 0;
}
item->setIcon(0, QIcon(pixmap.copy(THROBBER_SIZE*animation, 0, THROBBER_SIZE, THROBBER_SIZE)));
animation++;
item->setIcon(0, QIcon(pixmap.copy(THROBBER_SIZE*animation, 0, THROBBER_SIZE, THROBBER_SIZE)));
animation++;
}
void MediaThrobber::stop(int icon_type, bool replace) {
animator.stop();
switch (icon_type) {
case ICON_TYPE_VIDEO: item->setIcon(0, QIcon(":/icons/videosource.png")); break;
case ICON_TYPE_AUDIO: item->setIcon(0, QIcon(":/icons/audiosource.png")); break;
case ICON_TYPE_ERROR: item->setIcon(0, QIcon::fromTheme("dialog-error")); break;
case ICON_TYPE_VIDEO: item->setIcon(0, QIcon(":/icons/videosource.png")); break;
case ICON_TYPE_AUDIO: item->setIcon(0, QIcon(":/icons/audiosource.png")); break;
case ICON_TYPE_ERROR: item->setIcon(0, QIcon::fromTheme("dialog-error")); break;
}
// refresh all clips
@@ -1481,6 +1485,7 @@ void MediaThrobber::stop(int icon_type, bool replace) {
update_ui(replace);
panel_project->source_table->viewport()->update();
item->setData(0, Qt::UserRole + 5, NULL);
deleteLater();
}
+2 -2
View File
@@ -108,7 +108,7 @@ private slots:
class MediaThrobber : public QObject {
Q_OBJECT
public:
MediaThrobber(QTreeWidgetItem*);
MediaThrobber(QTreeWidgetItem*);
public slots:
void stop(int, bool replace);
private slots:
@@ -116,7 +116,7 @@ private slots:
private:
QPixmap pixmap;
int animation;
QTreeWidgetItem* item;
QTreeWidgetItem* item;
QTimer animator;
};
-3
View File
@@ -59,9 +59,6 @@
<property name="itemsExpandable">
<bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="headerHidden">
<bool>false</bool>
</property>
+33 -3
View File
@@ -21,6 +21,7 @@
#include "ui/viewerwidget.h"
#include "project/marker.h"
#include "mainwindow.h"
#include "debug.h"
QUndoStack undo_stack;
@@ -350,13 +351,24 @@ AddMediaCommand::AddMediaCommand(QTreeWidgetItem* iitem, QTreeWidgetItem* iparen
AddMediaCommand::~AddMediaCommand() {
if (!done) {
panel_project->delete_media(item);
if (item->data(0, Qt::UserRole + 5) != NULL) delete reinterpret_cast<MediaThrobber*>(item->data(0, Qt::UserRole + 5).value<quintptr>());
delete item;
}
}
void AddMediaCommand::undo() {
if (parent == NULL) {
panel_project->source_table->takeTopLevelItem(panel_project->source_table->indexOfTopLevelItem(item));
bool found = false;
for (int i=0;i<panel_project->source_table->topLevelItemCount();i++) {
if (panel_project->source_table->topLevelItem(i) == item) {
dout << "item at index is:" << panel_project->source_table->topLevelItem(i)->text(0);
QTreeWidgetItem* deleted_item = panel_project->source_table->takeTopLevelItem(i);
dout << "wanted to take" << item->text(0) << "took" << deleted_item->text(0);
found = true;
break;
}
}
dout << "took:" << found;
} else {
parent->removeChild(item);
}
@@ -369,8 +381,25 @@ void AddMediaCommand::redo() {
panel_project->source_table->addTopLevelItem(item);
} else {
parent->addChild(item);
}
done = true;
}
/* Here we force the source_table to sort itself.
*
* For some reason, sometimes when you add items to the QTreeWidget,
* (usually upon first import) they appear at the bottom, regardless
* of where they should be placed alphabetically. Then when this
* function is "undone", and it tries to remove this item from the
* QTreeWidget, it immediately sorts and then removes THE WRONG ONE.
* If this happens to be a sequence, the sequence data doesn't save
* and is then lost forever (outside of autorecoveries).
*
* The following 2 lines seem to force the source_table to re-sort
* correctly and therefore works around this problem. But holy shit.
*/
panel_project->source_table->setSortingEnabled(false);
panel_project->source_table->setSortingEnabled(true);
done = true;
mainWindow->setWindowModified(true);
}
@@ -382,6 +411,7 @@ DeleteMediaCommand::DeleteMediaCommand(QTreeWidgetItem* i) :
DeleteMediaCommand::~DeleteMediaCommand() {
if (done) {
panel_project->delete_media(item);
if (item->data(0, Qt::UserRole + 5) != NULL) delete reinterpret_cast<MediaThrobber*>(item->data(0, Qt::UserRole + 5).value<quintptr>());
delete item;
}
}
+1
View File
@@ -19,6 +19,7 @@
SourceTable::SourceTable(QWidget* parent) : QTreeWidget(parent) {
editing_item = NULL;
setSortingEnabled(true);
sortByColumn(0, Qt::AscendingOrder);
rename_timer.setInterval(1000);
setContextMenuPolicy(Qt::CustomContextMenu);
+1 -1
View File
@@ -491,7 +491,7 @@ void TimelineWidget::wheelEvent(QWheelEvent *event) {
}
void TimelineWidget::dragLeaveEvent(QDragLeaveEvent*) {
if (sequence != NULL && panel_timeline->importing) {
if (panel_timeline->importing) {
if (panel_timeline->importing_files) {
undo_stack.undo();
}