diff --git a/dialogs/mediapropertiesdialog.cpp b/dialogs/mediapropertiesdialog.cpp index 591794cd4..8bcee21ed 100644 --- a/dialogs/mediapropertiesdialog.cpp +++ b/dialogs/mediapropertiesdialog.cpp @@ -37,175 +37,175 @@ #include "project/undo.h" MediaPropertiesDialog::MediaPropertiesDialog(QWidget *parent, Media *i) : - QDialog(parent), - item(i) + QDialog(parent), + item(i) { - setWindowTitle(tr("\"%1\" Properties").arg(i->get_name())); - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + setWindowTitle(tr("\"%1\" Properties").arg(i->get_name())); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - QGridLayout* grid = new QGridLayout(this); + QGridLayout* grid = new QGridLayout(this); - int row = 0; + int row = 0; - FootagePtr f = item->to_footage(); + Footage* f = item->to_footage(); - grid->addWidget(new QLabel(tr("Tracks:"), this), row, 0, 1, 2); - row++; + grid->addWidget(new QLabel(tr("Tracks:"), this), row, 0, 1, 2); + row++; - track_list = new QListWidget(this); - for (int i=0;ivideo_tracks.size();i++) { - const FootageStream& fs = f->video_tracks.at(i); + track_list = new QListWidget(this); + for (int i=0;ivideo_tracks.size();i++) { + const FootageStream& fs = f->video_tracks.at(i); - QListWidgetItem* item = new QListWidgetItem( - tr("Video %1: %2x%3 %4FPS").arg( - QString::number(fs.file_index), - QString::number(fs.video_width), - QString::number(fs.video_height), - QString::number(fs.video_frame_rate) - ), - track_list - ); - item->setFlags(item->flags() | Qt::ItemIsUserCheckable); - item->setCheckState(fs.enabled ? Qt::Checked : Qt::Unchecked); - item->setData(Qt::UserRole+1, fs.file_index); - track_list->addItem(item); - } - for (int i=0;iaudio_tracks.size();i++) { - const FootageStream& fs = f->audio_tracks.at(i); - QListWidgetItem* item = new QListWidgetItem( - tr("Audio %1: %2Hz %3").arg( - QString::number(fs.file_index), - QString::number(fs.audio_frequency), - tr("%n channel(s)", "", fs.audio_channels) - ), - track_list - ); - item->setFlags(item->flags() | Qt::ItemIsUserCheckable); - item->setCheckState(fs.enabled ? Qt::Checked : Qt::Unchecked); - item->setData(Qt::UserRole+1, fs.file_index); - track_list->addItem(item); - } - grid->addWidget(track_list, row, 0, 1, 2); - row++; + QListWidgetItem* item = new QListWidgetItem( + tr("Video %1: %2x%3 %4FPS").arg( + QString::number(fs.file_index), + QString::number(fs.video_width), + QString::number(fs.video_height), + QString::number(fs.video_frame_rate) + ), + track_list + ); + item->setFlags(item->flags() | Qt::ItemIsUserCheckable); + item->setCheckState(fs.enabled ? Qt::Checked : Qt::Unchecked); + item->setData(Qt::UserRole+1, fs.file_index); + track_list->addItem(item); + } + for (int i=0;iaudio_tracks.size();i++) { + const FootageStream& fs = f->audio_tracks.at(i); + QListWidgetItem* item = new QListWidgetItem( + tr("Audio %1: %2Hz %3").arg( + QString::number(fs.file_index), + QString::number(fs.audio_frequency), + tr("%n channel(s)", "", fs.audio_channels) + ), + track_list + ); + item->setFlags(item->flags() | Qt::ItemIsUserCheckable); + item->setCheckState(fs.enabled ? Qt::Checked : Qt::Unchecked); + item->setData(Qt::UserRole+1, fs.file_index); + track_list->addItem(item); + } + grid->addWidget(track_list, row, 0, 1, 2); + row++; - if (f->video_tracks.size() > 0) { - // frame conforming - if (!f->video_tracks.at(0).infinite_length) { - grid->addWidget(new QLabel(tr("Conform to Frame Rate:"), this), row, 0); - conform_fr = new QDoubleSpinBox(this); - conform_fr->setMinimum(0.01); - conform_fr->setValue(f->video_tracks.at(0).video_frame_rate * f->speed); - grid->addWidget(conform_fr, row, 1); - } + if (f->video_tracks.size() > 0) { + // frame conforming + if (!f->video_tracks.at(0).infinite_length) { + grid->addWidget(new QLabel(tr("Conform to Frame Rate:"), this), row, 0); + conform_fr = new QDoubleSpinBox(this); + conform_fr->setMinimum(0.01); + conform_fr->setValue(f->video_tracks.at(0).video_frame_rate * f->speed); + grid->addWidget(conform_fr, row, 1); + } - row++; + row++; - // premultiplied alpha mode - premultiply_alpha_setting = new QCheckBox(tr("Alpha is Premultiplied"), this); - premultiply_alpha_setting->setChecked(f->alpha_is_premultiplied); - grid->addWidget(premultiply_alpha_setting, row, 0); + // premultiplied alpha mode + premultiply_alpha_setting = new QCheckBox(tr("Alpha is Premultiplied"), this); + premultiply_alpha_setting->setChecked(f->alpha_is_premultiplied); + grid->addWidget(premultiply_alpha_setting, row, 0); - row++; + row++; - // deinterlacing mode - interlacing_box = new QComboBox(this); - interlacing_box->addItem( - tr("Auto (%1)").arg( - get_interlacing_name(f->video_tracks.at(0).video_auto_interlacing) - ) - ); - interlacing_box->addItem(get_interlacing_name(VIDEO_PROGRESSIVE)); - interlacing_box->addItem(get_interlacing_name(VIDEO_TOP_FIELD_FIRST)); - interlacing_box->addItem(get_interlacing_name(VIDEO_BOTTOM_FIELD_FIRST)); + // deinterlacing mode + interlacing_box = new QComboBox(this); + interlacing_box->addItem( + tr("Auto (%1)").arg( + get_interlacing_name(f->video_tracks.at(0).video_auto_interlacing) + ) + ); + interlacing_box->addItem(get_interlacing_name(VIDEO_PROGRESSIVE)); + interlacing_box->addItem(get_interlacing_name(VIDEO_TOP_FIELD_FIRST)); + interlacing_box->addItem(get_interlacing_name(VIDEO_BOTTOM_FIELD_FIRST)); - interlacing_box->setCurrentIndex( - (f->video_tracks.at(0).video_auto_interlacing == f->video_tracks.at(0).video_interlacing) - ? 0 - : f->video_tracks.at(0).video_interlacing + 1); + interlacing_box->setCurrentIndex( + (f->video_tracks.at(0).video_auto_interlacing == f->video_tracks.at(0).video_interlacing) + ? 0 + : f->video_tracks.at(0).video_interlacing + 1); - grid->addWidget(new QLabel(tr("Interlacing:"), this), row, 0); - grid->addWidget(interlacing_box, row, 1); + grid->addWidget(new QLabel(tr("Interlacing:"), this), row, 0); + grid->addWidget(interlacing_box, row, 1); - row++; - } + row++; + } - name_box = new QLineEdit(item->get_name(), this); - grid->addWidget(new QLabel(tr("Name:"), this), row, 0); - grid->addWidget(name_box, row, 1); - row++; + name_box = new QLineEdit(item->get_name(), this); + grid->addWidget(new QLabel(tr("Name:"), this), row, 0); + grid->addWidget(name_box, row, 1); + row++; - QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); - buttons->setCenterButtons(true); - grid->addWidget(buttons, row, 0, 1, 2); + QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); + buttons->setCenterButtons(true); + grid->addWidget(buttons, row, 0, 1, 2); - connect(buttons, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttons, SIGNAL(rejected()), this, SLOT(reject())); + connect(buttons, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttons, SIGNAL(rejected()), this, SLOT(reject())); } void MediaPropertiesDialog::accept() { - FootagePtr f = item->to_footage(); + Footage* f = item->to_footage(); - ComboAction* ca = new ComboAction(); + ComboAction* ca = new ComboAction(); - // set track enable - for (int i=0;icount();i++) { - QListWidgetItem* item = track_list->item(i); - const QVariant& data = item->data(Qt::UserRole+1); - if (!data.isNull()) { - int index = data.toInt(); - bool found = false; - for (int j=0;jvideo_tracks.size();j++) { - if (f->video_tracks.at(j).file_index == index) { - f->video_tracks[j].enabled = (item->checkState() == Qt::Checked); - found = true; - break; - } - } - if (!found) { - for (int j=0;jaudio_tracks.size();j++) { - if (f->audio_tracks.at(j).file_index == index) { - f->audio_tracks[j].enabled = (item->checkState() == Qt::Checked); - break; - } - } - } - } - } + // set track enable + for (int i=0;icount();i++) { + QListWidgetItem* item = track_list->item(i); + const QVariant& data = item->data(Qt::UserRole+1); + if (!data.isNull()) { + int index = data.toInt(); + bool found = false; + for (int j=0;jvideo_tracks.size();j++) { + if (f->video_tracks.at(j).file_index == index) { + f->video_tracks[j].enabled = (item->checkState() == Qt::Checked); + found = true; + break; + } + } + if (!found) { + for (int j=0;jaudio_tracks.size();j++) { + if (f->audio_tracks.at(j).file_index == index) { + f->audio_tracks[j].enabled = (item->checkState() == Qt::Checked); + break; + } + } + } + } + } - bool refresh_clips = false; + bool refresh_clips = false; - // set interlacing - if (f->video_tracks.size() > 0) { - if (interlacing_box->currentIndex() > 0) { - ca->append(new SetInt(&f->video_tracks[0].video_interlacing, interlacing_box->currentIndex() - 1)); - } else { - ca->append(new SetInt(&f->video_tracks[0].video_interlacing, f->video_tracks.at(0).video_auto_interlacing)); - } + // set interlacing + if (f->video_tracks.size() > 0) { + if (interlacing_box->currentIndex() > 0) { + ca->append(new SetInt(&f->video_tracks[0].video_interlacing, interlacing_box->currentIndex() - 1)); + } else { + ca->append(new SetInt(&f->video_tracks[0].video_interlacing, f->video_tracks.at(0).video_auto_interlacing)); + } - // set frame rate conform - if (!f->video_tracks.at(0).infinite_length) { - if (!qFuzzyCompare(conform_fr->value(), f->video_tracks.at(0).video_frame_rate)) { - ca->append(new SetDouble(&f->speed, f->speed, conform_fr->value()/f->video_tracks.at(0).video_frame_rate)); - refresh_clips = true; - } - } + // set frame rate conform + if (!f->video_tracks.at(0).infinite_length) { + if (!qFuzzyCompare(conform_fr->value(), f->video_tracks.at(0).video_frame_rate)) { + ca->append(new SetDouble(&f->speed, f->speed, conform_fr->value()/f->video_tracks.at(0).video_frame_rate)); + refresh_clips = true; + } + } - // set premultiplied alpha - f->alpha_is_premultiplied = premultiply_alpha_setting->isChecked(); - } + // set premultiplied alpha + f->alpha_is_premultiplied = premultiply_alpha_setting->isChecked(); + } - // set name - MediaRename* mr = new MediaRename(item, name_box->text()); + // set name + MediaRename* mr = new MediaRename(item, name_box->text()); - ca->append(mr); - ca->appendPost(new CloseAllClipsCommand()); - ca->appendPost(new UpdateFootageTooltip(item)); - if (refresh_clips) { - ca->appendPost(new RefreshClips(item)); - } - ca->appendPost(new UpdateViewer()); + ca->append(mr); + ca->appendPost(new CloseAllClipsCommand()); + ca->appendPost(new UpdateFootageTooltip(item)); + if (refresh_clips) { + ca->appendPost(new RefreshClips(item)); + } + ca->appendPost(new UpdateViewer()); - olive::UndoStack.push(ca); + olive::UndoStack.push(ca); - QDialog::accept(); + QDialog::accept(); } diff --git a/dialogs/newsequencedialog.cpp b/dialogs/newsequencedialog.cpp index 0186b6ce0..b4b6e05a5 100644 --- a/dialogs/newsequencedialog.cpp +++ b/dialogs/newsequencedialog.cpp @@ -40,245 +40,245 @@ #include extern "C" { - #include +#include } NewSequenceDialog::NewSequenceDialog(QWidget *parent, Media *existing) : - QDialog(parent), - existing_item(existing) + QDialog(parent), + existing_item(existing) { - setup_ui(); + setup_ui(); - if (existing != nullptr) { - existing_sequence = existing->to_sequence(); - setWindowTitle(tr("Editing \"%1\"").arg(existing_sequence->name)); + if (existing != nullptr) { + existing_sequence = existing->to_sequence(); + setWindowTitle(tr("Editing \"%1\"").arg(existing_sequence->name)); - width_numeric->setValue(existing_sequence->width); - height_numeric->setValue(existing_sequence->height); - int comp_rate = qRound(existing_sequence->frame_rate*100); - for (int i=0;icount();i++) { - if (qRound(frame_rate_combobox->itemData(i).toDouble()*100) == comp_rate) { - frame_rate_combobox->setCurrentIndex(i); - break; - } - } - sequence_name_edit->setText(existing_sequence->name); - for (int i=0;icount();i++) { - if (audio_frequency_combobox->itemData(i) == existing_sequence->audio_frequency) { - audio_frequency_combobox->setCurrentIndex(i); - break; - } - } - } else { - existing_sequence = nullptr; - setWindowTitle(tr("New Sequence")); - } + width_numeric->setValue(existing_sequence->width); + height_numeric->setValue(existing_sequence->height); + int comp_rate = qRound(existing_sequence->frame_rate*100); + for (int i=0;icount();i++) { + if (qRound(frame_rate_combobox->itemData(i).toDouble()*100) == comp_rate) { + frame_rate_combobox->setCurrentIndex(i); + break; + } + } + sequence_name_edit->setText(existing_sequence->name); + for (int i=0;icount();i++) { + if (audio_frequency_combobox->itemData(i) == existing_sequence->audio_frequency) { + audio_frequency_combobox->setCurrentIndex(i); + break; + } + } + } else { + existing_sequence = nullptr; + setWindowTitle(tr("New Sequence")); + } } NewSequenceDialog::~NewSequenceDialog() {} void NewSequenceDialog::set_sequence_name(const QString& s) { - sequence_name_edit->setText(s); + sequence_name_edit->setText(s); } void NewSequenceDialog::create() { - if (existing_sequence == nullptr) { - SequencePtr s(new Sequence()); + if (existing_sequence == nullptr) { + SequencePtr s = std::make_shared(); - s->name = sequence_name_edit->text(); - s->width = width_numeric->value(); - s->height = height_numeric->value(); - s->frame_rate = frame_rate_combobox->currentData().toDouble(); - s->audio_frequency = audio_frequency_combobox->currentData().toInt(); - s->audio_layout = AV_CH_LAYOUT_STEREO; + s->name = sequence_name_edit->text(); + s->width = width_numeric->value(); + s->height = height_numeric->value(); + s->frame_rate = frame_rate_combobox->currentData().toDouble(); + s->audio_frequency = audio_frequency_combobox->currentData().toInt(); + s->audio_layout = AV_CH_LAYOUT_STEREO; - ComboAction* ca = new ComboAction(); - panel_project->create_sequence_internal(ca, s, true, nullptr); - olive::UndoStack.push(ca); - } else { - ComboAction* ca = new ComboAction(); + ComboAction* ca = new ComboAction(); + panel_project->create_sequence_internal(ca, s, true, nullptr); + olive::UndoStack.push(ca); + } else { + ComboAction* ca = new ComboAction(); - double multiplier = frame_rate_combobox->currentData().toDouble() / existing_sequence->frame_rate; + double multiplier = frame_rate_combobox->currentData().toDouble() / existing_sequence->frame_rate; - EditSequenceCommand* esc = new EditSequenceCommand(existing_item, existing_sequence); - esc->name = sequence_name_edit->text(); - esc->width = width_numeric->value(); - esc->height = height_numeric->value(); - esc->frame_rate = frame_rate_combobox->currentData().toDouble(); - esc->audio_frequency = audio_frequency_combobox->currentData().toInt(); - esc->audio_layout = AV_CH_LAYOUT_STEREO; - ca->append(esc); + EditSequenceCommand* esc = new EditSequenceCommand(existing_item, existing_sequence); + esc->name = sequence_name_edit->text(); + esc->width = width_numeric->value(); + esc->height = height_numeric->value(); + esc->frame_rate = frame_rate_combobox->currentData().toDouble(); + esc->audio_frequency = audio_frequency_combobox->currentData().toInt(); + esc->audio_layout = AV_CH_LAYOUT_STEREO; + ca->append(esc); - for (int i=0;iclips.size();i++) { - ClipPtr c = existing_sequence->clips.at(i); - if (c != nullptr) { - c->refactor_frame_rate(ca, multiplier, true); - } - } + for (int i=0;iclips.size();i++) { + ClipPtr c = existing_sequence->clips.at(i); + if (c != nullptr) { + c->refactor_frame_rate(ca, multiplier, true); + } + } - olive::UndoStack.push(ca); - } + olive::UndoStack.push(ca); + } - accept(); + accept(); } void NewSequenceDialog::preset_changed(int index) { - switch (index) { - case 0: // FILM 4K - width_numeric->setValue(4096); - height_numeric->setValue(2160); - break; - case 1: // TV 4K - width_numeric->setValue(3840); - height_numeric->setValue(2160); - break; - case 2: // 1080p - width_numeric->setValue(1920); - height_numeric->setValue(1080); - break; - case 3: // 720p - width_numeric->setValue(1280); - height_numeric->setValue(720); - break; - case 4: // 480p - width_numeric->setValue(640); - height_numeric->setValue(480); - break; - case 5: // 360p - width_numeric->setValue(640); - height_numeric->setValue(360); - break; - case 6: // 240p - width_numeric->setValue(320); - height_numeric->setValue(240); - break; - case 7: // 144p - width_numeric->setValue(192); - height_numeric->setValue(144); - break; - case 8: // NTSC (480i) - width_numeric->setValue(720); - height_numeric->setValue(480); - break; - case 9: // PAL (576i) - width_numeric->setValue(720); - height_numeric->setValue(576); - break; - } + switch (index) { + case 0: // FILM 4K + width_numeric->setValue(4096); + height_numeric->setValue(2160); + break; + case 1: // TV 4K + width_numeric->setValue(3840); + height_numeric->setValue(2160); + break; + case 2: // 1080p + width_numeric->setValue(1920); + height_numeric->setValue(1080); + break; + case 3: // 720p + width_numeric->setValue(1280); + height_numeric->setValue(720); + break; + case 4: // 480p + width_numeric->setValue(640); + height_numeric->setValue(480); + break; + case 5: // 360p + width_numeric->setValue(640); + height_numeric->setValue(360); + break; + case 6: // 240p + width_numeric->setValue(320); + height_numeric->setValue(240); + break; + case 7: // 144p + width_numeric->setValue(192); + height_numeric->setValue(144); + break; + case 8: // NTSC (480i) + width_numeric->setValue(720); + height_numeric->setValue(480); + break; + case 9: // PAL (576i) + width_numeric->setValue(720); + height_numeric->setValue(576); + break; + } } void NewSequenceDialog::setup_ui() { - QVBoxLayout* verticalLayout = new QVBoxLayout(this); + QVBoxLayout* verticalLayout = new QVBoxLayout(this); - QWidget* widget = new QWidget(this); + QWidget* widget = new QWidget(this); - QHBoxLayout* preset_layout = new QHBoxLayout(widget); - preset_layout->setContentsMargins(0, 0, 0, 0); + QHBoxLayout* preset_layout = new QHBoxLayout(widget); + preset_layout->setContentsMargins(0, 0, 0, 0); - preset_layout->addWidget(new QLabel(tr("Preset:"), this)); + preset_layout->addWidget(new QLabel(tr("Preset:"), this)); - preset_combobox = new QComboBox(widget); + preset_combobox = new QComboBox(widget); - preset_combobox->addItem(tr("Film 4K")); - preset_combobox->addItem(tr("TV 4K (Ultra HD/2160p)")); - preset_combobox->addItem(tr("1080p")); - preset_combobox->addItem(tr("720p")); - preset_combobox->addItem(tr("480p")); - preset_combobox->addItem(tr("360p")); - preset_combobox->addItem(tr("240p")); - preset_combobox->addItem(tr("144p")); - preset_combobox->addItem(tr("NTSC (480i)")); - preset_combobox->addItem(tr("PAL (576i)")); - preset_combobox->addItem(tr("Custom")); - preset_combobox->setCurrentIndex(2); + preset_combobox->addItem(tr("Film 4K")); + preset_combobox->addItem(tr("TV 4K (Ultra HD/2160p)")); + preset_combobox->addItem(tr("1080p")); + preset_combobox->addItem(tr("720p")); + preset_combobox->addItem(tr("480p")); + preset_combobox->addItem(tr("360p")); + preset_combobox->addItem(tr("240p")); + preset_combobox->addItem(tr("144p")); + preset_combobox->addItem(tr("NTSC (480i)")); + preset_combobox->addItem(tr("PAL (576i)")); + preset_combobox->addItem(tr("Custom")); + preset_combobox->setCurrentIndex(2); - preset_layout->addWidget(preset_combobox); + preset_layout->addWidget(preset_combobox); - verticalLayout->addWidget(widget); + verticalLayout->addWidget(widget); - QGroupBox* videoGroupBox = new QGroupBox(this); - videoGroupBox->setTitle(tr("Video")); + QGroupBox* videoGroupBox = new QGroupBox(this); + videoGroupBox->setTitle(tr("Video")); - QGridLayout* videoLayout = new QGridLayout(videoGroupBox); + QGridLayout* videoLayout = new QGridLayout(videoGroupBox); - videoLayout->addWidget(new QLabel(tr("Width:"), this), 0, 0, 1, 1); - width_numeric = new QSpinBox(videoGroupBox); - width_numeric->setMaximum(9999); - width_numeric->setValue(1920); - videoLayout->addWidget(width_numeric, 0, 2, 1, 2); + videoLayout->addWidget(new QLabel(tr("Width:"), this), 0, 0, 1, 1); + width_numeric = new QSpinBox(videoGroupBox); + width_numeric->setMaximum(9999); + width_numeric->setValue(1920); + videoLayout->addWidget(width_numeric, 0, 2, 1, 2); - videoLayout->addWidget(new QLabel(tr("Height:"), this), 1, 0, 1, 2); - height_numeric = new QSpinBox(videoGroupBox); - height_numeric->setMaximum(9999); - height_numeric->setValue(1080); - videoLayout->addWidget(height_numeric, 1, 2, 1, 2); + videoLayout->addWidget(new QLabel(tr("Height:"), this), 1, 0, 1, 2); + height_numeric = new QSpinBox(videoGroupBox); + height_numeric->setMaximum(9999); + height_numeric->setValue(1080); + videoLayout->addWidget(height_numeric, 1, 2, 1, 2); - videoLayout->addWidget(new QLabel(tr("Frame Rate:"), this), 2, 0, 1, 1); - frame_rate_combobox = new QComboBox(videoGroupBox); - frame_rate_combobox->addItem("10 FPS", 10.0); - frame_rate_combobox->addItem("12.5 FPS", 12.5); - frame_rate_combobox->addItem("15 FPS", 15.0); - frame_rate_combobox->addItem("23.976 FPS", 23.976); - frame_rate_combobox->addItem("24 FPS", 24.0); - frame_rate_combobox->addItem("25 FPS", 25.0); - frame_rate_combobox->addItem("29.97 FPS", 29.97); - frame_rate_combobox->addItem("30 FPS", 30.0); - frame_rate_combobox->addItem("50 FPS", 50.0); - frame_rate_combobox->addItem("59.94 FPS", 59.94); - frame_rate_combobox->addItem("60 FPS", 60.0); - frame_rate_combobox->setCurrentIndex(6); - videoLayout->addWidget(frame_rate_combobox, 2, 2, 1, 2); + videoLayout->addWidget(new QLabel(tr("Frame Rate:"), this), 2, 0, 1, 1); + frame_rate_combobox = new QComboBox(videoGroupBox); + frame_rate_combobox->addItem("10 FPS", 10.0); + frame_rate_combobox->addItem("12.5 FPS", 12.5); + frame_rate_combobox->addItem("15 FPS", 15.0); + frame_rate_combobox->addItem("23.976 FPS", 23.976); + frame_rate_combobox->addItem("24 FPS", 24.0); + frame_rate_combobox->addItem("25 FPS", 25.0); + frame_rate_combobox->addItem("29.97 FPS", 29.97); + frame_rate_combobox->addItem("30 FPS", 30.0); + frame_rate_combobox->addItem("50 FPS", 50.0); + frame_rate_combobox->addItem("59.94 FPS", 59.94); + frame_rate_combobox->addItem("60 FPS", 60.0); + frame_rate_combobox->setCurrentIndex(6); + videoLayout->addWidget(frame_rate_combobox, 2, 2, 1, 2); - videoLayout->addWidget(new QLabel(tr("Pixel Aspect Ratio:"), this), 4, 0, 1, 1); - par_combobox = new QComboBox(videoGroupBox); - par_combobox->addItem(tr("Square Pixels (1.0)")); - videoLayout->addWidget(par_combobox, 4, 2, 1, 2); + videoLayout->addWidget(new QLabel(tr("Pixel Aspect Ratio:"), this), 4, 0, 1, 1); + par_combobox = new QComboBox(videoGroupBox); + par_combobox->addItem(tr("Square Pixels (1.0)")); + videoLayout->addWidget(par_combobox, 4, 2, 1, 2); - videoLayout->addWidget(new QLabel(tr("Interlacing:"), this), 6, 0, 1, 1); - interlacing_combobox = new QComboBox(videoGroupBox); - interlacing_combobox->addItem(tr("None (Progressive)")); -// interlacing_combobox->addItem("Upper Field First"); -// interlacing_combobox->addItem("Lower Field First"); - videoLayout->addWidget(interlacing_combobox, 6, 2, 1, 2); + videoLayout->addWidget(new QLabel(tr("Interlacing:"), this), 6, 0, 1, 1); + interlacing_combobox = new QComboBox(videoGroupBox); + interlacing_combobox->addItem(tr("None (Progressive)")); + // interlacing_combobox->addItem("Upper Field First"); + // interlacing_combobox->addItem("Lower Field First"); + videoLayout->addWidget(interlacing_combobox, 6, 2, 1, 2); - verticalLayout->addWidget(videoGroupBox); + verticalLayout->addWidget(videoGroupBox); - QGroupBox* audioGroupBox = new QGroupBox(this); - audioGroupBox->setTitle(tr("Audio")); + QGroupBox* audioGroupBox = new QGroupBox(this); + audioGroupBox->setTitle(tr("Audio")); - QGridLayout* audioLayout = new QGridLayout(audioGroupBox); + QGridLayout* audioLayout = new QGridLayout(audioGroupBox); - audioLayout->addWidget(new QLabel(tr("Sample Rate: "), this), 0, 0, 1, 1); + audioLayout->addWidget(new QLabel(tr("Sample Rate: "), this), 0, 0, 1, 1); - audio_frequency_combobox = new QComboBox(audioGroupBox); - combobox_audio_sample_rates(audio_frequency_combobox); - audio_frequency_combobox->setCurrentIndex(4); + audio_frequency_combobox = new QComboBox(audioGroupBox); + combobox_audio_sample_rates(audio_frequency_combobox); + audio_frequency_combobox->setCurrentIndex(4); - audioLayout->addWidget(audio_frequency_combobox, 0, 1, 1, 1); + audioLayout->addWidget(audio_frequency_combobox, 0, 1, 1, 1); - verticalLayout->addWidget(audioGroupBox); + verticalLayout->addWidget(audioGroupBox); - QWidget* nameWidget = new QWidget(this); - QHBoxLayout* nameLayout = new QHBoxLayout(nameWidget); - nameLayout->setContentsMargins(0, 0, 0, 0); + QWidget* nameWidget = new QWidget(this); + QHBoxLayout* nameLayout = new QHBoxLayout(nameWidget); + nameLayout->setContentsMargins(0, 0, 0, 0); - nameLayout->addWidget(new QLabel(tr("Name:"), this)); + nameLayout->addWidget(new QLabel(tr("Name:"), this)); - sequence_name_edit = new QLineEdit(nameWidget); + sequence_name_edit = new QLineEdit(nameWidget); - nameLayout->addWidget(sequence_name_edit); + nameLayout->addWidget(sequence_name_edit); - verticalLayout->addWidget(nameWidget); + verticalLayout->addWidget(nameWidget); - QDialogButtonBox* buttonBox = new QDialogButtonBox(this); - buttonBox->setOrientation(Qt::Horizontal); - buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); - buttonBox->setCenterButtons(true); + QDialogButtonBox* buttonBox = new QDialogButtonBox(this); + buttonBox->setOrientation(Qt::Horizontal); + buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + buttonBox->setCenterButtons(true); - verticalLayout->addWidget(buttonBox); + verticalLayout->addWidget(buttonBox); - connect(preset_combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(preset_changed(int))); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(create())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + connect(preset_combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(preset_changed(int))); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(create())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); } diff --git a/dialogs/newsequencedialog.h b/dialogs/newsequencedialog.h index 8638b0e99..b77fa0852 100644 --- a/dialogs/newsequencedialog.h +++ b/dialogs/newsequencedialog.h @@ -32,32 +32,32 @@ class NewSequenceDialog : public QDialog { - Q_OBJECT + Q_OBJECT public: - explicit NewSequenceDialog(QWidget *parent = nullptr, Media* existing = nullptr); - ~NewSequenceDialog(); + explicit NewSequenceDialog(QWidget *parent = nullptr, Media* existing = nullptr); + ~NewSequenceDialog(); - void set_sequence_name(const QString& s); + void set_sequence_name(const QString& s); private slots: - void create(); - void preset_changed(int index); + void create(); + void preset_changed(int index); private: - SequencePtr existing_sequence; - Media* existing_item; + Sequence* existing_sequence; + Media* existing_item; - void setup_ui(); + void setup_ui(); - QComboBox* preset_combobox; - QSpinBox* height_numeric; - QSpinBox* width_numeric; - QComboBox* par_combobox; - QComboBox* interlacing_combobox; - QComboBox* frame_rate_combobox; - QComboBox* audio_frequency_combobox; - QLineEdit* sequence_name_edit; + QComboBox* preset_combobox; + QSpinBox* height_numeric; + QSpinBox* width_numeric; + QComboBox* par_combobox; + QComboBox* interlacing_combobox; + QComboBox* frame_rate_combobox; + QComboBox* audio_frequency_combobox; + QLineEdit* sequence_name_edit; }; #endif // NEWSEQUENCEDIALOG_H diff --git a/dialogs/proxydialog.cpp b/dialogs/proxydialog.cpp index 9043c9f1e..fb2641de1 100644 --- a/dialogs/proxydialog.cpp +++ b/dialogs/proxydialog.cpp @@ -103,7 +103,7 @@ void ProxyDialog::accept() { info.codec_type = 0; info.size_multiplier = size_combobox->currentData().toDouble(); - FootagePtr footage = selected_media.at(i)->to_footage(); + Footage* footage = selected_media.at(i)->to_footage(); QString base_footage_fn = QFileInfo(footage->url).baseName(); @@ -148,7 +148,7 @@ void ProxyDialog::accept() { // all proxy info checks out, queue it with the proxy generator for (int i=0;ito_footage(); + Footage* footage = info_list.at(i).media->to_footage(); footage->proxy = true; footage->proxy_path.clear(); diff --git a/effects/internal/voideffect.cpp b/effects/internal/voideffect.cpp index 49c71eff8..d68f2ddbe 100644 --- a/effects/internal/voideffect.cpp +++ b/effects/internal/voideffect.cpp @@ -28,7 +28,6 @@ #include "debug.h" VoidEffect::VoidEffect(Clip* c, const QString& n) : Effect(c, nullptr) { - name = n; QString display_name; if (n.isEmpty()) { display_name = tr("(unknown)"); @@ -39,15 +38,15 @@ VoidEffect::VoidEffect(Clip* c, const QString& n) : Effect(c, nullptr) { new LabelField(row, display_name); - container->setText(display_name); + name = display_name; void_meta.type = EFFECT_TYPE_EFFECT; meta = &void_meta; } EffectPtr VoidEffect::copy(Clip* c) { - EffectPtr copy(new VoidEffect(c, name)); - copy->set_enabled(is_enabled()); + EffectPtr copy = std::make_shared(c, name); + copy->SetEnabled(IsEnabled()); copy_field_keyframes(copy); return copy; } @@ -55,31 +54,31 @@ EffectPtr VoidEffect::copy(Clip* c) { void VoidEffect::load(QXmlStreamReader &stream) { QString tag = stream.name().toString(); - QXmlStreamWriter writer(&bytes); + QXmlStreamWriter writer(&bytes); - // copy XML from reader to writer - while (!stream.atEnd() && !(stream.name() == tag && stream.isEndElement())) { + // copy XML from reader to writer + while (!stream.atEnd() && !(stream.name() == tag && stream.isEndElement())) { stream.readNext(); - if (stream.isStartElement()) { - writer.writeStartElement(stream.name().toString()); - } - if (stream.isEndElement()) { - writer.writeEndElement(); - } - if (stream.isCharacters()) { - writer.writeCharacters(stream.text().toString()); - } - for (int i=0;i tag, ignored when loading stream.writeStartElement("void"); diff --git a/io/loadthread.cpp b/io/loadthread.cpp index 6b2dc103b..fa23eb733 100644 --- a/io/loadthread.cpp +++ b/io/loadthread.cpp @@ -372,7 +372,7 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) { } else if (attr.name() == "alayout") { s->audio_layout = attr.value().toInt(); } else if (attr.name() == "open") { - open_seq = s; + open_seq = s.get(); } else if (attr.name() == "workarea") { s->using_workarea = (attr.value() == "1"); } else if (attr.name() == "workareaIn") { @@ -400,7 +400,7 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) { int media_type = -1; int media_id, stream_id; - ClipPtr c = std::make_shared(s); + ClipPtr c = std::make_shared(s.get()); QColor clip_color; ClipSpeed speed_info = c->speed(); @@ -457,7 +457,7 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) { case MEDIA_TYPE_FOOTAGE: if (media_id >= 0) { for (int j=0;jto_footage(); + Footage* m = loaded_media_items.at(j)->to_footage(); if (m->save_id == media_id) { c->set_media(loaded_media_items.at(j), stream_id); break; @@ -784,12 +784,12 @@ void LoadThread::create_effect_ui( if (meta == nullptr) { // create void effect EffectPtr ve(new VoidEffect(c, *effect_name)); - ve->set_enabled(effect_enabled); + ve->SetEnabled(effect_enabled); ve->load(*stream); c->effects.append(ve); } else { EffectPtr e(Effect::Create(c, meta)); - e->set_enabled(effect_enabled); + e->SetEnabled(effect_enabled); e->load(*stream); c->effects.append(e); @@ -797,7 +797,7 @@ void LoadThread::create_effect_ui( } else { TransitionPtr t = Transition::Create(c, nullptr, meta); if (effect_length > -1) t->set_length(effect_length); - t->set_enabled(effect_enabled); + t->SetEnabled(effect_enabled); t->load(*stream); if (type == kTransitionOpening) { diff --git a/io/loadthread.h b/io/loadthread.h index 14b92e7b2..2ecd4a593 100644 --- a/io/loadthread.h +++ b/io/loadthread.h @@ -72,7 +72,7 @@ private: void read_next_start_element(QXmlStreamReader& stream); void update_current_element_count(QXmlStreamReader& stream); - SequencePtr open_seq; + Sequence* open_seq; QVector loaded_media_items; QDir proj_dir; QDir internal_proj_dir; diff --git a/io/previewgenerator.h b/io/previewgenerator.h index 8abd5f0e4..8b273be64 100644 --- a/io/previewgenerator.h +++ b/io/previewgenerator.h @@ -55,7 +55,7 @@ private: AVFormatContext* fmt_ctx_; Media* media_; - FootagePtr footage_; + Footage* footage_; bool retrieve_duration_; bool contains_still_image_; bool cancelled_; diff --git a/io/proxygenerator.cpp b/io/proxygenerator.cpp index 9bba533a2..cb37a5a0a 100644 --- a/io/proxygenerator.cpp +++ b/io/proxygenerator.cpp @@ -42,7 +42,7 @@ enum AVCodecID temp_enc_codec = AV_CODEC_ID_PRORES; ProxyGenerator::ProxyGenerator() : cancelled(false) {} void ProxyGenerator::transcode(const ProxyInfo& info) { - FootagePtr footage = info.media->to_footage(); + Footage* footage = info.media->to_footage(); // set progress to 0 current_progress = 0.0; diff --git a/mainwindow.cpp b/mainwindow.cpp index 2ed4ea568..ad4d885c2 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -939,7 +939,7 @@ void MainWindow::closeEvent(QCloseEvent *e) { // stop proxy generator thread olive::proxy_generator.cancel(); - panel_effect_controls->clear_effects(true); + panel_effect_controls->Clear(true); olive::Global->set_sequence(nullptr); diff --git a/olive.pro b/olive.pro index 87d239992..baa966ea2 100644 --- a/olive.pro +++ b/olive.pro @@ -170,7 +170,8 @@ SOURCES += \ project/effectfields/combofield.cpp \ project/effectfields/filefield.cpp \ project/effectfields/labelfield.cpp \ - project/effectfields/buttonfield.cpp + project/effectfields/buttonfield.cpp \ + ui/effectui.cpp HEADERS += \ mainwindow.h \ @@ -294,7 +295,8 @@ HEADERS += \ project/effectfields/combofield.h \ project/effectfields/filefield.h \ project/effectfields/labelfield.h \ - project/effectfields/buttonfield.h + project/effectfields/buttonfield.h \ + ui/effectui.h FORMS += diff --git a/oliveglobal.cpp b/oliveglobal.cpp index 35b9f3d01..b293f79e0 100644 --- a/oliveglobal.cpp +++ b/oliveglobal.cpp @@ -147,7 +147,7 @@ void OliveGlobal::load_translation_from_config() { void OliveGlobal::new_project() { if (can_close_project()) { // clear effects panel - panel_effect_controls->clear_effects(true); + panel_effect_controls->Clear(true); // clear project contents (footage, sequences, etc.) panel_project->new_project(); @@ -286,9 +286,9 @@ void OliveGlobal::open_preferences() { pd.exec(); } -void OliveGlobal::set_sequence(SequencePtr s) +void OliveGlobal::set_sequence(Sequence* s) { - panel_effect_controls->clear_effects(true); + panel_effect_controls->Clear(true); olive::ActiveSequence = s; panel_sequence_viewer->set_main_sequence(); diff --git a/oliveglobal.h b/oliveglobal.h index 305beefb8..2cfd348f8 100644 --- a/oliveglobal.h +++ b/oliveglobal.h @@ -274,7 +274,7 @@ public slots: * * The Sequence to set as the active Sequence. */ - void set_sequence(SequencePtr s); + void set_sequence(Sequence *s); private: /** diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp index 174baa795..ab155daea 100644 --- a/panels/effectcontrols.cpp +++ b/panels/effectcontrols.cpp @@ -44,6 +44,7 @@ #include "panels/viewer.h" #include "panels/grapheditor.h" #include "ui/viewerwidget.h" +#include "ui/menuhelper.h" #include "io/clipboard.h" #include "io/config.h" #include "ui/timelineheader.h" @@ -53,14 +54,14 @@ EffectControls::EffectControls(QWidget *parent) : Panel(parent), - multiple(false), zoom(1), - mode(kTransitionNone) + mode_(kTransitionNone) { setup_ui(); Retranslate(); - clear_effects(false); + Clear(false); + headers->viewer = panel_sequence_viewer; headers->snapping = false; @@ -69,8 +70,6 @@ EffectControls::EffectControls(QWidget *parent) : effects_area->header = headers; keyframeView->header = headers; - lblMultipleClipsSelected->setVisible(false); - connect(keyframeView, SIGNAL(wheel_event_signal(QWheelEvent*)), effects_area, SLOT(receive_wheel_event(QWheelEvent*))); connect(horizontalScrollBar, SIGNAL(valueChanged(int)), headers, SLOT(set_scroll(int))); connect(horizontalScrollBar, SIGNAL(resize_move(double)), keyframeView, SLOT(resize_move(double))); @@ -80,10 +79,9 @@ EffectControls::EffectControls(QWidget *parent) : connect(scrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)), verticalScrollBar, SLOT(setValue(int))); } -EffectControls::~EffectControls() {} - -int EffectControls::get_mode() { - return mode; +EffectControls::~EffectControls() +{ + Clear(true); } bool EffectControls::keyframe_focus() { @@ -98,8 +96,8 @@ void EffectControls::set_zoom(bool in) { void EffectControls::menu_select(QAction* q) { ComboAction* ca = new ComboAction(); - for (int i=0;iclips.at(selected_clips.at(i)).get(); + for (int i=0;itrack() < 0) == (effect_menu_subtype == EFFECT_TYPE_VIDEO)) { const EffectMeta* meta = reinterpret_cast(q->data().value()); if (effect_menu_type == EFFECT_TYPE_TRANSITION) { @@ -126,7 +124,7 @@ void EffectControls::menu_select(QAction* q) { if (effect_menu_type == EFFECT_TYPE_TRANSITION) { update_ui(true); } else { - reload_clips(); + Reload(); panel_sequence_viewer->viewer_widget->frame_update(); } } @@ -141,39 +139,39 @@ void EffectControls::delete_selected_keyframes() { } void EffectControls::copy(bool del) { - if (mode == kTransitionNone) { + if (mode_ == kTransitionNone) { bool cleared = false; - ComboAction* ca = new ComboAction(); - EffectDeleteCommand* del_com = (del) ? new EffectDeleteCommand() : nullptr; - for (int i=0;iclips.at(selected_clips.at(i)).get(); - for (int j=0;jeffects.size();j++) { - EffectPtr effect = c->effects.at(j); - if (effect->container->selected) { - if (!cleared) { - clear_clipboard(); - cleared = true; - clipboard_type = CLIPBOARD_TYPE_EFFECT; - } + ComboAction* ca = nullptr; + if (del) { + ca = new ComboAction(); + } - clipboard.append(EffectPtr(effect->copy(nullptr))); + for (int i=0;iIsSelected()) { + Effect* e = open_effects_.at(i)->GetEffect(); - if (del_com != nullptr) { - del_com->clips.append(c); - del_com->fx.append(j); - } + if (!cleared) { + clear_clipboard(); + cleared = true; + clipboard_type = CLIPBOARD_TYPE_EFFECT; + } + + clipboard.append(e->copy(nullptr)); + + if (del) { + ca->append(new EffectDeleteCommand(e)); } } } - if (del_com != nullptr) { - if (del_com->clips.size() > 0) { - ca->append(del_com); + + if (del) { + if (ca->hasActions()) { + olive::UndoStack.push(ca); } else { - delete del_com; + delete ca; } } - olive::UndoStack.push(ca); } } @@ -181,11 +179,6 @@ void EffectControls::scroll_to_frame(long frame) { scroll_to_frame_internal(horizontalScrollBar, frame - keyframeView->visible_in, zoom, keyframeView->width()); } -void EffectControls::add_effect_paste_action(QMenu *menu) { - QAction* paste_action = menu->addAction(tr("&Paste"), panel_timeline, SLOT(paste(bool))); - paste_action->setEnabled(clipboard.size() > 0 && clipboard_type == CLIPBOARD_TYPE_EFFECT); -} - void EffectControls::cut() { copy(true); } @@ -260,56 +253,68 @@ void EffectControls::show_effect_menu(int type, int subtype) { effects_menu.exec(QCursor::pos()); } -void EffectControls::clear_effects(bool clear_cache) { +void EffectControls::Clear(bool clear_cache) { // clear existing clips deselect_all_effects(nullptr); // clear graph editor if (panel_graph_editor != nullptr) panel_graph_editor->set_row(nullptr); - QVBoxLayout* video_layout = static_cast(video_effect_area->layout()); - QVBoxLayout* audio_layout = static_cast(audio_effect_area->layout()); - QLayoutItem* item; - while ((item = video_layout->takeAt(0))) { - item->widget()->setParent(nullptr); - disconnect(static_cast(item->widget()), SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); + for (int i=0;itakeAt(0))) { - item->widget()->setParent(nullptr); - disconnect(static_cast(item->widget()), SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); - } - lblMultipleClipsSelected->setVisible(false); + open_effects_.clear(); + vcontainer->setVisible(false); acontainer->setVisible(false); headers->setVisible(false); keyframeView->setEnabled(false); - if (clear_cache) selected_clips.clear(); + + if (clear_cache) { + selected_clips_.clear(); + } + UpdateTitle(); } -void EffectControls::deselect_all_effects(QWidget* sender) { - for (int i=0;iclips.at(selected_clips.at(i)); - for (int j=0;jeffects.size();j++) { - if (c->effects.at(j)->container != sender) { - c->effects.at(j)->container->header_click(false, false); - } +bool EffectControls::IsEffectSelected(Effect *e) +{ + for (int i=0;iGetEffect() == e && open_effects_.at(i)->IsSelected()) { + return true; } } + return false; +} + +void EffectControls::deselect_all_effects(QWidget* sender) { + + for (int i=0;iheader_click(false, false); + } + } + panel_sequence_viewer->viewer_widget->update(); } -void EffectControls::open_effect(QVBoxLayout* layout, EffectPtr e) { - CollapsibleWidget* container = e->container; - layout->addWidget(container); +void EffectControls::open_effect(QVBoxLayout* layout, Effect* e) { + EffectUI* container = new EffectUI(e); + + connect(container, SIGNAL(CutRequested()), this, SLOT(cut())); + connect(container, SIGNAL(CopyRequested()), this, SLOT(copy(bool))); connect(container, SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); + + open_effects_.append(container); + + layout->addWidget(container); } void EffectControls::UpdateTitle() { - if (selected_clips.empty()) { + if (selected_clips_.isEmpty()) { setWindowTitle(panel_name + tr("(none)")); } else { - setWindowTitle(panel_name + olive::ActiveSequence->clips.at(selected_clips.at(0))->name()); + setWindowTitle(panel_name + selected_clips_.first()->name()); } } @@ -386,9 +391,9 @@ void EffectControls::setup_ui() { vcontainerLayout->addWidget(veHeader); video_effect_area = new QWidget(); - QVBoxLayout* veAreaLayout = new QVBoxLayout(video_effect_area); - veAreaLayout->setSpacing(0); - veAreaLayout->setMargin(0); + video_effect_layout = new QVBoxLayout(video_effect_area); + video_effect_layout->setSpacing(0); + video_effect_layout->setMargin(0); vcontainerLayout->addWidget(video_effect_area); @@ -428,18 +433,14 @@ void EffectControls::setup_ui() { acontainerLayout->addWidget(aeHeader); audio_effect_area = new QWidget(); - QVBoxLayout* aeAreaLayout = new QVBoxLayout(audio_effect_area); - aeAreaLayout->setSpacing(0); - aeAreaLayout->setMargin(0); + audio_effect_layout = new QVBoxLayout(audio_effect_area); + audio_effect_layout->setSpacing(0); + audio_effect_layout->setMargin(0); acontainerLayout->addWidget(audio_effect_area); effects_area_layout->addWidget(acontainer); - lblMultipleClipsSelected = new QLabel(); - lblMultipleClipsSelected->setAlignment(Qt::AlignCenter); - effects_area_layout->addWidget(lblMultipleClipsSelected); - effects_area_layout->addStretch(); scrollAreaLayout->addWidget(effects_area); @@ -501,7 +502,6 @@ void EffectControls::Retranslate() { btnAddAudioEffect->setToolTip(tr("Add Audio Effect")); lblAudioEffects->setText(tr("AUDIO EFFECTS")); btnAddAudioTransition->setToolTip(tr("Add Audio Transition")); - lblMultipleClipsSelected->setText(tr("(Multiple clips selected)")); UpdateTitle(); } @@ -529,85 +529,83 @@ void EffectControls::queue_post_update() { void EffectControls::effects_area_context_menu() { QMenu menu(this); - add_effect_paste_action(&menu); + olive::MenuHelper.create_effect_paste_action(&menu); menu.exec(QCursor::pos()); } -void EffectControls::load_effects() { - lblMultipleClipsSelected->setVisible(multiple); +void EffectControls::delete_effects() { + // load in new clips + if (mode_ == kTransitionNone) { - if (!multiple) { - // load in new clips - for (int i=0;iclips.at(selected_clips.at(i)); - QVBoxLayout* layout; - if (c->track() < 0) { - vcontainer->setVisible(true); - layout = static_cast(video_effect_area->layout()); - } else { - acontainer->setVisible(true); - layout = static_cast(audio_effect_area->layout()); - } - if (mode == kTransitionNone) { - for (int j=0;jeffects.size();j++) { - open_effect(layout, c->effects.at(j)); - } - } else if (mode == kTransitionOpening && c->opening_transition != nullptr) { - open_effect(layout, c->opening_transition); - } else if (mode == kTransitionClosing && c->closing_transition != nullptr) { - open_effect(layout, c->closing_transition); + ComboAction* ca = new ComboAction(); + + for (int i=0;iIsSelected()) { + ca->append(new EffectDeleteCommand(open_effects_.at(i)->GetEffect())); } } - if (selected_clips.size() > 0) { - keyframeView->setEnabled(true); - headers->setVisible(true); - QTimer::singleShot(50, this, SLOT(queue_post_update())); + if (ca->hasActions()) { + olive::UndoStack.push(ca); + panel_sequence_viewer->viewer_widget->frame_update(); + } else { + delete ca; } } +} + +void EffectControls::Reload() { + Clear(false); + Load(); +} + +void EffectControls::SetClips(const QVector &clips, int mode) +{ + Clear(true); + + // replace clip vector + selected_clips_ = clips; + mode_ = mode; + + Load(); +} + +void EffectControls::Load() { + // load in new clips + for (int i=0;itrack() < 0) { + vcontainer->setVisible(true); + layout = video_effect_layout; + } else { + acontainer->setVisible(true); + layout = audio_effect_layout; + } + + if (mode_ == kTransitionNone) { + for (int j=0;jeffects.size();j++) { + open_effect(layout, c->effects.at(j).get()); + } + } else if (mode_ == kTransitionOpening && c->opening_transition != nullptr) { + open_effect(layout, c->opening_transition.get()); + } else if (mode_ == kTransitionClosing && c->closing_transition != nullptr) { + open_effect(layout, c->closing_transition.get()); + } + } + if (selected_clips_.size() > 0) { + keyframeView->setEnabled(true); + headers->setVisible(true); + + QTimer::singleShot(50, this, SLOT(queue_post_update())); + } UpdateTitle(); } -void EffectControls::delete_effects() { - // load in new clips - if (mode == kTransitionNone) { - EffectDeleteCommand* command = new EffectDeleteCommand(); - for (int i=0;iclips.at(selected_clips.at(i)).get(); - for (int j=0;jeffects.size();j++) { - EffectPtr effect = c->effects.at(j); - if (effect->container->selected) { - command->clips.append(c); - command->fx.append(j); - } - } - } - if (command->clips.size() > 0) { - olive::UndoStack.push(command); - panel_sequence_viewer->viewer_widget->frame_update(); - } else { - delete command; - } - } -} - -void EffectControls::reload_clips() { - clear_effects(false); - load_effects(); -} - -void EffectControls::set_clips(QVector& clips, int m) { - clear_effects(true); - - // replace clip vector - selected_clips = clips; - mode = m; - - load_effects(); -} - void EffectControls::video_effect_click() { show_effect_menu(EFFECT_TYPE_EFFECT, EFFECT_TYPE_VIDEO); } @@ -630,18 +628,13 @@ void EffectControls::resizeEvent(QResizeEvent*) { bool EffectControls::is_focused() { if (this->hasFocus()) return true; - for (int i=0;iclips.at(selected_clips.at(i)); - if (c != nullptr) { - for (int j=0;jeffects.size();j++) { - if (c->effects.at(j)->container->is_focused()) { - return true; - } - } - } else { - qWarning() << "Tried to check focus of a nullptr clip"; + + for (int i=0;iIsFocused()) { + return true; } } + return false; } diff --git a/panels/effectcontrols.h b/panels/effectcontrols.h index 4cc3a9116..39482789b 100644 --- a/panels/effectcontrols.h +++ b/panels/effectcontrols.h @@ -37,11 +37,12 @@ #include "ui/resizablescrollbar.h" #include "ui/keyframeview.h" #include "ui/panel.h" +#include "ui/effectui.h" class EffectsArea : public QWidget { Q_OBJECT public: - EffectsArea(QWidget* parent = 0); + EffectsArea(QWidget* parent = nullptr); QScrollArea* parent_widget; KeyframeView* keyframe_area; TimelineHeader* header; @@ -53,22 +54,23 @@ class EffectControls : public Panel { Q_OBJECT public: - explicit EffectControls(QWidget *parent = 0); - ~EffectControls(); - int get_mode(); - void set_clips(QVector& clips, int mode); - void clear_effects(bool clear_cache); + explicit EffectControls(QWidget *parent = nullptr); + virtual ~EffectControls() override; + + + void Reload(); + void SetClips(const QVector &clips, int mode); + void Clear(bool clear_cache = true); + + bool IsEffectSelected(Effect* e); + void delete_effects(); bool is_focused(); - void reload_clips(); void set_zoom(bool in); bool keyframe_focus(); void delete_selected_keyframes(); - bool multiple; void scroll_to_frame(long frame); - QVector selected_clips; - double zoom; ResizableScrollBar* horizontalScrollBar; @@ -76,8 +78,6 @@ public: QMutex effects_loaded; - void add_effect_paste_action(QMenu* menu); - virtual void Retranslate() override; virtual void LoadLayoutState(const QByteArray& data) override; @@ -103,10 +103,14 @@ private slots: protected: virtual void resizeEvent(QResizeEvent *event) override; private: + QVector selected_clips_; + QVector open_effects_; + + void Load(); + void show_effect_menu(int type, int subtype); - void load_effects(); void load_keyframes(); - void open_effect(QVBoxLayout* hlayout, EffectPtr e); + void open_effect(QVBoxLayout* hlayout, Effect *e); void UpdateTitle(); void setup_ui(); @@ -114,22 +118,24 @@ private: int effect_menu_type; int effect_menu_subtype; QString panel_name; - int mode; + int mode_; + + QWidget* video_effect_area; + QWidget* audio_effect_area; + QVBoxLayout* video_effect_layout; + QVBoxLayout* audio_effect_layout; QSplitter* splitter; QPushButton* btnAddVideoEffect; QLabel* lblVideoEffects; + QLabel* lblAudioEffects; QPushButton* btnAddVideoTransition; QPushButton* btnAddAudioEffect; QPushButton* btnAddAudioTransition; - QLabel* lblMultipleClipsSelected; - QLabel* lblAudioEffects; TimelineHeader* headers; EffectsArea* effects_area; QScrollArea* scrollArea; KeyframeView* keyframeView; - QWidget* video_effect_area; - QWidget* audio_effect_area; QWidget* vcontainer; QWidget* acontainer; }; diff --git a/panels/panels.cpp b/panels/panels.cpp index 1d87a8c2f..cdd3691ef 100644 --- a/panels/panels.cpp +++ b/panels/panels.cpp @@ -39,16 +39,11 @@ Timeline* panel_timeline = nullptr; GraphEditor* panel_graph_editor = nullptr; void update_effect_controls() { - // SEND CLIPS TO EFFECT CONTROLS - // find out how many clips are selected - // limits to one video clip and one audio clip and only if they're linked - // one of these days it might be nice to have multiple clips in the effects panel - bool multiple = false; - int vclip = -1; - int aclip = -1; - QVector selected_clips; + QVector selected_clips; int mode = kTransitionNone; + if (olive::ActiveSequence != nullptr) { + /* for (int i=0;iclips.size();i++) { Clip* clip = olive::ActiveSequence->clips.at(i).get(); if (clip != nullptr) { @@ -102,26 +97,14 @@ void update_effect_controls() { } } } + */ + + selected_clips = olive::ActiveSequence->SelectedClips(); + + // TODO handle selecting transitions } - - - bool same = (selected_clips.size() == panel_effect_controls->selected_clips.size() - && panel_effect_controls->get_mode() == mode); - if (same) { - for (int i=0;iselected_clips.at(i)) { - same = false; - break; - } - } - } - - if (panel_effect_controls->multiple != multiple || !same) { - panel_effect_controls->multiple = multiple; - - panel_effect_controls->set_clips(selected_clips, mode); - } + panel_effect_controls->SetClips(selected_clips, mode); } void update_ui(bool modified) { @@ -172,7 +155,7 @@ QDockWidget *get_focused_panel(bool force_hover) { void alloc_panels(QWidget* parent) { // TODO maybe replace these with non-pointers later on? panel_sequence_viewer = new Viewer(parent); - panel_sequence_viewer->setObjectName("seq_viewer"); + panel_sequence_viewer->setObjectName("seq_viewer"); panel_footage_viewer = new Viewer(parent); panel_footage_viewer->setObjectName("footage_viewer"); panel_project = new Project(parent); diff --git a/panels/project.cpp b/panels/project.cpp index 1ae425d72..1806c1354 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -264,7 +264,7 @@ SequencePtr create_sequence_from_media(QVector& media_list) { switch (media->get_type()) { case MEDIA_TYPE_FOOTAGE: { - FootagePtr m = media->to_footage(); + Footage* m = media->to_footage(); if (m->ready) { if (!got_video_values) { for (int j=0;jvideo_tracks.size();j++) { @@ -292,7 +292,7 @@ SequencePtr create_sequence_from_media(QVector& media_list) { break; case MEDIA_TYPE_SEQUENCE: { - SequencePtr seq = media->to_sequence(); + Sequence* seq = media->to_sequence(); s->width = seq->width; s->height = seq->height; s->frame_rate = seq->frame_rate; @@ -440,13 +440,15 @@ Media* Project::create_sequence_internal(ComboAction *ca, SequencePtr s, bool op if (ca != nullptr) { ca->append(new NewSequenceCommand(item, parent)); - if (open) ca->append(new ChangeSequenceAction(s)); - } else { + if (open) { + ca->append(new ChangeSequenceAction(s.get())); + } + } else { olive::project_model.appendChild(parent, item); if (open) { - olive::Global->set_sequence(s); + olive::Global->set_sequence(s.get()); } } return item; @@ -530,10 +532,10 @@ void Project::delete_selected_media() { get_all_media_from_table(items, media_items, MEDIA_TYPE_FOOTAGE); for (int i=0;ito_footage(); + Footage* media = item->to_footage(); bool confirm_delete = false; for (int j=0;jto_sequence(); + Sequence* s = sequence_items.at(j)->to_sequence(); for (int k=0;kclips.size();k++) { ClipPtr c = s->clips.at(k); if (c != nullptr && c->media() == item) { @@ -600,7 +602,7 @@ void Project::delete_selected_media() { // remove if (remove) { - panel_effect_controls->clear_effects(true); + panel_effect_controls->Clear(true); if (olive::ActiveSequence != nullptr) olive::ActiveSequence->selections.clear(); // remove media and parents @@ -619,13 +621,13 @@ void Project::delete_selected_media() { if (items.at(i)->get_type() == MEDIA_TYPE_SEQUENCE) { redraw = true; - SequencePtr s = items.at(i)->to_sequence(); + Sequence* s = items.at(i)->to_sequence(); if (s == olive::ActiveSequence) { ca->append(new ChangeSequenceAction(nullptr)); } - if (s == panel_footage_viewer->seq) { + if (s == panel_footage_viewer->seq.get()) { panel_footage_viewer->set_media(nullptr); } } else if (items.at(i)->get_type() == MEDIA_TYPE_FOOTAGE) { @@ -1009,12 +1011,11 @@ void Project::delete_clips_using_selected_media() { void Project::clear() { // clear effects cache - panel_effect_controls->clear_effects(true); + panel_effect_controls->Clear(true); // delete sequences first because it's important to close all the clips before deleting the media QVector sequences = list_all_project_sequences(); for (int i=0;ito_sequence().reset(); sequences.at(i)->set_sequence(nullptr); } @@ -1079,7 +1080,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, } else { int folder = m->parentItem()->temp_id; if (type == MEDIA_TYPE_FOOTAGE) { - FootagePtr f = m->to_footage(); + Footage* f = m->to_footage(); f->save_id = media_id; stream.writeStartElement("footage"); stream.writeAttribute("id", QString::number(media_id)); @@ -1128,7 +1129,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, stream.writeEndElement(); // footage media_id++; } else if (type == MEDIA_TYPE_SEQUENCE) { - SequencePtr s = m->to_sequence(); + Sequence* s = m->to_sequence(); if (set_ids_only) { s->save_id = sequence_id; sequence_id++; diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 8834fa126..9de1f4154 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -177,7 +177,7 @@ void Timeline::next_cut() { } } -void ripple_clips(ComboAction* ca, SequencePtr s, long point, long length, const QVector& ignore) { +void ripple_clips(ComboAction* ca, Sequence* s, long point, long length, const QVector& ignore) { ca->append(new RippleAction(s, point, length, ignore)); } @@ -193,7 +193,7 @@ void Timeline::toggle_show_all() { } } -void Timeline::create_ghosts_from_media(SequencePtr seq, long entry_point, QVector& media_list) { +void Timeline::create_ghosts_from_media(Sequence* seq, long entry_point, QVector& media_list) { video_ghosts = false; audio_ghosts = false; @@ -201,8 +201,8 @@ void Timeline::create_ghosts_from_media(SequencePtr seq, long entry_point, QVect bool can_import = true; Media* medium = media_list.at(i); - FootagePtr m = nullptr; - SequencePtr s = nullptr; + Footage* m = nullptr; + Sequence* s = nullptr; long sequence_length = 0; long default_clip_in = 0; long default_clip_out = 0; @@ -298,7 +298,7 @@ void Timeline::create_ghosts_from_media(SequencePtr seq, long entry_point, QVect } } -void Timeline::add_clips_from_ghosts(ComboAction* ca, SequencePtr s) { +void Timeline::add_clips_from_ghosts(ComboAction* ca, Sequence* s) { // add clips long earliest_point = LONG_MAX; QVector added_clips; @@ -314,7 +314,7 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, SequencePtr s) { c->set_clip_in(g.clip_in); c->set_track(g.track); if (c->media()->get_type() == MEDIA_TYPE_FOOTAGE) { - FootagePtr m = c->media()->to_footage(); + Footage* m = c->media()->to_footage(); if (m->video_tracks.size() == 0) { // audio only (greenish) c->set_color(128, 192, 128); @@ -330,7 +330,7 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, SequencePtr s) { // sequence (red?ish?) c->set_color(192, 128, 128); - SequencePtr media = c->media()->to_sequence(); + Sequence* media = c->media()->to_sequence(); c->set_name(media->name); } c->refresh(); @@ -420,7 +420,7 @@ void Timeline::nest() { ComboAction* ca = new ComboAction(); // create "nest" sequence with the same attributes as the current sequence - SequencePtr s(new Sequence()); + SequencePtr s = std::make_shared(); s->name = panel_project->get_next_sequence_name(tr("Nested Sequence")); s->width = olive::ActiveSequence->width; @@ -435,7 +435,7 @@ void Timeline::nest() { ca->append(new DeleteClipAction(olive::ActiveSequence, selected_clips.at(i))); // copy to new - ClipPtr copy(olive::ActiveSequence->clips.at(selected_clips.at(i))->copy(s)); + ClipPtr copy(olive::ActiveSequence->clips.at(selected_clips.at(i))->copy(s.get())); copy->set_timeline_in(copy->timeline_in() - earliest_point); copy->set_timeline_out(copy->timeline_out() - earliest_point); s->clips.append(copy); @@ -453,7 +453,7 @@ void Timeline::nest() { create_ghosts_from_media(olive::ActiveSequence, earliest_point, media_list); add_clips_from_ghosts(ca, olive::ActiveSequence); - panel_effect_controls->clear_effects(true); + panel_effect_controls->Clear(true); olive::ActiveSequence->selections.clear(); olive::UndoStack.push(ca); @@ -680,7 +680,7 @@ void Timeline::toggle_enable_on_selected_clips() { void Timeline::delete_selection(QVector& selections, bool ripple_delete) { if (selections.size() > 0) { - panel_effect_controls->clear_effects(true); + panel_effect_controls->Clear(true); ComboAction* ca = new ComboAction(); @@ -1014,7 +1014,7 @@ bool selection_contains_transition(const Selection& s, Clip* c, int type) { void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& areas, bool deselect_areas) { clean_up_selections(areas); - panel_effect_controls->clear_effects(true); + panel_effect_controls->Clear(true); QVector pre_clips; QVector post_clips; @@ -1281,10 +1281,7 @@ void Timeline::paste(bool insert) { if (found >= 0 && skip) { // do nothing } else if (found >= 0 && replace) { - EffectDeleteCommand* delcom = new EffectDeleteCommand(); - delcom->clips.append(c); - delcom->fx.append(found); - ca->append(delcom); + ca->append(new EffectDeleteCommand(c->effects.at(found).get())); ca->append(new AddEffectCommand(c, e->copy(c), nullptr, found)); } else { diff --git a/panels/timeline.h b/panels/timeline.h index 96499a088..198e23c46 100644 --- a/panels/timeline.h +++ b/panels/timeline.h @@ -74,7 +74,7 @@ namespace olive { int getScreenPointFromFrame(double zoom, long frame); long getFrameFromScreenPoint(double zoom, int x); bool selection_contains_transition(const Selection& s, Clip *c, int type); -void ripple_clips(ComboAction *ca, SequencePtr s, long point, long length, const QVector& ignore = QVector()); +void ripple_clips(ComboAction *ca, Sequence *s, long point, long length, const QVector& ignore = QVector()); struct Ghost { int clip; @@ -125,8 +125,8 @@ public: void edit_to_point_internal(bool in, bool ripple); void delete_in_out_internal(bool ripple); - void create_ghosts_from_media(SequencePtr seq, long entry_point, QVector &media_list); - void add_clips_from_ghosts(ComboAction *ca, SequencePtr s); + void create_ghosts_from_media(Sequence *seq, long entry_point, QVector &media_list); + void add_clips_from_ghosts(ComboAction *ca, Sequence *s); int getTimelineScreenPointFromFrame(long frame); long getTimelineFrameFromScreenPoint(int x); diff --git a/panels/viewer.cpp b/panels/viewer.cpp index c6455b347..8cf5db31a 100644 --- a/panels/viewer.cpp +++ b/panels/viewer.cpp @@ -449,9 +449,9 @@ void Viewer::pause() { panel_project->process_file_list(file_list); // add it to the sequence - ClipPtr c = std::make_shared(seq); + ClipPtr c = std::make_shared(seq.get()); Media* m = panel_project->last_imported_media.at(0); - FootagePtr f = m->to_footage(); + Footage* f = m->to_footage(); // wait for footage to be completely ready before taking metadata from it f->ready_lock.lock(); @@ -468,7 +468,7 @@ void Viewer::pause() { QVector add_clips; add_clips.append(c); - olive::UndoStack.push(new AddClipCommand(seq, add_clips)); // add clip + olive::UndoStack.push(new AddClipCommand(seq.get(), add_clips)); // add clip } } } @@ -514,7 +514,7 @@ int Viewer::get_playback_speed() { } void Viewer::set_marker() { - set_marker_internal(seq); + set_marker_internal(seq.get()); } void Viewer::resizeEvent(QResizeEvent *e) { @@ -537,7 +537,7 @@ void Viewer::update_viewer() { void Viewer::clear_in() { if (seq != nullptr && seq->using_workarea) { - olive::UndoStack.push(new SetTimelineInOutCommand(seq, true, 0, seq->workarea_out)); + olive::UndoStack.push(new SetTimelineInOutCommand(seq.get(), true, 0, seq->workarea_out)); update_parents(); } } @@ -545,7 +545,7 @@ void Viewer::clear_in() { void Viewer::clear_out() { if (seq != nullptr && seq->using_workarea) { - olive::UndoStack.push(new SetTimelineInOutCommand(seq, true, seq->workarea_in, seq->getEndFrame())); + olive::UndoStack.push(new SetTimelineInOutCommand(seq.get(), true, seq->workarea_in, seq->getEndFrame())); update_parents(); } } @@ -553,7 +553,7 @@ void Viewer::clear_out() { void Viewer::clear_inout_point() { if (seq != nullptr && seq->using_workarea) { - olive::UndoStack.push(new SetTimelineInOutCommand(seq, false, 0, 0)); + olive::UndoStack.push(new SetTimelineInOutCommand(seq.get(), false, 0, 0)); update_parents(); } } @@ -720,11 +720,11 @@ void Viewer::set_media(Media* m) { switch (media->get_type()) { case MEDIA_TYPE_FOOTAGE: { - FootagePtr footage = media->to_footage(); + Footage* footage = media->to_footage(); marker_ref = &footage->markers; - seq = SequencePtr(new Sequence()); + seq = std::make_shared(); created_sequence = true; seq->wrapper_sequence = true; seq->name = footage->name; @@ -744,7 +744,7 @@ void Viewer::set_media(Media* m) { seq->height = video_stream.video_height; if (video_stream.video_frame_rate > 0 && !video_stream.infinite_length) seq->frame_rate = video_stream.video_frame_rate * footage->speed; - ClipPtr c = std::make_shared(seq); + ClipPtr c = std::make_shared(seq.get()); c->set_media(media, video_stream.file_index); c->set_timeline_in(0); c->set_timeline_out(footage->get_length_in_frames(seq->frame_rate)); @@ -766,7 +766,7 @@ void Viewer::set_media(Media* m) { const FootageStream& audio_stream = footage->audio_tracks.at(0); seq->audio_frequency = audio_stream.audio_frequency; - ClipPtr c = std::make_shared(seq); + ClipPtr c = std::make_shared(seq.get()); c->set_media(media, audio_stream.file_index); c->set_timeline_in(0); c->set_timeline_out(footage->get_length_in_frames(seq->frame_rate)); @@ -790,11 +790,11 @@ void Viewer::set_media(Media* m) { } break; case MEDIA_TYPE_SEQUENCE: - seq = media->to_sequence(); + seq = SequencePtr(media->to_sequence()); break; } } - set_sequence(false, seq); + set_sequence(false, seq.get()); } void Viewer::update_playhead() { @@ -857,17 +857,17 @@ void Viewer::clean_created_seq() { } } -void Viewer::set_sequence(bool main, SequencePtr s) { +void Viewer::set_sequence(bool main, Sequence* s) { pause(); reset_all_audio(); if (seq != nullptr) { - close_active_clips(seq); + close_active_clips(seq.get()); } main_sequence = main; - seq = (main) ? olive::ActiveSequence : s; + seq = SequencePtr((main) ? olive::ActiveSequence : s); bool null_sequence = (seq == nullptr); diff --git a/panels/viewer.h b/panels/viewer.h index 0f4ad5bb8..2b8bc2a76 100644 --- a/panels/viewer.h +++ b/panels/viewer.h @@ -126,7 +126,7 @@ private: void update_window_title(); void clean_created_seq(); - void set_sequence(bool main, SequencePtr s); + void set_sequence(bool main, Sequence *s); bool main_sequence; bool created_sequence; long cached_end_frame; diff --git a/project/clip.cpp b/project/clip.cpp index cf85fb55c..a85326cfe 100644 --- a/project/clip.cpp +++ b/project/clip.cpp @@ -38,7 +38,7 @@ const int kRGBAComponentCount = 4; -Clip::Clip(SequencePtr s) : +Clip::Clip(Sequence* s) : sequence(s), cacher(this) { @@ -62,7 +62,7 @@ Clip::Clip(SequencePtr s) : reset(); } -ClipPtr Clip::copy(SequencePtr s) { +ClipPtr Clip::copy(Sequence* s) { ClipPtr copy = std::make_shared(s); copy->set_enabled(enabled()); @@ -197,7 +197,7 @@ void Clip::reset_audio() { cacher.ResetAudio(); } if (media() != nullptr && media()->get_type() == MEDIA_TYPE_SEQUENCE) { - SequencePtr nested_sequence = media()->to_sequence(); + Sequence* nested_sequence = media()->to_sequence(); for (int i=0;iclips.size();i++) { ClipPtr c = nested_sequence->clips.at(i); if (c != nullptr) c->reset_audio(); @@ -208,7 +208,7 @@ void Clip::reset_audio() { void Clip::refresh() { // validates media if it was replaced if (replaced && media() != nullptr && media()->get_type() == MEDIA_TYPE_FOOTAGE) { - FootagePtr m = media()->to_footage(); + Footage* m = media()->to_footage(); if (track() < 0 && m->video_tracks.size() > 0) { set_media(media(), m->video_tracks.at(0).file_index); @@ -231,6 +231,16 @@ QVector &Clip::get_markers() { return markers; } +int Clip::IndexOfEffect(Effect *e) +{ + for (int i=0;iget_type()) { case MEDIA_TYPE_FOOTAGE: { - FootagePtr m = media_->to_footage(); + Footage* m = media_->to_footage(); const FootageStream* ms = m->get_stream_from_file_index(track_ < 0, media_stream_index()); if (ms != nullptr && ms->infinite_length) { return LONG_MAX; @@ -381,7 +391,7 @@ long Clip::media_length() { } case MEDIA_TYPE_SEQUENCE: { - SequencePtr s = media_->to_sequence(); + Sequence* s = media_->to_sequence(); return rescale_frame_number(s->getEndFrame(), s->frame_rate, fr); } } @@ -402,7 +412,7 @@ int Clip::media_width() { } case MEDIA_TYPE_SEQUENCE: { - SequencePtr s = media_->to_sequence(); + Sequence* s = media_->to_sequence(); return s->width; } } @@ -421,7 +431,7 @@ int Clip::media_height() { break; case MEDIA_TYPE_SEQUENCE: { - SequencePtr s = media_->to_sequence(); + Sequence* s = media_->to_sequence(); return s->height; } } @@ -575,7 +585,7 @@ bool Clip::Retrieve() for (int i=0;iFlags() & Effect::ImageFlag) && e->is_enabled()) { + if ((e->Flags() & Effect::ImageFlag) && e->IsEnabled()) { if (data_buffer_1 == frame->data[0]) { data_buffer_1 = new uint8_t[frame_size]; data_buffer_2 = new uint8_t[frame_size]; diff --git a/project/clip.h b/project/clip.h index db2bf6c11..f7b52da8a 100644 --- a/project/clip.h +++ b/project/clip.h @@ -51,13 +51,12 @@ struct ClipSpeed { using ClipPtr = std::shared_ptr; class Sequence; -using SequencePtr = std::shared_ptr; -class Clip : public std::enable_shared_from_this { +class Clip { public: - Clip(SequencePtr s); + Clip(Sequence *s); ~Clip(); - ClipPtr copy(SequencePtr s); + ClipPtr copy(Sequence *s); bool IsActiveAt(long timecode); @@ -121,12 +120,13 @@ public: long length(); void refactor_frame_rate(ComboAction* ca, double multiplier, bool change_timeline_points); - SequencePtr sequence; + Sequence* sequence; // markers QVector& get_markers(); // other variables (should be deep copied/duplicated in copy()) + int IndexOfEffect(Effect* e); QList effects; QVector linked; TransitionPtr opening_transition; diff --git a/project/effect.cpp b/project/effect.cpp index 74f41bf94..a54a2d4cc 100644 --- a/project/effect.cpp +++ b/project/effect.cpp @@ -73,32 +73,32 @@ EffectPtr Effect::Create(Clip* c, const EffectMeta* em) { if (em->internal >= 0 && em->internal < EFFECT_INTERNAL_COUNT) { // must be an internal effect switch (em->internal) { - case EFFECT_INTERNAL_TRANSFORM: return std::make_shared(c, em); - case EFFECT_INTERNAL_TEXT: return std::make_shared(c, em); - case EFFECT_INTERNAL_TIMECODE: return std::make_shared(c, em); - case EFFECT_INTERNAL_SOLID: return std::make_shared(c, em); - case EFFECT_INTERNAL_NOISE: return std::make_shared(c, em); - case EFFECT_INTERNAL_VOLUME: return std::make_shared(c, em); - case EFFECT_INTERNAL_PAN: return std::make_shared(c, em); - case EFFECT_INTERNAL_TONE: return std::make_shared(c, em); - case EFFECT_INTERNAL_SHAKE: return std::make_shared(c, em); - case EFFECT_INTERNAL_CORNERPIN: return std::make_shared(c, em); - case EFFECT_INTERNAL_FILLLEFTRIGHT: return std::make_shared(c, em); + case EFFECT_INTERNAL_TRANSFORM: return std::make_shared(c, em); + case EFFECT_INTERNAL_TEXT: return std::make_shared(c, em); + case EFFECT_INTERNAL_TIMECODE: return std::make_shared(c, em); + case EFFECT_INTERNAL_SOLID: return std::make_shared(c, em); + case EFFECT_INTERNAL_NOISE: return std::make_shared(c, em); + case EFFECT_INTERNAL_VOLUME: return std::make_shared(c, em); + case EFFECT_INTERNAL_PAN: return std::make_shared(c, em); + case EFFECT_INTERNAL_TONE: return std::make_shared(c, em); + case EFFECT_INTERNAL_SHAKE: return std::make_shared(c, em); + case EFFECT_INTERNAL_CORNERPIN: return std::make_shared(c, em); + case EFFECT_INTERNAL_FILLLEFTRIGHT: return std::make_shared(c, em); #ifndef NOVST - case EFFECT_INTERNAL_VST: return std::make_shared(c, em); + case EFFECT_INTERNAL_VST: return std::make_shared(c, em); #endif #ifndef NOFREI0R - case EFFECT_INTERNAL_FREI0R: return std::make_shared(c, em); + case EFFECT_INTERNAL_FREI0R: return std::make_shared(c, em); #endif } } else if (!em->filename.isEmpty()) { // load effect from file - return std::make_shared(c, em); + return std::make_shared(c, em); } else { qCritical() << "Invalid effect data"; - QMessageBox::critical(olive::MainWindow, - QCoreApplication::translate("Effect", "Invalid effect"), - QCoreApplication::translate("Effect", "No candidate for effect '%1'. This effect may be corrupt. Try reinstalling it or Olive.").arg(em->name)); + QMessageBox::critical(olive::MainWindow, + QCoreApplication::translate("Effect", "Invalid effect"), + QCoreApplication::translate("Effect", "No candidate for effect '%1'. This effect may be corrupt. Try reinstalling it or Olive.").arg(em->name)); } return nullptr; } @@ -123,19 +123,9 @@ Effect::Effect(Clip* c, const EffectMeta *em) : bound(false), iterations(1) { - // set up base UI - container = new CollapsibleWidget(); - connect(container->enabled_check, SIGNAL(clicked(bool)), this, SLOT(field_changed())); - ui = new QWidget(container); - ui_layout = new QGridLayout(ui); - ui_layout->setSpacing(4); - container->setContents(ui); - - connect(container->title_bar, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu(const QPoint&))); - if (em != nullptr) { // set up UI from effect file - container->setText(em->name); + name = em->name; if (!em->filename.isEmpty() && em->internal == -1) { QFile effect_file(em->filename); @@ -353,12 +343,12 @@ Effect::~Effect() { if (isOpen) { close(); } +} - delete container; - - for (int i=0;isetParent(this); + rows.append(row); } void Effect::copy_field_keyframes(EffectPtr e) { @@ -388,7 +378,7 @@ int Effect::row_count() { } EffectGizmo *Effect::add_gizmo(int type) { - EffectGizmo* gizmo = new EffectGizmo(type); + EffectGizmo* gizmo = new EffectGizmo(this, type); gizmos.append(gizmo); return gizmo; } @@ -408,83 +398,45 @@ void Effect::field_changed() { panel_graph_editor->update_panel(); } -void Effect::show_context_menu(const QPoint& pos) { - if (meta->type == EFFECT_TYPE_EFFECT) { - QMenu menu(olive::MainWindow); - - int index = get_index_in_clip(); - - menu.addAction(tr("Cu&t"), panel_effect_controls, SLOT(cut())); - menu.addAction(tr("&Copy"), panel_effect_controls, SLOT(copy(bool))); - - panel_effect_controls->add_effect_paste_action(&menu); - - menu.addSeparator(); - - if (index > 0) { - menu.addAction(tr("Move &Up"), this, SLOT(move_up())); - } - - if (index < parent_clip->effects.size() - 1) { - menu.addAction(tr("Move &Down"), this, SLOT(move_down())); - } - - menu.addSeparator(); - - menu.addAction(tr("D&elete"), this, SLOT(delete_self())); - - menu.addSeparator(); - - menu.addAction(tr("Load Settings From File"), this, SLOT(load_from_file())); - - menu.addAction(tr("Save Settings to File"), this, SLOT(save_to_file())); - - menu.exec(container->title_bar->mapToGlobal(pos)); - } -} - void Effect::delete_self() { - EffectDeleteCommand* command = new EffectDeleteCommand(); - command->clips.append(parent_clip); - command->fx.append(get_index_in_clip()); - olive::UndoStack.push(command); + olive::UndoStack.push(new EffectDeleteCommand(this)); update_ui(true); } void Effect::move_up() { MoveEffectCommand* command = new MoveEffectCommand(); command->clip = parent_clip; - command->from = get_index_in_clip(); + command->from = parent_clip->IndexOfEffect(this); command->to = command->from - 1; olive::UndoStack.push(command); - panel_effect_controls->reload_clips(); + panel_effect_controls->Reload(); panel_sequence_viewer->viewer_widget->frame_update(); } void Effect::move_down() { MoveEffectCommand* command = new MoveEffectCommand(); command->clip = parent_clip; - command->from = get_index_in_clip(); + command->from = parent_clip->IndexOfEffect(this); command->to = command->from + 1; olive::UndoStack.push(command); - panel_effect_controls->reload_clips(); + panel_effect_controls->Reload(); panel_sequence_viewer->viewer_widget->frame_update(); } void Effect::save_to_file() { // save effect settings to file - QString file = QFileDialog::getSaveFileName(olive::MainWindow, - tr("Save Effect Settings"), - QString(), - tr("Effect XML Settings %1").arg("(*.xml)")); + QString file = QFileDialog::getSaveFileName(olive::MainWindow, + tr("Save Effect Settings"), + QString(), + tr("Effect XML Settings %1").arg("(*.xml)")); // if the user picked a file if (!file.isEmpty()) { - // ensure file ends with .xml extension - if (!file.endsWith(".xml", Qt::CaseInsensitive)) { - file.append(".xml"); - } + // ensure file ends with .xml extension + if (!file.endsWith(".xml", Qt::CaseInsensitive)) { + file.append(".xml"); + } QFile file_handle(file); if (file_handle.open(QFile::WriteOnly)) { @@ -493,36 +445,36 @@ void Effect::save_to_file() { file_handle.close(); } else { - QMessageBox::critical(olive::MainWindow, - tr("Save Settings Failed"), - tr("Failed to open \"%1\" for writing.").arg(file), - QMessageBox::Ok); + QMessageBox::critical(olive::MainWindow, + tr("Save Settings Failed"), + tr("Failed to open \"%1\" for writing.").arg(file), + QMessageBox::Ok); } } } void Effect::load_from_file() { // load effect settings from file - QString file = QFileDialog::getOpenFileName(olive::MainWindow, - tr("Load Effect Settings"), - QString(), - tr("Effect XML Settings %1").arg("(*.xml)")); + QString file = QFileDialog::getOpenFileName(olive::MainWindow, + tr("Load Effect Settings"), + QString(), + tr("Effect XML Settings %1").arg("(*.xml)")); // if the user picked a file if (!file.isEmpty()) { QFile file_handle(file); if (file_handle.open(QFile::ReadOnly)) { - olive::UndoStack.push(new SetEffectData(EffectPtr(this), file_handle.readAll())); + olive::UndoStack.push(new SetEffectData(EffectPtr(this), file_handle.readAll())); file_handle.close(); update_ui(false); } else { - QMessageBox::critical(olive::MainWindow, - tr("Load Settings Failed"), - tr("Failed to open \"%1\" for reading.").arg(file), - QMessageBox::Ok); + QMessageBox::critical(olive::MainWindow, + tr("Load Settings Failed"), + tr("Failed to open \"%1\" for reading.").arg(file), + QMessageBox::Ok); } } } @@ -537,23 +489,13 @@ void Effect::SetAlwaysUpdate(bool b) enable_always_update_ = b; } -int Effect::get_index_in_clip() { - if (parent_clip != nullptr) { - for (int i=0;ieffects.size();i++) { - if (parent_clip->effects.at(i).get() == this) { - return i; - } - } - } - return -1; +bool Effect::IsEnabled() { + return enabled_; } -bool Effect::is_enabled() { - return container->enabled_check->isChecked(); -} - -void Effect::set_enabled(bool b) { - container->enabled_check->setChecked(b); +void Effect::SetEnabled(bool b) { + enabled_ = b; + emit EnabledChanged(b); } void Effect::load(QXmlStreamReader& stream) { @@ -649,7 +591,7 @@ void Effect::custom_load(QXmlStreamReader &) {} void Effect::save(QXmlStreamWriter& stream) { stream.writeAttribute("name", meta->category + "/" + meta->name); - stream.writeAttribute("enabled", QString::number(is_enabled())); + stream.writeAttribute("enabled", QString::number(IsEnabled())); for (int i=0;iset_enabled(is_enabled()); + EffectPtr copy = Effect::Create(c, meta); + copy->SetEnabled(IsEnabled()); copy_field_keyframes(copy); return copy; } @@ -894,7 +836,7 @@ void Effect::process_shader(double timecode, GLTextureCoords&, int iteration) { GLfloat(color_field->GetColorAt(timecode).redF()), GLfloat(color_field->GetColorAt(timecode).greenF()), GLfloat(color_field->GetColorAt(timecode).blueF()) - ); + ); } break; case EffectField::EFFECT_FIELD_BOOL: @@ -904,7 +846,7 @@ void Effect::process_shader(double timecode, GLTextureCoords&, int iteration) { glslProgram->setUniformValue(field->id().toUtf8().constData(), field->GetValueAt(timecode).toInt()); break; - // can you even send a string to a uniform value? + // can you even send a string to a uniform value? case EffectField::EFFECT_FIELD_STRING: case EffectField::EFFECT_FIELD_FONT: case EffectField::EFFECT_FIELD_FILE: @@ -1105,7 +1047,7 @@ const EffectMeta* get_meta_from_name(const QString& input) { for (int j=0;j rows; QVector gizmos; - QGridLayout* ui_layout; - QWidget* ui; bool bound; int iterations; + bool enabled_; + int flags_; // enable effect to update constantly @@ -255,15 +255,7 @@ private: bool valueHasChanged(double timecode); QVector cachedValues; void delete_texture(); - int get_index_in_clip(); void validate_meta_path(); }; -class EffectInit : public QThread { -public: - EffectInit(); -protected: - void run(); -}; - #endif // EFFECT_H diff --git a/project/effectfields/doublefield.cpp b/project/effectfields/doublefield.cpp index 783f65ed0..35b42835f 100644 --- a/project/effectfields/doublefield.cpp +++ b/project/effectfields/doublefield.cpp @@ -54,6 +54,11 @@ QString DoubleField::ConvertValueToString(const QVariant &v) return QString::number(v.toDouble()); } +//QWidget *DoubleField::CreateWidget() +//{ + +//} + void DoubleField::ValueHasBeenSet() { value_set_ = true; diff --git a/project/effectfields/doublefield.h b/project/effectfields/doublefield.h index c5deb0c21..4ef8d6762 100644 --- a/project/effectfields/doublefield.h +++ b/project/effectfields/doublefield.h @@ -34,6 +34,8 @@ public: virtual QVariant ConvertStringToValue(const QString& s); virtual QString ConvertValueToString(const QVariant& v); + + //virtual QWidget* CreateWidget() override; private: double min_; double max_; diff --git a/project/effectfields/effectfield.cpp b/project/effectfields/effectfield.cpp index bb0536f20..094e86b74 100644 --- a/project/effectfields/effectfield.cpp +++ b/project/effectfields/effectfield.cpp @@ -151,6 +151,11 @@ QString EffectField::ConvertValueToString(const QVariant &v) return v.toString(); } +QWidget *EffectField::CreateWidget() +{ + return new QLabel(tr("(Invalid field)")); +} + QVariant EffectField::GetValueAt(double timecode) { Q_ASSERT(!keyframes.isEmpty()); diff --git a/project/effectfields/effectfield.h b/project/effectfields/effectfield.h index c413078a7..c640d2124 100644 --- a/project/effectfields/effectfield.h +++ b/project/effectfields/effectfield.h @@ -61,6 +61,8 @@ public: virtual QVariant ConvertStringToValue(const QString& s); virtual QString ConvertValueToString(const QVariant& v); + virtual QWidget* CreateWidget(); + double GetValidKeyframeHandlePosition(int key, bool post); bool IsEnabled(); diff --git a/project/effectgizmo.cpp b/project/effectgizmo.cpp index b506eaf61..f2c8eba08 100644 --- a/project/effectgizmo.cpp +++ b/project/effectgizmo.cpp @@ -22,8 +22,10 @@ #include "ui/labelslider.h" #include "effectfields/doublefield.h" +#include "project/effect.h" -EffectGizmo::EffectGizmo(int type) : +EffectGizmo::EffectGizmo(Effect *parent, int type) : + QObject(parent), x_field1(nullptr), x_field_multi1(1.0), y_field1(nullptr), diff --git a/project/effectgizmo.h b/project/effectgizmo.h index 98a50962f..4fa854107 100644 --- a/project/effectgizmo.h +++ b/project/effectgizmo.h @@ -30,6 +30,7 @@ enum GizmoType { #define GIZMO_DOT_SIZE 2.5 #define GIZMO_TARGET_SIZE 5.0 +#include #include #include #include @@ -37,11 +38,12 @@ enum GizmoType { #include class DoubleField; +class Effect; -class EffectGizmo -{ +class EffectGizmo : public QObject { + Q_OBJECT public: - EffectGizmo(int type); + EffectGizmo(Effect* parent, int type); QVector world_pos; QVector screen_pos; diff --git a/project/effectloaders.h b/project/effectloaders.h index 9a4c2a86e..a5370df41 100644 --- a/project/effectloaders.h +++ b/project/effectloaders.h @@ -22,7 +22,15 @@ #define EFFECTLOADERS_H #include +#include void init_effects(); +class EffectInit : public QThread { +public: + EffectInit(); +protected: + void run(); +}; + #endif // EFFECTLOADERS_H diff --git a/project/effectrow.cpp b/project/effectrow.cpp index 2558ee326..779f97051 100644 --- a/project/effectrow.cpp +++ b/project/effectrow.cpp @@ -44,6 +44,8 @@ EffectRow::EffectRow(Effect *parent, const QString &n, bool savable, bool keyfra savable_(savable) { Q_ASSERT(parent != nullptr); + + parent->AddRow(this); } void EffectRow::AddField(EffectField *field) diff --git a/project/marker.cpp b/project/marker.cpp index e3a4f9dda..ef2cb5014 100644 --- a/project/marker.cpp +++ b/project/marker.cpp @@ -32,96 +32,96 @@ #include void draw_marker(QPainter &p, int x, int y, int bottom, bool selected) { - const QPoint points[5] = { - QPoint(x, bottom), - QPoint(x + MARKER_SIZE, bottom - MARKER_SIZE), - QPoint(x + MARKER_SIZE, y), - QPoint(x - MARKER_SIZE, y), - QPoint(x - MARKER_SIZE, bottom - MARKER_SIZE) - }; - p.setPen(Qt::black); - if (selected) { - p.setBrush(QColor(208, 255, 208)); - } else { - p.setBrush(QColor(128, 224, 128)); - } - p.drawPolygon(points, 5); + const QPoint points[5] = { + QPoint(x, bottom), + QPoint(x + MARKER_SIZE, bottom - MARKER_SIZE), + QPoint(x + MARKER_SIZE, y), + QPoint(x - MARKER_SIZE, y), + QPoint(x - MARKER_SIZE, bottom - MARKER_SIZE) + }; + p.setPen(Qt::black); + if (selected) { + p.setBrush(QColor(208, 255, 208)); + } else { + p.setBrush(QColor(128, 224, 128)); + } + p.drawPolygon(points, 5); } -void set_marker_internal(SequencePtr seq, const QVector& clips) { - // if clips is empty, the marker is being added to the sequence +void set_marker_internal(Sequence* seq, const QVector& clips) { + // if clips is empty, the marker is being added to the sequence - // add_marker is used to determine whether we're adding a marker, depending on whether the user input a marker name - // however if (config.set_name_with_marker) is true, we don't need a marker name so we just add - bool add_marker = !olive::CurrentConfig.set_name_with_marker; + // add_marker is used to determine whether we're adding a marker, depending on whether the user input a marker name + // however if (config.set_name_with_marker) is true, we don't need a marker name so we just add + bool add_marker = !olive::CurrentConfig.set_name_with_marker; - QString marker_name; + QString marker_name; - // if (config.set_name_with_marker) is false (set above), ask for a marker name - if (!add_marker) { + // if (config.set_name_with_marker) is false (set above), ask for a marker name + if (!add_marker) { QInputDialog d(olive::MainWindow); - d.setWindowTitle(QCoreApplication::translate("Marker", "Set Marker")); - d.setLabelText(clips.size() > 0 - ? QCoreApplication::translate("Marker", "Set clip marker name:") - : QCoreApplication::translate("Marker", "Set sequence marker name:")); - d.setInputMode(QInputDialog::TextInput); - add_marker = (d.exec() == QDialog::Accepted); - marker_name = d.textValue(); - } + d.setWindowTitle(QCoreApplication::translate("Marker", "Set Marker")); + d.setLabelText(clips.size() > 0 + ? QCoreApplication::translate("Marker", "Set clip marker name:") + : QCoreApplication::translate("Marker", "Set sequence marker name:")); + d.setInputMode(QInputDialog::TextInput); + add_marker = (d.exec() == QDialog::Accepted); + marker_name = d.textValue(); + } - // if we've decided to add a marker - if (add_marker) { + // if we've decided to add a marker + if (add_marker) { - ComboAction* ca = new ComboAction(); + ComboAction* ca = new ComboAction(); - if (clips.size() > 0) { + if (clips.size() > 0) { - // add a marker action for each clip - foreach (int i, clips) { + // add a marker action for each clip + foreach (int i, clips) { ClipPtr c = seq->clips.at(i); - ca->append(new AddMarkerAction(&c->get_markers(), + ca->append(new AddMarkerAction(&c->get_markers(), seq->playhead - c->timeline_in() + c->clip_in(), - marker_name)); - } + marker_name)); + } - } else { + } else { - // if no clips are selected, we're adding a marker to the sequence + // if no clips are selected, we're adding a marker to the sequence - // kind of hacky, we get the correct marker structure from the viewer panel object that the sequence is attached to - if (seq == panel_footage_viewer->seq) { + // kind of hacky, we get the correct marker structure from the viewer panel object that the sequence is attached to + if (seq == panel_footage_viewer->seq.get()) { - // get correct marker reference from footage viewer - ca->append(new AddMarkerAction(panel_footage_viewer->marker_ref, seq->playhead, marker_name)); + // get correct marker reference from footage viewer + ca->append(new AddMarkerAction(panel_footage_viewer->marker_ref, seq->playhead, marker_name)); - } else if (seq == panel_sequence_viewer->seq) { + } else if (seq == panel_sequence_viewer->seq.get()) { - // get correct marker reference from sequence viewer - ca->append(new AddMarkerAction(panel_sequence_viewer->marker_ref, seq->playhead, marker_name)); + // get correct marker reference from sequence viewer + ca->append(new AddMarkerAction(panel_sequence_viewer->marker_ref, seq->playhead, marker_name)); - } else { + } else { - // fallback to using markers from sequence provided - ca->append(new AddMarkerAction(&seq->markers, seq->playhead, marker_name)); + // fallback to using markers from sequence provided + ca->append(new AddMarkerAction(&seq->markers, seq->playhead, marker_name)); - } + } - } + } - // push action + // push action olive::UndoStack.push(ca); - // redraw UI for new markers - update_ui(false); - panel_footage_viewer->update_viewer(); + // redraw UI for new markers + update_ui(false); + panel_footage_viewer->update_viewer(); - } + } } -void set_marker_internal(SequencePtr seq) { - // create empty clip array - QVector clips; +void set_marker_internal(Sequence *seq) { + // create empty clip array + QVector clips; - set_marker_internal(seq, clips); + set_marker_internal(seq, clips); } diff --git a/project/marker.h b/project/marker.h index c2f7fe727..285f56773 100644 --- a/project/marker.h +++ b/project/marker.h @@ -37,7 +37,7 @@ struct Marker { void draw_marker(QPainter& p, int x, int y, int bottom, bool selected); -void set_marker_internal(SequencePtr seq, const QVector& clips); -void set_marker_internal(SequencePtr seq); +void set_marker_internal(Sequence *seq, const QVector& clips); +void set_marker_internal(Sequence* seq); #endif // MARKER_H diff --git a/project/media.cpp b/project/media.cpp index 354c4a4e9..ba8c747b8 100644 --- a/project/media.cpp +++ b/project/media.cpp @@ -73,12 +73,12 @@ Media::~Media() { } } -FootagePtr Media::to_footage() { - return std::static_pointer_cast(object); +Footage* Media::to_footage() { + return static_cast(object.get()); } -SequencePtr Media::to_sequence() { - return std::static_pointer_cast(object); +Sequence* Media::to_sequence() { + return static_cast(object.get()); } void Media::set_footage(FootagePtr f) { @@ -90,7 +90,9 @@ void Media::set_sequence(SequencePtr s) { set_icon(olive::icon::MediaSequence); type = MEDIA_TYPE_SEQUENCE; object = VoidPtr(s); - if (s != nullptr) update_tooltip(); + if (s != nullptr) { + update_tooltip(); + } } void Media::set_folder() { @@ -119,7 +121,7 @@ void Media::update_tooltip(const QString& error) { switch (type) { case MEDIA_TYPE_FOOTAGE: { - FootagePtr f = to_footage(); + Footage* f = to_footage(); tooltip = QCoreApplication::translate("Media", "Name:") + " " + f->name + "\n" + QCoreApplication::translate("Media", "Filename:") + " " + f->url + "\n"; if (error.isEmpty()) { @@ -190,7 +192,7 @@ void Media::update_tooltip(const QString& error) { break; case MEDIA_TYPE_SEQUENCE: { - SequencePtr s = to_sequence(); + Sequence* s = to_sequence(); tooltip = QCoreApplication::translate("Media", "Name: %1" "\nVideo Dimensions: %2x%3" @@ -238,7 +240,7 @@ double Media::get_frame_rate(int stream) { switch (get_type()) { case MEDIA_TYPE_FOOTAGE: { - FootagePtr f = to_footage(); + Footage* f = to_footage(); if (stream < 0) return f->video_tracks.at(0).video_frame_rate * f->speed; return f->get_stream_from_file_index(true, stream)->video_frame_rate * f->speed; } @@ -251,7 +253,7 @@ int Media::get_sampling_rate(int stream) { switch (get_type()) { case MEDIA_TYPE_FOOTAGE: { - FootagePtr f = to_footage(); + Footage* f = to_footage(); if (stream < 0) return f->audio_tracks.at(0).audio_frequency * f->speed; return to_footage()->get_stream_from_file_index(false, stream)->audio_frequency * f->speed; } @@ -293,7 +295,7 @@ QVariant Media::data(int column, int role) { case Qt::DecorationRole: if (column == 0) { if (get_type() == MEDIA_TYPE_FOOTAGE) { - FootagePtr f = to_footage(); + Footage* f = to_footage(); if (f->video_tracks.size() > 0 && f->video_tracks.at(0).preview_done) { return f->video_tracks.at(0).video_preview_square; @@ -309,11 +311,11 @@ QVariant Media::data(int column, int role) { case 1: if (root) return QCoreApplication::translate("Media", "Duration"); if (get_type() == MEDIA_TYPE_SEQUENCE) { - SequencePtr s = to_sequence(); + Sequence* s = to_sequence(); return frame_to_timecode(s->getEndFrame(), olive::CurrentConfig.timecode_view, s->frame_rate); } if (get_type() == MEDIA_TYPE_FOOTAGE) { - FootagePtr f = to_footage(); + Footage* f = to_footage(); double r = 30; if (f->video_tracks.size() > 0 && !qIsNull(f->video_tracks.at(0).video_frame_rate)) @@ -327,7 +329,7 @@ QVariant Media::data(int column, int role) { if (root) return QCoreApplication::translate("Media", "Rate"); if (get_type() == MEDIA_TYPE_SEQUENCE) return QString::number(get_frame_rate()) + " FPS"; if (get_type() == MEDIA_TYPE_FOOTAGE) { - FootagePtr f = to_footage(); + Footage* f = to_footage(); double r; if (f->video_tracks.size() > 0 && !qIsNull(r = get_frame_rate())) { return QString::number(get_frame_rate()) + " FPS"; diff --git a/project/media.h b/project/media.h index 014aab03a..ba33a360d 100644 --- a/project/media.h +++ b/project/media.h @@ -44,8 +44,8 @@ class Media public: Media(Media* iparent); ~Media(); - FootagePtr to_footage(); - SequencePtr to_sequence(); + Footage *to_footage(); + Sequence *to_sequence(); void set_icon(const QString& str); void set_icon(const QIcon &ico); void set_footage(FootagePtr f); diff --git a/project/sequence.cpp b/project/sequence.cpp index dc3c8c83b..ddca16a04 100644 --- a/project/sequence.cpp +++ b/project/sequence.cpp @@ -22,6 +22,8 @@ #include +#include "panels/panels.h" + #include "debug.h" Sequence::Sequence() { @@ -35,7 +37,7 @@ Sequence::Sequence() { Sequence::~Sequence() {} SequencePtr Sequence::copy() { - SequencePtr s(new Sequence()); + SequencePtr s = std::make_shared(); s->name = QCoreApplication::translate("Sequence", "%1 (copy)").arg(name); s->width = width; s->height = height; @@ -50,7 +52,7 @@ SequencePtr Sequence::copy() { if (c == nullptr) { s->clips[i] = nullptr; } else { - ClipPtr copy = c->copy(s); + ClipPtr copy = c->copy(s.get()); copy->linked = c->linked; s->clips[i] = copy; } @@ -137,7 +139,7 @@ Effect *Sequence::GetSelectedGizmo() if (gizmo_ptr == nullptr) { gizmo_ptr = e; } - if (e->container->selected) { + if (panel_effect_controls->IsEffectSelected(e)) { gizmo_ptr = e; break; } @@ -190,4 +192,4 @@ void Sequence::getTrackLimits(int* video_tracks, int* audio_tracks) { } // static variable for the currently active sequence -SequencePtr olive::ActiveSequence = nullptr; +Sequence* olive::ActiveSequence = nullptr; diff --git a/project/sequence.h b/project/sequence.h index 1d8161061..385c92c42 100644 --- a/project/sequence.h +++ b/project/sequence.h @@ -71,7 +71,7 @@ using SequencePtr = std::shared_ptr; // static variable for the currently active sequence namespace olive { -extern SequencePtr ActiveSequence; + extern Sequence* ActiveSequence; } #endif // SEQUENCE_H diff --git a/project/sourcescommon.cpp b/project/sourcescommon.cpp index c2e12bf85..a48f80b88 100644 --- a/project/sourcescommon.cpp +++ b/project/sourcescommon.cpp @@ -65,8 +65,8 @@ void SourcesCommon::create_seq_from_selected() { SequencePtr s = create_sequence_from_media(media_list); // add clips to it - panel_timeline->create_ghosts_from_media(s, 0, media_list); - panel_timeline->add_clips_from_ghosts(ca, s); + panel_timeline->create_ghosts_from_media(s.get(), 0, media_list); + panel_timeline->add_clips_from_ghosts(ca, s.get()); project_parent->create_sequence_internal(ca, s, true, nullptr); olive::UndoStack.push(ca); @@ -342,7 +342,7 @@ void SourcesCommon::dropEvent(QWidget* parent, QDropEvent *event, const QModelIn void SourcesCommon::reveal_in_browser() { Media* media = project_parent->item_to_media(selected_items.at(0)); - FootagePtr m = media->to_footage(); + Footage* m = media->to_footage(); #if defined(Q_OS_WIN) QStringList args; @@ -405,7 +405,7 @@ void SourcesCommon::clear_proxies_from_selected() { QList delete_list; for (int i=0;ito_footage(); + Footage* f = cached_selected_footage.at(i)->to_footage(); if (f->proxy && !f->proxy_path.isEmpty()) { if (QFileInfo::exists(f->proxy_path)) { diff --git a/project/undo.cpp b/project/undo.cpp index e34eb697d..5863e111f 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -94,7 +94,7 @@ void MoveClipAction::doRedo() { } } -DeleteClipAction::DeleteClipAction(SequencePtr s, int clip) { +DeleteClipAction::DeleteClipAction(Sequence *s, int clip) { seq = s; index = clip; opening_transition = -1; @@ -140,7 +140,7 @@ void DeleteClipAction::doRedo() { } } -ChangeSequenceAction::ChangeSequenceAction(SequencePtr s) { +ChangeSequenceAction::ChangeSequenceAction(Sequence *s) { new_sequence = s; } @@ -153,7 +153,7 @@ void ChangeSequenceAction::doRedo() { olive::Global->set_sequence(new_sequence); } -SetTimelineInOutCommand::SetTimelineInOutCommand(SequencePtr s, bool enabled, long in, long out) { +SetTimelineInOutCommand::SetTimelineInOutCommand(Sequence* s, bool enabled, long in, long out) { seq = s; new_enabled = enabled; new_in = in; @@ -167,7 +167,7 @@ void SetTimelineInOutCommand::doUndo() { // footage viewer functions if (seq->wrapper_sequence) { - FootagePtr m = seq->clips.at(0)->media()->to_footage(); + Footage* m = seq->clips.at(0)->media()->to_footage(); m->using_inout = old_enabled; m->in = old_in; m->out = old_out; @@ -185,7 +185,7 @@ void SetTimelineInOutCommand::doRedo() { // footage viewer functions if (seq->wrapper_sequence) { - FootagePtr m = seq->clips.at(0)->media()->to_footage(); + Footage* m = seq->clips.at(0)->media()->to_footage(); m->using_inout = new_enabled; m->in = new_in; m->out = new_out; @@ -397,7 +397,7 @@ void DeleteMediaCommand::doRedo() { done = true; } -AddClipCommand::AddClipCommand(SequencePtr s, QVector& add) { +AddClipCommand::AddClipCommand(Sequence *s, QVector& add) { link_offset_ = 0; seq = s; clips = add; @@ -407,7 +407,7 @@ AddClipCommand::~AddClipCommand() {} void AddClipCommand::doUndo() { // clear effects panel - panel_effect_controls->clear_effects(true); + panel_effect_controls->Clear(true); for (int i=0;iclips.last(); @@ -514,7 +514,7 @@ void ReplaceMediaCommand::replace(QString& filename) { // close any clips currently using this media QVector all_sequences = panel_project->list_all_project_sequences(); for (int i=0;ito_sequence(); + Sequence* s = all_sequences.at(i)->to_sequence(); for (int j=0;jclips.size();j++) { ClipPtr c = s->clips.at(j); if (c != nullptr && c->media() == item && c->IsOpen()) { @@ -588,34 +588,28 @@ void ReplaceClipMediaCommand::doRedo() { update_ui(true); } -EffectDeleteCommand::EffectDeleteCommand() { - done = false; -} - -EffectDeleteCommand::~EffectDeleteCommand() {} +EffectDeleteCommand::EffectDeleteCommand(Effect *e) : + effect_(e) +{} void EffectDeleteCommand::doUndo() { - for (int i=0;ieffects.insert(fx.at(i), deleted_objects.at(i)); - } - panel_effect_controls->reload_clips(); - done = false; + parent_clip_->effects.insert(index_, deleted_obj_); + panel_effect_controls->Reload(); } void EffectDeleteCommand::doRedo() { - deleted_objects.clear(); - for (int i=0;ieffects.at(fx_id); - e->close(); - deleted_objects.append(e); - c->effects.removeAt(fx_id); - } - panel_effect_controls->reload_clips(); - done = true; + parent_clip_ = effect_->parent_clip; + + index_ = parent_clip_->IndexOfEffect(effect_); + + Q_ASSERT(index_ > -1); + + effect_->close(); + deleted_obj_ = parent_clip_->effects.at(index_); + parent_clip_->effects.removeAt(index_); + + panel_effect_controls->Reload(); } MediaMove::MediaMove() {} @@ -868,7 +862,7 @@ void SetBool::doRedo() { *boolean = new_setting; } -SetSelectionsCommand::SetSelectionsCommand(SequencePtr s) { +SetSelectionsCommand::SetSelectionsCommand(Sequence *s) { seq = s; done = true; } @@ -885,7 +879,7 @@ void SetSelectionsCommand::doRedo() { } } -EditSequenceCommand::EditSequenceCommand(Media* i, SequencePtr s) { +EditSequenceCommand::EditSequenceCommand(Media* i, Sequence *s) { item = i; seq = s; old_name = s->name; @@ -918,7 +912,8 @@ void EditSequenceCommand::doRedo() { void EditSequenceCommand::update() { // update tooltip - item->set_sequence(seq); + // TODO/FIXME: this is a lousy way to do this, Media should have a separate fuctionn for updating the tooltip + item->update_tooltip(); for (int i=0;iclips.size();i++) { if (seq->clips.at(i) != nullptr) seq->clips.at(i)->refresh(); @@ -1042,10 +1037,10 @@ void ReloadEffectsCommand::doUndo() { } void ReloadEffectsCommand::doRedo() { - panel_effect_controls->reload_clips(); + panel_effect_controls->Reload(); } -RippleAction::RippleAction(SequencePtr is, long ipoint, long ilength, const QVector &iignore) { +RippleAction::RippleAction(Sequence *is, long ipoint, long ilength, const QVector &iignore) { s = is; point = ipoint; length = ilength; @@ -1161,7 +1156,7 @@ void RefreshClips::doRedo() { // close any clips currently using this media QVector all_sequences = panel_project->list_all_project_sequences(); for (int i=0;ito_sequence(); + Sequence* s = all_sequences.at(i)->to_sequence(); for (int j=0;jclips.size();j++) { ClipPtr c = s->clips.at(j); if (c != nullptr && c->media() == media) { diff --git a/project/undo.h b/project/undo.h index efb9b9d4f..d2ba4d0dd 100644 --- a/project/undo.h +++ b/project/undo.h @@ -84,11 +84,11 @@ private: class RippleAction : public OliveAction { public: - RippleAction(SequencePtr is, long ipoint, long ilength, const QVector& iignore); + RippleAction(Sequence* is, long ipoint, long ilength, const QVector& iignore); virtual void doUndo() override; virtual void doRedo() override; private: - SequencePtr s; + Sequence* s; long point; long length; QVector ignore; @@ -97,12 +97,12 @@ private: class DeleteClipAction : public OliveAction { public: - DeleteClipAction(SequencePtr s, int clip); + DeleteClipAction(Sequence* s, int clip); virtual ~DeleteClipAction() override; virtual void doUndo() override; virtual void doRedo() override; private: - SequencePtr seq; + Sequence* seq; ClipPtr ref; int index; @@ -115,12 +115,12 @@ private: class ChangeSequenceAction : public OliveAction { public: - ChangeSequenceAction(SequencePtr s); + ChangeSequenceAction(Sequence* s); virtual void doUndo() override; virtual void doRedo() override; private: - SequencePtr old_sequence; - SequencePtr new_sequence; + Sequence* old_sequence; + Sequence* new_sequence; }; class AddEffectCommand : public OliveAction { @@ -176,11 +176,11 @@ private: class SetTimelineInOutCommand : public OliveAction { public: - SetTimelineInOutCommand(SequencePtr s, bool enabled, long in, long out); + SetTimelineInOutCommand(Sequence* s, bool enabled, long in, long out); virtual void doUndo() override; virtual void doRedo() override; private: - SequencePtr seq; + Sequence* seq; bool old_enabled; long old_in; @@ -229,12 +229,12 @@ private: class AddClipCommand : public OliveAction { public: - AddClipCommand(SequencePtr s, QVector& add); + AddClipCommand(Sequence* s, QVector& add); virtual ~AddClipCommand() override; virtual void doUndo() override; virtual void doRedo() override; private: - SequencePtr seq; + Sequence* seq; QVector clips; int link_offset_; }; @@ -244,7 +244,7 @@ public: LinkCommand(); virtual void doUndo() override; virtual void doRedo() override; - SequencePtr s; + Sequence* s; QVector clips; bool link; private: @@ -291,15 +291,14 @@ private: class EffectDeleteCommand : public OliveAction { public: - EffectDeleteCommand(); - virtual ~EffectDeleteCommand() override; + EffectDeleteCommand(Effect* e); virtual void doUndo() override; virtual void doRedo() override; - QVector clips; - QVector fx; private: - bool done; - QVector deleted_objects; + Effect* effect_; + EffectPtr deleted_obj_; + Clip* parent_clip_; + int index_; }; class MediaMove : public OliveAction { @@ -444,19 +443,19 @@ private: class SetSelectionsCommand : public OliveAction { public: - SetSelectionsCommand(SequencePtr s); + SetSelectionsCommand(Sequence* s); virtual void doUndo() override; virtual void doRedo() override; QVector old_data; QVector new_data; private: - SequencePtr seq; + Sequence* seq; bool done; }; class EditSequenceCommand : public OliveAction { public: - EditSequenceCommand(Media *i, SequencePtr s); + EditSequenceCommand(Media *i, Sequence* s); virtual void doUndo() override; virtual void doRedo() override; void update(); @@ -469,7 +468,7 @@ public: int audio_layout; private: Media* item; - SequencePtr seq; + Sequence* seq; QString old_name; int old_width; diff --git a/rendering/cacher.cpp b/rendering/cacher.cpp index 380b1c996..7c2460eed 100644 --- a/rendering/cacher.cpp +++ b/rendering/cacher.cpp @@ -56,8 +56,10 @@ void apply_audio_effects(Clip* clip, double timecode_start, AVFrame* frame, int timecode_end = timecode_start + bytes_to_seconds(nb_bytes, frame->channels, frame->sample_rate); for (int j=0;jeffects.size();j++) { - EffectPtr e = clip->effects.at(j); - if (e->is_enabled()) e->process_audio(timecode_start, timecode_end, frame->data[0], nb_bytes, 2); + Effect* e = clip->effects.at(j).get(); + if (e->IsEnabled()) { + e->process_audio(timecode_start, timecode_end, frame->data[0], nb_bytes, 2); + } } if (clip->opening_transition != nullptr) { if (clip->media() != nullptr && clip->media()->get_type() == MEDIA_TYPE_FOOTAGE) { @@ -839,7 +841,7 @@ void Cacher::OpenWorker() { } } else if (clip->media()->get_type() == MEDIA_TYPE_FOOTAGE) { // opens file resource for FFmpeg and prepares Clip struct for playback - FootagePtr m = clip->media()->to_footage(); + Footage* m = clip->media()->to_footage(); // byte array for retriving raw bytes from QString URL QByteArray ba; diff --git a/rendering/renderfunctions.cpp b/rendering/renderfunctions.cpp index 68d91073c..deb51acf5 100644 --- a/rendering/renderfunctions.cpp +++ b/rendering/renderfunctions.cpp @@ -114,7 +114,7 @@ void process_effect(Clip* c, bool& fbo_switcher, bool& texture_failed, int data) { - if (e->is_enabled()) { + if (e->IsEnabled()) { if (e->Flags() & Effect::CoordsFlag) { e->process_coords(timecode, coords, data); } @@ -159,7 +159,7 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { GLuint final_fbo = params.main_buffer; - SequencePtr s = params.seq; + Sequence* s = params.seq; long playhead = s->playhead; if (!params.nests.isEmpty()) { @@ -194,7 +194,7 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { // is the clip a "footage" clip? if (c->media() != nullptr && c->media()->get_type() == MEDIA_TYPE_FOOTAGE) { - FootagePtr m = c->media()->to_footage(); + Footage* m = c->media()->to_footage(); // does the clip have a valid media source? if (!m->invalid && !(c->track() >= 0 && !is_audio_device_set())) { @@ -658,7 +658,7 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { return 0; } -void compose_audio(Viewer* viewer, SequencePtr seq, int playback_speed, bool wait_for_mutexes) { +void compose_audio(Viewer* viewer, Sequence* seq, int playback_speed, bool wait_for_mutexes) { ComposeSequenceParams params; params.viewer = viewer; params.ctx = nullptr; @@ -707,7 +707,7 @@ int64_t playhead_to_timestamp(Clip* c, long playhead) { return seconds_to_timestamp(c, playhead_to_clip_seconds(c, playhead)); } -void close_active_clips(SequencePtr s) { +void close_active_clips(Sequence* s) { if (s != nullptr) { for (int i=0;iclips.size();i++) { Clip* c = s->clips.at(i).get(); diff --git a/rendering/renderfunctions.h b/rendering/renderfunctions.h index 3c1f49734..21507c990 100644 --- a/rendering/renderfunctions.h +++ b/rendering/renderfunctions.h @@ -59,7 +59,7 @@ struct ComposeSequenceParams { * In addition to clips, sequences also contain the playhead position so compose_sequence() knows which frame * to render. */ - SequencePtr seq; + Sequence* seq; /** * @brief Array to store the nested sequence hierarchy @@ -263,7 +263,7 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms); * * Whether to wait for media to open or simply fail if the media is not yet open. This should usually be **FALSE**. */ -void compose_audio(Viewer* viewer, SequencePtr seq, int playback_speed, bool wait_for_mutexes); +void compose_audio(Viewer* viewer, Sequence *seq, int playback_speed, bool wait_for_mutexes); /** * @brief Rescale a frame number between two frame rates @@ -400,6 +400,6 @@ int64_t playhead_to_timestamp(Clip *c, long playhead); * * The Sequence to close all clips on. */ -void close_active_clips(SequencePtr s); +void close_active_clips(Sequence* s); #endif // RENDERFUNCTIONS_H diff --git a/rendering/renderthread.cpp b/rendering/renderthread.cpp index 0c3ff96f3..7dc2f0715 100644 --- a/rendering/renderthread.cpp +++ b/rendering/renderthread.cpp @@ -230,7 +230,12 @@ void RenderThread::paint() { ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } -void RenderThread::start_render(QOpenGLContext *share, SequencePtr s, const QString& save, GLvoid* pixels, int pixel_linesize, int idivider) { +void RenderThread::start_render(QOpenGLContext *share, + Sequence* s, + const QString& save, + GLvoid* pixels, + int pixel_linesize, + int idivider) { Q_UNUSED(idivider); seq = s; diff --git a/rendering/renderthread.h b/rendering/renderthread.h index e18be91d3..8f0d9c3a4 100644 --- a/rendering/renderthread.h +++ b/rendering/renderthread.h @@ -52,7 +52,7 @@ public: Effect* gizmos; void paint(); void start_render(QOpenGLContext* share, - SequencePtr s, + Sequence *s, const QString &save = nullptr, GLvoid *pixels = nullptr, int pixel_linesize = 0, @@ -101,7 +101,7 @@ private: GLuint ocio_lut_texture; QOpenGLShaderProgram* ocio_shader; - SequencePtr seq; + Sequence* seq; int divider; int tex_width; int tex_height; diff --git a/ui/collapsiblewidget.cpp b/ui/collapsiblewidget.cpp index 07292287d..dd0e9ced9 100644 --- a/ui/collapsiblewidget.cpp +++ b/ui/collapsiblewidget.cpp @@ -53,7 +53,7 @@ CollapsibleWidget::CollapsibleWidget(QWidget* parent) : QWidget(parent) { collapse_button = new QPushButton(title_bar); collapse_button->setIconSize(collapse_button->iconSize()*0.5); collapse_button->setStyleSheet("QPushButton { border: none; }"); - setText(tr("")); + SetText(tr("")); title_bar_layout->addWidget(collapse_button); title_bar_layout->addWidget(enabled_check); title_bar_layout->addWidget(header); @@ -80,20 +80,25 @@ void CollapsibleWidget::header_click(bool s, bool deselect) { if (deselect) emit deselect_others(this); } -bool CollapsibleWidget::is_focused() { +bool CollapsibleWidget::IsFocused() { if (hasFocus()) return true; return title_bar->hasFocus(); } -bool CollapsibleWidget::is_expanded() { +bool CollapsibleWidget::IsExpanded() { return contents->isVisible(); } +bool CollapsibleWidget::IsSelected() +{ + return selected; +} + void CollapsibleWidget::set_button_icon(bool open) { collapse_button->setIcon(open ? olive::icon::DownArrow : olive::icon::RightArrow); } -void CollapsibleWidget::setContents(QWidget* c) { +void CollapsibleWidget::SetContents(QWidget* c) { bool existing = (contents != nullptr); contents = c; if (!existing) { @@ -103,7 +108,7 @@ void CollapsibleWidget::setContents(QWidget* c) { } } -void CollapsibleWidget::setText(const QString &s) { +void CollapsibleWidget::SetText(const QString &s) { header->setText(s); } diff --git a/ui/collapsiblewidget.h b/ui/collapsiblewidget.h index c506ce153..74b5d3502 100644 --- a/ui/collapsiblewidget.h +++ b/ui/collapsiblewidget.h @@ -35,7 +35,7 @@ class CollapsibleWidgetHeader : public QWidget { Q_OBJECT public: - CollapsibleWidgetHeader(QWidget* parent = 0); + CollapsibleWidgetHeader(QWidget* parent = nullptr); bool selected; protected: void mousePressEvent(QMouseEvent* event); @@ -48,17 +48,18 @@ class CollapsibleWidget : public QWidget { Q_OBJECT public: - CollapsibleWidget(QWidget* parent = 0); - void setContents(QWidget* c); - void setText(const QString &); - bool is_focused(); - bool is_expanded(); - + CollapsibleWidget(QWidget* parent = nullptr); + void SetContents(QWidget* c); + void SetText(const QString &); + bool IsFocused(); + bool IsExpanded(); + bool IsSelected(); +protected: CheckboxEx* enabled_check; - bool selected; - QWidget* contents; CollapsibleWidgetHeader* title_bar; private: + bool selected; + QWidget* contents; QLabel* header; QVBoxLayout* layout; QPushButton* collapse_button; diff --git a/ui/effectui.cpp b/ui/effectui.cpp new file mode 100644 index 000000000..c8dcdc9d8 --- /dev/null +++ b/ui/effectui.cpp @@ -0,0 +1,94 @@ +#include "effectui.h" + +#include +#include + +#include "project/clip.h" +#include "ui/menuhelper.h" + +EffectUI::EffectUI(Effect* e) : + effect_(e) +{ + Q_ASSERT(e != nullptr); + + SetText(e->name); + + QWidget* ui = new QWidget(this); + SetContents(ui); + + layout_ = new QGridLayout(ui); + layout_->setSpacing(4); + + connect(title_bar, + SIGNAL(customContextMenuRequested(const QPoint&)), + this, + SIGNAL(TitleBarContextMenuRequested(const QPoint&))); + + for (int i=0;irow_count();i++) { + EffectRow* row = e->row(i); + + QLabel* row_label = new QLabel(row->name()); + + labels_.append(row_label); + + layout_->addWidget(row_label, i, 0); + + for (int j=0;jFieldCount();j++) { + EffectField* field = row->Field(j); + + QWidget* widget = field->CreateWidget(); + + layout_->addWidget(widget, i, j + 1); + } + } + + connect(enabled_check, SIGNAL(clicked(bool)), this, SLOT(field_changed())); +} + +Effect *EffectUI::GetEffect() +{ + return effect_; +} + +int EffectUI::GetRowPos(int row) +{ + QLabel* row_label = labels_.at(row); + return mapToGlobal(row_label->rect().center()).y(); +} + +void EffectUI::show_context_menu(const QPoint& pos) { + if (effect_->meta->type == EFFECT_TYPE_EFFECT) { + QMenu menu; + + Clip* c = effect_->parent_clip; + + int index = c->IndexOfEffect(effect_); + + menu.addAction(tr("Cu&t"), this, SIGNAL(CutRequested())); + menu.addAction(tr("&Copy"), this, SIGNAL(CopyRequested())); + + olive::MenuHelper.create_effect_paste_action(&menu); + + menu.addSeparator(); + + if (index > 0) { + menu.addAction(tr("Move &Up"), this, SLOT(move_up())); + } + + if (index < c->effects.size() - 1) { + menu.addAction(tr("Move &Down"), this, SLOT(move_down())); + } + + menu.addSeparator(); + + menu.addAction(tr("D&elete"), this, SLOT(delete_self())); + + menu.addSeparator(); + + menu.addAction(tr("Load Settings From File"), this, SLOT(load_from_file())); + + menu.addAction(tr("Save Settings to File"), this, SLOT(save_to_file())); + + menu.exec(title_bar->mapToGlobal(pos)); + } +} diff --git a/ui/effectui.h b/ui/effectui.h new file mode 100644 index 000000000..3191fc90c --- /dev/null +++ b/ui/effectui.h @@ -0,0 +1,27 @@ +#ifndef EFFECTUI_H +#define EFFECTUI_H + +#include "collapsiblewidget.h" +#include "project/effect.h" + +class EffectUI : public CollapsibleWidget { + Q_OBJECT +public: + EffectUI(Effect* e); + + Effect* GetEffect(); + + int GetRowPos(int row); +signals: + void CutRequested(); + void CopyRequested(); + void TitleBarContextMenuRequested(const QPoint&); +private: + Effect* effect_; + QGridLayout* layout_; + QVector labels_; +private slots: + void show_context_menu(const QPoint&); +}; + +#endif // EFFECTUI_H diff --git a/ui/keyframeview.cpp b/ui/keyframeview.cpp index dd36d8343..b0a0beb46 100644 --- a/ui/keyframeview.cpp +++ b/ui/keyframeview.cpp @@ -23,7 +23,6 @@ #include "project/effect.h" #include "ui/collapsiblewidget.h" #include "panels/panels.h" -#include "panels/effectcontrols.h" #include "project/clip.h" #include "panels/timeline.h" #include "ui/timelineheader.h" @@ -62,6 +61,11 @@ KeyframeView::KeyframeView(QWidget *parent) : connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu(const QPoint&))); } +void KeyframeView::SetEffects(const QVector &open_effects) +{ + open_effects_ = open_effects; +} + void KeyframeView::show_context_menu(const QPoint& pos) { if (selected_fields.size() > 0) { QMenu menu(this); @@ -101,73 +105,61 @@ void KeyframeView::paintEvent(QPaintEvent*) { rowY.clear(); rows.clear(); - if (panel_effect_controls->selected_clips.size() > 0) { + if (!open_effects_.isEmpty()) { visible_in = LONG_MAX; visible_out = 0; - for (int j=0;jselected_clips.size();j++) { - ClipPtr c = olive::ActiveSequence->clips.at(panel_effect_controls->selected_clips.at(j)); + for (int i=0;iGetEffect()->parent_clip; visible_in = qMin(visible_in, c->timeline_in()); visible_out = qMax(visible_out, c->timeline_out()); } - for (int j=0;jselected_clips.size();j++) { - ClipPtr c = olive::ActiveSequence->clips.at(panel_effect_controls->selected_clips.at(j)); - for (int i=0;ieffects.size();i++) { - EffectPtr e = c->effects.at(i); - if (e->container->is_expanded()) { - for (int j=0;jrow_count();j++) { - EffectRow* row = e->row(j); + for (int j=0;jGetEffect(); - /* + if (container->IsExpanded()) { + for (int j=0;jrow_count();j++) { + EffectRow* row = e->row(j); - ClickableLabel* label = row->label; - QWidget* contents = e->container->contents; + int keyframe_y = container->GetRowPos(j); - QVector key_times; + QVector key_times; - int keyframe_y = label->y() - + (label->height()>>1) - + mapFrom(panel_effect_controls, contents->mapTo(panel_effect_controls, contents->pos())).y() - - e->container->title_bar->height(); + for (int l=0;lFieldCount();l++) { + EffectField* f = row->Field(l); + for (int k=0;kkeyframes.size();k++) { + if (!key_times.contains(f->keyframes.at(k).time)) { + bool keyframe_selected = keyframeIsSelected(f, k); + long keyframe_frame = adjust_row_keyframe(row, f->keyframes.at(k).time, visible_in); - for (int l=0;lFieldCount();l++) { - EffectField* f = row->Field(l); - for (int k=0;kkeyframes.size();k++) { - if (!key_times.contains(f->keyframes.at(k).time)) { - bool keyframe_selected = keyframeIsSelected(f, k); - long keyframe_frame = adjust_row_keyframe(row, f->keyframes.at(k).time, visible_in); - - // see if any other keyframes have this time - int appearances = 0; - for (int m=0;mFieldCount();m++) { - EffectField* compf = row->Field(m); - for (int n=0;nkeyframes.size();n++) { - if (f->keyframes.at(k).time == compf->keyframes.at(n).time) { - appearances++; - } + // see if any other keyframes have this time + int appearances = 0; + for (int m=0;mFieldCount();m++) { + EffectField* compf = row->Field(m); + for (int n=0;nkeyframes.size();n++) { + if (f->keyframes.at(k).time == compf->keyframes.at(n).time) { + appearances++; } } - - if (appearances != row->FieldCount()) { - QColor cc = get_curve_color(l, row->FieldCount()); - draw_keyframe(p, f->keyframes.at(k).type, getScreenPointFromFrame(panel_effect_controls->zoom, keyframe_frame) - x_scroll, keyframe_y, keyframe_selected, cc.red(), cc.green(), cc.blue()); - } else { - draw_keyframe(p, f->keyframes.at(k).type, getScreenPointFromFrame(panel_effect_controls->zoom, keyframe_frame) - x_scroll, keyframe_y, keyframe_selected); - } - - key_times.append(f->keyframes.at(k).time); } + + if (appearances != row->FieldCount()) { + QColor cc = get_curve_color(l, row->FieldCount()); + draw_keyframe(p, f->keyframes.at(k).type, getScreenPointFromFrame(panel_effect_controls->zoom, keyframe_frame) - x_scroll, keyframe_y, keyframe_selected, cc.red(), cc.green(), cc.blue()); + } else { + draw_keyframe(p, f->keyframes.at(k).type, getScreenPointFromFrame(panel_effect_controls->zoom, keyframe_frame) - x_scroll, keyframe_y, keyframe_selected); + } + + key_times.append(f->keyframes.at(k).time); } } - - rows.append(row); - rowY.append(keyframe_y); - - */ } + + rows.append(row); + rowY.append(keyframe_y); } } } diff --git a/ui/keyframeview.h b/ui/keyframeview.h index b704aa1d1..645861ec8 100644 --- a/ui/keyframeview.h +++ b/ui/keyframeview.h @@ -24,6 +24,8 @@ #include #include +#include "ui/effectui.h" + class Clip; class Effect; class EffectRow; @@ -31,56 +33,60 @@ class EffectField; class TimelineHeader; class KeyframeView : public QWidget { - Q_OBJECT + Q_OBJECT public: - KeyframeView(QWidget* parent = 0); + KeyframeView(QWidget* parent = nullptr); - void delete_selected_keyframes(); + void SetEffects(const QVector& open_effects); - TimelineHeader* header; + void delete_selected_keyframes(); - long visible_in; - long visible_out; + TimelineHeader* header; + + long visible_in; + long visible_out; signals: - void wheel_event_signal(QWheelEvent*); + void wheel_event_signal(QWheelEvent*); public slots: - void set_x_scroll(int); - void set_y_scroll(int); - void resize_move(double d); + void set_x_scroll(int); + void set_y_scroll(int); + void resize_move(double d); private: - QVector selected_fields; - QVector selected_keyframes; - QVector rowY; - QVector rows; - QVector old_key_vals; - void mousePressEvent(QMouseEvent* event); - void mouseMoveEvent(QMouseEvent* event); - void mouseReleaseEvent(QMouseEvent *event); - void paintEvent(QPaintEvent *event); - void wheelEvent(QWheelEvent* e); - bool mousedown; - bool dragging; - bool keys_selected; - bool select_rect; - bool scroll_drag; + QVector open_effects_; - bool keyframeIsSelected(EffectField *field, int keyframe); + QVector selected_fields; + QVector selected_keyframes; + QVector rowY; + QVector rows; + QVector old_key_vals; + void mousePressEvent(QMouseEvent* event); + void mouseMoveEvent(QMouseEvent* event); + void mouseReleaseEvent(QMouseEvent *event); + void paintEvent(QPaintEvent *event); + void wheelEvent(QWheelEvent* e); + bool mousedown; + bool dragging; + bool keys_selected; + bool select_rect; + bool scroll_drag; - long drag_frame_start; - long last_frame_diff; - int rect_select_x; - int rect_select_y; - int rect_select_w; - int rect_select_h; - int rect_select_offset; + bool keyframeIsSelected(EffectField *field, int keyframe); - int x_scroll; - int y_scroll; + long drag_frame_start; + long last_frame_diff; + int rect_select_x; + int rect_select_y; + int rect_select_w; + int rect_select_h; + int rect_select_offset; - void update_keys(); + int x_scroll; + int y_scroll; + + void update_keys(); private slots: - void show_context_menu(const QPoint& pos); - void menu_set_key_type(QAction*); + void show_context_menu(const QPoint& pos); + void menu_set_key_type(QAction*); }; #endif // KEYFRAMEVIEW_H diff --git a/ui/menuhelper.cpp b/ui/menuhelper.cpp index 6cb2ed788..aad6a8fac 100644 --- a/ui/menuhelper.cpp +++ b/ui/menuhelper.cpp @@ -20,21 +20,18 @@ #include "menuhelper.h" -#include "oliveglobal.h" - -#include "ui/focusfilter.h" - -#include "io/config.h" - -#include "panels/panels.h" - -#include "mainwindow.h" - #include #include #include #include +#include "io/config.h" +#include "io/clipboard.h" +#include "mainwindow.h" +#include "oliveglobal.h" +#include "panels/panels.h" +#include "ui/focusfilter.h" + MenuHelper olive::MenuHelper; void MenuHelper::InitializeSharedMenus() @@ -262,6 +259,12 @@ void MenuHelper::open_recent_from_menu() { olive::Global.get()->open_recent(index); } +void MenuHelper::create_effect_paste_action(QMenu *menu) +{ + QAction* paste_action = menu->addAction(tr("&Paste"), panel_timeline, SLOT(paste(bool))); + paste_action->setEnabled(clipboard.size() > 0 && clipboard_type == CLIPBOARD_TYPE_EFFECT); +} + QMenu* MenuHelper::create_submenu(QMenuBar* parent, const QObject *receiver, const char *member) { diff --git a/ui/menuhelper.h b/ui/menuhelper.h index 9fdf42aa8..e1a14d0d9 100644 --- a/ui/menuhelper.h +++ b/ui/menuhelper.h @@ -186,6 +186,15 @@ public slots: */ void open_recent_from_menu(); + /** + * @brief Create a "Paste" action on the specified menu that's enabled only if the clipboard contains effects + * + * @param menu + * + * Menu to add action to + */ + void create_effect_paste_action(QMenu *menu); + private: QAction* new_project_; QAction* new_sequence_; diff --git a/ui/timelineheader.cpp b/ui/timelineheader.cpp index b3e3711c2..f32621ea7 100644 --- a/ui/timelineheader.cpp +++ b/ui/timelineheader.cpp @@ -115,7 +115,7 @@ void TimelineHeader::set_in_point(long new_in) { new_out = viewer->seq->getEndFrame(); } - olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq, true, new_in, new_out)); + olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq.get(), true, new_in, new_out)); update_parents(); } @@ -127,7 +127,7 @@ void TimelineHeader::set_out_point(long new_out) { new_in = 0; } - olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq, true, new_in, new_out)); + olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq.get(), true, new_in, new_out)); update_parents(); } @@ -280,7 +280,7 @@ void TimelineHeader::mouseReleaseEvent(QMouseEvent*) { if (viewer->seq != nullptr) { dragging = false; if (resizing_workarea) { - olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq, true, temp_workarea_in, temp_workarea_out)); + olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq.get(), true, temp_workarea_in, temp_workarea_out)); } else if (dragging_markers && selected_markers.size() > 0) { bool moved = false; ComboAction* ca = new ComboAction(); diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index 828f2d5e1..fbb2d3100 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -259,7 +259,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { } if (event->source() == panel_footage_viewer->viewer_widget) { - SequencePtr proposed_seq = panel_footage_viewer->seq; + Sequence* proposed_seq = panel_footage_viewer->seq.get(); if (proposed_seq != olive::ActiveSequence) { // don't allow nesting the same sequence media_list.append(panel_footage_viewer->media); import_init = true; @@ -280,7 +280,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { for (int i=0;ilast_imported_media.size();i++) { // waits for media to have a duration // TODO would be much nicer if this was multithreaded - FootagePtr f = panel_project->last_imported_media.at(i)->to_footage(); + Footage* f = panel_project->last_imported_media.at(i)->to_footage(); f->ready_lock.lock(); f->ready_lock.unlock(); @@ -302,14 +302,14 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { event->acceptProposedAction(); long entry_point; - SequencePtr seq = olive::ActiveSequence; + Sequence* seq = olive::ActiveSequence; if (seq == nullptr) { // if no sequence, we're going to create a new one using the clips as a reference entry_point = 0; self_created_sequence = create_sequence_from_media(media_list); - seq = self_created_sequence; + seq = self_created_sequence.get(); } else { entry_point = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x()); panel_timeline->drag_frame_start = entry_point + getFrameFromScreenPoint(panel_timeline->zoom, 50); @@ -515,11 +515,11 @@ void TimelineWidget::dropEvent(QDropEvent* event) { ComboAction* ca = new ComboAction(); - SequencePtr s = olive::ActiveSequence; + Sequence* s = olive::ActiveSequence; // if we're dropping into nothing, create a new sequences based on the clip being dragged if (s == nullptr) { - s = self_created_sequence; + s = self_created_sequence.get(); panel_project->create_sequence_internal(ca, self_created_sequence, true, nullptr); self_created_sequence = nullptr; } else if (event->keyboardModifiers() & Qt::ControlModifier) { @@ -2953,7 +2953,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { if (clip->media() != nullptr && clip->media()->get_type() == MEDIA_TYPE_FOOTAGE) { bool draw_checkerboard = false; QRect checkerboard_rect(clip_rect); - FootagePtr m = clip->media()->to_footage(); + Footage* m = clip->media()->to_footage(); FootageStream* ms = clip->media_stream(); if (ms == nullptr) { draw_checkerboard = true; diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index eb3f139c7..0ac1d6dfa 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -91,7 +91,7 @@ ViewerWidget::~ViewerWidget() { } void ViewerWidget::delete_function() { - close_active_clips(viewer->seq); + close_active_clips(viewer->seq.get()); } void ViewerWidget::set_waveform_scroll(int s) { @@ -168,7 +168,7 @@ void ViewerWidget::save_frame() { fn += selected_ext; } - renderer->start_render(context(), viewer->seq, fn); + renderer->start_render(context(), viewer->seq.get(), fn); } } @@ -228,11 +228,11 @@ void ViewerWidget::frame_update() { update(); } else { doneCurrent(); - renderer->start_render(context(), viewer->seq); + renderer->start_render(context(), viewer->seq.get()); } // render the audio - compose_audio(viewer, viewer->seq, viewer->get_playback_speed(), viewer->WaitingForPlayWake()); + compose_audio(viewer, viewer->seq.get(), viewer->get_playback_speed(), viewer->WaitingForPlayWake()); } } @@ -253,7 +253,7 @@ void ViewerWidget::seek_from_click(int x) { void ViewerWidget::context_destroy() { makeCurrent(); if (viewer->seq != nullptr) { - close_active_clips(viewer->seq); + close_active_clips(viewer->seq.get()); } renderer->delete_ctx(); doneCurrent(); @@ -619,7 +619,7 @@ void ViewerWidget::paintGL() { if (renderer->did_texture_fail() && !viewer->playing) { doneCurrent(); - renderer->start_render(context(), viewer->seq); + renderer->start_render(context(), viewer->seq.get()); } } }