#include "project.h" #include "ui_project.h" #include "io/media.h" #include "panels/panels.h" #include "panels/timeline.h" #include "panels/viewer.h" #include #include #include #include #include #include #include #include #include "panels/timeline.h" #include "project/sequence.h" #include "project/effect.h" extern "C" { #include #include } Project::Project(QWidget *parent) : QDockWidget(parent), ui(new Ui::Project) { ui->setupUi(this); } Project::~Project() { delete ui; } QString Project::get_next_sequence_name() { int n = 1; bool found = true; QString name; while (found) { found = false; name = "Sequence "; if (n < 10) { name += "0"; } name += QString::number(n); for (int i=0;itreeWidget->topLevelItemCount();i++) { if (QString::compare(ui->treeWidget->topLevelItem(i)->text(0), name, Qt::CaseInsensitive) == 0) { found = true; n++; break; } } } return name; } void Project::new_sequence(Sequence *s) { Media* m = new Media(); m->is_sequence = true; m->sequence = s; QTreeWidgetItem* item = new QTreeWidgetItem(); item->setText(0, s->name); set_media_of_tree(item, m); ui->treeWidget->addTopLevelItem(item); source_table = ui->treeWidget; } void Project::import_dialog() { QStringList files = QFileDialog::getOpenFileNames(this, "Import media...", "", "All Files (*.*)"); for (int i=0;iis_sequence = false; m->url = file; // detect video/audio streams in file for (int i=0;i<(int)pFormatCtx->nb_streams;i++) { // Find the decoder for the video stream if (avcodec_find_decoder(pFormatCtx->streams[i]->codecpar->codec_id) == NULL) { qDebug() << "[ERROR] Unsupported codec in stream %d.\n"; } else { if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { qDebug() << "[WARNING] INFINITE_LENGTH calculation is inaccurate in this build\n"; // TODO BETTER infinite length calculator bool infinite_length = (pFormatCtx->streams[i]->nb_frames == 0); // bool infinite_length = false; m->video_tracks.append({i, pFormatCtx->streams[i]->codecpar->width, pFormatCtx->streams[i]->codecpar->height, infinite_length}); } else if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { m->audio_tracks.append({i, 0, 0, false}); } } } m->name = files.at(i).mid(files.at(i).lastIndexOf('/')+1); m->length = pFormatCtx->duration; QTreeWidgetItem* item = new QTreeWidgetItem(); if (m->video_tracks.size() == 0) { item->setIcon(0, QIcon(":/icons/audiosource.png")); } else { item->setIcon(0, QIcon(":/icons/videosource.png")); } item->setText(0, m->name); item->setText(1, QString::number(m->length)); set_media_of_tree(item, m); ui->treeWidget->addTopLevelItem(item); } } avformat_close_input(&pFormatCtx); delete [] filename; } } Media* Project::get_media_from_tree(QTreeWidgetItem* item) { return reinterpret_cast(item->data(0, Qt::UserRole + 1).value()); } void Project::set_media_of_tree(QTreeWidgetItem* item, Media* media) { item->setData(0, Qt::UserRole + 1, QVariant::fromValue(reinterpret_cast(media))); } void Project::remove_item(int i) { Media* m = get_media_from_tree(ui->treeWidget->topLevelItem(i)); if (m->is_sequence) { delete m->sequence; } delete m; ui->treeWidget->takeTopLevelItem(i); } void Project::clear() { int len = ui->treeWidget->topLevelItemCount(); for (int i=0;iset_sequence(s); panel_viewer->set_sequence(s); } void Project::load_project() { // clear existing project set_sequence(NULL); clear(); QFile file("C:/Users/Matt/Desktop/test.xml"); if (!file.open(QIODevice::ReadOnly/* | QIODevice::Text*/)) { qDebug() << "[ERROR] Could not open file"; return; } QXmlStreamReader stream(&file); while (!stream.atEnd()) { stream.readNext(); } if (stream.hasError()) { qDebug() << "[ERROR] Error parsing XML." << stream.error(); } } void Project::save_project() { QFile file("C:/Users/Matt/Desktop/test.xml"); if (!file.open(QIODevice::WriteOnly/* | QIODevice::Text*/)) { qDebug() << "[ERROR] Could not open file"; return; } QXmlStreamWriter stream(&file); stream.setAutoFormatting(true); stream.writeStartDocument(); int len = ui->treeWidget->topLevelItemCount(); stream.writeStartElement("media"); for (int i=0;itreeWidget->topLevelItem(i)); if (!m->is_sequence) { m->save_id = i; stream.writeStartElement("footage"); stream.writeAttribute("id", QString::number(m->save_id)); stream.writeTextElement("name", m->name); stream.writeTextElement("url", m->url); stream.writeEndElement(); } } stream.writeEndElement(); stream.writeStartElement("timeline"); for (int i=0;itreeWidget->topLevelItem(i)); if (m->is_sequence) { Sequence* s = m->sequence; stream.writeStartElement("sequence"); stream.writeTextElement("name", s->name); stream.writeTextElement("width", QString::number(s->width)); stream.writeTextElement("height", QString::number(s->height)); stream.writeTextElement("framerate", QString::number(s->frame_rate)); stream.writeTextElement("afreq", QString::number(s->audio_frequency)); stream.writeTextElement("alayout", QString::number(s->audio_layout)); stream.writeStartElement("clips"); for (int i=0;iclip_count();i++) { Clip* c = s->get_clip(i); stream.writeStartElement("clip"); stream.writeTextElement("name", c->name); stream.writeTextElement("clipin", QString::number(c->clip_in)); stream.writeTextElement("in", QString::number(c->timeline_in)); stream.writeTextElement("out", QString::number(c->timeline_out)); stream.writeTextElement("track", QString::number(c->track)); stream.writeStartElement("color"); stream.writeAttribute("r", QString::number(c->color_r)); stream.writeAttribute("g", QString::number(c->color_g)); stream.writeAttribute("b", QString::number(c->color_b)); stream.writeEndElement(); stream.writeTextElement("media", QString::number(c->media->save_id)); stream.writeTextElement("stream", QString::number(c->media_stream->file_index)); stream.writeStartElement("effects"); for (int j=0;jeffects.size();j++) { stream.writeStartElement("effect"); Effect* e = c->effects.at(j); stream.writeAttribute("id", QString::number(e->id)); e->save(&stream); stream.writeEndElement(); } stream.writeEndElement(); stream.writeEndElement(); } stream.writeEndElement(); } } stream.writeEndElement(); stream.writeEndDocument(); file.close(); }