diff --git a/dialogs/aboutdialog.cpp b/dialogs/aboutdialog.cpp index 40a2096c6..7d1bdb7e9 100644 --- a/dialogs/aboutdialog.cpp +++ b/dialogs/aboutdialog.cpp @@ -1,14 +1,27 @@ #include "aboutdialog.h" -#include "ui_aboutdialog.h" + +#include +#include +#include AboutDialog::AboutDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::AboutDialog) + QDialog(parent) { - ui->setupUi(this); -} + setWindowTitle("About Olive"); + setMaximumWidth(360); -AboutDialog::~AboutDialog() -{ - delete ui; + QVBoxLayout* layout = new QVBoxLayout(); + layout->setSpacing(20); + setLayout(layout); + + QLabel* label = new QLabel("

https://www.olivevideoeditor.org/

Olive is a non-linear video editor. This software is free and protected by the GNU GPL.

Olive Team is obliged to inform users that Olive source code is available for download from its website.

Olive uses (at least) the following libraries in accordance with the GNU GPL/LGPL:

Qt, FFmpeg, libass, libfreetype, libmp3lame, libopenjpeg, libopus, libtheora, libtwolame, libvpx, libwavpack, libwebp, libx264, libx265, lzma, bzlib, zlib, libvidstab, libvorbis.

"); + label->setAlignment(Qt::AlignCenter); + label->setWordWrap(true); + layout->addWidget(label); + + QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok, this); + buttons->setCenterButtons(true); + layout->addWidget(buttons); + + connect(buttons, SIGNAL(accepted()), this, SLOT(accept())); } diff --git a/dialogs/aboutdialog.h b/dialogs/aboutdialog.h index 18a87e537..5ecf637a9 100644 --- a/dialogs/aboutdialog.h +++ b/dialogs/aboutdialog.h @@ -3,20 +3,12 @@ #include -namespace Ui { -class AboutDialog; -} - class AboutDialog : public QDialog { Q_OBJECT public: explicit AboutDialog(QWidget *parent = 0); - ~AboutDialog(); - -private: - Ui::AboutDialog *ui; }; #endif // ABOUTDIALOG_H diff --git a/dialogs/aboutdialog.ui b/dialogs/aboutdialog.ui deleted file mode 100644 index e56d0baa1..000000000 --- a/dialogs/aboutdialog.ui +++ /dev/null @@ -1,80 +0,0 @@ - - - AboutDialog - - - - 0 - 0 - 358 - 422 - - - - About Olive - - - - - - <html><head/><body><p><img src=":/icons/olive-splash.png"/></p><p><a href="https://www.olivevideoeditor.org/"><span style=" text-decoration: underline; color:#007af4;">https://www.olivevideoeditor.org/</span></a></p><p>Olive is a non-linear video editor. This software is free and protected by the GNU GPL.</p><p>Olive Team is obliged to inform users that Olive source code is available for download from its website.</p><p>Olive uses (at least) the following libraries in accordance with the GNU GPL/LGPL:</p><p>Qt, FFmpeg, libass, libfreetype, libmp3lame, libopenjpeg, libopus, libtheora, libtwolame, libvpx, libwavpack, libwebp, libx264, libx265, lzma, bzlib, zlib, libvidstab, libvorbis.</p></body></html> - - - Qt::AlignCenter - - - true - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Ok - - - true - - - - - - - - - buttonBox - accepted() - AboutDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - AboutDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/dialogs/demonotice.cpp b/dialogs/demonotice.cpp index 95826803a..d16f9bd47 100644 --- a/dialogs/demonotice.cpp +++ b/dialogs/demonotice.cpp @@ -1,14 +1,33 @@ #include "demonotice.h" -#include "ui_demonotice.h" + +#include +#include +#include DemoNotice::DemoNotice(QWidget *parent) : - QDialog(parent), - ui(new Ui::DemoNotice) + QDialog(parent) { - ui->setupUi(this); -} + setWindowTitle("Welcome to Olive!"); + setMaximumWidth(600); -DemoNotice::~DemoNotice() -{ - delete ui; + QVBoxLayout* vlayout = new QVBoxLayout(); + setLayout(vlayout); + + QHBoxLayout* layout = new QHBoxLayout(); + layout->setMargin(10); + layout->setSpacing(20); + + QLabel* icon = new QLabel("

"); + layout->addWidget(icon); + + QLabel* text = new QLabel("

Welcome to Olive!

Olive is a free open-source video editor released under the GNU GPL. If you have paid for this software, you have been scammed.

This software is currently in ALPHA which means it is unstable and very likely to crash, have bugs, and have missing features. We offer no warranty so use at your own risk. Please report any bugs or feature requests at www.olivevideoeditor.org

Thank you for trying Olive and we hope you enjoy it!

"); + text->setWordWrap(true); + layout->addWidget(text); + + vlayout->addLayout(layout); + + QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok, this); + buttons->setCenterButtons(true); + connect(buttons, SIGNAL(accepted()), this, SLOT(accept())); + vlayout->addWidget(buttons); } diff --git a/dialogs/demonotice.h b/dialogs/demonotice.h index 34cf6fcb2..ec57e13e5 100644 --- a/dialogs/demonotice.h +++ b/dialogs/demonotice.h @@ -3,20 +3,11 @@ #include -namespace Ui { -class DemoNotice; -} - class DemoNotice : public QDialog { Q_OBJECT - public: explicit DemoNotice(QWidget *parent = 0); - ~DemoNotice(); - -private: - Ui::DemoNotice *ui; }; #endif // DEMONOTICE_H diff --git a/dialogs/demonotice.ui b/dialogs/demonotice.ui deleted file mode 100644 index fa7ff3e64..000000000 --- a/dialogs/demonotice.ui +++ /dev/null @@ -1,97 +0,0 @@ - - - DemoNotice - - - - 0 - 0 - 511 - 249 - - - - Welcome - - - - - - 12 - - - - - - 0 - 0 - - - - <html><head/><body><p><img src=":/icons/olive-splash.png"/></p></body></html> - - - - - - - <html><head/><body><p><span style=" font-size:14pt;">Welcome to Olive!</span></p><p>Olive is a free open-source video editor released under the GNU GPL. If you have paid for this software, you have been scammed.</p><p>This software is currently in ALPHA which means it is unstable and very likely to crash, have bugs, and have missing features. We offer no warranty so use at your own risk. Please report any bugs or feature requests at <a href="https://olivevideoeditor.org/"><span style=" text-decoration: underline; color:#007af4;">www.olivevideoeditor.org</span></a></p><p>Thank you for trying Olive and we hope you enjoy it!</p></body></html> - - - true - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Ok - - - true - - - - - - - - - buttonBox - accepted() - DemoNotice - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - DemoNotice - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/dialogs/exportdialog.cpp b/dialogs/exportdialog.cpp index 20b010913..44835dacd 100644 --- a/dialogs/exportdialog.cpp +++ b/dialogs/exportdialog.cpp @@ -1,5 +1,4 @@ #include "exportdialog.h" -#include "ui_exportdialog.h" #include #include @@ -7,6 +6,14 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include "debug.h" #include "panels/panels.h" @@ -48,15 +55,14 @@ enum ExportFormats { }; ExportDialog::ExportDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::ExportDialog) + QDialog(parent) { - ui->setupUi(this); + setup_ui(); - ui->rangeCombobox->setCurrentIndex(0); + rangeCombobox->setCurrentIndex(0); if (sequence->using_workarea) { - ui->rangeCombobox->setEnabled(sequence->using_workarea); - ui->rangeCombobox->setCurrentIndex(1); + rangeCombobox->setEnabled(sequence->using_workarea); + rangeCombobox->setCurrentIndex(1); } format_strings.resize(FORMAT_SIZE); @@ -83,27 +89,25 @@ ExportDialog::ExportDialog(QWidget *parent) : format_strings[FORMAT_WMV] = "Windows Media"; for (int i=0;iformatCombobox->addItem(format_strings[i]); + formatCombobox->addItem(format_strings[i]); } - ui->formatCombobox->setCurrentIndex(FORMAT_MPEG4); + formatCombobox->setCurrentIndex(FORMAT_MPEG4); - ui->widthSpinbox->setValue(sequence->width); - ui->heightSpinbox->setValue(sequence->height); - ui->samplingRateSpinbox->setValue(sequence->audio_frequency); - ui->framerateSpinbox->setValue(sequence->frame_rate); + widthSpinbox->setValue(sequence->width); + heightSpinbox->setValue(sequence->height); + samplingRateSpinbox->setValue(sequence->audio_frequency); + framerateSpinbox->setValue(sequence->frame_rate); } ExportDialog::~ExportDialog() -{ - delete ui; -} +{} -void ExportDialog::on_formatCombobox_currentIndexChanged(int index) +void ExportDialog::format_changed(int index) { format_vcodecs.clear(); format_acodecs.clear(); - ui->vcodecCombobox->clear(); - ui->acodecCombobox->clear(); + vcodecCombobox->clear(); + acodecCombobox->clear(); int default_vcodec = 0; int default_acodec = 0; @@ -241,7 +245,7 @@ void ExportDialog::on_formatCombobox_currentIndexChanged(int index) format_acodecs.append(AV_CODEC_ID_OPUS); format_acodecs.append(AV_CODEC_ID_VORBIS); - default_acodec = 1; + default_acodec = 1; break; case FORMAT_MOV: format_vcodecs.append(AV_CODEC_ID_QTRLE); @@ -288,60 +292,56 @@ void ExportDialog::on_formatCombobox_currentIndexChanged(int index) for (int i=0;ivcodecCombobox->addItem("NULL"); + vcodecCombobox->addItem("NULL"); } else { - ui->vcodecCombobox->addItem(codec_info->long_name); + vcodecCombobox->addItem(codec_info->long_name); } } for (int i=0;iacodecCombobox->addItem("NULL"); + acodecCombobox->addItem("NULL"); } else { - ui->acodecCombobox->addItem(codec_info->long_name); + acodecCombobox->addItem(codec_info->long_name); } } - ui->vcodecCombobox->setCurrentIndex(default_vcodec); - ui->acodecCombobox->setCurrentIndex(default_acodec); + vcodecCombobox->setCurrentIndex(default_vcodec); + acodecCombobox->setCurrentIndex(default_acodec); bool video_enabled = format_vcodecs.size() != 0; bool audio_enabled = format_acodecs.size() != 0; - ui->videoGroupbox->setChecked(video_enabled); - ui->audioGroupbox->setChecked(audio_enabled); - ui->videoGroupbox->setEnabled(video_enabled); - ui->audioGroupbox->setEnabled(audio_enabled); -} - -void ExportDialog::on_pushButton_2_clicked() { - close(); + videoGroupbox->setChecked(video_enabled); + audioGroupbox->setChecked(audio_enabled); + videoGroupbox->setEnabled(video_enabled); + audioGroupbox->setEnabled(audio_enabled); } void ExportDialog::render_thread_finished() { - if (ui->progressBar->value() < 100 && !cancelled) { - QMessageBox::critical(this, "Export Failed", "Export failed - " + export_error, QMessageBox::Ok); - } - prep_ui_for_render(false); - panel_sequence_viewer->viewer_widget->makeCurrent(); - panel_sequence_viewer->viewer_widget->initializeGL(); - update_ui(false); - if (ui->progressBar->value() == 100) close(); + if (progressBar->value() < 100 && !cancelled) { + QMessageBox::critical(this, "Export Failed", "Export failed - " + export_error, QMessageBox::Ok); + } + prep_ui_for_render(false); + panel_sequence_viewer->viewer_widget->makeCurrent(); + panel_sequence_viewer->viewer_widget->initializeGL(); + update_ui(false); + if (progressBar->value() == 100) accept(); } void ExportDialog::prep_ui_for_render(bool r) { - ui->pushButton->setEnabled(!r); - ui->pushButton_2->setEnabled(!r); - ui->renderCancel->setEnabled(r); + export_button->setEnabled(!r); + cancel_button->setEnabled(!r); + renderCancel->setEnabled(r); } -void ExportDialog::on_pushButton_clicked() { - if (ui->widthSpinbox->value()%2 == 1 || ui->heightSpinbox->value()%2 == 1) { +void ExportDialog::export_action() { + if (widthSpinbox->value()%2 == 1 || heightSpinbox->value()%2 == 1) { QMessageBox::critical(this, "Invalid dimensions", "Export width and height must both be even numbers/divisible by 2.", QMessageBox::Ok); return; } QString ext; - switch (ui->formatCombobox->currentIndex()) { + switch (formatCombobox->currentIndex()) { case FORMAT_3GPP: ext = "3gp"; break; @@ -366,57 +366,57 @@ void ExportDialog::on_pushButton_clicked() { case FORMAT_GIF: ext = "gif"; break; - case FORMAT_IMG: - switch (format_vcodecs.at(ui->vcodecCombobox->currentIndex())) { - case AV_CODEC_ID_BMP: - ext = "bmp"; - break; - case AV_CODEC_ID_MJPEG: - ext = "jpg"; - break; - case AV_CODEC_ID_JPEG2000: - ext = "jp2"; - break; - case AV_CODEC_ID_PSD: - ext = "psd"; - break; - case AV_CODEC_ID_PNG: - ext = "png"; - break; - case AV_CODEC_ID_TIFF: - ext = "tif"; - break; - default: + case FORMAT_IMG: + switch (format_vcodecs.at(vcodecCombobox->currentIndex())) { + case AV_CODEC_ID_BMP: + ext = "bmp"; + break; + case AV_CODEC_ID_MJPEG: + ext = "jpg"; + break; + case AV_CODEC_ID_JPEG2000: + ext = "jp2"; + break; + case AV_CODEC_ID_PSD: + ext = "psd"; + break; + case AV_CODEC_ID_PNG: + ext = "png"; + break; + case AV_CODEC_ID_TIFF: + ext = "tif"; + break; + default: dout << "[ERROR] Invalid codec selection for an image sequence"; - QMessageBox::critical(this, "Invalid codec", "Couldn't determine output parameters for the selected codec. This is a bug, please contact the developers.", QMessageBox::Ok); - return; - } + QMessageBox::critical(this, "Invalid codec", "Couldn't determine output parameters for the selected codec. This is a bug, please contact the developers.", QMessageBox::Ok); + return; + } break; case FORMAT_MP3: ext = "mp3"; break; case FORMAT_MPEG1: - if (ui->videoGroupbox->isChecked() && !ui->audioGroupbox->isChecked()) { + if (videoGroupbox->isChecked() && !audioGroupbox->isChecked()) { ext = "m1v"; - } else if (!ui->videoGroupbox->isChecked() && ui->audioGroupbox->isChecked()) { + } else if (!videoGroupbox->isChecked() && audioGroupbox->isChecked()) { ext = "m1a"; } else { ext = "mpg"; } break; case FORMAT_MPEG2: - if (ui->videoGroupbox->isChecked() && !ui->audioGroupbox->isChecked()) { + if (videoGroupbox->isChecked() && !audioGroupbox->isChecked()) { ext = "m2v"; - } else if (!ui->videoGroupbox->isChecked() && ui->audioGroupbox->isChecked()) { + } else if (!videoGroupbox->isChecked() && audioGroupbox->isChecked()) { ext = "m2a"; } else { ext = "mpg"; } break; case FORMAT_MPEG4: - if (ui->videoGroupbox->isChecked() && !ui->audioGroupbox->isChecked()) { + if (videoGroupbox->isChecked() && !audioGroupbox->isChecked()) { ext = "m4v"; - } else if (!ui->videoGroupbox->isChecked() && ui->audioGroupbox->isChecked()) { + } else if (!videoGroupbox->isChecked() && audioGroupbox->isChecked()) { ext = "m4a"; } else { ext = "mp4"; @@ -426,7 +426,7 @@ void ExportDialog::on_pushButton_clicked() { ext = "ts"; break; case FORMAT_MKV: - if (!ui->videoGroupbox->isChecked()) { + if (!videoGroupbox->isChecked()) { ext = "mka"; } else { ext = "mkv"; @@ -438,14 +438,14 @@ void ExportDialog::on_pushButton_clicked() { case FORMAT_MOV: ext = "mov"; break; - case FORMAT_WAV: - ext = "wav"; - break; + case FORMAT_WAV: + ext = "wav"; + break; case FORMAT_WEBM: ext = "webm"; break; case FORMAT_WMV: - if (ui->videoGroupbox->isChecked()) { + if (videoGroupbox->isChecked()) { ext = "wmv"; } else { ext = "wma"; @@ -453,66 +453,66 @@ void ExportDialog::on_pushButton_clicked() { break; default: dout << "[ERROR] Invalid format - this is a bug, please inform the developers"; - QMessageBox::critical(this, "Invalid format", "Couldn't determine output format. This is a bug, please contact the developers.", QMessageBox::Ok); + QMessageBox::critical(this, "Invalid format", "Couldn't determine output format. This is a bug, please contact the developers.", QMessageBox::Ok); return; } - QString filename = QFileDialog::getSaveFileName(this, "Export Media", "", format_strings[ui->formatCombobox->currentIndex()] + " (*." + ext + ")"); + QString filename = QFileDialog::getSaveFileName(this, "Export Media", "", format_strings[formatCombobox->currentIndex()] + " (*." + ext + ")"); if (!filename.isEmpty()) { - if (!filename.endsWith("." + ext, Qt::CaseInsensitive)) { - filename += "." + ext; - } + if (!filename.endsWith("." + ext, Qt::CaseInsensitive)) { + filename += "." + ext; + } - if (ui->formatCombobox->currentIndex() == FORMAT_IMG) { - int ext_location = filename.lastIndexOf('.'); - if (ext_location > filename.lastIndexOf('/')) { - filename.insert(ext_location, 'd'); - filename.insert(ext_location, '5'); - filename.insert(ext_location, '0'); - filename.insert(ext_location, '%'); - } - } + if (formatCombobox->currentIndex() == FORMAT_IMG) { + int ext_location = filename.lastIndexOf('.'); + if (ext_location > filename.lastIndexOf('/')) { + filename.insert(ext_location, 'd'); + filename.insert(ext_location, '5'); + filename.insert(ext_location, '0'); + filename.insert(ext_location, '%'); + } + } et = new ExportThread(); connect(et, SIGNAL(finished()), et, SLOT(deleteLater())); - connect(et, SIGNAL(finished()), this, SLOT(render_thread_finished())); - connect(et, SIGNAL(progress_changed(int, qint64)), this, SLOT(update_progress_bar(int, qint64))); + connect(et, SIGNAL(finished()), this, SLOT(render_thread_finished())); + connect(et, SIGNAL(progress_changed(int, qint64)), this, SLOT(update_progress_bar(int, qint64))); closeActiveClips(sequence, true); - mainWindow->autorecover_interval(); + mainWindow->autorecover_interval(); rendering = true; panel_sequence_viewer->viewer_widget->context()->doneCurrent(); panel_sequence_viewer->viewer_widget->context()->moveToThread(et); - prep_ui_for_render(true); + prep_ui_for_render(true); et->filename = filename; - et->video_enabled = ui->videoGroupbox->isChecked(); - if (et->video_enabled) { - et->video_codec = format_vcodecs.at(ui->vcodecCombobox->currentIndex()); - et->video_width = ui->widthSpinbox->value(); - et->video_height = ui->heightSpinbox->value(); - et->video_frame_rate = ui->framerateSpinbox->value(); - et->video_compression_type = ui->compressionTypeCombobox->currentData().toInt(); - et->video_bitrate = ui->videobitrateSpinbox->value(); - } - et->audio_enabled = ui->audioGroupbox->isChecked(); - if (et->audio_enabled) { - et->audio_codec = format_acodecs.at(ui->acodecCombobox->currentIndex()); - et->audio_sampling_rate = ui->samplingRateSpinbox->value(); - et->audio_bitrate = ui->audiobitrateSpinbox->value(); - } + et->video_enabled = videoGroupbox->isChecked(); + if (et->video_enabled) { + et->video_codec = format_vcodecs.at(vcodecCombobox->currentIndex()); + et->video_width = widthSpinbox->value(); + et->video_height = heightSpinbox->value(); + et->video_frame_rate = framerateSpinbox->value(); + et->video_compression_type = compressionTypeCombobox->currentData().toInt(); + et->video_bitrate = videobitrateSpinbox->value(); + } + et->audio_enabled = audioGroupbox->isChecked(); + if (et->audio_enabled) { + et->audio_codec = format_acodecs.at(acodecCombobox->currentIndex()); + et->audio_sampling_rate = samplingRateSpinbox->value(); + et->audio_bitrate = audiobitrateSpinbox->value(); + } - et->start_frame = 0; - et->end_frame = sequence->getEndFrame(); // entire sequence - if (ui->rangeCombobox->currentIndex() == 1) { - et->start_frame = qMax(sequence->workarea_in, et->start_frame); - et->end_frame = qMin(sequence->workarea_out, et->end_frame); - } + et->start_frame = 0; + et->end_frame = sequence->getEndFrame(); // entire sequence + if (rangeCombobox->currentIndex() == 1) { + et->start_frame = qMax(sequence->workarea_in, et->start_frame); + et->end_frame = qMin(sequence->workarea_out, et->end_frame); + } - et->ed = this; + et->ed = this; cancelled = false; et->start(); @@ -520,54 +520,207 @@ void ExportDialog::on_pushButton_clicked() { } void ExportDialog::update_progress_bar(int value, qint64 remaining_ms) { - // convert ms to H:MM:SS - int seconds = qFloor(remaining_ms*0.001)%60; - int minutes = qFloor(remaining_ms/60000)%60; - int hours = qFloor(remaining_ms/3600000); - ui->progressBar->setFormat("%p% (ETA: " + QString::number(hours) + ":" + QString::number(minutes).rightJustified(2, '0') + ":" + QString::number(seconds).rightJustified(2, '0') + ")"); + // convert ms to H:MM:SS + int seconds = qFloor(remaining_ms*0.001)%60; + int minutes = qFloor(remaining_ms/60000)%60; + int hours = qFloor(remaining_ms/3600000); + progressBar->setFormat("%p% (ETA: " + QString::number(hours) + ":" + QString::number(minutes).rightJustified(2, '0') + ":" + QString::number(seconds).rightJustified(2, '0') + ")"); - ui->progressBar->setValue(value); + progressBar->setValue(value); } -void ExportDialog::on_renderCancel_clicked() { - panel_sequence_viewer->viewer_widget->force_quit = true; +void ExportDialog::cancel_render() { + panel_sequence_viewer->viewer_widget->force_quit = true; et->continueEncode = false; - cancelled = true; + cancelled = true; } -void ExportDialog::on_vcodecCombobox_currentIndexChanged(int index) { - ui->compressionTypeCombobox->clear(); +void ExportDialog::vcodec_changed(int index) { + compressionTypeCombobox->clear(); if ((format_vcodecs.size() > 0 && format_vcodecs.at(index) == AV_CODEC_ID_H264)) { - ui->compressionTypeCombobox->setEnabled(true); - ui->compressionTypeCombobox->addItem("Quality-based (Constant Rate Factor)", COMPRESSION_TYPE_CFR); -// ui->compressionTypeCombobox->addItem("File size-based (Two-Pass)", COMPRESSION_TYPE_TARGETSIZE); -// ui->compressionTypeCombobox->addItem("Average bitrate (Two-Pass)", COMPRESSION_TYPE_TARGETBR); + compressionTypeCombobox->setEnabled(true); + compressionTypeCombobox->addItem("Quality-based (Constant Rate Factor)", COMPRESSION_TYPE_CFR); +// compressionTypeCombobox->addItem("File size-based (Two-Pass)", COMPRESSION_TYPE_TARGETSIZE); +// compressionTypeCombobox->addItem("Average bitrate (Two-Pass)", COMPRESSION_TYPE_TARGETBR); } else { - ui->compressionTypeCombobox->addItem("Constant Bitrate", COMPRESSION_TYPE_CBR); - ui->compressionTypeCombobox->setCurrentIndex(0); - ui->compressionTypeCombobox->setEnabled(false); + compressionTypeCombobox->addItem("Constant Bitrate", COMPRESSION_TYPE_CBR); + compressionTypeCombobox->setCurrentIndex(0); + compressionTypeCombobox->setEnabled(false); } } -void ExportDialog::on_compressionTypeCombobox_currentIndexChanged(int) { - ui->videobitrateSpinbox->setToolTip(""); - ui->videobitrateSpinbox->setMinimum(0); - ui->videobitrateSpinbox->setMaximum(99.99); - switch (ui->compressionTypeCombobox->currentData().toInt()) { +void ExportDialog::comp_type_changed(int) { + videobitrateSpinbox->setToolTip(""); + videobitrateSpinbox->setMinimum(0); + videobitrateSpinbox->setMaximum(99.99); + switch (compressionTypeCombobox->currentData().toInt()) { case COMPRESSION_TYPE_CBR: case COMPRESSION_TYPE_TARGETBR: - ui->videoBitrateLabel->setText("Bitrate (Mbps):"); - ui->videobitrateSpinbox->setValue(qMax(0.5, (double) qRound((0.01528 * sequence->height) - 4.5))); + videoBitrateLabel->setText("Bitrate (Mbps):"); + videobitrateSpinbox->setValue(qMax(0.5, (double) qRound((0.01528 * sequence->height) - 4.5))); break; case COMPRESSION_TYPE_CFR: - ui->videoBitrateLabel->setText("Quality (CRF):"); - ui->videobitrateSpinbox->setValue(36); - ui->videobitrateSpinbox->setMaximum(51); - ui->videobitrateSpinbox->setToolTip("Quality Factor:\n\n0 = lossless\n17-18 = visually lossless (compressed, but unnoticeable)\n23 = high quality\n51 = lowest quality possible"); + videoBitrateLabel->setText("Quality (CRF):"); + videobitrateSpinbox->setValue(36); + videobitrateSpinbox->setMaximum(51); + videobitrateSpinbox->setToolTip("Quality Factor:\n\n0 = lossless\n17-18 = visually lossless (compressed, but unnoticeable)\n23 = high quality\n51 = lowest quality possible"); break; case COMPRESSION_TYPE_TARGETSIZE: - ui->videoBitrateLabel->setText("Target File Size (MB):"); - ui->videobitrateSpinbox->setValue(100); + videoBitrateLabel->setText("Target File Size (MB):"); + videobitrateSpinbox->setValue(100); break; } } + +void ExportDialog::setup_ui() { + QVBoxLayout* verticalLayout = new QVBoxLayout(this); + + QHBoxLayout* horizontalLayout = new QHBoxLayout(); + + horizontalLayout->addWidget(new QLabel("Format:")); + + formatCombobox = new QComboBox(this); + + horizontalLayout->addWidget(formatCombobox); + + verticalLayout->addLayout(horizontalLayout); + + QHBoxLayout* horizontalLayout_4 = new QHBoxLayout(); + + horizontalLayout_4->addWidget(new QLabel("Range:")); + + rangeCombobox = new QComboBox(this); + rangeCombobox->addItem("Entire Sequence"); + rangeCombobox->addItem("In to Out"); + + horizontalLayout_4->addWidget(rangeCombobox); + + verticalLayout->addLayout(horizontalLayout_4); + + videoGroupbox = new QGroupBox(this); + videoGroupbox->setTitle("Video"); + videoGroupbox->setFlat(false); + videoGroupbox->setCheckable(true); + QGridLayout* gridLayout = new QGridLayout(videoGroupbox); + + gridLayout->addWidget(new QLabel("Compression Type:"), 4, 0, 1, 1); + + compressionTypeCombobox = new QComboBox(videoGroupbox); + compressionTypeCombobox->addItem("Quality-based (Constant Rate Factor)"); + compressionTypeCombobox->addItem("File size-based (Two-Pass)"); + + gridLayout->addWidget(compressionTypeCombobox, 4, 1, 1, 1); + + gridLayout->addWidget(new QLabel("Codec:"), 0, 0, 1, 1); + + vcodecCombobox = new QComboBox(videoGroupbox); + + gridLayout->addWidget(vcodecCombobox, 0, 1, 1, 1); + + gridLayout->addWidget(new QLabel("Height:"), 2, 0, 1, 1); + + gridLayout->addWidget(new QLabel("Width:"), 1, 0, 1, 1); + + heightSpinbox = new QSpinBox(videoGroupbox); + heightSpinbox->setMaximum(16777216); + + gridLayout->addWidget(heightSpinbox, 2, 1, 1, 1); + + widthSpinbox = new QSpinBox(videoGroupbox); + widthSpinbox->setMaximum(16777216); + + gridLayout->addWidget(widthSpinbox, 1, 1, 1, 1); + + videobitrateSpinbox = new QDoubleSpinBox(videoGroupbox); + videobitrateSpinbox->setMaximum(100); + videobitrateSpinbox->setValue(2); + + gridLayout->addWidget(videobitrateSpinbox, 5, 1, 1, 1); + + videoBitrateLabel = new QLabel(videoGroupbox); + + gridLayout->addWidget(videoBitrateLabel, 5, 0, 1, 1); + + gridLayout->addWidget(new QLabel("Frame Rate:"), 3, 0, 1, 1); + + framerateSpinbox = new QDoubleSpinBox(videoGroupbox); + framerateSpinbox->setMaximum(60); + framerateSpinbox->setValue(0); + + gridLayout->addWidget(framerateSpinbox, 3, 1, 1, 1); + + + verticalLayout->addWidget(videoGroupbox); + + audioGroupbox = new QGroupBox(this); + audioGroupbox->setTitle("Audio"); + audioGroupbox->setCheckable(true); + + QGridLayout* gridLayout_2 = new QGridLayout(audioGroupbox); + gridLayout_2->addWidget(new QLabel("Codec:"), 0, 0, 1, 1); + + acodecCombobox = new QComboBox(audioGroupbox); + + gridLayout_2->addWidget(acodecCombobox, 0, 1, 1, 1); + + samplingRateSpinbox = new QSpinBox(audioGroupbox); + samplingRateSpinbox->setMaximum(96000); + samplingRateSpinbox->setValue(0); + + gridLayout_2->addWidget(samplingRateSpinbox, 1, 1, 1, 1); + + gridLayout_2->addWidget(new QLabel("Sampling Rate:"), 1, 0, 1, 1); + + gridLayout_2->addWidget(new QLabel("Bitrate (Kbps/CBR):"), 3, 0, 1, 1); + + audiobitrateSpinbox = new QSpinBox(audioGroupbox); + audiobitrateSpinbox->setMaximum(320); + audiobitrateSpinbox->setValue(256); + + gridLayout_2->addWidget(audiobitrateSpinbox, 3, 1, 1, 1); + + + verticalLayout->addWidget(audioGroupbox); + + QHBoxLayout* horizontalLayout_3 = new QHBoxLayout(); + progressBar = new QProgressBar(this); + progressBar->setFormat("%p% (ETA: 0:00:00)"); + progressBar->setEnabled(false); + progressBar->setValue(0); + + horizontalLayout_3->addWidget(progressBar); + + renderCancel = new QPushButton(this); + renderCancel->setText("x"); + renderCancel->setEnabled(false); + renderCancel->setMaximumSize(QSize(20, 16777215)); + connect(renderCancel, SIGNAL(clicked(bool)), this, SLOT(cancel_render())); + + horizontalLayout_3->addWidget(renderCancel); + + + verticalLayout->addLayout(horizontalLayout_3); + + QHBoxLayout* horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->addStretch(); + + export_button = new QPushButton(this); + export_button->setText("Export"); + connect(export_button, SIGNAL(clicked(bool)), this, SLOT(export_action())); + + horizontalLayout_2->addWidget(export_button); + + cancel_button = new QPushButton(this); + cancel_button->setText("Cancel"); + connect(cancel_button, SIGNAL(clicked(bool)), this, SLOT(reject())); + + horizontalLayout_2->addWidget(cancel_button); + + horizontalLayout_2->addStretch(); + + verticalLayout->addLayout(horizontalLayout_2); + + connect(formatCombobox, SIGNAL(currentIndexChanged(int)), this, SLOT(format_changed(int))); + connect(compressionTypeCombobox, SIGNAL(currentIndexChanged(int)), this, SLOT(comp_type_changed(int))); + connect(vcodecCombobox, SIGNAL(currentIndexChanged(int)), this, SLOT(vcodec_changed(int))); +} diff --git a/dialogs/exportdialog.h b/dialogs/exportdialog.h index 07585b6f9..7e78d2a95 100644 --- a/dialogs/exportdialog.h +++ b/dialogs/exportdialog.h @@ -3,48 +3,60 @@ #include -namespace Ui { -class ExportDialog; -} - struct Sequence; class ExportThread; +class QComboBox; +class QSpinBox; +class QDoubleSpinBox; +class QLabel; +class QProgressBar; +class QGroupBox; class ExportDialog : public QDialog { Q_OBJECT public: explicit ExportDialog(QWidget *parent = 0); - ~ExportDialog(); - QString export_error; + ~ExportDialog(); + QString export_error; private slots: - void on_formatCombobox_currentIndexChanged(int index); - - void on_pushButton_2_clicked(); - - void on_pushButton_clicked(); - - void update_progress_bar(int value, qint64 remaining_ms); - - void on_renderCancel_clicked(); - - void render_thread_finished(); - - void on_vcodecCombobox_currentIndexChanged(int index); - - void on_compressionTypeCombobox_currentIndexChanged(int index); + void format_changed(int index); + void export_action(); + void update_progress_bar(int value, qint64 remaining_ms); + void cancel_render(); + void render_thread_finished(); + void vcodec_changed(int index); + void comp_type_changed(int index); private: - Ui::ExportDialog *ui; - QVector format_strings; QVector format_vcodecs; QVector format_acodecs; + void setup_ui(); - ExportThread* et; + ExportThread* et; void prep_ui_for_render(bool r); - bool cancelled; + bool cancelled; + + QComboBox* rangeCombobox; + QSpinBox* widthSpinbox; + QDoubleSpinBox* videobitrateSpinbox; + QLabel* videoBitrateLabel; + QDoubleSpinBox* framerateSpinbox; + QComboBox* vcodecCombobox; + QComboBox* acodecCombobox; + QSpinBox* samplingRateSpinbox; + QSpinBox* audiobitrateSpinbox; + QProgressBar* progressBar; + QComboBox* formatCombobox; + QSpinBox* heightSpinbox; + QPushButton* export_button; + QPushButton* cancel_button; + QPushButton* renderCancel; + QGroupBox* videoGroupbox; + QGroupBox* audioGroupbox; + QComboBox* compressionTypeCombobox; }; #endif // EXPORTDIALOG_H diff --git a/dialogs/exportdialog.ui b/dialogs/exportdialog.ui deleted file mode 100644 index 4a9207014..000000000 --- a/dialogs/exportdialog.ui +++ /dev/null @@ -1,317 +0,0 @@ - - - ExportDialog - - - - 0 - 0 - 443 - 562 - - - - Export - - - - - - - - Format: - - - - - - - - - - - - - - Range: - - - - - - - - Entire Sequence - - - - - In to Out - - - - - - - - - - Video - - - false - - - true - - - - - - Compression Type: - - - - - - - - Quality-based (Constant Rate Factor) - - - - - File size-based (Two-Pass) - - - - - - - - Codec: - - - - - - - - - - Height: - - - - - - - Width: - - - - - - - 16777216 - - - - - - - 16777216 - - - - - - - 100.000000000000000 - - - 2.000000000000000 - - - - - - - Bitrate (Mbps): - - - - - - - Frame Rate: - - - - - - - 60.000000000000000 - - - 0.000000000000000 - - - - - - - - - - Audio - - - true - - - - - - Codec: - - - - - - - - - - 96000 - - - 0 - - - - - - - Sampling Rate: - - - - - - - Bitrate (Kbps/CBR): - - - - - - - 320 - - - 256 - - - - - - - - - - - - false - - - 0 - - - %p% (ETA: 0:00:00) - - - - - - - false - - - - 20 - 16777215 - - - - x - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Export - - - - - - - Cancel - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - formatCombobox - videoGroupbox - vcodecCombobox - widthSpinbox - heightSpinbox - framerateSpinbox - videobitrateSpinbox - audioGroupbox - acodecCombobox - samplingRateSpinbox - audiobitrateSpinbox - renderCancel - pushButton - pushButton_2 - - - - diff --git a/dialogs/loaddialog.cpp b/dialogs/loaddialog.cpp index 706b1193a..3751ebea9 100644 --- a/dialogs/loaddialog.cpp +++ b/dialogs/loaddialog.cpp @@ -14,39 +14,40 @@ #include "mainwindow.h" LoadDialog::LoadDialog(QWidget *parent, bool autorecovery) : QDialog(parent) { + setWindowTitle("Loading..."); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); QVBoxLayout* layout = new QVBoxLayout(); setLayout(layout); - layout->addWidget(new QLabel("Loading '" + project_url.mid(project_url.lastIndexOf('/')+1) + "'...")); + layout->addWidget(new QLabel("Loading '" + project_url.mid(project_url.lastIndexOf('/')+1) + "'...")); bar = new QProgressBar(); - bar->setValue(0); + bar->setValue(0); layout->addWidget(bar); - cancel_button = new QPushButton("Cancel"); - connect(cancel_button, SIGNAL(clicked(bool)), this, SLOT(cancel())); + cancel_button = new QPushButton("Cancel"); + connect(cancel_button, SIGNAL(clicked(bool)), this, SLOT(cancel())); - hboxLayout = new QHBoxLayout(); + hboxLayout = new QHBoxLayout(); hboxLayout->addStretch(); hboxLayout->addWidget(cancel_button); hboxLayout->addStretch(); layout->addLayout(hboxLayout); - update(); + update(); - lt = new LoadThread(this, autorecovery); - QObject::connect(lt, SIGNAL(success()), this, SLOT(thread_done())); + lt = new LoadThread(this, autorecovery); + QObject::connect(lt, SIGNAL(success()), this, SLOT(thread_done())); QObject::connect(lt, SIGNAL(error()), this, SLOT(die())); - QObject::connect(lt, SIGNAL(report_progress(int)), bar, SLOT(setValue(int))); - lt->start(); + QObject::connect(lt, SIGNAL(report_progress(int)), bar, SLOT(setValue(int))); + lt->start(); } void LoadDialog::cancel() { - lt->cancel(); - lt->wait(); + lt->cancel(); + lt->wait(); die(); } @@ -56,5 +57,5 @@ void LoadDialog::die() { } void LoadDialog::thread_done() { - accept(); + accept(); } diff --git a/dialogs/newsequencedialog.cpp b/dialogs/newsequencedialog.cpp index b3fabd374..cfcd0678e 100644 --- a/dialogs/newsequencedialog.cpp +++ b/dialogs/newsequencedialog.cpp @@ -1,5 +1,4 @@ #include "newsequencedialog.h" -#include "ui_newsequencedialog.h" #include "panels/panels.h" #include "panels/project.h" @@ -8,82 +7,70 @@ #include "project/clip.h" #include "panels/timeline.h" #include "playback/playback.h" +#include "project/media.h" #include +#include +#include +#include +#include +#include +#include +#include +#include extern "C" { #include } -NewSequenceDialog::NewSequenceDialog(QWidget *parent) : +NewSequenceDialog::NewSequenceDialog(QWidget *parent, Media *existing) : QDialog(parent), - existing_sequence(NULL), - ui(new Ui::NewSequenceDialog) + existing_item(existing) { - ui->setupUi(this); + setup_ui(); - ui->frame_rate_combobox->addItem("10 FPS", 10.0); - ui->frame_rate_combobox->addItem("12.5 FPS", 12.5); - ui->frame_rate_combobox->addItem("15 FPS", 15.0); - ui->frame_rate_combobox->addItem("23.976 FPS", 23.976); - ui->frame_rate_combobox->addItem("24 FPS", 24.0); - ui->frame_rate_combobox->addItem("25 FPS", 25.0); - ui->frame_rate_combobox->addItem("29.97 FPS", 29.97); - ui->frame_rate_combobox->addItem("30 FPS", 30.0); - ui->frame_rate_combobox->addItem("50 FPS", 50.0); - ui->frame_rate_combobox->addItem("59.94 FPS", 59.94); - ui->frame_rate_combobox->addItem("60 FPS", 60.0); - ui->frame_rate_combobox->setCurrentIndex(6); + if (existing != NULL) { + existing_sequence = existing->to_sequence(); + setWindowTitle("Editing \"" + existing_sequence->name + "\""); - ui->audio_frequency_combobox->addItem("22050 Hz", 22050); - ui->audio_frequency_combobox->addItem("24000 Hz", 24000); - ui->audio_frequency_combobox->addItem("32000 Hz", 32000); - ui->audio_frequency_combobox->addItem("44100 Hz", 44100); - ui->audio_frequency_combobox->addItem("48000 Hz", 48000); - ui->audio_frequency_combobox->addItem("88200 Hz", 88200); - ui->audio_frequency_combobox->addItem("96000 Hz", 96000); - ui->audio_frequency_combobox->setCurrentIndex(4); -} - -NewSequenceDialog::~NewSequenceDialog() -{ - delete ui; -} - -void NewSequenceDialog::set_sequence_name(const QString& s) { - ui->lineEdit->setText(s); -} - -void NewSequenceDialog::showEvent(QShowEvent *) { - if (existing_sequence != NULL) { - ui->width_numeric->setValue(existing_sequence->width); - ui->height_numeric->setValue(existing_sequence->height); + 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;iframe_rate_combobox->count();i++) { - if (qRound(ui->frame_rate_combobox->itemData(i).toDouble()*100) == comp_rate) { - ui->frame_rate_combobox->setCurrentIndex(i); + for (int i=0;icount();i++) { + if (qRound(frame_rate_combobox->itemData(i).toDouble()*100) == comp_rate) { + frame_rate_combobox->setCurrentIndex(i); break; } } - ui->lineEdit->setText(existing_sequence->name); - for (int i=0;iaudio_frequency_combobox->count();i++) { - if (ui->audio_frequency_combobox->itemData(i) == existing_sequence->audio_frequency) { - ui->audio_frequency_combobox->setCurrentIndex(i); + lineEdit->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 = NULL; + setWindowTitle("New Sequence"); } } -void NewSequenceDialog::on_buttonBox_accepted() { +NewSequenceDialog::~NewSequenceDialog() +{} + +void NewSequenceDialog::set_sequence_name(const QString& s) { + lineEdit->setText(s); +} + +void NewSequenceDialog::create() { if (existing_sequence == NULL) { Sequence* s = new Sequence(); - s->name = ui->lineEdit->text(); - s->width = ui->width_numeric->value(); - s->height = ui->height_numeric->value(); - s->frame_rate = ui->frame_rate_combobox->currentData().toDouble(); - s->audio_frequency = ui->audio_frequency_combobox->currentData().toInt(); + s->name = lineEdit->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(); @@ -92,14 +79,14 @@ void NewSequenceDialog::on_buttonBox_accepted() { } else { ComboAction* ca = new ComboAction(); - double multiplier = ui->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 = ui->lineEdit->text(); - esc->width = ui->width_numeric->value(); - esc->height = ui->height_numeric->value(); - esc->frame_rate = ui->frame_rate_combobox->currentData().toDouble(); - esc->audio_frequency = ui->audio_frequency_combobox->currentData().toInt(); + esc->name = lineEdit->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); @@ -112,51 +99,183 @@ void NewSequenceDialog::on_buttonBox_accepted() { undo_stack.push(ca); } + + accept(); } -void NewSequenceDialog::on_comboBox_currentIndexChanged(int index) +void NewSequenceDialog::preset_changed(int index) { switch (index) { case 0: // FILM 4K - ui->width_numeric->setValue(4096); - ui->height_numeric->setValue(2160); - + width_numeric->setValue(4096); + height_numeric->setValue(2160); break; case 1: // TV 4K - ui->width_numeric->setValue(3840); - ui->height_numeric->setValue(2160); + width_numeric->setValue(3840); + height_numeric->setValue(2160); break; case 2: // 1080p - ui->width_numeric->setValue(1920); - ui->height_numeric->setValue(1080); + width_numeric->setValue(1920); + height_numeric->setValue(1080); break; case 3: // 720p - ui->width_numeric->setValue(1280); - ui->height_numeric->setValue(720); + width_numeric->setValue(1280); + height_numeric->setValue(720); break; case 4: // 480p - ui->width_numeric->setValue(640); - ui->height_numeric->setValue(480); + width_numeric->setValue(640); + height_numeric->setValue(480); break; case 5: // 360p - ui->width_numeric->setValue(640); - ui->height_numeric->setValue(360); + width_numeric->setValue(640); + height_numeric->setValue(360); break; case 6: // 240p - ui->width_numeric->setValue(320); - ui->height_numeric->setValue(240); + width_numeric->setValue(320); + height_numeric->setValue(240); break; case 7: // 144p - ui->width_numeric->setValue(192); - ui->height_numeric->setValue(144); + width_numeric->setValue(192); + height_numeric->setValue(144); break; case 8: // NTSC (480i) - ui->width_numeric->setValue(720); - ui->height_numeric->setValue(480); + width_numeric->setValue(720); + height_numeric->setValue(480); break; case 9: // PAL (576i) - ui->width_numeric->setValue(720); - ui->height_numeric->setValue(576); + width_numeric->setValue(720); + height_numeric->setValue(576); break; } } + +void NewSequenceDialog::setup_ui() { + QVBoxLayout* verticalLayout = new QVBoxLayout(this); + + QWidget* widget = new QWidget(this); + + QHBoxLayout* horizontalLayout_2 = new QHBoxLayout(widget); + horizontalLayout_2->setContentsMargins(0, 0, 0, 0); + + horizontalLayout_2->addWidget(new QLabel("Preset:")); + + preset_combobox = new QComboBox(widget); + + preset_combobox->addItem("Film 4K"); + preset_combobox->addItem("TV 4K (Ultra HD/2160p)"); + preset_combobox->addItem("1080p"); + preset_combobox->addItem("720p"); + preset_combobox->addItem("480p"); + preset_combobox->addItem("360p"); + preset_combobox->addItem("240p"); + preset_combobox->addItem("144p"); + preset_combobox->addItem("NTSC (480i)"); + preset_combobox->addItem("PAL (576i)"); + preset_combobox->addItem("Custom"); + preset_combobox->setCurrentIndex(2); + + horizontalLayout_2->addWidget(preset_combobox); + + verticalLayout->addWidget(widget); + + QGroupBox* groupBox = new QGroupBox(this); + groupBox->setTitle("Video"); + + QGridLayout* gridLayout = new QGridLayout(groupBox); + + height_numeric = new QSpinBox(groupBox); + height_numeric->setMaximum(9999); + height_numeric->setValue(1080); + + gridLayout->addWidget(height_numeric, 1, 2, 1, 2); + + width_numeric = new QSpinBox(groupBox); + width_numeric->setMaximum(9999); + width_numeric->setValue(1920); + + gridLayout->addWidget(width_numeric, 0, 2, 1, 2); + + gridLayout->addWidget(new QLabel("Width:"), 0, 0, 1, 1); + + gridLayout->addWidget(new QLabel("Pixel Aspect Ratio:"), 4, 0, 1, 1); + + gridLayout->addWidget(new QLabel("Interlacing:"), 6, 0, 1, 1); + + gridLayout->addWidget(new QLabel("Height:"), 1, 0, 1, 2); + + par_combobox = new QComboBox(groupBox); + par_combobox->addItem("Square Pixels (1.0)"); + + gridLayout->addWidget(par_combobox, 4, 2, 1, 2); + + interlacing_combobox = new QComboBox(groupBox); + interlacing_combobox->addItem("None (Progressive)"); + interlacing_combobox->addItem("Upper Field First"); + interlacing_combobox->addItem("Lower Field First"); + + gridLayout->addWidget(interlacing_combobox, 6, 2, 1, 2); + + frame_rate_combobox = new QComboBox(groupBox); + 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); + + gridLayout->addWidget(frame_rate_combobox, 2, 2, 1, 2); + + gridLayout->addWidget(new QLabel("Frame Rate:"), 2, 0, 1, 1); + + verticalLayout->addWidget(groupBox); + + QGroupBox* groupBox_2 = new QGroupBox(this); + groupBox_2->setTitle("Audio"); + + QGridLayout* gridLayout_2 = new QGridLayout(groupBox_2); + + gridLayout_2->addWidget(new QLabel("Sample Rate: "), 0, 0, 1, 1); + + audio_frequency_combobox = new QComboBox(groupBox_2); + audio_frequency_combobox->addItem("22050 Hz", 22050); + audio_frequency_combobox->addItem("24000 Hz", 24000); + audio_frequency_combobox->addItem("32000 Hz", 32000); + audio_frequency_combobox->addItem("44100 Hz", 44100); + audio_frequency_combobox->addItem("48000 Hz", 48000); + audio_frequency_combobox->addItem("88200 Hz", 88200); + audio_frequency_combobox->addItem("96000 Hz", 96000); + audio_frequency_combobox->setCurrentIndex(4); + + gridLayout_2->addWidget(audio_frequency_combobox, 0, 1, 1, 1); + + verticalLayout->addWidget(groupBox_2); + + QWidget* widget_2 = new QWidget(this); + QHBoxLayout* horizontalLayout = new QHBoxLayout(widget_2); + horizontalLayout->setContentsMargins(0, 0, 0, 0); + + horizontalLayout->addWidget(new QLabel("Name:")); + + lineEdit = new QLineEdit(widget_2); + + horizontalLayout->addWidget(lineEdit); + + verticalLayout->addWidget(widget_2); + + QDialogButtonBox* buttonBox = new QDialogButtonBox(this); + buttonBox->setOrientation(Qt::Horizontal); + buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + buttonBox->setCenterButtons(true); + + 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())); +} diff --git a/dialogs/newsequencedialog.h b/dialogs/newsequencedialog.h index d6b9b2a2d..1a5cf2042 100644 --- a/dialogs/newsequencedialog.h +++ b/dialogs/newsequencedialog.h @@ -5,32 +5,39 @@ class Project; class Media; +class QComboBox; +class QSpinBox; +class QLineEdit; struct Sequence; -namespace Ui { -class NewSequenceDialog; -} - class NewSequenceDialog : public QDialog { Q_OBJECT public: - explicit NewSequenceDialog(QWidget *parent = 0); + explicit NewSequenceDialog(QWidget *parent = 0, Media* existing = 0); ~NewSequenceDialog(); - Sequence* existing_sequence; - Media* existing_item; + void set_sequence_name(const QString& s); -protected: - void showEvent(QShowEvent *); - private slots: - void on_buttonBox_accepted(); - void on_comboBox_currentIndexChanged(int index); + void create(); + void preset_changed(int index); private: - Ui::NewSequenceDialog *ui; + Sequence* existing_sequence; + Media* existing_item; + + 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* lineEdit; }; #endif // NEWSEQUENCEDIALOG_H diff --git a/dialogs/newsequencedialog.ui b/dialogs/newsequencedialog.ui deleted file mode 100644 index 3a9663340..000000000 --- a/dialogs/newsequencedialog.ui +++ /dev/null @@ -1,370 +0,0 @@ - - - NewSequenceDialog - - - - 0 - 0 - 298 - 341 - - - - New Sequence - - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Preset: - - - - - - - 2 - - - - Film 4K - - - - - TV 4K (Ultra HD/2160p) - - - - - 1080p - - - - - 720p - - - - - 480p - - - - - 360p - - - - - 240p - - - - - 144p - - - - - NTSC (480i) - - - - - PAL (576i) - - - - - Custom - - - - - - - - - - - Video - - - - - - 9999 - - - 1080 - - - - - - - - 0 - 0 - - - - 9999 - - - 1920 - - - - - - - - 0 - 0 - - - - Width: - - - - - - - - 0 - 0 - - - - Pixel Aspect Ratio: - - - - - - - - 0 - 0 - - - - Interlacing: - - - - - - - Height: - - - - - - - - 0 - 0 - - - - - Square Pixels (1.0) - - - - - - - - - None (Progressive) - - - - - Upper Field First - - - - - Lower Field First - - - - - - - - - - - Frame Rate: - - - - - - - - - - - 0 - 0 - - - - Audio - - - - - - - 0 - 0 - - - - Sample Rate: - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Name: - - - - - - - Sequence 01 - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - true - - - - - - - comboBox - width_numeric - height_numeric - frame_rate_combobox - par_combobox - interlacing_combobox - audio_frequency_combobox - lineEdit - - - - - buttonBox - accepted() - NewSequenceDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - NewSequenceDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/dialogs/preferencesdialog.cpp b/dialogs/preferencesdialog.cpp index 81bd53211..ec0eb76f5 100644 --- a/dialogs/preferencesdialog.cpp +++ b/dialogs/preferencesdialog.cpp @@ -1,83 +1,163 @@ #include "preferencesdialog.h" -#include "ui_preferencesdialog.h" #include "io/config.h" #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -KeySequenceEditor::KeySequenceEditor(QAction* a) - : QKeySequenceEdit(0), action(a) { - setKeySequence(action->shortcut()); - connect(this, SIGNAL(editingFinished()), this, SLOT(set_action_shortcut())); +KeySequenceEditor::KeySequenceEditor(QWidget* parent, QAction* a) + : QKeySequenceEdit(parent), action(a) { + setKeySequence(action->shortcut()); + //connect(this, SIGNAL(editingFinished()), this, SLOT(set_action_shortcut())); } void KeySequenceEditor::set_action_shortcut() { - action->setShortcut(keySequence()); + action->setShortcut(keySequence()); } PreferencesDialog::PreferencesDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::PreferencesDialog) + QDialog(parent) { - ui->setupUi(this); + setWindowTitle("Preferences"); + setup_ui(); - ui->accurateSeekButton->setChecked(!config.fast_seeking); - ui->fastSeekButton->setChecked(config.fast_seeking); - ui->recordingComboBox->setCurrentIndex(config.recording_mode - 1); - ui->imgSeqFormatEdit->setText(config.img_seq_formats); + accurateSeekButton->setChecked(!config.fast_seeking); + fastSeekButton->setChecked(config.fast_seeking); + recordingComboBox->setCurrentIndex(config.recording_mode - 1); + imgSeqFormatEdit->setText(config.img_seq_formats); } -PreferencesDialog::~PreferencesDialog() { - delete ui; +PreferencesDialog::~PreferencesDialog() {} + +void PreferencesDialog::setup_kbd_shortcut_worker(QMenu* menu, QTreeWidgetItem* parent) { + QList actions = menu->actions(); + for (int i=0;iisSeparator()) { + QTreeWidgetItem* item = new QTreeWidgetItem(); + item->setText(0, a->text().replace("&", "")); + + parent->addChild(item); + + if (a->menu() != NULL) { + setup_kbd_shortcut_worker(a->menu(), item); + } else { + key_shortcut_items.append(item); + key_shortcut_actions.append(a); + } + } + } } void PreferencesDialog::setup_kbd_shortcuts(QMenuBar* menubar) { - ui->treeWidget->clear(); - QList menus = menubar->findChildren(); + QList menus = menubar->actions(); - // caching for parent-child pairing - QVector added_action_items; - QVector added_actions; + for (int i=0;imenu(); - for (int i=0;iparent() != menubar) { - for (int j=0;jmenu() == menu) { - item = added_action_items.at(j); - break; - } - } - } - if (menu->parent() == menubar || item == NULL) { - item = new QTreeWidgetItem(); - item->setText(0, menu->title().replace("&", "")); - ui->treeWidget->addTopLevelItem(item); - } - for (int j=0;jactions().size();j++) { - QAction* action = menu->actions().at(j); - if (!action->isSeparator()) { - QTreeWidgetItem* child = new QTreeWidgetItem(); - child->setText(0, action->text().replace("&", "")); - item->addChild(child); + QTreeWidgetItem* item = new QTreeWidgetItem(); + item->setText(0, menu->title().replace("&", "")); - added_actions.append(action); - added_action_items.append(child); - } - } - } - for (int i=0;imenu() == NULL) { - KeySequenceEditor* editor = new KeySequenceEditor(added_actions.at(i)); - ui->treeWidget->setItemWidget(added_action_items.at(i), 1, editor); - } - } + keyboard_tree->addTopLevelItem(item); + + setup_kbd_shortcut_worker(menu, item); + } + + for (int i=0;isetItemWidget(key_shortcut_items.at(i), 1, editor); + key_shortcut_fields.append(editor); + } } -void PreferencesDialog::on_buttonBox_accepted() { - config.recording_mode = ui->recordingComboBox->currentIndex() + 1; - config.img_seq_formats = ui->imgSeqFormatEdit->text(); - config.fast_seeking = ui->fastSeekButton->isChecked(); +void PreferencesDialog::save() { + config.recording_mode = recordingComboBox->currentIndex() + 1; + config.img_seq_formats = imgSeqFormatEdit->text(); + config.fast_seeking = fastSeekButton->isChecked(); + + // save keyboard shortcuts + for (int i=0;iset_action_shortcut(); + } + + accept(); +} + +void PreferencesDialog::setup_ui() { + QVBoxLayout* verticalLayout = new QVBoxLayout(this); + QTabWidget* tabWidget = new QTabWidget(this); + + QTabWidget* tab = new QTabWidget(); + QGridLayout* gridLayout_2 = new QGridLayout(tab); + + gridLayout_2->addWidget(new QLabel("Image sequence formats:"), 0, 0, 1, 1); + + imgSeqFormatEdit = new QLineEdit(tab); + + gridLayout_2->addWidget(imgSeqFormatEdit, 0, 1, 1, 1); + + gridLayout_2->addWidget(new QLabel("Audio Recording:"), 1, 0, 1, 1); + + recordingComboBox = new QComboBox(tab); + recordingComboBox->addItem("Mono"); + recordingComboBox->addItem("Stereo"); + + gridLayout_2->addWidget(recordingComboBox, 1, 1, 1, 1); + + tabWidget->addTab(tab, "General"); + QWidget* tab_2 = new QWidget(); + tabWidget->addTab(tab_2, "Behavior"); + QWidget* tab_4 = new QWidget(); + QVBoxLayout* verticalLayout_2 = new QVBoxLayout(tab_4); + QGroupBox* groupBox = new QGroupBox(tab_4); + groupBox->setTitle("Seeking"); + QVBoxLayout* verticalLayout_3 = new QVBoxLayout(groupBox); + accurateSeekButton = new QRadioButton(groupBox); + accurateSeekButton->setText("Accurate Seeking\nAlways show the correct frame (visual may pause briefly as correct frame is retrieved)"); + + verticalLayout_3->addWidget(accurateSeekButton); + + fastSeekButton = new QRadioButton(groupBox); + fastSeekButton->setText("Fast Seeking\nSeek quickly (may briefly show inaccurate frames when seeking - doesn't affect playback/export)"); + + verticalLayout_3->addWidget(fastSeekButton); + + verticalLayout_2->addWidget(groupBox); + + tabWidget->addTab(tab_4, "Playback"); + QWidget* tab_3 = new QWidget(); + QHBoxLayout* horizontalLayout = new QHBoxLayout(tab_3); + horizontalLayout->setContentsMargins(0, 0, 0, 0); + + keyboard_tree = new QTreeWidget(); + QTreeWidgetItem* tree_header = keyboard_tree->headerItem(); + tree_header->setText(0, "Action"); + tree_header->setText(1, "Shortcut"); + horizontalLayout->addWidget(keyboard_tree); + + tabWidget->addTab(tab_3, "Keyboard"); + + verticalLayout->addWidget(tabWidget); + + QDialogButtonBox* buttonBox = new QDialogButtonBox(this); + buttonBox->setOrientation(Qt::Horizontal); + buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + + verticalLayout->addWidget(buttonBox); + + connect(buttonBox, SIGNAL(accepted()), this, SLOT(save())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + tabWidget->setCurrentIndex(2); } diff --git a/dialogs/preferencesdialog.h b/dialogs/preferencesdialog.h index 012f9b17a..b0560a247 100644 --- a/dialogs/preferencesdialog.h +++ b/dialogs/preferencesdialog.h @@ -4,36 +4,48 @@ #include #include class QMenuBar; +class QLineEdit; +class QComboBox; +class QRadioButton; +class QTreeWidget; +class QTreeWidgetItem; +class QMenu; -namespace Ui { -class PreferencesDialog; -} +class KeySequenceEditor : public QKeySequenceEdit { + Q_OBJECT +public: + KeySequenceEditor(QWidget *parent, QAction* a); + void set_action_shortcut(); +private: + QAction* action; +}; class PreferencesDialog : public QDialog { - Q_OBJECT + Q_OBJECT public: - explicit PreferencesDialog(QWidget *parent = 0); - ~PreferencesDialog(); + explicit PreferencesDialog(QWidget *parent = 0); + ~PreferencesDialog(); - void setup_kbd_shortcuts(QMenuBar* menu); + void setup_kbd_shortcuts(QMenuBar* menu); private slots: - void on_buttonBox_accepted(); + void save(); private: - Ui::PreferencesDialog *ui; -}; + void setup_ui(); + void setup_kbd_shortcut_worker(QMenu* menu, QTreeWidgetItem* parent); -class KeySequenceEditor : public QKeySequenceEdit { - Q_OBJECT -public: - KeySequenceEditor(QAction* a); -private slots: - void set_action_shortcut(); -private: - QAction* action; + QLineEdit* imgSeqFormatEdit; + QComboBox* recordingComboBox; + QRadioButton* accurateSeekButton; + QRadioButton* fastSeekButton; + QTreeWidget* keyboard_tree; + + QVector key_shortcut_actions; + QVector key_shortcut_items; + QVector key_shortcut_fields; }; #endif // PREFERENCESDIALOG_H diff --git a/dialogs/preferencesdialog.ui b/dialogs/preferencesdialog.ui deleted file mode 100644 index 814d3b4aa..000000000 --- a/dialogs/preferencesdialog.ui +++ /dev/null @@ -1,179 +0,0 @@ - - - PreferencesDialog - - - - 0 - 0 - 693 - 491 - - - - Dialog - - - - - - 2 - - - - General - - - - - - Image sequence formats: - - - - - - - - - - Audio Recording: - - - - - - - - Mono - - - - - Stereo - - - - - - - - - Behavior - - - - - Playback - - - - - - Seeking - - - - - - Accurate Seeking -Always show the correct frame (visual may pause briefly as correct frame is retrieved) - - - - - - - Fast Seeking -Seek quickly (may briefly show inaccurate frames when seeking - doesn't affect playback/export) - - - - - - - - - - - Keyboard - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - Action - - - - - Shortcut - - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - PreferencesDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - PreferencesDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/dialogs/replaceclipmediadialog.cpp b/dialogs/replaceclipmediadialog.cpp index e8732164f..c1f042f22 100644 --- a/dialogs/replaceclipmediadialog.cpp +++ b/dialogs/replaceclipmediadialog.cpp @@ -19,9 +19,8 @@ #include #include -ReplaceClipMediaDialog::ReplaceClipMediaDialog(QWidget *parent, SourceTable *table, Media *old_media) : +ReplaceClipMediaDialog::ReplaceClipMediaDialog(QWidget *parent, Media *old_media) : QDialog(parent), - source_table(table), media(old_media) { resize(300, 400); @@ -30,11 +29,11 @@ ReplaceClipMediaDialog::ReplaceClipMediaDialog(QWidget *parent, SourceTable *tab layout->addWidget(new QLabel("Select which media you want to replace this media's clips with:")); - tree = new QTreeView(); + tree = new QTreeView(); layout->addWidget(tree); - use_same_media_in_points = new QCheckBox("Keep the same media in-points"); + use_same_media_in_points = new QCheckBox("Keep the same media in-points"); use_same_media_in_points->setChecked(true); layout->addWidget(use_same_media_in_points); @@ -56,34 +55,34 @@ ReplaceClipMediaDialog::ReplaceClipMediaDialog(QWidget *parent, SourceTable *tab setLayout(layout); - tree->setModel(&project_model); + tree->setModel(&project_model); - //copy_tree(NULL, NULL); + //copy_tree(NULL, NULL); } void ReplaceClipMediaDialog::replace() { - QModelIndexList selected_items = tree->selectionModel()->selectedRows(); - if (selected_items.size() != 1) { + QModelIndexList selected_items = panel_project->get_current_selected(); + if (selected_items.size() != 1) { QMessageBox::critical(this, "No media selected", "Please select a media to replace with or click 'Cancel'.", QMessageBox::Ok); } else { - Media* new_item = static_cast(selected_items.at(0).internalPointer()); + Media* new_item = static_cast(selected_items.at(0).internalPointer()); if (media == new_item) { QMessageBox::critical(this, "Same media selected", "You selected the same media that you're replacing. Please select a different one or click 'Cancel'.", QMessageBox::Ok); - } else if (new_item->get_type() == MEDIA_TYPE_FOLDER) { + } else if (new_item->get_type() == MEDIA_TYPE_FOLDER) { QMessageBox::critical(this, "Folder selected", "You cannot replace footage with a folder.", QMessageBox::Ok); } else { - if (new_item->get_type() == MEDIA_TYPE_SEQUENCE && sequence == new_item->to_sequence()) { + if (new_item->get_type() == MEDIA_TYPE_SEQUENCE && sequence == new_item->to_sequence()) { QMessageBox::critical(this, "Active sequence selected", "You cannot insert a sequence into itself.", QMessageBox::Ok); - } else { + } else { ReplaceClipMediaCommand* rcmc = new ReplaceClipMediaCommand( - media, - new_item, + media, + new_item, use_same_media_in_points->isChecked() ); - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL && c->media == media) { + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL && c->media == media) { rcmc->clips.append(c); } } diff --git a/dialogs/replaceclipmediadialog.h b/dialogs/replaceclipmediadialog.h index 15498336b..114d6fb9d 100644 --- a/dialogs/replaceclipmediadialog.h +++ b/dialogs/replaceclipmediadialog.h @@ -11,14 +11,13 @@ class QCheckBox; class ReplaceClipMediaDialog : public QDialog { Q_OBJECT public: - ReplaceClipMediaDialog(QWidget* parent, SourceTable* table, Media *old_media); + ReplaceClipMediaDialog(QWidget* parent, Media *old_media); private slots: void replace(); private: - SourceTable* source_table; - QTreeView* tree; - Media* media; - QCheckBox* use_same_media_in_points; + Media* media; + QTreeView* tree; + QCheckBox* use_same_media_in_points; }; #endif // REPLACECLIPMEDIADIALOG_H diff --git a/dialogs/speeddialog.cpp b/dialogs/speeddialog.cpp index 0efcb45d1..c48baacd3 100644 --- a/dialogs/speeddialog.cpp +++ b/dialogs/speeddialog.cpp @@ -84,12 +84,12 @@ void SpeedDialog::run() { clip_percent = c->speed; if (c->track < 0) { bool process_video = true; - if (c->media != NULL && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { - Footage* m = c->media->to_footage(); - FootageStream* ms = m->get_stream_from_file_index(true, c->media_stream); - if (ms != NULL && ms->infinite_length) { - process_video = false; - } + if (c->media != NULL && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { + Footage* m = c->media->to_footage(); + FootageStream* ms = m->get_stream_from_file_index(true, c->media_stream); + if (ms != NULL && ms->infinite_length) { + process_video = false; + } } if (process_video) { @@ -313,7 +313,7 @@ void set_speed(ComboAction* ca, Clip* c, double speed, bool ripple, long& ep, lo } ep = qMin(ep, c->timeline_out); lr = qMax(lr, proposed_out - c->timeline_out); - move_clip(ca, c, c->timeline_in, proposed_out, c->clip_in * multiplier, c->track); + move_clip(ca, c, c->timeline_in, proposed_out, c->clip_in * multiplier, c->track); c->refactor_frame_rate(ca, multiplier, false); @@ -345,7 +345,7 @@ void SpeedDialog::accept() { if (reverse->checkState() != Qt::PartiallyChecked && c->reverse != reverse->isChecked()) { long new_clip_in = (c->getMaximumLength() - (c->getLength() + c->clip_in)); - move_clip(ca, c, c->timeline_in, c->timeline_out, new_clip_in, c->track); + move_clip(ca, c, c->timeline_in, c->timeline_out, new_clip_in, c->track); c->clip_in = new_clip_in; ca->append(new SetBool(&c->reverse, reverse->isChecked())); } @@ -398,7 +398,7 @@ void SpeedDialog::accept() { } if (ripple->isChecked()) { - ca->append(new RippleCommand(clips.at(0)->sequence, earliest_point, longest_ripple)); + ripple_clips(ca, clips.at(0)->sequence, earliest_point, longest_ripple); } sel_command->new_data = sequence->selections; diff --git a/io/clipboard.cpp b/io/clipboard.cpp index b02761d5e..8a699e379 100644 --- a/io/clipboard.cpp +++ b/io/clipboard.cpp @@ -5,14 +5,18 @@ int clipboard_type = CLIPBOARD_TYPE_CLIP; QVector clipboard; +QVector clipboard_transitions; void clear_clipboard() { - for (int i=0;i(clipboard.at(i)); - } else if (clipboard_type == CLIPBOARD_TYPE_EFFECT) { - delete static_cast(clipboard.at(i)); - } - } - clipboard.clear(); + for (int i=0;i(clipboard.at(i)); + } else if (clipboard_type == CLIPBOARD_TYPE_EFFECT) { + delete static_cast(clipboard.at(i)); + } + } + for (int i=0;clipboard_transitions.size();i++) { + delete clipboard_transitions.at(i); + } + clipboard.clear(); } diff --git a/io/clipboard.h b/io/clipboard.h index d76b7fa59..700841e95 100644 --- a/io/clipboard.h +++ b/io/clipboard.h @@ -3,10 +3,13 @@ #include +class Transition; + #define CLIPBOARD_TYPE_CLIP 0 #define CLIPBOARD_TYPE_EFFECT 1 extern int clipboard_type; +extern QVector clipboard_transitions; extern QVector clipboard; void clear_clipboard(); diff --git a/mainwindow.cpp b/mainwindow.cpp index 738e7c9b6..f84212d13 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,5 +1,4 @@ #include "mainwindow.h" -#include "ui_mainwindow.h" #include "io/config.h" #include "io/path.h" @@ -12,6 +11,8 @@ #include "ui/sourcetable.h" #include "ui/viewerwidget.h" +#include "ui/sourceiconview.h" +#include "ui/timelineheader.h" #include "panels/panels.h" #include "panels/project.h" @@ -29,8 +30,6 @@ #include "playback/audio.h" #include "playback/playback.h" -#include "ui_timeline.h" - #include "debug.h" #include @@ -41,6 +40,13 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include MainWindow* mainWindow; @@ -52,44 +58,43 @@ QString appName = "Olive (December 2018 | Alpha)"; bool demoNoticeShown = false; void MainWindow::setup_layout(bool reset) { - panel_project->show(); - panel_effect_controls->show(); - panel_footage_viewer->show(); - panel_sequence_viewer->show(); - panel_timeline->show(); + panel_project->show(); + panel_effect_controls->show(); + panel_footage_viewer->show(); + panel_sequence_viewer->show(); + panel_timeline->show(); - bool load_default = true; + bool load_default = true; - /*if (!reset) { - QFile panel_config(get_data_path() + "/layout"); - if (panel_config.exists() && panel_config.open(QFile::ReadOnly)) { - if (restoreState(panel_config.readAll(), 0)) { - load_default = false; - } - panel_config.close(); - } - }*/ + /*if (!reset) { + QFile panel_config(get_data_path() + "/layout"); + if (panel_config.exists() && panel_config.open(QFile::ReadOnly)) { + if (restoreState(panel_config.readAll(), 0)) { + load_default = false; + } + panel_config.close(); + } + }*/ - if (load_default) { - addDockWidget(Qt::TopDockWidgetArea, panel_project); - addDockWidget(Qt::TopDockWidgetArea, panel_footage_viewer); - tabifyDockWidget(panel_footage_viewer, panel_effect_controls); - panel_footage_viewer->raise(); - addDockWidget(Qt::TopDockWidgetArea, panel_sequence_viewer); - addDockWidget(Qt::BottomDockWidgetArea, panel_timeline); + if (load_default) { + addDockWidget(Qt::TopDockWidgetArea, panel_project); + addDockWidget(Qt::TopDockWidgetArea, panel_footage_viewer); + tabifyDockWidget(panel_footage_viewer, panel_effect_controls); + panel_footage_viewer->raise(); + addDockWidget(Qt::TopDockWidgetArea, panel_sequence_viewer); + addDockWidget(Qt::BottomDockWidgetArea, panel_timeline); // workaround for strange Qt dock bug (see https://bugreports.qt.io/browse/QTBUG-65592) #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) - resizeDocks({panel_project}, {40}, Qt::Horizontal); + resizeDocks({panel_project}, {40}, Qt::Horizontal); #endif - } + } - layout()->update(); + layout()->update(); } MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), - ui(new Ui::MainWindow) + QMainWindow(parent) { setup_debug(); @@ -98,14 +103,14 @@ MainWindow::MainWindow(QWidget *parent) : // set up style? qApp->setStyle(QStyleFactory::create("Fusion")); - setStyleSheet("QPushButton::checked { background: rgb(25, 25, 25); }"); + setStyleSheet("QPushButton::checked { background: rgb(25, 25, 25); }"); QPalette darkPalette; - darkPalette.setColor(QPalette::Window, QColor(53,53,53)); + darkPalette.setColor(QPalette::Window, QColor(53,53,53)); darkPalette.setColor(QPalette::WindowText, Qt::white); darkPalette.setColor(QPalette::Base, QColor(25,25,25)); darkPalette.setColor(QPalette::AlternateBase, QColor(53,53,53)); - darkPalette.setColor(QPalette::ToolTipBase, QColor(25,25,25)); + darkPalette.setColor(QPalette::ToolTipBase, QColor(25,25,25)); darkPalette.setColor(QPalette::ToolTipText, Qt::white); darkPalette.setColor(QPalette::Text, Qt::white); darkPalette.setColor(QPalette::Button, QColor(53,53,53)); @@ -113,38 +118,32 @@ MainWindow::MainWindow(QWidget *parent) : darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(128, 128, 128)); darkPalette.setColor(QPalette::Link, QColor(42, 130, 218)); darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218)); - darkPalette.setColor(QPalette::HighlightedText, Qt::black); + darkPalette.setColor(QPalette::HighlightedText, Qt::black); qApp->setPalette(darkPalette); // end style - ui->setupUi(this); + QWidget* centralWidget = new QWidget(this); + centralWidget->setMaximumSize(QSize(0, 0)); + setCentralWidget(centralWidget); - setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); + setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); updateTitle(""); - statusBar()->showMessage("Welcome to " + appName); - - setDockNestingEnabled(true); + setDockNestingEnabled(true); layout()->invalidate(); - connect(ui->menuWindow, SIGNAL(aboutToShow()), this, SLOT(windowMenu_About_To_Be_Shown())); - connect(ui->menu_View, SIGNAL(aboutToShow()), this, SLOT(viewMenu_About_To_Be_Shown())); - connect(ui->menu_Tools, SIGNAL(aboutToShow()), this, SLOT(toolMenu_About_To_Be_Shown())); - connect(ui->menuEdit, SIGNAL(aboutToShow()), this, SLOT(editMenu_About_To_Be_Shown())); - connect(ui->menu_File, SIGNAL(aboutToShow()), this, SLOT(fileMenu_About_To_Be_Shown())); - - QString data_dir = get_data_path(); - if (!data_dir.isEmpty()) { - QDir dir(data_dir); - dir.mkpath("."); - if (dir.exists()) { + QString data_dir = get_data_path(); + if (!data_dir.isEmpty()) { + QDir dir(data_dir); + dir.mkpath("."); + if (dir.exists()) { qint64 a_month_ago = QDateTime::currentMSecsSinceEpoch() - 2592000000; qint64 a_week_ago = QDateTime::currentMSecsSinceEpoch() - 604800000; - // TODO put delete functions in another thread? + // TODO put delete functions in another thread? // delete auto-recoveries older than 7 days QStringList old_autorecoveries = dir.entryList(QStringList("autorecovery.ove.*"), QDir::Files); @@ -171,61 +170,59 @@ MainWindow::MainWindow(QWidget *parent) : } } if (deleted_ars > 0) dout << "[INFO] Deleted" << deleted_ars << "preview" << ((deleted_ars == 1) ? "file that was" : "files that were") << "last read over 30 days ago"; - } + } - // search for open recents list - recent_proj_file = data_dir + "/recents"; - QFile f(recent_proj_file); - if (f.exists() && f.open(QFile::ReadOnly | QFile::Text)) { - QTextStream text_stream(&f); - while (true) { - QString line = text_stream.readLine(); - if (line.isNull()) { - break; - } else { - recent_projects.append(line); - } - } - f.close(); - } + // search for open recents list + recent_proj_file = data_dir + "/recents"; + QFile f(recent_proj_file); + if (f.exists() && f.open(QFile::ReadOnly | QFile::Text)) { + QTextStream text_stream(&f); + while (true) { + QString line = text_stream.readLine(); + if (line.isNull()) { + break; + } else { + recent_projects.append(line); + } + } + f.close(); + } - config_dir = data_dir + "/config.xml"; - config.load(config_dir); - } - } + config_dir = data_dir + "/config.xml"; + config.load(config_dir); + } + } - // TODO maybe replace these with non-pointers later on? - panel_sequence_viewer = new Viewer(this); - panel_footage_viewer = new Viewer(this); - panel_project = new Project(this); - panel_effect_controls = new EffectControls(this); - panel_timeline = new Timeline(this); + // TODO maybe replace these with non-pointers later on? + panel_sequence_viewer = new Viewer(this); + panel_footage_viewer = new Viewer(this); + panel_project = new Project(this); + panel_effect_controls = new EffectControls(this); + panel_timeline = new Timeline(this); - if (!data_dir.isEmpty()) { - // detect auto-recovery file - autorecovery_filename = data_dir + "/autorecovery.ove"; - if (QFile::exists(autorecovery_filename)) { - if (QMessageBox::question(NULL, "Auto-recovery", "Olive didn't close properly and an autorecovery file was detected. Would you like to open it?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { - updateTitle(autorecovery_filename); - panel_project->load_project(true); - } - } - autorecovery_timer.setInterval(60000); - QObject::connect(&autorecovery_timer, SIGNAL(timeout()), this, SLOT(autorecover_interval())); - autorecovery_timer.start(); - } + QStatusBar* statusBar = new QStatusBar(this); + statusBar->showMessage("Welcome to " + appName); + setStatusBar(statusBar); - setup_layout(false); + setup_menus(); - init_audio(); + if (!data_dir.isEmpty()) { + // detect auto-recovery file + autorecovery_filename = data_dir + "/autorecovery.ove"; + if (QFile::exists(autorecovery_filename)) { + if (QMessageBox::question(NULL, "Auto-recovery", "Olive didn't close properly and an autorecovery file was detected. Would you like to open it?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { + updateTitle(autorecovery_filename); + panel_project->load_project(true); + } + } + autorecovery_timer.setInterval(60000); + QObject::connect(&autorecovery_timer, SIGNAL(timeout()), this, SLOT(autorecover_interval())); + autorecovery_timer.start(); + } - connect(ui->action_Undo, SIGNAL(triggered(bool)), this, SLOT(undo())); - connect(ui->action_Redo, SIGNAL(triggered(bool)), this, SLOT(redo())); - connect(ui->actionCu_t, SIGNAL(triggered(bool)), this, SLOT(cut())); - connect(ui->actionCop_y, SIGNAL(triggered(bool)), this, SLOT(copy())); - connect(ui->action_Paste, SIGNAL(triggered(bool)), this, SLOT(paste())); - connect(ui->actionProject, SIGNAL(triggered(bool)), this, SLOT(new_project())); - connect(ui->actionFull_Screen, SIGNAL(triggered(bool)), this, SLOT(toggle_full_screen())); + setup_layout(false); + + init_audio(); } MainWindow::~MainWindow() { @@ -235,148 +232,128 @@ MainWindow::~MainWindow() { set_sequence(NULL); - QString data_dir = get_data_path(); - if (!data_dir.isEmpty() && !autorecovery_filename.isEmpty()) { - if (QFile::exists(autorecovery_filename)) { - QFile::rename(autorecovery_filename, autorecovery_filename + "." + QDateTime::currentDateTimeUtc().toString("yyyyMMddHHmmss")); - } - } - if (!config_dir.isEmpty()) { - // save settings - config.save(config_dir); + QString data_dir = get_data_path(); + if (!data_dir.isEmpty() && !autorecovery_filename.isEmpty()) { + if (QFile::exists(autorecovery_filename)) { + QFile::rename(autorecovery_filename, autorecovery_filename + "." + QDateTime::currentDateTimeUtc().toString("yyyyMMddHHmmss")); + } + } + if (!config_dir.isEmpty()) { + // save settings + config.save(config_dir); - // save panel layout - QFile panel_config(data_dir + "/layout"); - if (panel_config.open(QFile::WriteOnly)) { - panel_config.write(saveState(0)); - panel_config.close(); - } else { - dout << "[ERROR] Failed to save layout"; - } - } + // save panel layout + QFile panel_config(data_dir + "/layout"); + if (panel_config.open(QFile::WriteOnly)) { + panel_config.write(saveState(0)); + panel_config.close(); + } else { + dout << "[ERROR] Failed to save layout"; + } + } stop_audio(); - delete ui; - - delete panel_sequence_viewer; - panel_sequence_viewer = NULL; - delete panel_footage_viewer; - panel_footage_viewer = NULL; - delete panel_project; - panel_project = NULL; - delete panel_effect_controls; - panel_effect_controls = NULL; + delete panel_sequence_viewer; + panel_sequence_viewer = NULL; + delete panel_footage_viewer; + panel_footage_viewer = NULL; + delete panel_project; + panel_project = NULL; + delete panel_effect_controls; + panel_effect_controls = NULL; delete panel_timeline; - panel_timeline = NULL; + panel_timeline = NULL; close_debug(); } -void MainWindow::on_action_Import_triggered() -{ - panel_project->import_dialog(); +void MainWindow::make_new_menu(QMenu *parent) { + parent->addAction("&Project", this, SLOT(new_project()), QKeySequence("Ctrl+N")); + parent->addSeparator(); + parent->addAction("&Sequence", this, SLOT(new_sequence()), QKeySequence("Ctrl+Shift+N")); + parent->addAction("&Folder", this, SLOT(new_folder())); } -void MainWindow::on_actionExit_triggered() -{ - close(); +void MainWindow::make_inout_menu(QMenu *parent) { + parent->addAction("Set In Point", this, SLOT(set_in_point()), QKeySequence("I")); + parent->addAction("Set Out Point", this, SLOT(set_out_point()), QKeySequence("O")); + parent->addAction("Clear In/Out Point", this, SLOT(clear_inout()), QKeySequence("G")); } -void MainWindow::on_actionAbout_triggered() -{ +void MainWindow::show_about() { AboutDialog a(this); a.exec(); } -void MainWindow::on_actionDelete_triggered() -{ - if (panel_timeline->ui->headers->hasFocus()) { - panel_timeline->ui->headers->delete_markers(); +void MainWindow::delete_slot() { + if (panel_timeline->headers->hasFocus()) { + panel_timeline->headers->delete_markers(); } else if (panel_timeline->focused()) { panel_timeline->delete_selection(sequence->selections, false); - } else if (panel_effect_controls->is_focused()) { - panel_effect_controls->delete_effects(); - } else if (panel_project->is_focused()) { - panel_project->delete_selected_media(); + } else if (panel_effect_controls->is_focused()) { + panel_effect_controls->delete_effects(); + } else if (panel_project->is_focused()) { + panel_project->delete_selected_media(); } else if (panel_effect_controls->keyframe_focus()) { panel_effect_controls->delete_selected_keyframes(); } } -void MainWindow::on_actionSelect_All_triggered() -{ +void MainWindow::select_all() { if (panel_timeline->focused()) { panel_timeline->select_all(); } } -void MainWindow::on_actionSequence_triggered() -{ - NewSequenceDialog nsd(this); +void MainWindow::new_sequence() { + NewSequenceDialog nsd(this); nsd.set_sequence_name(panel_project->get_next_sequence_name()); nsd.exec(); } -void MainWindow::on_actionZoom_In_triggered() { - QDockWidget* focused_panel = get_focused_panel(); - if (focused_panel == panel_timeline) { - panel_timeline->set_zoom(true); - } else if (focused_panel == panel_effect_controls) { +void MainWindow::zoom_in() { + QDockWidget* focused_panel = get_focused_panel(); + if (focused_panel == panel_timeline) { + panel_timeline->set_zoom(true); + } else if (focused_panel == panel_effect_controls) { panel_effect_controls->set_zoom(true); - } else if (focused_panel == panel_footage_viewer) { - panel_footage_viewer->set_zoom(true); - } else if (focused_panel == panel_sequence_viewer) { - panel_sequence_viewer->set_zoom(true); - } + } else if (focused_panel == panel_footage_viewer) { + panel_footage_viewer->set_zoom(true); + } else if (focused_panel == panel_sequence_viewer) { + panel_sequence_viewer->set_zoom(true); + } } -void MainWindow::on_actionZoom_out_triggered() { - QDockWidget* focused_panel = get_focused_panel(); - if (focused_panel == panel_timeline) { - panel_timeline->set_zoom(false); - } else if (focused_panel == panel_effect_controls) { +void MainWindow::zoom_out() { + QDockWidget* focused_panel = get_focused_panel(); + if (focused_panel == panel_timeline) { + panel_timeline->set_zoom(false); + } else if (focused_panel == panel_effect_controls) { panel_effect_controls->set_zoom(false); - } else if (focused_panel == panel_footage_viewer) { - panel_footage_viewer->set_zoom(false); - } else if (focused_panel == panel_sequence_viewer) { - panel_sequence_viewer->set_zoom(false); - } + } else if (focused_panel == panel_footage_viewer) { + panel_footage_viewer->set_zoom(false); + } else if (focused_panel == panel_sequence_viewer) { + panel_sequence_viewer->set_zoom(false); + } } -void MainWindow::on_actionExport_triggered() { - if (sequence == NULL) { - QMessageBox::information(this, "No active sequence", "Please open the sequence you wish to export.", QMessageBox::Ok); - } else { - ExportDialog e(this); - e.exec(); - } +void MainWindow::export_dialog() { + if (sequence == NULL) { + QMessageBox::information(this, "No active sequence", "Please open the sequence you wish to export.", QMessageBox::Ok); + } else { + ExportDialog e(this); + e.exec(); + } } -void MainWindow::on_actionProject_2_triggered() { - panel_project->setVisible(!panel_project->isVisible()); -} - -void MainWindow::on_actionEffect_Controls_triggered() { - panel_effect_controls->setVisible(!panel_effect_controls->isVisible()); -} - -void MainWindow::on_actionViewer_triggered() { - panel_sequence_viewer->setVisible(!panel_sequence_viewer->isVisible()); -} - -void MainWindow::on_actionTimeline_triggered() { - panel_timeline->setVisible(!panel_timeline->isVisible()); -} - -void MainWindow::on_actionRipple_Delete_triggered() -{ +void MainWindow::ripple_delete() { panel_timeline->delete_selection(sequence->selections, true); } void MainWindow::editMenu_About_To_Be_Shown() { - ui->action_Undo->setEnabled(undo_stack.canUndo()); - ui->action_Redo->setEnabled(undo_stack.canRedo()); + undo_action->setEnabled(undo_stack.canUndo()); + redo_action->setEnabled(undo_stack.canRedo()); } void MainWindow::undo() { @@ -391,12 +368,12 @@ void MainWindow::redo() { update_ui(true); } -void MainWindow::openSpeedDialog() { +void MainWindow::open_speed_dialog() { if (sequence != NULL) { SpeedDialog s(this); for (int i=0;iclips.size();i++) { Clip* c = sequence->clips.at(i); - if (c != NULL && panel_timeline->is_clip_selected(c, true)) { + if (c != NULL && panel_timeline->is_clip_selected(c, true)) { s.clips.append(c); } } @@ -405,111 +382,429 @@ void MainWindow::openSpeedDialog() { } void MainWindow::cut() { - if (sequence != NULL) { - QDockWidget* focused_panel = get_focused_panel(); - if (panel_timeline == focused_panel) { - panel_timeline->copy(true); - } else if (panel_effect_controls == focused_panel) { - panel_effect_controls->copy(true); - } - } + if (sequence != NULL) { + QDockWidget* focused_panel = get_focused_panel(); + if (panel_timeline == focused_panel) { + panel_timeline->copy(true); + } else if (panel_effect_controls == focused_panel) { + panel_effect_controls->copy(true); + } + } } void MainWindow::copy() { - if (sequence != NULL) { - QDockWidget* focused_panel = get_focused_panel(); - if (panel_timeline == focused_panel) { - panel_timeline->copy(false); - } else if (panel_effect_controls == focused_panel) { - panel_effect_controls->copy(false); - } - } + if (sequence != NULL) { + QDockWidget* focused_panel = get_focused_panel(); + if (panel_timeline == focused_panel) { + panel_timeline->copy(false); + } else if (panel_effect_controls == focused_panel) { + panel_effect_controls->copy(false); + } + } } void MainWindow::paste() { - QDockWidget* focused_panel = get_focused_panel(); - if ((panel_timeline == focused_panel || panel_effect_controls == focused_panel) && sequence != NULL) { - panel_timeline->paste(false); - } + QDockWidget* focused_panel = get_focused_panel(); + if ((panel_timeline == focused_panel || panel_effect_controls == focused_panel) && sequence != NULL) { + panel_timeline->paste(false); + } } void MainWindow::new_project() { - if (can_close_project()) { - panel_effect_controls->clear_effects(true); - undo_stack.clear(); - project_url.clear(); - panel_project->new_project(); - updateTitle(""); - update_ui(false); - panel_project->tree_view->update(); - } -} - -void MainWindow::on_actionSplit_at_Playhead_triggered() { - if (panel_timeline->focused()) { - panel_timeline->split_at_playhead(); - } + if (can_close_project()) { + panel_effect_controls->clear_effects(true); + undo_stack.clear(); + project_url.clear(); + panel_project->new_project(); + updateTitle(""); + update_ui(false); + panel_project->tree_view->update(); + } } void MainWindow::autorecover_interval() { - if (!rendering && isWindowModified()) { - panel_project->save_project(true); + if (!rendering && isWindowModified()) { + panel_project->save_project(true); dout << "[INFO] Auto-recovery project saved"; - } + } } bool MainWindow::save_project_as() { - QString fn = QFileDialog::getSaveFileName(this, "Save Project As...", "", OLIVE_FILE_FILTER); - if (!fn.isEmpty()) { - if (!fn.endsWith(".ove", Qt::CaseInsensitive)) { - fn += ".ove"; - } + QString fn = QFileDialog::getSaveFileName(this, "Save Project As...", "", OLIVE_FILE_FILTER); + if (!fn.isEmpty()) { + if (!fn.endsWith(".ove", Qt::CaseInsensitive)) { + fn += ".ove"; + } updateTitle(fn); - panel_project->save_project(false); - return true; - } - return false; + panel_project->save_project(false); + return true; + } + return false; } bool MainWindow::save_project() { - if (project_url.isEmpty()) { - return save_project_as(); - } else { - panel_project->save_project(false); - return true; - } + if (project_url.isEmpty()) { + return save_project_as(); + } else { + panel_project->save_project(false); + return true; + } } bool MainWindow::can_close_project() { if (isWindowModified()) { - QMessageBox* m = new QMessageBox( - QMessageBox::Question, - "Unsaved Project", - "This project has changed since it was last saved. Would you like to save it before closing?", - QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel, - this - ); - m->setWindowModality(Qt::WindowModal); - int r = m->exec(); - if (r == QMessageBox::Yes) { - return save_project(); - } else if (r == QMessageBox::Cancel) { - return false; - } - } + QMessageBox* m = new QMessageBox( + QMessageBox::Question, + "Unsaved Project", + "This project has changed since it was last saved. Would you like to save it before closing?", + QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel, + this + ); + m->setWindowModality(Qt::WindowModal); + int r = m->exec(); + if (r == QMessageBox::Yes) { + return save_project(); + } else if (r == QMessageBox::Cancel) { + return false; + } + } return true; } +void MainWindow::setup_menus() { + QMenuBar* menuBar = new QMenuBar(this); + setMenuBar(menuBar); + + // INITIALIZE FILE MENU + + QMenu* file_menu = menuBar->addMenu("&File"); + connect(file_menu, SIGNAL(aboutToShow()), this, SLOT(fileMenu_About_To_Be_Shown())); + + QMenu* new_menu = file_menu->addMenu("&New"); + make_new_menu(new_menu); + + file_menu->addAction("&Open Project", this, SLOT(open_project()), QKeySequence("Ctrl+O")); + + open_recent = file_menu->addMenu("Open Recent"); + + file_menu->addAction("&Save Project", this, SLOT(save_project()), QKeySequence("Ctrl+S")); + file_menu->addAction("Save Project &As", this, SLOT(save_project_as()), QKeySequence("Ctrl+Shift+S")); + + file_menu->addSeparator(); + + file_menu->addAction("&Import...", panel_project, SLOT(import_dialog()), QKeySequence("Ctrl+I")); + + file_menu->addSeparator(); + + file_menu->addAction("&Export...", this, SLOT(export_dialog()), QKeySequence("Ctrl+M")); + + file_menu->addSeparator(); + + file_menu->addAction("E&xit", this, SLOT(close())); + + // INITIALIZE EDIT MENU + + QMenu* edit_menu = menuBar->addMenu("&Edit"); + connect(edit_menu, SIGNAL(aboutToShow()), this, SLOT(editMenu_About_To_Be_Shown())); + + undo_action = edit_menu->addAction("&Undo", this, SLOT(undo()), QKeySequence("Ctrl+Z")); + redo_action = edit_menu->addAction("Redo", this, SLOT(redo()), QKeySequence("Ctrl+Shift+Z")); + + edit_menu->addSeparator(); + + edit_menu->addAction("Cu&t", this, SLOT(cut()), QKeySequence("Ctrl+X")); + edit_menu->addAction("Cop&y", this, SLOT(copy()), QKeySequence("Ctrl+C")); + edit_menu->addAction("&Paste", this, SLOT(paste()), QKeySequence("Ctrl+V")); + edit_menu->addAction("Paste Insert", this, SLOT(paste_insert()), QKeySequence("Ctrl+Shift+V")); + edit_menu->addAction("Duplicate", this, SLOT(duplicate()), QKeySequence("Ctrl+D")); + edit_menu->addAction("Delete", this, SLOT(delete_slot()), QKeySequence("Del")); + edit_menu->addAction("Ripple Delete", this, SLOT(ripple_delete()), QKeySequence("Shift+Del")); + edit_menu->addAction("Split", panel_timeline, SLOT(split_at_playhead()), QKeySequence("Ctrl+K")); + + edit_menu->addSeparator(); + + edit_menu->addAction("Select &All", this, SLOT(select_all()), QKeySequence("Ctrl+A")); + + edit_menu->addAction("Deselect All", panel_timeline, SLOT(deselect()), QKeySequence("Ctrl+Shift+A")); + + edit_menu->addSeparator(); + + edit_menu->addAction("Add Default Transition", this, SLOT(add_default_transition()), QKeySequence("Ctrl+Shift+D")); + edit_menu->addAction("Link/Unlink", panel_timeline, SLOT(toggle_links()), QKeySequence("Ctrl+L")); + edit_menu->addAction("Enable/Disable", this, SLOT(toggle_enable_clips()), QKeySequence("Shift+E")); + edit_menu->addAction("Nest", this, SLOT(nest())); + + edit_menu->addSeparator(); + + edit_menu->addAction("Ripple to In Point", this, SLOT(ripple_to_in_point()), QKeySequence("Q")); + edit_menu->addAction("Ripple to Out Point", this, SLOT(ripple_to_out_point()), QKeySequence("W")); + edit_menu->addAction("Edit to In Point", this, SLOT(edit_to_in_point()), QKeySequence("Ctrl+Alt+Q")); + edit_menu->addAction("Edit to Out Point", this, SLOT(edit_to_out_point()), QKeySequence("Ctrl+Alt+W")); + + edit_menu->addSeparator(); + + make_inout_menu(edit_menu); + edit_menu->addAction("Delete In/Out Point", this, SLOT(delete_inout()), QKeySequence(";")); + edit_menu->addAction("Ripple Delete In/Out Point", this, SLOT(ripple_delete_inout()), QKeySequence("'")); + + edit_menu->addSeparator(); + + edit_menu->addAction("Set/Edit Marker", this, SLOT(set_marker()), QKeySequence("M")); + + // INITIALIZE VIEW MENU + + QMenu* view_menu = menuBar->addMenu("&View"); + connect(view_menu, SIGNAL(aboutToShow()), this, SLOT(viewMenu_About_To_Be_Shown())); + + view_menu->addAction("Zoom In", this, SLOT(zoom_in()), QKeySequence("=")); + view_menu->addAction("Zoom Out", this, SLOT(zoom_out()), QKeySequence("-")); + view_menu->addAction("Increase Track Height", this, SLOT(zoom_in_tracks()), QKeySequence("Ctrl+=")); + view_menu->addAction("Decrease Track Height", this, SLOT(zoom_out_tracks()), QKeySequence("Ctrl+-")); + + show_all = view_menu->addAction("Toggle Show All", panel_timeline, SLOT(toggle_show_all()), QKeySequence("\\")); + show_all->setCheckable(true); + + view_menu->addSeparator(); + + track_lines = view_menu->addAction("Track Lines", this, SLOT(toggle_bool_action())); + track_lines->setCheckable(true); + track_lines->setData(reinterpret_cast(&config.show_track_lines)); + + rectified_waveforms = view_menu->addAction("Rectified Waveforms", this, SLOT(toggle_bool_action())); + rectified_waveforms->setCheckable(true); + rectified_waveforms->setData(reinterpret_cast(&config.rectified_waveforms)); + + view_menu->addSeparator(); + + frames_action = view_menu->addAction("Frames", this, SLOT(set_timecode_view())); + frames_action->setData(TIMECODE_FRAMES); + frames_action->setCheckable(true); + drop_frame_action = view_menu->addAction("Drop Frame", this, SLOT(set_timecode_view())); + drop_frame_action->setData(TIMECODE_DROP); + drop_frame_action->setCheckable(true); + nondrop_frame_action = view_menu->addAction("Non-Drop Frame", this, SLOT(set_timecode_view())); + nondrop_frame_action->setData(TIMECODE_NONDROP); + nondrop_frame_action->setCheckable(true); + milliseconds_action = view_menu->addAction("Milliseconds", this, SLOT(set_timecode_view())); + milliseconds_action->setData(TIMECODE_MILLISECONDS); + milliseconds_action->setCheckable(true); + + view_menu->addSeparator(); + + QMenu* title_safe_area_menu = view_menu->addMenu("Title/Action Safe Area"); + + title_safe_off = title_safe_area_menu->addAction("Off"); + title_safe_off->setCheckable(true); + connect(title_safe_off, SIGNAL(triggered(bool)), this, SLOT(set_tsa_disable())); + + title_safe_default = title_safe_area_menu->addAction("Default"); + title_safe_default->setCheckable(true); + connect(title_safe_default, SIGNAL(triggered(bool)), this, SLOT(set_tsa_default())); + + title_safe_43 = title_safe_area_menu->addAction("4:3"); + title_safe_43->setCheckable(true); + connect(title_safe_43, SIGNAL(triggered(bool)), this, SLOT(set_tsa_43())); + + title_safe_169 = title_safe_area_menu->addAction("16:9"); + title_safe_169->setCheckable(true); + connect(title_safe_169, SIGNAL(triggered(bool)), this, SLOT(set_tsa_169())); + + title_safe_custom = title_safe_area_menu->addAction("Custom"); + title_safe_custom->setCheckable(true); + connect(title_safe_custom, SIGNAL(triggered(bool)), this, SLOT(set_tsa_custom())); + + view_menu->addSeparator(); + + full_screen = view_menu->addAction("Full Screen", this, SLOT(toggle_full_screen()), QKeySequence("F11")); + full_screen->setCheckable(true); + + // INITIALIZE PLAYBACK MENU + + QMenu* playback_menu = menuBar->addMenu("&Playback"); + + playback_menu->addAction("Go to Start", this, SLOT(go_to_start()), QKeySequence("Home")); + playback_menu->addAction("Previous Frame", this, SLOT(prev_frame()), QKeySequence("Left")); + playback_menu->addAction("Play/Pause", this, SLOT(playpause()), QKeySequence("Space")); + playback_menu->addAction("Next Frame", this, SLOT(next_frame()), QKeySequence("Right")); + playback_menu->addAction("Go to End", this, SLOT(go_to_end()), QKeySequence("End")); + playback_menu->addSeparator(); + playback_menu->addAction("Go to Previous Cut", this, SLOT(prev_cut()), QKeySequence("Up")); + playback_menu->addAction("Go to Next Cut", this, SLOT(next_cut()), QKeySequence("Down")); + + // INITIALIZE WINDOW MENU + + window_menu = menuBar->addMenu("&Window"); + connect(window_menu, SIGNAL(aboutToShow()), this, SLOT(windowMenu_About_To_Be_Shown())); + + QAction* window_project_action = window_menu->addAction("Project", this, SLOT(toggle_panel_visibility())); + window_project_action->setCheckable(true); + window_project_action->setData(reinterpret_cast(panel_project)); + + QAction* window_effectcontrols_action = window_menu->addAction("Effect Controls", this, SLOT(toggle_panel_visibility())); + window_effectcontrols_action->setCheckable(true); + window_effectcontrols_action->setData(reinterpret_cast(panel_effect_controls)); + + QAction* window_timeline_action = window_menu->addAction("Timeline", this, SLOT(toggle_panel_visibility())); + window_timeline_action->setCheckable(true); + window_timeline_action->setData(reinterpret_cast(panel_timeline)); + + QAction* window_footageviewer_action = window_menu->addAction("Footage Viewer", this, SLOT(toggle_panel_visibility())); + window_footageviewer_action->setCheckable(true); + window_footageviewer_action->setData(reinterpret_cast(panel_footage_viewer)); + + QAction* window_sequenceviewer_action = window_menu->addAction("Sequence Viewer", this, SLOT(toggle_panel_visibility())); + window_sequenceviewer_action->setCheckable(true); + window_sequenceviewer_action->setData(reinterpret_cast(panel_sequence_viewer)); + + window_menu->addSeparator(); + + window_menu->addAction("Reset to Default Layout", this, SLOT(reset_layout())); + + // INITIALIZE TOOLS MENU + + QMenu* tools_menu = menuBar->addMenu("&Tools"); + connect(tools_menu, SIGNAL(aboutToShow()), this, SLOT(toolMenu_About_To_Be_Shown())); + + pointer_tool_action = tools_menu->addAction("Pointer Tool", this, SLOT(menu_click_button()), QKeySequence("V")); + pointer_tool_action->setCheckable(true); + pointer_tool_action->setData(reinterpret_cast(panel_timeline->toolArrowButton)); + + edit_tool_action = tools_menu->addAction("Edit Tool", this, SLOT(menu_click_button()), QKeySequence("X")); + edit_tool_action->setCheckable(true); + edit_tool_action->setData(reinterpret_cast(panel_timeline->toolEditButton)); + + ripple_tool_action = tools_menu->addAction("Ripple Tool", this, SLOT(menu_click_button()), QKeySequence("B")); + ripple_tool_action->setCheckable(true); + ripple_tool_action->setData(reinterpret_cast(panel_timeline->toolRippleButton)); + + razor_tool_action = tools_menu->addAction("Razor Tool", this, SLOT(menu_click_button()), QKeySequence("C")); + razor_tool_action->setCheckable(true); + razor_tool_action->setData(reinterpret_cast(panel_timeline->toolRazorButton)); + + slip_tool_action = tools_menu->addAction("Slip Tool", this, SLOT(menu_click_button()), QKeySequence("Y")); + slip_tool_action->setCheckable(true); + slip_tool_action->setData(reinterpret_cast(panel_timeline->toolSlipButton)); + + slide_tool_action = tools_menu->addAction("Slide Tool", this, SLOT(menu_click_button()), QKeySequence("U")); + slide_tool_action->setCheckable(true); + slide_tool_action->setData(reinterpret_cast(panel_timeline->toolSlideButton)); + + hand_tool_action = tools_menu->addAction("Hand Tool", this, SLOT(menu_click_button()), QKeySequence("H")); + hand_tool_action->setCheckable(true); + hand_tool_action->setData(reinterpret_cast(panel_timeline->toolHandButton)); + + transition_tool_action = tools_menu->addAction("Transition Tool", this, SLOT(menu_click_button()), QKeySequence("T")); + transition_tool_action->setCheckable(true); + transition_tool_action->setData(reinterpret_cast(panel_timeline->toolTransitionButton)); + + tools_menu->addSeparator(); + + snap_toggle = tools_menu->addAction("Enable Snapping", this, SLOT(menu_click_button()), QKeySequence("S")); + snap_toggle->setCheckable(true); + snap_toggle->setData(reinterpret_cast(panel_timeline->snappingButton)); + + tools_menu->addSeparator(); + + selecting_also_seeks = tools_menu->addAction("Selecting Also Seeks", this, SLOT(toggle_bool_action())); + selecting_also_seeks->setCheckable(true); + selecting_also_seeks->setData(reinterpret_cast(&config.select_also_seeks)); + + edit_tool_also_seeks = tools_menu->addAction("Edit Tool Also Seeks", this, SLOT(toggle_bool_action())); + edit_tool_also_seeks->setCheckable(true); + edit_tool_also_seeks->setData(reinterpret_cast(&config.edit_tool_also_seeks)); + + edit_tool_selects_links = tools_menu->addAction("Edit Tool Selects Links", this, SLOT(toggle_bool_action())); + edit_tool_selects_links->setCheckable(true); + edit_tool_selects_links->setData(reinterpret_cast(&config.edit_tool_selects_links)); + + seek_to_end_of_pastes = tools_menu->addAction("Seek to the End of Pastes", this, SLOT(toggle_bool_action())); + seek_to_end_of_pastes->setCheckable(true); + seek_to_end_of_pastes->setData(reinterpret_cast(&config.paste_seeks)); + + scroll_wheel_zooms = tools_menu->addAction("Scroll Wheel Zooms", this, SLOT(toggle_bool_action())); + scroll_wheel_zooms->setCheckable(true); + scroll_wheel_zooms->setData(reinterpret_cast(&config.scroll_zooms)); + + enable_drag_files_to_timeline = tools_menu->addAction("Enable Drag Files to Timeline", this, SLOT(toggle_bool_action())); + enable_drag_files_to_timeline->setCheckable(true); + enable_drag_files_to_timeline->setData(reinterpret_cast(&config.enable_drag_files_to_timeline)); + + autoscale_by_default = tools_menu->addAction("Auto-Scale By Default", this, SLOT(toggle_bool_action())); + autoscale_by_default->setCheckable(true); + autoscale_by_default->setData(reinterpret_cast(&config.autoscale_by_default)); + + enable_seek_to_import = tools_menu->addAction("Enable Seek to Import", this, SLOT(toggle_bool_action())); + enable_seek_to_import->setCheckable(true); + enable_seek_to_import->setData(reinterpret_cast(&config.enable_seek_to_import)); + + enable_audio_scrubbing = tools_menu->addAction("Audio Scrubbing", this, SLOT(toggle_bool_action())); + enable_audio_scrubbing->setCheckable(true); + enable_audio_scrubbing->setData(reinterpret_cast(&config.enable_audio_scrubbing)); + + enable_drop_on_media_to_replace = tools_menu->addAction("Enable Drop on Media to Replace", this, SLOT(toggle_bool_action())); + enable_drop_on_media_to_replace->setCheckable(true); + enable_drop_on_media_to_replace->setData(reinterpret_cast(&config.drop_on_media_to_replace)); + + enable_hover_focus = tools_menu->addAction("Enable Hover Focus", this, SLOT(toggle_bool_action())); + enable_hover_focus->setCheckable(true); + enable_hover_focus->setData(reinterpret_cast(&config.hover_focus)); + + tools_menu->addSeparator(); + + no_autoscroll = tools_menu->addAction("No Auto-Scroll", this, SLOT(set_autoscroll())); + no_autoscroll->setData(AUTOSCROLL_NO_SCROLL); + no_autoscroll->setCheckable(true); + + page_autoscroll = tools_menu->addAction("Page Auto-Scroll", this, SLOT(set_autoscroll())); + page_autoscroll->setData(AUTOSCROLL_PAGE_SCROLL); + page_autoscroll->setCheckable(true); + + smooth_autoscroll = tools_menu->addAction("Smooth Auto-Scroll", this, SLOT(set_autoscroll())); + smooth_autoscroll->setData(AUTOSCROLL_SMOOTH_SCROLL); + smooth_autoscroll->setCheckable(true); + + tools_menu->addSeparator(); + + tools_menu->addAction("Preferences", this, SLOT(preferences()), QKeySequence("Ctrl+.")); + +#ifdef QT_DEBUG + tools_menu->addAction("Clear Undo", this, SLOT(clear_undo_stack()), QKeySequence("Ctrl+.")); +#endif + + // INITIALIZE HELP MENU + + QMenu* help_menu = menuBar->addMenu("&Help"); + + help_menu->addAction("&About...", this, SLOT(show_about())); +} + +void MainWindow::set_bool_action_checked(QAction *a) { + if (!a->data().isNull()) { + bool* variable = reinterpret_cast(a->data().value()); + a->setChecked(*variable); + } +} + +void MainWindow::set_int_action_checked(QAction *a, const int& i) { + if (!a->data().isNull()) { + a->setChecked(a->data() == i); + } +} + +void MainWindow::set_button_action_checked(QAction *a) { + a->setChecked(reinterpret_cast(a->data().value())->isChecked()); +} + void MainWindow::updateTitle(const QString& url) { project_url = url; setWindowTitle(appName + " - " + ((project_url.isEmpty()) ? "" : project_url) + "[*]"); } void MainWindow::closeEvent(QCloseEvent *e) { - if (can_close_project()) { - e->accept(); - } else { - e->ignore(); + if (can_close_project()) { + e->accept(); + } else { + e->ignore(); } } @@ -524,40 +819,24 @@ void MainWindow::paintEvent(QPaintEvent *event) { #endif } -void MainWindow::on_action_Save_Project_triggered() -{ - save_project(); +void MainWindow::clear_undo_stack() { + undo_stack.clear(); } -void MainWindow::on_action_Open_Project_triggered() -{ - QString fn = QFileDialog::getOpenFileName(this, "Open Project...", "", OLIVE_FILE_FILTER); +void MainWindow::open_project() { + QString fn = QFileDialog::getOpenFileName(this, "Open Project...", "", OLIVE_FILE_FILTER); if (!fn.isEmpty() && can_close_project()) { updateTitle(fn); - panel_project->load_project(false); - undo_stack.clear(); - } + panel_project->load_project(false); + undo_stack.clear(); + } } -void MainWindow::on_actionSave_Project_As_triggered() -{ - save_project_as(); +void MainWindow::reset_layout() { + setup_layout(true); } -void MainWindow::on_actionDeselect_All_triggered() -{ - if (panel_timeline->focused()) { - panel_timeline->deselect(); - } -} - -void MainWindow::on_actionReset_to_default_layout_triggered() -{ - setup_layout(true); -} - -void MainWindow::on_actionGo_to_start_triggered() -{ +void MainWindow::go_to_start() { if (panel_timeline->focused() || panel_sequence_viewer->is_focused() || panel_effect_controls->keyframe_focus()) { panel_sequence_viewer->go_to_start(); } else if (panel_footage_viewer->is_focused()) { @@ -565,7 +844,7 @@ void MainWindow::on_actionGo_to_start_triggered() } } -void MainWindow::on_actionPrevious_Frame_triggered() { +void MainWindow::prev_frame() { if (panel_timeline->focused() || panel_sequence_viewer->is_focused() || panel_effect_controls->keyframe_focus()) { panel_sequence_viewer->previous_frame(); } else if (panel_footage_viewer->is_focused()) { @@ -573,7 +852,7 @@ void MainWindow::on_actionPrevious_Frame_triggered() { } } -void MainWindow::on_actionNext_Frame_triggered() { +void MainWindow::next_frame() { if (panel_timeline->focused() || panel_sequence_viewer->is_focused() || panel_effect_controls->keyframe_focus()) { panel_sequence_viewer->next_frame(); } else if (panel_footage_viewer->is_focused()) { @@ -581,7 +860,7 @@ void MainWindow::on_actionNext_Frame_triggered() { } } -void MainWindow::on_actionGo_to_End_triggered() { +void MainWindow::go_to_end() { if (panel_timeline->focused() || panel_sequence_viewer->is_focused() || panel_effect_controls->keyframe_focus()) { panel_sequence_viewer->go_to_end(); } else if (panel_footage_viewer->is_focused()) { @@ -589,7 +868,7 @@ void MainWindow::on_actionGo_to_End_triggered() { } } -void MainWindow::on_actionPlay_Pause_triggered() { +void MainWindow::playpause() { if (panel_timeline->focused() || panel_sequence_viewer->is_focused() || panel_effect_controls->keyframe_focus()) { panel_sequence_viewer->toggle_play(); } else if (panel_footage_viewer->is_focused()) { @@ -597,224 +876,156 @@ void MainWindow::on_actionPlay_Pause_triggered() { } } -void MainWindow::on_actionEdit_Tool_triggered() -{ - if (panel_timeline->focused()) panel_timeline->ui->toolEditButton->click(); -} - -void MainWindow::on_actionToggle_Snapping_triggered() -{ - if (panel_timeline->focused() || panel_effect_controls->keyframe_focus()) panel_timeline->ui->snappingButton->click(); -} - -void MainWindow::on_actionPointer_Tool_triggered() -{ - if (panel_timeline->focused() - || panel_effect_controls->keyframe_focus() - || panel_footage_viewer->is_focused() - || panel_sequence_viewer->is_focused()) - panel_timeline->ui->toolArrowButton->click(); -} - -void MainWindow::on_actionRazor_Tool_triggered() -{ - if (panel_timeline->focused()) panel_timeline->ui->toolRazorButton->click(); -} - -void MainWindow::on_actionRipple_Tool_triggered() -{ - if (panel_timeline->focused()) panel_timeline->ui->toolRippleButton->click(); -} - -void MainWindow::on_actionRolling_Tool_triggered() -{ - if (panel_timeline->focused()) panel_timeline->ui->toolRollingButton->click(); -} - -void MainWindow::on_actionSlip_Tool_triggered() -{ - if (panel_timeline->focused()) panel_timeline->ui->toolSlipButton->click(); -} - -void MainWindow::on_actionGo_to_Previous_Cut_triggered() -{ +void MainWindow::prev_cut() { if (sequence != NULL && (panel_timeline->focused() || panel_sequence_viewer->is_focused())) { - panel_timeline->previous_cut(); - } + panel_timeline->previous_cut(); + } } -void MainWindow::on_actionGo_to_Next_Cut_triggered() -{ +void MainWindow::next_cut() { if (sequence != NULL && (panel_timeline->focused() || panel_sequence_viewer->is_focused())) { - panel_timeline->next_cut(); - } + panel_timeline->next_cut(); + } } -void MainWindow::on_actionPreferences_triggered() +void MainWindow::preferences() { - PreferencesDialog pd(this); - pd.setup_kbd_shortcuts(menuBar()); - pd.exec(); + PreferencesDialog pd(this); + pd.setup_kbd_shortcuts(menuBar()); + pd.exec(); } -void MainWindow::on_actionIncrease_Track_Height_triggered() -{ - panel_timeline->increase_track_height(); +void MainWindow::zoom_in_tracks() { + panel_timeline->increase_track_height(); } -void MainWindow::on_actionDecrease_Track_Height_triggered() -{ - panel_timeline->decrease_track_height(); +void MainWindow::zoom_out_tracks() { + panel_timeline->decrease_track_height(); } void MainWindow::windowMenu_About_To_Be_Shown() { - ui->actionProject_2->setChecked(panel_project->isVisible()); - ui->actionEffect_Controls->setChecked(panel_effect_controls->isVisible()); - ui->actionTimeline->setChecked(panel_timeline->isVisible()); - ui->actionViewer->setChecked(panel_sequence_viewer->isVisible()); - ui->actionFootage_Viewer->setChecked(panel_footage_viewer->isVisible()); + QList window_actions = window_menu->actions(); + for (int i=0;idata().isNull()) { + a->setChecked(reinterpret_cast(a->data().value())->isVisible()); + } + } } void MainWindow::viewMenu_About_To_Be_Shown() { - ui->actionTimeline_Track_Lines->setChecked(config.show_track_lines); - ui->actionFrames->setChecked(config.timecode_view == TIMECODE_FRAMES); - ui->actionDrop_Frame->setChecked(config.timecode_view == TIMECODE_DROP); - ui->actionNon_Drop_Frame->setChecked(config.timecode_view == TIMECODE_NONDROP); - ui->actionMilliseconds->setChecked(config.timecode_view == TIMECODE_MILLISECONDS); + set_bool_action_checked(track_lines); - ui->actionOff->setChecked(!config.show_title_safe_area); - ui->actionDefault->setChecked(config.show_title_safe_area && !config.use_custom_title_safe_ratio); - ui->action4_3->setChecked(config.show_title_safe_area && config.use_custom_title_safe_ratio && config.custom_title_safe_ratio == 4.0/3.0); - ui->action16_9->setChecked(config.show_title_safe_area && config.use_custom_title_safe_ratio && config.custom_title_safe_ratio == 16.0/9.0); - ui->actionCustom->setChecked(config.show_title_safe_area && config.use_custom_title_safe_ratio && !ui->action4_3->isChecked() && !ui->action16_9->isChecked()); + set_int_action_checked(frames_action, config.timecode_view); + set_int_action_checked(drop_frame_action, config.timecode_view); + set_int_action_checked(nondrop_frame_action, config.timecode_view); + set_int_action_checked(milliseconds_action, config.timecode_view); - ui->actionFull_Screen->setChecked(windowState() == Qt::WindowFullScreen); -} + title_safe_off->setChecked(!config.show_title_safe_area); + title_safe_default->setChecked(config.show_title_safe_area && !config.use_custom_title_safe_ratio); + title_safe_43->setChecked(config.show_title_safe_area && config.use_custom_title_safe_ratio && config.custom_title_safe_ratio == 4.0/3.0); + title_safe_169->setChecked(config.show_title_safe_area && config.use_custom_title_safe_ratio && config.custom_title_safe_ratio == 16.0/9.0); + title_safe_custom->setChecked(config.show_title_safe_area && config.use_custom_title_safe_ratio && !title_safe_43->isChecked() && !title_safe_169->isChecked()); -void MainWindow::on_actionFrames_triggered() -{ - config.timecode_view = TIMECODE_FRAMES; - update_ui(false); -} + full_screen->setChecked(windowState() == Qt::WindowFullScreen); -void MainWindow::on_actionDrop_Frame_triggered() -{ - config.timecode_view = TIMECODE_DROP; - update_ui(false); -} - -void MainWindow::on_actionNon_Drop_Frame_triggered() -{ - config.timecode_view = TIMECODE_NONDROP; - update_ui(false); + show_all->setChecked(panel_timeline->showing_all); } void MainWindow::toolMenu_About_To_Be_Shown() { - ui->actionEdit_Tool_Also_Seeks->setChecked(config.edit_tool_also_seeks); - ui->actionEdit_Tool_Selects_Links->setChecked(config.edit_tool_selects_links); - ui->actionSelecting_Also_Seeks->setChecked(config.select_also_seeks); - ui->actionSeek_to_the_End_of_Pastes->setChecked(config.paste_seeks); - ui->actionToggle_Snapping->setChecked(panel_timeline->snapping); - ui->actionScroll_Wheel_Zooms->setChecked(config.scroll_zooms); - ui->actionRectified_Waveforms->setChecked(config.rectified_waveforms); - ui->actionEnable_Drag_Files_to_Timeline->setChecked(config.enable_drag_files_to_timeline); - ui->actionAuto_scale_by_Default->setChecked(config.autoscale_by_default); - ui->actionEnable_Seek_to_Import->setChecked(config.enable_seek_to_import); - ui->actionAudio_Scrubbing->setChecked(config.enable_audio_scrubbing); - ui->actionEnable_Drop_on_Media_to_Replace->setChecked(config.drop_on_media_to_replace); - ui->actionEnable_Hover_Focus->setChecked(config.hover_focus); + set_button_action_checked(pointer_tool_action); + set_button_action_checked(edit_tool_action); + set_button_action_checked(ripple_tool_action); + set_button_action_checked(razor_tool_action); + set_button_action_checked(slip_tool_action); + set_button_action_checked(slide_tool_action); + set_button_action_checked(hand_tool_action); + set_button_action_checked(transition_tool_action); + set_button_action_checked(snap_toggle); - ui->actionNo_autoscroll->setChecked(config.autoscroll == AUTOSCROLL_NO_SCROLL); - ui->actionPage_Autoscroll->setChecked(config.autoscroll == AUTOSCROLL_PAGE_SCROLL); - ui->actionSmooth_Auto_scroll->setChecked(config.autoscroll == AUTOSCROLL_SMOOTH_SCROLL); + set_bool_action_checked(selecting_also_seeks); + set_bool_action_checked(edit_tool_also_seeks); + set_bool_action_checked(edit_tool_selects_links); + set_bool_action_checked(seek_to_end_of_pastes); + set_bool_action_checked(scroll_wheel_zooms); + set_bool_action_checked(rectified_waveforms); + set_bool_action_checked(enable_drag_files_to_timeline); + set_bool_action_checked(autoscale_by_default); + set_bool_action_checked(enable_seek_to_import); + set_bool_action_checked(enable_audio_scrubbing); + set_bool_action_checked(enable_drop_on_media_to_replace); + set_bool_action_checked(enable_hover_focus); + + set_int_action_checked(no_autoscroll, config.autoscroll); + set_int_action_checked(page_autoscroll, config.autoscroll); + set_int_action_checked(smooth_autoscroll, config.autoscroll); } -void MainWindow::on_actionEdit_Tool_Selects_Links_triggered() { - config.edit_tool_selects_links = !config.edit_tool_selects_links; +void MainWindow::duplicate() { + if (panel_project->is_focused()) { + panel_project->duplicate_selected(); + } } -void MainWindow::on_actionEdit_Tool_Also_Seeks_triggered() { - config.edit_tool_also_seeks = !config.edit_tool_also_seeks; +void MainWindow::add_default_transition() { + if (panel_timeline->focused()) panel_timeline->add_transition(); } -void MainWindow::on_actionDuplicate_triggered() { - if (panel_project->is_focused()) { - panel_project->duplicate_selected(); - } -} +void MainWindow::new_folder() { + Media* m = panel_project->new_folder(0); + undo_stack.push(new AddMediaCommand(m, panel_project->get_selected_folder())); -void MainWindow::on_actionSelecting_Also_Seeks_triggered() { - config.select_also_seeks = !config.select_also_seeks; -} - -void MainWindow::on_actionSeek_to_the_End_of_Pastes_triggered() -{ - config.paste_seeks = !config.paste_seeks; -} - -void MainWindow::on_actionAdd_Default_Transition_triggered() { - if (panel_timeline->focused()) panel_timeline->add_transition(); -} - -void MainWindow::on_actionSlide_Tool_triggered() -{ - if (panel_timeline->focused()) panel_timeline->ui->toolSlideButton->click(); -} - -void MainWindow::on_actionFolder_triggered() { - undo_stack.push(new AddMediaCommand(panel_project->new_folder(0), panel_project->get_selected_folder())); + QModelIndex index = project_model.create_index(m->row(), 0, m); + switch (config.project_view_type) { + case PROJECT_VIEW_TREE: + panel_project->tree_view->edit(panel_project->sorter->mapFromSource(index)); + break; + case PROJECT_VIEW_ICON: + panel_project->icon_view->edit(panel_project->sorter->mapFromSource(index)); + break; + } } void MainWindow::fileMenu_About_To_Be_Shown() { - if (recent_projects.size() > 0) { - ui->menuOpen_Recent->clear(); - ui->menuOpen_Recent->setEnabled(true); - for (int i=0;imenuOpen_Recent->addAction(recent_projects.at(i)); - action->setData(i); - connect(action, SIGNAL(triggered()), this, SLOT(load_recent_project())); - } - ui->menuOpen_Recent->addSeparator(); - QAction* clear_action = ui->menuOpen_Recent->addAction("Clear Recent List"); - connect(clear_action, SIGNAL(triggered()), panel_project, SLOT(clear_recent_projects())); - } else { - ui->menuOpen_Recent->setEnabled(false); - } + if (recent_projects.size() > 0) { + open_recent->clear(); + open_recent->setEnabled(true); + for (int i=0;iaddAction(recent_projects.at(i)); + action->setData(i); + connect(action, SIGNAL(triggered()), this, SLOT(load_recent_project())); + } + open_recent->addSeparator(); + QAction* clear_action = open_recent->addAction("Clear Recent List"); + connect(clear_action, SIGNAL(triggered()), panel_project, SLOT(clear_recent_projects())); + } else { + open_recent->setEnabled(false); + } } void MainWindow::load_recent_project() { - int index = static_cast(sender())->data().toInt(); - QString recent_url = recent_projects.at(index); - if (!QFile::exists(recent_url)) { - if (QMessageBox::question(this, "Missing recent project", "The project '" + recent_url + "' no longer exists. Would you like to remove it from the recent projects list?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { - recent_projects.removeAt(index); - panel_project->save_recent_projects(); - } + int index = static_cast(sender())->data().toInt(); + QString recent_url = recent_projects.at(index); + if (!QFile::exists(recent_url)) { + if (QMessageBox::question(this, "Missing recent project", "The project '" + recent_url + "' no longer exists. Would you like to remove it from the recent projects list?", QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { + recent_projects.removeAt(index); + panel_project->save_recent_projects(); + } } else if (can_close_project()) { updateTitle(recent_url); - panel_project->load_project(false); - } + panel_project->load_project(false); + } } -void MainWindow::on_actionScroll_Wheel_Zooms_triggered() -{ - config.scroll_zooms = !config.scroll_zooms; -} - -void MainWindow::on_actionLink_Unlink_triggered() -{ - if (panel_timeline->focused()) panel_timeline->toggle_links(); -} - -void MainWindow::on_actionRipple_To_In_Point_triggered() { +void MainWindow::ripple_to_in_point() { if (panel_timeline->focused()) panel_timeline->ripple_to_in_point(true, true); } -void MainWindow::on_actionRipple_to_Out_Point_triggered() { +void MainWindow::ripple_to_out_point() { if (panel_timeline->focused()) panel_timeline->ripple_to_in_point(false, true); } -void MainWindow::on_actionSet_In_Point_triggered() { +void MainWindow::set_in_point() { if (panel_timeline->focused() || panel_sequence_viewer->is_focused()) { panel_sequence_viewer->set_in_point(); } else if (panel_footage_viewer->is_focused()) { @@ -822,7 +1033,7 @@ void MainWindow::on_actionSet_In_Point_triggered() { } } -void MainWindow::on_actionSet_Out_Point_triggered() { +void MainWindow::set_out_point() { if (panel_timeline->focused() || panel_sequence_viewer->is_focused()) { panel_sequence_viewer->set_out_point(); } else if (panel_footage_viewer->is_focused()) { @@ -830,111 +1041,90 @@ void MainWindow::on_actionSet_Out_Point_triggered() { } } -void MainWindow::on_actionClear_In_Out_triggered() { - if (panel_timeline->focused() || panel_sequence_viewer->is_focused()) { - panel_sequence_viewer->clear_inout_point(); - } else if (panel_footage_viewer->is_focused()) { - panel_footage_viewer->clear_inout_point(); - } +void MainWindow::clear_inout() { + if (panel_timeline->focused() || panel_sequence_viewer->is_focused()) { + panel_sequence_viewer->clear_inout_point(); + } else if (panel_footage_viewer->is_focused()) { + panel_footage_viewer->clear_inout_point(); + } } void MainWindow::toggle_full_screen() { - if (windowState() == Qt::WindowFullScreen) { - setWindowState(Qt::WindowNoState); // seems to be necessary for it to return to Maximized correctly on Linux - setWindowState(Qt::WindowMaximized); - } else { - setWindowState(Qt::WindowFullScreen); - } + if (windowState() == Qt::WindowFullScreen) { + setWindowState(Qt::WindowNoState); // seems to be necessary for it to return to Maximized correctly on Linux + setWindowState(Qt::WindowMaximized); + } else { + setWindowState(Qt::WindowFullScreen); + } } -void MainWindow::on_actionDelete_In_Out_triggered() +void MainWindow::delete_inout() { + if (panel_timeline->focused()) { + panel_timeline->delete_in_out(false); + } +} + +void MainWindow::ripple_delete_inout() { - if (panel_timeline->focused()) { - panel_timeline->delete_in_out(false); - } + if (panel_timeline->focused()) { + panel_timeline->delete_in_out(true); + } } -void MainWindow::on_actionRipple_Delete_In_Out_triggered() -{ - if (panel_timeline->focused()) { - panel_timeline->delete_in_out(true); - } +void MainWindow::set_tsa_default() { + config.show_title_safe_area = true; + config.use_custom_title_safe_ratio = false; + panel_sequence_viewer->viewer_widget->update(); } -void MainWindow::on_actionTimeline_Track_Lines_triggered() -{ - config.show_track_lines = !config.show_track_lines; - panel_timeline->repaint_timeline(); +void MainWindow::set_tsa_disable() { + config.show_title_safe_area = false; + panel_sequence_viewer->viewer_widget->update(); } -void MainWindow::on_actionRectified_Waveforms_triggered() -{ - config.rectified_waveforms = !config.rectified_waveforms; - panel_timeline->repaint_timeline(); +void MainWindow::set_tsa_43() { + config.show_title_safe_area = true; + config.use_custom_title_safe_ratio = true; + config.custom_title_safe_ratio = 4.0/3.0; + panel_sequence_viewer->viewer_widget->update(); } -void MainWindow::on_actionDefault_triggered() { - config.show_title_safe_area = true; - config.use_custom_title_safe_ratio = false; - panel_sequence_viewer->viewer_widget->update(); +void MainWindow::set_tsa_169() { + config.show_title_safe_area = true; + config.use_custom_title_safe_ratio = true; + config.custom_title_safe_ratio = 16.0/9.0; + panel_sequence_viewer->viewer_widget->update(); } -void MainWindow::on_actionOff_triggered() { - config.show_title_safe_area = false; - panel_sequence_viewer->viewer_widget->update(); +void MainWindow::set_tsa_custom() { + QString input; + bool invalid = false; + QRegExp arTest("[0-9.]+:[0-9.]+"); + + do { + if (invalid) { + QMessageBox::critical(this, "Invalid aspect ratio", "The aspect ratio '" + input + "' is invalid. Please try again."); + } + + input = QInputDialog::getText(this, "Enter custom aspect ratio", "Enter the aspect ratio to use for the title/action safe area (e.g. 16:9):"); + invalid = !arTest.exactMatch(input) && !input.isEmpty(); + } while (invalid); + + if (!input.isEmpty()) { + QStringList inputList = input.split(':'); + + config.show_title_safe_area = true; + config.use_custom_title_safe_ratio = true; + config.custom_title_safe_ratio = inputList.at(0).toDouble()/inputList.at(1).toDouble(); + panel_sequence_viewer->viewer_widget->update(); + } } -void MainWindow::on_action4_3_triggered() { - config.show_title_safe_area = true; - config.use_custom_title_safe_ratio = true; - config.custom_title_safe_ratio = 4.0/3.0; - panel_sequence_viewer->viewer_widget->update(); -} - -void MainWindow::on_action16_9_triggered() { - config.show_title_safe_area = true; - config.use_custom_title_safe_ratio = true; - config.custom_title_safe_ratio = 16.0/9.0; - panel_sequence_viewer->viewer_widget->update(); -} - -void MainWindow::on_actionCustom_triggered() { - QString input; - bool invalid = false; - QRegExp arTest("[0-9.]+:[0-9.]+"); - - do { - if (invalid) { - QMessageBox::critical(this, "Invalid aspect ratio", "The aspect ratio '" + input + "' is invalid. Please try again."); - } - - input = QInputDialog::getText(this, "Enter custom aspect ratio", "Enter the aspect ratio to use for the title/action safe area (e.g. 16:9):"); - invalid = !arTest.exactMatch(input) && !input.isEmpty(); - } while (invalid); - - if (!input.isEmpty()) { - QStringList inputList = input.split(':'); - - config.show_title_safe_area = true; - config.use_custom_title_safe_ratio = true; - config.custom_title_safe_ratio = inputList.at(0).toDouble()/inputList.at(1).toDouble(); - panel_sequence_viewer->viewer_widget->update(); - } -} - -void MainWindow::on_actionEnable_Drag_Files_to_Timeline_triggered() { - config.enable_drag_files_to_timeline = !config.enable_drag_files_to_timeline; -} - -void MainWindow::on_actionAuto_scale_by_Default_triggered() { - config.autoscale_by_default = !config.autoscale_by_default; -} - -void MainWindow::on_actionSet_Edit_Marker_triggered() { +void MainWindow::set_marker() { if (sequence != NULL) panel_timeline->set_marker(); } -void MainWindow::on_actionEnable_Disable_Clip_triggered() { +void MainWindow::toggle_enable_clips() { if (sequence != NULL) { ComboAction* ca = new ComboAction(); bool push_undo = false; @@ -954,47 +1144,35 @@ void MainWindow::on_actionEnable_Disable_Clip_triggered() { } } -void MainWindow::on_actionEnable_Seek_to_Import_triggered() { - config.enable_seek_to_import = !config.enable_seek_to_import; -} - -void MainWindow::on_actionAudio_Scrubbing_triggered() { - config.enable_audio_scrubbing = !config.enable_audio_scrubbing; -} - -void MainWindow::on_actionTransition_Tool_triggered() { - if (panel_timeline->focused()) panel_timeline->ui->toolTransitionButton->click(); -} - -void MainWindow::on_actionEdit_to_In_Point_triggered() { +void MainWindow::edit_to_in_point() { if (panel_timeline->focused()) panel_timeline->ripple_to_in_point(true, false); } -void MainWindow::on_actionEdit_to_Out_Point_triggered() { +void MainWindow::edit_to_out_point() { if (panel_timeline->focused()) panel_timeline->ripple_to_in_point(false, false); } -void MainWindow::on_actionNest_triggered() { - if (sequence != NULL) { - QVector selected_clips; - long earliest_point = LONG_MAX; +void MainWindow::nest() { + if (sequence != NULL) { + QVector selected_clips; + long earliest_point = LONG_MAX; - // get selected clips + // get selected clips for (int i=0;iclips.size();i++) { Clip* c = sequence->clips.at(i); if (c != NULL && panel_timeline->is_clip_selected(c, true)) { - selected_clips.append(i); - earliest_point = qMin(c->timeline_in, earliest_point); + selected_clips.append(i); + earliest_point = qMin(c->timeline_in, earliest_point); } } - // nest them + // nest them if (!selected_clips.isEmpty()) { - ComboAction* ca = new ComboAction(); + ComboAction* ca = new ComboAction(); Sequence* s = new Sequence(); - // create "nest" sequence + // create "nest" sequence s->name = panel_project->get_next_sequence_name("Nested Sequence"); s->width = sequence->width; s->height = sequence->height; @@ -1002,76 +1180,70 @@ void MainWindow::on_actionNest_triggered() { s->audio_frequency = sequence->audio_frequency; s->audio_layout = sequence->audio_layout; - // copy all selected clips to the nest + // copy all selected clips to the nest for (int i=0;iappend(new DeleteClipAction(sequence, selected_clips.at(i))); + // delete clip from old sequence + ca->append(new DeleteClipAction(sequence, selected_clips.at(i))); - // copy to new - Clip* copy = sequence->clips.at(selected_clips.at(i))->copy(s); - copy->timeline_in -= earliest_point; - copy->timeline_out -= earliest_point; - s->clips.append(copy); + // copy to new + Clip* copy = sequence->clips.at(selected_clips.at(i))->copy(s); + copy->timeline_in -= earliest_point; + copy->timeline_out -= earliest_point; + s->clips.append(copy); } - // add sequence to project - Media* m = panel_project->new_sequence(ca, s, false, NULL); + // add sequence to project + Media* m = panel_project->new_sequence(ca, s, false, NULL); - // add nested sequence to active sequence - QVector media_list = {m}; - panel_timeline->create_ghosts_from_media(sequence, earliest_point, media_list); - panel_timeline->add_clips_from_ghosts(ca, sequence); + // add nested sequence to active sequence + QVector media_list = {m}; + panel_timeline->create_ghosts_from_media(sequence, earliest_point, media_list); + panel_timeline->add_clips_from_ghosts(ca, sequence); - undo_stack.push(ca); + panel_effect_controls->clear_effects(true); + sequence->selections.clear(); - update_ui(true); - } + undo_stack.push(ca); + + update_ui(true); + } } } -void MainWindow::on_actionToggle_Show_All_triggered() { - if (sequence != NULL) panel_timeline->toggle_show_all(); +void MainWindow::paste_insert() { + if (panel_timeline->focused() && sequence != NULL) { + panel_timeline->paste(true); + } } -void MainWindow::on_actionEnable_Drop_on_Media_to_Replace_triggered() { - config.drop_on_media_to_replace = !config.drop_on_media_to_replace; +void MainWindow::toggle_bool_action() { + QAction* action = static_cast(sender()); + bool* variable = reinterpret_cast(action->data().value()); + *variable = !(*variable); + update_ui(false); } -void MainWindow::on_actionFootage_Viewer_triggered() { - panel_footage_viewer->setVisible(!panel_footage_viewer->isVisible()); +void MainWindow::set_autoscroll() { + QAction* action = static_cast(sender()); + config.autoscroll = action->data().toInt(); } -void MainWindow::on_actionPasteInsert_triggered() { - if (panel_timeline->focused() && sequence != NULL) { - panel_timeline->paste(true); - } +void MainWindow::menu_click_button() { + if (panel_timeline->focused() + || panel_effect_controls->keyframe_focus() + || panel_footage_viewer->is_focused() + || panel_sequence_viewer->is_focused()) + reinterpret_cast(static_cast(sender())->data().value())->click(); } -void MainWindow::on_actionNo_autoscroll_triggered() { - config.autoscroll = AUTOSCROLL_NO_SCROLL; +void MainWindow::toggle_panel_visibility() { + QAction* action = static_cast(sender()); + QDockWidget* w = reinterpret_cast(action->data().value()); + w->setVisible(!w->isVisible()); } -void MainWindow::on_actionPage_Autoscroll_triggered() { - config.autoscroll = AUTOSCROLL_PAGE_SCROLL; -} - -void MainWindow::on_actionSmooth_Auto_scroll_triggered() { - config.autoscroll = AUTOSCROLL_SMOOTH_SCROLL; -} - -void MainWindow::on_actionMilliseconds_triggered() { - config.timecode_view = TIMECODE_MILLISECONDS; - update_ui(false); -} - -void MainWindow::on_actionEnable_Hover_Focus_triggered() { - config.hover_focus = !config.hover_focus; -} - -void MainWindow::on_actionHand_Tool_triggered() { - if (panel_timeline->focused() - || panel_effect_controls->keyframe_focus() - || panel_footage_viewer->is_focused() - || panel_sequence_viewer->is_focused()) - panel_timeline->ui->toolHandButton->click(); +void MainWindow::set_timecode_view() { + QAction* action = static_cast(sender()); + config.timecode_view = action->data().toInt(); + update_ui(false); } diff --git a/mainwindow.h b/mainwindow.h index a1b380542..043b083b3 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -8,219 +8,167 @@ class EffectControls; class Viewer; class Timeline; -namespace Ui { -class MainWindow; -} - -class MainWindow : public QMainWindow -{ +class MainWindow : public QMainWindow { Q_OBJECT - public: explicit MainWindow(QWidget *parent = 0); - void updateTitle(const QString &url); - ~MainWindow(); + void updateTitle(const QString &url); + ~MainWindow(); + + void make_new_menu(QMenu* parent); + void make_inout_menu(QMenu* parent); public slots: void undo(); void redo(); - void openSpeedDialog(); + void open_speed_dialog(); void cut(); void copy(); void paste(); - void new_project(); - void autorecover_interval(); - void on_actionNest_triggered(); - void on_actionClear_In_Out_triggered(); - void toggle_full_screen(); + void new_project(); + void autorecover_interval(); + void nest(); + void toggle_full_screen(); protected: void closeEvent(QCloseEvent *); void paintEvent(QPaintEvent *event); private slots: - void on_action_Import_triggered(); + void clear_undo_stack(); - void on_actionExit_triggered(); + void show_about(); + void delete_slot(); + void select_all(); - void on_actionAbout_triggered(); + void new_sequence(); - void on_actionDelete_triggered(); + void zoom_in(); + void zoom_out(); + void export_dialog(); + void ripple_delete(); - void on_actionSelect_All_triggered(); + void open_project(); + bool save_project_as(); + bool save_project(); - void on_actionSequence_triggered(); + void go_to_start(); + void prev_frame(); + void playpause(); + void next_frame(); + void go_to_end(); + void prev_cut(); + void next_cut(); - void on_actionZoom_In_triggered(); + void reset_layout(); - void on_actionZoom_out_triggered(); + void preferences(); - void on_actionExport_triggered(); + void zoom_in_tracks(); - void on_actionProject_2_triggered(); + void zoom_out_tracks(); - void on_actionEffect_Controls_triggered(); + void fileMenu_About_To_Be_Shown(); + void editMenu_About_To_Be_Shown(); + void windowMenu_About_To_Be_Shown(); + void viewMenu_About_To_Be_Shown(); + void toolMenu_About_To_Be_Shown(); - void on_actionViewer_triggered(); + void duplicate(); - void on_actionTimeline_triggered(); + void add_default_transition(); - void on_actionRipple_Delete_triggered(); + void new_folder(); - void on_actionSplit_at_Playhead_triggered(); + void load_recent_project(); - void on_action_Save_Project_triggered(); + void ripple_to_in_point(); + void ripple_to_out_point(); - void on_action_Open_Project_triggered(); + void set_in_point(); + void set_out_point(); - void on_actionSave_Project_As_triggered(); + void clear_inout(); + void delete_inout(); + void ripple_delete_inout(); - void on_actionDeselect_All_triggered(); + // title safe area functions + void set_tsa_disable(); + void set_tsa_default(); + void set_tsa_43(); + void set_tsa_169(); + void set_tsa_custom(); - void on_actionGo_to_start_triggered(); + void set_marker(); - void on_actionReset_to_default_layout_triggered(); - - void on_actionPrevious_Frame_triggered(); - - void on_actionNext_Frame_triggered(); - - void on_actionGo_to_End_triggered(); - - void on_actionPlay_Pause_triggered(); - - void on_actionEdit_Tool_triggered(); - - void on_actionToggle_Snapping_triggered(); - - void on_actionPointer_Tool_triggered(); - - void on_actionRazor_Tool_triggered(); - - void on_actionRipple_Tool_triggered(); - - void on_actionRolling_Tool_triggered(); - - void on_actionSlip_Tool_triggered(); - - void on_actionGo_to_Previous_Cut_triggered(); - - void on_actionGo_to_Next_Cut_triggered(); - - void on_actionPreferences_triggered(); - - void on_actionIncrease_Track_Height_triggered(); - - void on_actionDecrease_Track_Height_triggered(); - - void windowMenu_About_To_Be_Shown(); - - void on_actionFrames_triggered(); - - void on_actionDrop_Frame_triggered(); - - void on_actionNon_Drop_Frame_triggered(); - - void viewMenu_About_To_Be_Shown(); - - void on_actionEdit_Tool_Selects_Links_triggered(); - - void on_actionEdit_Tool_Also_Seeks_triggered(); - - void toolMenu_About_To_Be_Shown(); - - void on_actionDuplicate_triggered(); - - void on_actionSelecting_Also_Seeks_triggered(); - - void on_actionSeek_to_the_End_of_Pastes_triggered(); - - void on_actionAdd_Default_Transition_triggered(); - - void on_actionSlide_Tool_triggered(); - - void on_actionFolder_triggered(); - - void editMenu_About_To_Be_Shown(); - - void fileMenu_About_To_Be_Shown(); - - void load_recent_project(); - - void on_actionScroll_Wheel_Zooms_triggered(); - - void on_actionLink_Unlink_triggered(); - - void on_actionRipple_To_In_Point_triggered(); - - void on_actionRipple_to_Out_Point_triggered(); - - void on_actionSet_In_Point_triggered(); - - void on_actionSet_Out_Point_triggered(); - - void on_actionDelete_In_Out_triggered(); - - void on_actionRipple_Delete_In_Out_triggered(); - - void on_actionTimeline_Track_Lines_triggered(); - - void on_actionRectified_Waveforms_triggered(); - - void on_actionDefault_triggered(); - - void on_actionOff_triggered(); - - void on_action4_3_triggered(); - - void on_action16_9_triggered(); - - void on_actionCustom_triggered(); - - void on_actionEnable_Drag_Files_to_Timeline_triggered(); - - void on_actionAuto_scale_by_Default_triggered(); - - void on_actionSet_Edit_Marker_triggered(); - - void on_actionEnable_Disable_Clip_triggered(); - - void on_actionEnable_Seek_to_Import_triggered(); - - void on_actionAudio_Scrubbing_triggered(); - - void on_actionTransition_Tool_triggered(); - - void on_actionEdit_to_In_Point_triggered(); - - void on_actionEdit_to_Out_Point_triggered(); - - void on_actionToggle_Show_All_triggered(); - - void on_actionEnable_Drop_on_Media_to_Replace_triggered(); - - void on_actionFootage_Viewer_triggered(); - - void on_actionPasteInsert_triggered(); - - void on_actionNo_autoscroll_triggered(); - - void on_actionPage_Autoscroll_triggered(); - - void on_actionSmooth_Auto_scroll_triggered(); - - void on_actionMilliseconds_triggered(); - - void on_actionEnable_Hover_Focus_triggered(); - - void on_actionHand_Tool_triggered(); + void toggle_enable_clips(); + void edit_to_in_point(); + void edit_to_out_point(); + void paste_insert(); + void toggle_bool_action(); + void set_autoscroll(); + void menu_click_button(); + void toggle_panel_visibility(); + void set_timecode_view(); private: - Ui::MainWindow *ui; - void setup_layout(bool reset); - bool save_project_as(); - bool save_project(); - bool can_close_project(); + void setup_layout(bool reset); + bool can_close_project(); + void setup_menus(); + + // menu bar menus + QMenu* window_menu; + + // file menu actions + QMenu* open_recent; + + // view menu actions + QAction* track_lines; + QAction* frames_action; + QAction* drop_frame_action; + QAction* nondrop_frame_action; + QAction* milliseconds_action; + QAction* no_autoscroll; + QAction* page_autoscroll; + QAction* smooth_autoscroll; + QAction* title_safe_off; + QAction* title_safe_default; + QAction* title_safe_43; + QAction* title_safe_169; + QAction* title_safe_custom; + QAction* full_screen; + QAction* show_all; + + // tool menu actions + QAction* pointer_tool_action; + QAction* edit_tool_action; + QAction* ripple_tool_action; + QAction* razor_tool_action; + QAction* slip_tool_action; + QAction* slide_tool_action; + QAction* hand_tool_action; + QAction* transition_tool_action; + QAction* snap_toggle; + QAction* selecting_also_seeks; + QAction* edit_tool_also_seeks; + QAction* edit_tool_selects_links; + QAction* seek_to_end_of_pastes; + QAction* scroll_wheel_zooms; + QAction* rectified_waveforms; + QAction* enable_drag_files_to_timeline; + QAction* autoscale_by_default; + QAction* enable_seek_to_import; + QAction* enable_audio_scrubbing; + QAction* enable_drop_on_media_to_replace; + QAction* enable_hover_focus; + + // edit menu actions + QAction* undo_action; + QAction* redo_action; + + void set_bool_action_checked(QAction* a); + void set_int_action_checked(QAction* a, const int& i); + void set_button_action_checked(QAction* a); }; extern MainWindow* mainWindow; diff --git a/mainwindow.ui b/mainwindow.ui deleted file mode 100644 index fe24d5e23..000000000 --- a/mainwindow.ui +++ /dev/null @@ -1,964 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 653 - 394 - - - - MainWindow - - - - - 0 - 0 - - - - - 0 - 0 - - - - - - - 0 - 0 - 653 - 16 - - - - - &File - - - - &New - - - - - - - - - Open Recent - - - - - - - - - - - - - - - - - &Edit - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - &Window - - - - - - - - - - - - &Help - - - - - - &View - - - - Title/Action Safe Area - - - - - - - - - - - - - - - - - - - - - - - - - - - &Playback - - - - - - - - - - - - - &Tools - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - &Open Project - - - Ctrl+O - - - - - &Save Project - - - Ctrl+S - - - - - Save Project &As - - - Ctrl+Shift+S - - - - - &Import... - - - Ctrl+I - - - - - &Export... - - - Ctrl+M - - - - - E&xit - - - - - About... - - - - - &Undo - - - Ctrl+Z - - - - - &Redo - - - Ctrl+Shift+Z - - - - - Cu&t - - - Ctrl+X - - - - - Cop&y - - - Ctrl+C - - - - - &Paste - - - Ctrl+V - - - - - Paste Insert - - - Ctrl+Shift+V - - - - - Delete - - - Del - - - - - Select &All - - - Ctrl+A - - - - - true - - - Track Lines - - - - - Project... - - - Ctrl+N - - - - - Sequence... - - - Ctrl+Shift+N - - - - - Zoom In - - - = - - - - - Zoom Out - - - - - - - - - true - - - true - - - Project - - - - - true - - - true - - - Effect Controls - - - - - true - - - true - - - Sequence Viewer - - - - - true - - - true - - - Timeline - - - - - Ripple Delete - - - Shift+Del - - - - - Split at Playhead - - - Ctrl+K - - - - - Deselect All - - - - - Go to Start - - - Home - - - - - Reset to default layout - - - - - Previous Frame - - - Left - - - - - Play/Pause - - - Space - - - - - Next Frame - - - Right - - - - - Go to End - - - End - - - - - Crash - - - false - - - - - Pointer Tool - - - V - - - - - Edit Tool - - - X - - - - - Razor Tool - - - C - - - - - Ripple Tool - - - B - - - - - Rolling Tool - - - N - - - false - - - - - Preferences - - - Ctrl+. - - - - - true - - - Snapping - - - Snapping - - - S - - - - - Slip Tool - - - Y - - - - - Go to Previous Cut - - - Up - - - - - Go to Next Cut - - - Down - - - - - true - - - Edit Tool Also Seeks - - - - - Increase Track Height - - - Ctrl+= - - - - - Decrease Track Height - - - Ctrl+- - - - - - true - - - Frames - - - - - true - - - Drop-Frame - - - - - true - - - Non-Drop Frame - - - - - true - - - Edit Tool Selects Links - - - - - Duplicate - - - Ctrl+D - - - - - true - - - Selecting Also Seeks - - - - - true - - - Seek to the End of Pastes - - - - - Add Default Transition - - - Ctrl+Shift+D - - - - - Slide Tool - - - U - - - - - Folder - - - - - Clear Recent List - - - - - true - - - Scroll Wheel Zooms - - - - - Link/Unlink - - - Ctrl+L - - - - - Ripple to In Point - - - Q - - - - - Ripple to Out Point - - - W - - - - - Set In Point - - - I - - - - - Set Out Point - - - O - - - - - Clear In/Out - - - G - - - - - Delete In/Out - - - ; - - - - - Ripple Delete In/Out - - - ' - - - - - true - - - Rectified Waveforms - - - - - true - - - Default - - - - - true - - - Off - - - - - true - - - 4:3 - - - - - true - - - 16:9 - - - - - true - - - Custom - - - - - true - - - Enable Drag Files to Timeline - - - - - true - - - Auto-scale by Default - - - - - Set/Edit Marker - - - M - - - - - Enable/Disable Clip - - - Shift+E - - - - - true - - - Enable Seek to Import - - - - - true - - - Audio Scrubbing - - - - - Transition Tool - - - T - - - - - Edit to In Point - - - Ctrl+Alt+Q - - - - - Edit to Out Point - - - Ctrl+Alt+W - - - - - Nest - - - - - Toggle Show All - - - \ - - - - - true - - - Enable Drop File on Media to Replace - - - - - true - - - Footage Viewer - - - - - true - - - No Auto-scroll - - - - - true - - - Page Auto-scroll - - - - - true - - - Smooth Auto-scroll - - - - - true - - - Milliseconds - - - - - true - - - Enable Hover Focus for Zooming - - - - - true - - - Full Screen - - - F11 - - - - - Hand Tool - - - H - - - - - - - diff --git a/olive.pro b/olive.pro index 6dc271e34..1ab9f79e8 100644 --- a/olive.pro +++ b/olive.pro @@ -187,16 +187,7 @@ HEADERS += \ project/sourcescommon.h \ ui/keyframenavigator.h -FORMS += \ - mainwindow.ui \ - panels/effectcontrols.ui \ - panels/viewer.ui \ - panels/timeline.ui \ - dialogs/aboutdialog.ui \ - dialogs/newsequencedialog.ui \ - dialogs/exportdialog.ui \ - dialogs/preferencesdialog.ui \ - dialogs/demonotice.ui +FORMS += win32 { RC_FILE = icons/resources.rc @@ -226,8 +217,6 @@ unix:!mac:target.path = $$PREFIX/bin effects.files = $$PWD/effects/*.frag $$PWD/effects/*.xml $$PWD/effects/*.vert unix:!mac:effects.path = $$PREFIX/share/olive-editor/effects -INSTALLS += target effects - unix:!mac { metainfo.files = $$PWD/packaging/linux/org.olivevideoeditor.Olive.appdata.xml metainfo.path = $$PREFIX/share/metainfo @@ -251,5 +240,5 @@ unix:!mac { icon512.path = $$PREFIX/share/icons/hicolor/512x512/apps icon1024.files = $$PWD/packaging/linux/icons/1024x1024/org.olivevideoeditor.Olive.png icon1024.path = $$PREFIX/share/icons/hicolor/1024x1024/apps - INSTALLS += metainfo desktop mime icon16 icon32 icon48 icon64 icon128 icon256 icon512 icon1024 -} \ No newline at end of file + INSTALLS += target effects metainfo desktop mime icon16 icon32 icon48 icon64 icon128 icon256 icon512 icon1024 +} diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp index 468fb43b5..123633448 100644 --- a/panels/effectcontrols.cpp +++ b/panels/effectcontrols.cpp @@ -1,10 +1,16 @@ #include "effectcontrols.h" -#include "ui_effectcontrols.h" #include #include #include #include +#include +#include +#include +#include +#include +#include +#include #include "panels/panels.h" #include "project/effect.h" @@ -18,44 +24,44 @@ #include "panels/viewer.h" #include "ui/viewerwidget.h" #include "io/clipboard.h" +#include "ui/timelineheader.h" +#include "ui/keyframeview.h" +#include "ui/resizablescrollbar.h" #include "debug.h" EffectControls::EffectControls(QWidget *parent) : QDockWidget(parent), multiple(false), - zoom(1), - ui(new Ui::EffectControls), - panel_name("Effects: "), - mode(TA_NO_TRANSITION) + zoom(1), + panel_name("Effects: "), + mode(TA_NO_TRANSITION) { - ui->setupUi(this); + setup_ui(); init_effects(); - clear_effects(false); - ui->headers->viewer = panel_sequence_viewer; - ui->headers->snapping = false; + clear_effects(false); + headers->viewer = panel_sequence_viewer; + headers->snapping = false; - ui->effects_area->parent_widget = ui->scrollArea; - ui->effects_area->keyframe_area = ui->keyframeView; - ui->effects_area->header = ui->headers; - ui->keyframeView->header = ui->headers; + effects_area->parent_widget = scrollArea; + effects_area->keyframe_area = keyframeView; + effects_area->header = headers; + keyframeView->header = headers; - ui->lblMultipleClipsSelected->setVisible(false); + lblMultipleClipsSelected->setVisible(false); - connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), ui->headers, SLOT(set_scroll(int))); - connect(ui->horizontalScrollBar, SIGNAL(resize_move(double)), ui->keyframeView, SLOT(resize_move(double))); - connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), ui->keyframeView, SLOT(set_x_scroll(int))); - connect(ui->verticalScrollBar, SIGNAL(valueChanged(int)), ui->keyframeView, SLOT(set_y_scroll(int))); - connect(ui->verticalScrollBar, SIGNAL(valueChanged(int)), ui->scrollArea->verticalScrollBar(), SLOT(setValue(int))); - connect(ui->scrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)), ui->verticalScrollBar, SLOT(setValue(int))); + connect(horizontalScrollBar, SIGNAL(valueChanged(int)), headers, SLOT(set_scroll(int))); + connect(horizontalScrollBar, SIGNAL(resize_move(double)), keyframeView, SLOT(resize_move(double))); + connect(horizontalScrollBar, SIGNAL(valueChanged(int)), keyframeView, SLOT(set_x_scroll(int))); + connect(verticalScrollBar, SIGNAL(valueChanged(int)), keyframeView, SLOT(set_y_scroll(int))); + connect(verticalScrollBar, SIGNAL(valueChanged(int)), scrollArea->verticalScrollBar(), SLOT(setValue(int))); + connect(scrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)), verticalScrollBar, SLOT(setValue(int))); } -EffectControls::~EffectControls() { - delete ui; -} +EffectControls::~EffectControls() {} bool EffectControls::keyframe_focus() { - return ui->headers->hasFocus() || ui->keyframeView->hasFocus(); + return headers->hasFocus() || keyframeView->hasFocus(); } void EffectControls::set_zoom(bool in) { @@ -64,292 +70,473 @@ 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)); - if ((c->track < 0) == (effect_menu_subtype == EFFECT_TYPE_VIDEO)) { + ComboAction* ca = new ComboAction(); + for (int i=0;iclips.at(selected_clips.at(i)); + if ((c->track < 0) == (effect_menu_subtype == EFFECT_TYPE_VIDEO)) { const EffectMeta* meta = reinterpret_cast(q->data().value()); - if (effect_menu_type == EFFECT_TYPE_TRANSITION) { - if (c->get_opening_transition() == NULL) { - ca->append(new AddTransitionCommand(c, NULL, NULL, meta, TA_OPENING_TRANSITION, 30)); + if (effect_menu_type == EFFECT_TYPE_TRANSITION) { + if (c->get_opening_transition() == NULL) { + ca->append(new AddTransitionCommand(c, NULL, NULL, meta, TA_OPENING_TRANSITION, 30)); } - if (c->get_closing_transition() == NULL) { - ca->append(new AddTransitionCommand(c, NULL, NULL, meta, TA_CLOSING_TRANSITION, 30)); + if (c->get_closing_transition() == NULL) { + ca->append(new AddTransitionCommand(c, NULL, NULL, meta, TA_CLOSING_TRANSITION, 30)); } } else { - ca->append(new AddEffectCommand(c, NULL, meta)); + ca->append(new AddEffectCommand(c, NULL, meta)); } - } - } - undo_stack.push(ca); - if (effect_menu_type == EFFECT_TYPE_TRANSITION) { + } + } + undo_stack.push(ca); + if (effect_menu_type == EFFECT_TYPE_TRANSITION) { update_ui(true); } else { reload_clips(); panel_sequence_viewer->viewer_widget->update(); - } + } } void EffectControls::update_keyframes() { - ui->headers->update_zoom(zoom); - ui->keyframeView->update(); + headers->update_zoom(zoom); + keyframeView->update(); } void EffectControls::delete_selected_keyframes() { - ui->keyframeView->delete_selected_keyframes(); + keyframeView->delete_selected_keyframes(); } void EffectControls::copy(bool del) { - if (mode == TA_NO_TRANSITION) { - bool cleared = false; + if (mode == TA_NO_TRANSITION) { + bool cleared = false; - ComboAction* ca = new ComboAction(); - EffectDeleteCommand* del_com = (del) ? new EffectDeleteCommand() : NULL; - for (int i=0;iclips.at(selected_clips.at(i)); - for (int j=0;jeffects.size();j++) { - Effect* effect = c->effects.at(j); - if (effect->container->selected) { - if (!cleared) { - clear_clipboard(); - cleared = true; + ComboAction* ca = new ComboAction(); + EffectDeleteCommand* del_com = (del) ? new EffectDeleteCommand() : NULL; + for (int i=0;iclips.at(selected_clips.at(i)); + for (int j=0;jeffects.size();j++) { + Effect* effect = c->effects.at(j); + if (effect->container->selected) { + if (!cleared) { + clear_clipboard(); + cleared = true; clipboard_type = CLIPBOARD_TYPE_EFFECT; - } + } - clipboard.append(effect->copy(NULL)); + clipboard.append(effect->copy(NULL)); - if (del_com != NULL) { - del_com->clips.append(c); - del_com->fx.append(j); - } - } - } - } - if (del_com != NULL) { - if (del_com->clips.size() > 0) { - ca->append(del_com); - } else { - delete del_com; - } - } - undo_stack.push(ca); - } + if (del_com != NULL) { + del_com->clips.append(c); + del_com->fx.append(j); + } + } + } + } + if (del_com != NULL) { + if (del_com->clips.size() > 0) { + ca->append(del_com); + } else { + delete del_com; + } + } + undo_stack.push(ca); + } } void EffectControls::show_effect_menu(int type, int subtype) { - effect_menu_type = type; - effect_menu_subtype = subtype; + effect_menu_type = type; + effect_menu_subtype = subtype; - effects_loaded.lock(); + effects_loaded.lock(); - QMenu effects_menu(this); - for (int i=0;isetText(em.name); - action->setData(reinterpret_cast(&em)); + if (em.type == type && em.subtype == subtype) { + QAction* action = new QAction(&effects_menu); + action->setText(em.name); + action->setData(reinterpret_cast(&em)); - QMenu* parent = &effects_menu; - if (!em.category.isEmpty()) { - bool found = false; - for (int j=0;jmenu() != NULL) { - if (action->menu()->title() == em.category) { - parent = action->menu(); - found = true; - break; - } - } - } - if (!found) { - parent = new QMenu(&effects_menu); - parent->setTitle(em.category); + QMenu* parent = &effects_menu; + if (!em.category.isEmpty()) { + bool found = false; + for (int j=0;jmenu() != NULL) { + if (action->menu()->title() == em.category) { + parent = action->menu(); + found = true; + break; + } + } + } + if (!found) { + parent = new QMenu(&effects_menu); + parent->setTitle(em.category); - bool found = false; - for (int i=0;itext() > em.category) { - effects_menu.insertMenu(comp_action, parent); - found = true; - break; - } - } - if (!found) effects_menu.addMenu(parent); - } - } + bool found = false; + for (int i=0;itext() > em.category) { + effects_menu.insertMenu(comp_action, parent); + found = true; + break; + } + } + if (!found) effects_menu.addMenu(parent); + } + } - bool found = false; - for (int i=0;iactions().size();i++) { - QAction* comp_action = parent->actions().at(i); - if (comp_action->text() > action->text()) { - parent->insertAction(comp_action, action); - found = true; - break; - } - } - if (!found) parent->addAction(action); - } - } + bool found = false; + for (int i=0;iactions().size();i++) { + QAction* comp_action = parent->actions().at(i); + if (comp_action->text() > action->text()) { + parent->insertAction(comp_action, action); + found = true; + break; + } + } + if (!found) parent->addAction(action); + } + } - effects_loaded.unlock(); + effects_loaded.unlock(); - connect(&effects_menu, SIGNAL(triggered(QAction*)), this, SLOT(menu_select(QAction*))); - effects_menu.exec(QCursor::pos()); + connect(&effects_menu, SIGNAL(triggered(QAction*)), this, SLOT(menu_select(QAction*))); + effects_menu.exec(QCursor::pos()); } void EffectControls::clear_effects(bool clear_cache) { // clear existing clips deselect_all_effects(NULL); - QVBoxLayout* video_layout = static_cast(ui->video_effect_area->layout()); - QVBoxLayout* audio_layout = static_cast(ui->audio_effect_area->layout()); - QLayoutItem* item; - while ((item = video_layout->takeAt(0))) { - item->widget()->setParent(NULL); + 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(NULL); disconnect(static_cast(item->widget()), SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); - } - while ((item = audio_layout->takeAt(0))) { - item->widget()->setParent(NULL); - disconnect(static_cast(item->widget()), SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); - } - ui->lblMultipleClipsSelected->setVisible(false); - ui->vcontainer->setVisible(false); - ui->acontainer->setVisible(false); - ui->headers->setVisible(false); - ui->keyframeView->setEnabled(false); - if (clear_cache) selected_clips.clear(); - setWindowTitle(panel_name + "(none)"); + } + while ((item = audio_layout->takeAt(0))) { + item->widget()->setParent(NULL); + disconnect(static_cast(item->widget()), SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); + } + lblMultipleClipsSelected->setVisible(false); + vcontainer->setVisible(false); + acontainer->setVisible(false); + headers->setVisible(false); + keyframeView->setEnabled(false); + if (clear_cache) selected_clips.clear(); + setWindowTitle(panel_name + "(none)"); } 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); - } - } - } - panel_sequence_viewer->viewer_widget->update(); + 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); + } + } + } + panel_sequence_viewer->viewer_widget->update(); } void EffectControls::open_effect(QVBoxLayout* layout, Effect* e) { - CollapsibleWidget* container = e->container; - layout->addWidget(container); - connect(container, SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); + CollapsibleWidget* container = e->container; + layout->addWidget(container); + connect(container, SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); +} + +void EffectControls::setup_ui() { + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + + QWidget* contents = new QWidget(); + + QHBoxLayout* layout = new QHBoxLayout(contents); + layout->setSpacing(0); + layout->setMargin(0); + + QSplitter* splitter = new QSplitter(contents); + splitter->setOrientation(Qt::Horizontal); + splitter->setChildrenCollapsible(false); + + scrollArea = new QScrollArea(splitter); + scrollArea->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); + scrollArea->setFrameShape(QFrame::NoFrame); + scrollArea->setFrameShadow(QFrame::Plain); + scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + scrollArea->setWidgetResizable(true); + + QWidget* scrollAreaWidgetContents = new QWidget(); + + QHBoxLayout* scrollAreaLayout = new QHBoxLayout(scrollAreaWidgetContents); + scrollAreaLayout->setSpacing(0); + scrollAreaLayout->setMargin(0); + + effects_area = new EffectsArea(scrollAreaWidgetContents); + + QVBoxLayout* effects_area_layout = new QVBoxLayout(effects_area); + effects_area_layout->setSpacing(0); + effects_area_layout->setMargin(0); + + vcontainer = new QWidget(effects_area); + QVBoxLayout* vcontainerLayout = new QVBoxLayout(vcontainer); + vcontainerLayout->setSpacing(0); + vcontainerLayout->setMargin(0); + + QWidget* veHeader = new QWidget(vcontainer); + veHeader->setObjectName(QStringLiteral("veHeader")); + veHeader->setStyleSheet(QLatin1String("#veHeader { background: rgba(0, 0, 0, 0.25); }")); + + QHBoxLayout* veHeaderLayout = new QHBoxLayout(veHeader); + veHeaderLayout->setSpacing(0); + veHeaderLayout->setMargin(0); + + QPushButton* btnAddVideoEffect = new QPushButton(veHeader); + btnAddVideoEffect->setIcon(QIcon(":/icons/add-effect.png")); + btnAddVideoEffect->setToolTip("Add Video Effect"); + veHeaderLayout->addWidget(btnAddVideoEffect); + connect(btnAddVideoEffect, SIGNAL(clicked(bool)), this, SLOT(video_effect_click())); + + veHeaderLayout->addStretch(); + + QLabel* lblVideoEffects = new QLabel(veHeader); + QFont font; + font.setPointSize(9); + lblVideoEffects->setFont(font); + lblVideoEffects->setAlignment(Qt::AlignCenter); + lblVideoEffects->setText("VIDEO EFFECTS"); + veHeaderLayout->addWidget(lblVideoEffects); + + veHeaderLayout->addStretch(); + + QPushButton* btnAddVideoTransition = new QPushButton(veHeader); + btnAddVideoTransition->setIcon(QIcon(":/icons/add-transition.png")); + btnAddVideoTransition->setToolTip("Add Video Transition"); + connect(btnAddVideoTransition, SIGNAL(clicked(bool)), this, SLOT(video_transition_click())); + + veHeaderLayout->addWidget(btnAddVideoTransition); + + vcontainerLayout->addWidget(veHeader); + + video_effect_area = new QWidget(vcontainer); + QVBoxLayout* veAreaLayout = new QVBoxLayout(video_effect_area); + veAreaLayout->setSpacing(0); + veAreaLayout->setMargin(0); + + vcontainerLayout->addWidget(video_effect_area); + + effects_area_layout->addWidget(vcontainer); + + acontainer = new QWidget(effects_area); + QVBoxLayout* acontainerLayout = new QVBoxLayout(acontainer); + acontainerLayout->setSpacing(0); + acontainerLayout->setMargin(0); + QWidget* aeHeader = new QWidget(acontainer); + aeHeader->setObjectName(QStringLiteral("aeHeader")); + aeHeader->setStyleSheet(QLatin1String("#aeHeader { background: rgba(0, 0, 0, 0.25); }")); + + QHBoxLayout* aeHeaderLayout = new QHBoxLayout(aeHeader); + aeHeaderLayout->setSpacing(0); + aeHeaderLayout->setMargin(0); + + QPushButton* btnAddAudioEffect = new QPushButton(aeHeader); + btnAddAudioEffect->setIcon(QIcon(":/icons/add-effect.png")); + btnAddAudioEffect->setToolTip("Add Audio Effect"); + connect(btnAddAudioEffect, SIGNAL(clicked(bool)), this, SLOT(audio_effect_click())); + aeHeaderLayout->addWidget(btnAddAudioEffect); + + aeHeaderLayout->addStretch(); + + QLabel* lblAudioEffects = new QLabel(aeHeader); + lblAudioEffects->setFont(font); + lblAudioEffects->setAlignment(Qt::AlignCenter); + lblAudioEffects->setText("AUDIO EFFECTS"); + aeHeaderLayout->addWidget(lblAudioEffects); + + aeHeaderLayout->addStretch(); + + QPushButton* btnAddAudioTransition = new QPushButton(aeHeader); + btnAddAudioTransition->setIcon(QIcon(":/icons/add-transition.png")); + btnAddAudioTransition->setToolTip("Add Audio Transition"); + connect(btnAddAudioTransition, SIGNAL(clicked(bool)), this, SLOT(audio_transition_click())); + aeHeaderLayout->addWidget(btnAddAudioTransition); + + acontainerLayout->addWidget(aeHeader); + + audio_effect_area = new QWidget(acontainer); + QVBoxLayout* aeAreaLayout = new QVBoxLayout(audio_effect_area); + aeAreaLayout->setSpacing(0); + aeAreaLayout->setMargin(0); + + acontainerLayout->addWidget(audio_effect_area); + + effects_area_layout->addWidget(acontainer); + + lblMultipleClipsSelected = new QLabel(effects_area); + lblMultipleClipsSelected->setAlignment(Qt::AlignCenter); + lblMultipleClipsSelected->setText("(Multiple clips selected)"); + effects_area_layout->addWidget(lblMultipleClipsSelected); + + effects_area_layout->addStretch(); + + scrollAreaLayout->addWidget(effects_area); + + scrollArea->setWidget(scrollAreaWidgetContents); + splitter->addWidget(scrollArea); + QWidget* keyframeArea = new QWidget(splitter); + QSizePolicy keyframe_sp; + keyframe_sp.setHorizontalPolicy(QSizePolicy::Minimum); + keyframe_sp.setVerticalPolicy(QSizePolicy::Preferred); + keyframe_sp.setHorizontalStretch(1); + keyframeArea->setSizePolicy(keyframe_sp); + QVBoxLayout* keyframeAreaLayout = new QVBoxLayout(keyframeArea); + keyframeAreaLayout->setSpacing(0); + keyframeAreaLayout->setMargin(0); + headers = new TimelineHeader(keyframeArea); + + keyframeAreaLayout->addWidget(headers); + + QWidget* keyframeCenterWidget = new QWidget(keyframeArea); + + QHBoxLayout* keyframeCenterLayout = new QHBoxLayout(keyframeCenterWidget); + keyframeCenterLayout->setSpacing(0); + keyframeCenterLayout->setMargin(0); + + keyframeView = new KeyframeView(keyframeCenterWidget); + + keyframeCenterLayout->addWidget(keyframeView); + + verticalScrollBar = new QScrollBar(keyframeCenterWidget); + verticalScrollBar->setOrientation(Qt::Vertical); + + keyframeCenterLayout->addWidget(verticalScrollBar); + + + keyframeAreaLayout->addWidget(keyframeCenterWidget); + + horizontalScrollBar = new ResizableScrollBar(keyframeArea); + horizontalScrollBar->setOrientation(Qt::Horizontal); + + keyframeAreaLayout->addWidget(horizontalScrollBar); + + splitter->addWidget(keyframeArea); + + layout->addWidget(splitter); + + setWidget(contents); } void EffectControls::load_effects() { - ui->lblMultipleClipsSelected->setVisible(multiple); + lblMultipleClipsSelected->setVisible(multiple); - if (!multiple) { + if (!multiple) { // load in new clips for (int i=0;iclips.at(selected_clips.at(i)); + Clip* c = sequence->clips.at(selected_clips.at(i)); QVBoxLayout* layout; if (c->track < 0) { - ui->vcontainer->setVisible(true); - layout = static_cast(ui->video_effect_area->layout()); + vcontainer->setVisible(true); + layout = static_cast(video_effect_area->layout()); } else { - ui->acontainer->setVisible(true); - layout = static_cast(ui->audio_effect_area->layout()); + acontainer->setVisible(true); + layout = static_cast(audio_effect_area->layout()); + } + if (mode == TA_NO_TRANSITION) { + for (int j=0;jeffects.size();j++) { + open_effect(layout, c->effects.at(j)); + } + } else if (mode == TA_OPENING_TRANSITION && c->get_opening_transition() != NULL) { + open_effect(layout, c->get_opening_transition()); + } else if (mode == TA_CLOSING_TRANSITION && c->get_closing_transition() != NULL) { + open_effect(layout, c->get_closing_transition()); } - if (mode == TA_NO_TRANSITION) { - for (int j=0;jeffects.size();j++) { - open_effect(layout, c->effects.at(j)); - } - } else if (mode == TA_OPENING_TRANSITION && c->get_opening_transition() != NULL) { - open_effect(layout, c->get_opening_transition()); - } else if (mode == TA_CLOSING_TRANSITION && c->get_closing_transition() != NULL) { - open_effect(layout, c->get_closing_transition()); - } } if (selected_clips.size() > 0) { - setWindowTitle(panel_name + sequence->clips.at(selected_clips.at(0))->name); - ui->verticalScrollBar->setMaximum(qMax(0, ui->effects_area->sizeHint().height() - ui->headers->height() + ui->scrollArea->horizontalScrollBar()->height()/* - ui->keyframeView->height() - ui->headers->height()*/)); - ui->keyframeView->setEnabled(true); - ui->headers->setVisible(true); - ui->keyframeView->update(); + setWindowTitle(panel_name + sequence->clips.at(selected_clips.at(0))->name); + verticalScrollBar->setMaximum(qMax(0, effects_area->sizeHint().height() - headers->height() + scrollArea->horizontalScrollBar()->height()/* - keyframeView->height() - headers->height()*/)); + keyframeView->setEnabled(true); + headers->setVisible(true); + keyframeView->update(); } } } void EffectControls::delete_effects() { - // load in new clips - if (mode == TA_NO_TRANSITION) { - EffectDeleteCommand* command = new EffectDeleteCommand(); - for (int i=0;iclips.at(selected_clips.at(i)); - for (int j=0;jeffects.size();j++) { - Effect* effect = c->effects.at(j); - if (effect->container->selected) { - command->clips.append(c); - command->fx.append(j); - } - } - } - if (command->clips.size() > 0) { - undo_stack.push(command); - panel_sequence_viewer->viewer_widget->update(); - } else { - delete command; - } - } + // load in new clips + if (mode == TA_NO_TRANSITION) { + EffectDeleteCommand* command = new EffectDeleteCommand(); + for (int i=0;iclips.at(selected_clips.at(i)); + for (int j=0;jeffects.size();j++) { + Effect* effect = c->effects.at(j); + if (effect->container->selected) { + command->clips.append(c); + command->fx.append(j); + } + } + } + if (command->clips.size() > 0) { + undo_stack.push(command); + panel_sequence_viewer->viewer_widget->update(); + } else { + delete command; + } + } } void EffectControls::reload_clips() { - clear_effects(false); - load_effects(); + clear_effects(false); + load_effects(); } void EffectControls::set_clips(QVector& clips, int m) { - clear_effects(true); + clear_effects(true); - // replace clip vector - selected_clips = clips; - mode = m; + // replace clip vector + selected_clips = clips; + mode = m; - load_effects(); + load_effects(); } -void EffectControls::on_btnAddVideoEffect_clicked() { - show_effect_menu(EFFECT_TYPE_EFFECT, EFFECT_TYPE_VIDEO); +void EffectControls::video_effect_click() { + show_effect_menu(EFFECT_TYPE_EFFECT, EFFECT_TYPE_VIDEO); } -void EffectControls::on_btnAddAudioEffect_clicked() { - show_effect_menu(EFFECT_TYPE_EFFECT, EFFECT_TYPE_AUDIO); +void EffectControls::audio_effect_click() { + show_effect_menu(EFFECT_TYPE_EFFECT, EFFECT_TYPE_AUDIO); } -void EffectControls::on_btnAddVideoTransition_clicked() { - show_effect_menu(EFFECT_TYPE_TRANSITION, EFFECT_TYPE_VIDEO); +void EffectControls::video_transition_click() { + show_effect_menu(EFFECT_TYPE_TRANSITION, EFFECT_TYPE_VIDEO); } -void EffectControls::on_btnAddAudioTransition_clicked() { - show_effect_menu(EFFECT_TYPE_TRANSITION, EFFECT_TYPE_AUDIO); +void EffectControls::audio_transition_click() { + show_effect_menu(EFFECT_TYPE_TRANSITION, EFFECT_TYPE_AUDIO); } void EffectControls::resizeEvent(QResizeEvent*) { - ui->verticalScrollBar->setMaximum(qMax(0, ui->effects_area->height() - ui->keyframeView->height() - ui->headers->height())); + verticalScrollBar->setMaximum(qMax(0, effects_area->height() - keyframeView->height() - headers->height())); } bool EffectControls::is_focused() { - if (this->hasFocus()) return true; - for (int i=0;iclips.at(selected_clips.at(i)); - if (c != NULL) { - for (int j=0;jeffects.size();j++) { - if (c->effects.at(j)->container->is_focused()) { - return true; - } - } - } else { + if (this->hasFocus()) return true; + for (int i=0;iclips.at(selected_clips.at(i)); + if (c != NULL) { + for (int j=0;jeffects.size();j++) { + if (c->effects.at(j)->container->is_focused()) { + return true; + } + } + } else { dout << "[WARNING] Tried to check focus of a NULL clip"; - } - } - return false; + } + } + return false; } EffectsArea::EffectsArea(QWidget* parent) : QWidget(parent) {} diff --git a/panels/effectcontrols.h b/panels/effectcontrols.h index 68d3e6861..564b4f0a8 100644 --- a/panels/effectcontrols.h +++ b/panels/effectcontrols.h @@ -11,6 +11,10 @@ class TimelineHeader; class QScrollArea; class KeyframeView; class QVBoxLayout; +class ResizableScrollBar; +class QLabel; +class KeyframeView; +class QScrollBar; class EffectsArea : public QWidget { public: @@ -21,10 +25,6 @@ public: TimelineHeader* header; }; -namespace Ui { -class EffectControls; -} - class EffectControls : public QDockWidget { Q_OBJECT @@ -32,45 +32,58 @@ class EffectControls : public QDockWidget public: explicit EffectControls(QWidget *parent = 0); ~EffectControls(); - void set_clips(QVector& clips, int mode); - void clear_effects(bool clear_cache); - void delete_effects(); - bool is_focused(); - void reload_clips(); + void set_clips(QVector& clips, int mode); + void clear_effects(bool clear_cache); + void delete_effects(); + bool is_focused(); + void reload_clips(); void set_zoom(bool in); bool keyframe_focus(); void delete_selected_keyframes(); - void copy(bool del); + void copy(bool del); bool multiple; QVector selected_clips; double zoom; - Ui::EffectControls *ui; + ResizableScrollBar* horizontalScrollBar; + QScrollBar* verticalScrollBar; public slots: - void update_keyframes(); + void update_keyframes(); private slots: - void menu_select(QAction* q); + void menu_select(QAction* q); - void on_btnAddVideoEffect_clicked(); - void on_btnAddAudioEffect_clicked(); - void on_btnAddVideoTransition_clicked(); - void on_btnAddAudioTransition_clicked(); + void video_effect_click(); + void audio_effect_click(); + void video_transition_click(); + void audio_transition_click(); - void deselect_all_effects(QWidget*); + void deselect_all_effects(QWidget*); protected: void resizeEvent(QResizeEvent *event); private: - void show_effect_menu(int type, int subtype); + void show_effect_menu(int type, int subtype); void load_effects(); void load_keyframes(); - void open_effect(QVBoxLayout* layout, Effect* e); + void open_effect(QVBoxLayout* layout, Effect* e); - int effect_menu_type; - int effect_menu_subtype; - QString panel_name; - int mode; + void setup_ui(); + + int effect_menu_type; + int effect_menu_subtype; + QString panel_name; + int mode; + + TimelineHeader* headers; + EffectsArea* effects_area; + QScrollArea* scrollArea; + QLabel* lblMultipleClipsSelected; + KeyframeView* keyframeView; + QWidget* video_effect_area; + QWidget* audio_effect_area; + QWidget* vcontainer; + QWidget* acontainer; }; #endif // EFFECTCONTROLS_H diff --git a/panels/effectcontrols.ui b/panels/effectcontrols.ui deleted file mode 100644 index 934fc26ef..000000000 --- a/panels/effectcontrols.ui +++ /dev/null @@ -1,554 +0,0 @@ - - - EffectControls - - - - 0 - 0 - 621 - 510 - - - - - 0 - 0 - - - - QDockWidget::AllDockWidgetFeatures - - - Effect Controls - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Horizontal - - - - - 0 - 0 - - - - QFrame::NoFrame - - - QFrame::Plain - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOn - - - true - - - - - 0 - 0 - 189 - 483 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - #veHeader { - background: rgba(0, 0, 0, 0.25); -} - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Add Video Effect - - - - - - - :/icons/add-effect.png - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 9 - - - - VIDEO EFFECTS - - - Qt::AlignCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Add Video Transition - - - - - - - :/icons/add-transition.png - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - #aeHeader { - background: rgba(0, 0, 0, 0.25); -} - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Add Audio Effect - - - - - - - :/icons/add-effect.png - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 9 - - - - AUDIO EFFECTS - - - Qt::AlignCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Add Audio Transition - - - - - - - :/icons/add-transition.png - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - (Multiple clips selected) - - - Qt::AlignCenter - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - 1 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - 0 - - - 20 - - - 1826 - - - Qt::Vertical - - - - - - - - - - 0 - - - 20 - - - 1826 - - - Qt::Horizontal - - - - - - - - - - - - - KeyframeView - QWidget -
ui/keyframeview.h
- 1 -
- - TimelineHeader - QWidget -
ui/timelineheader.h
- 1 -
- - EffectsArea - QWidget -
panels/effectcontrols.h
- 1 -
- - ResizableScrollBar - QScrollBar -
ui/resizablescrollbar.h
-
-
- - -
diff --git a/panels/project.cpp b/panels/project.cpp index ce3264a6c..96640180b 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -60,84 +60,74 @@ QString recent_proj_file; Project::Project(QWidget *parent) : QDockWidget(parent) { - setObjectName("Project"); - resize(504, 371); - QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - sizePolicy.setHorizontalStretch(0); - sizePolicy.setVerticalStretch(0); - sizePolicy.setHeightForWidth(this->sizePolicy().hasHeightForWidth()); - setSizePolicy(sizePolicy); + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); QWidget* dockWidgetContents = new QWidget(); QVBoxLayout* verticalLayout = new QVBoxLayout(dockWidgetContents); verticalLayout->setContentsMargins(0, 0, 0, 0); - verticalLayout->setSpacing(0); + verticalLayout->setSpacing(0); setWidget(dockWidgetContents); - sources_common = new SourcesCommon(this); + sources_common = new SourcesCommon(this); - sorter = new QSortFilterProxyModel(this); - sorter->setSourceModel(&project_model); + sorter = new QSortFilterProxyModel(this); + sorter->setSourceModel(&project_model); - tree_view = new SourceTable(dockWidgetContents); - tree_view->project_parent = this; - tree_view->setAcceptDrops(true); - tree_view->setEditTriggers(QAbstractItemView::NoEditTriggers); - tree_view->setDragDropMode(QAbstractItemView::DragDrop); - tree_view->setSelectionMode(QAbstractItemView::ExtendedSelection); - tree_view->setModel(sorter); - verticalLayout->addWidget(tree_view); + tree_view = new SourceTable(dockWidgetContents); + tree_view->project_parent = this; + tree_view->setModel(sorter); + verticalLayout->addWidget(tree_view); - icon_view_container = new QWidget(); + icon_view_container = new QWidget(); - QVBoxLayout* icon_view_container_layout = new QVBoxLayout(); - icon_view_container_layout->setMargin(0); - icon_view_container_layout->setSpacing(0); - icon_view_container->setLayout(icon_view_container_layout); + QVBoxLayout* icon_view_container_layout = new QVBoxLayout(); + icon_view_container_layout->setMargin(0); + icon_view_container_layout->setSpacing(0); + icon_view_container->setLayout(icon_view_container_layout); - QHBoxLayout* icon_view_controls = new QHBoxLayout(); - icon_view_controls->setMargin(0); - icon_view_controls->setSpacing(0); + QHBoxLayout* icon_view_controls = new QHBoxLayout(); + icon_view_controls->setMargin(0); + icon_view_controls->setSpacing(0); - QIcon directory_up_button; - directory_up_button.addFile(":/icons/dirup.png", QSize(), QIcon::Normal); - directory_up_button.addFile(":/icons/dirup-disabled.png", QSize(), QIcon::Disabled); + QIcon directory_up_button; + directory_up_button.addFile(":/icons/dirup.png", QSize(), QIcon::Normal); + directory_up_button.addFile(":/icons/dirup-disabled.png", QSize(), QIcon::Disabled); - directory_up = new QPushButton(); - directory_up->setIcon(directory_up_button); - directory_up->setEnabled(false); - icon_view_controls->addWidget(directory_up); + directory_up = new QPushButton(); + directory_up->setIcon(directory_up_button); + directory_up->setEnabled(false); + icon_view_controls->addWidget(directory_up); - icon_view_controls->addStretch(); + icon_view_controls->addStretch(); - QSlider* icon_size_slider = new QSlider(Qt::Horizontal); - icon_size_slider->setMinimum(16); - icon_size_slider->setMaximum(120); - icon_view_controls->addWidget(icon_size_slider); - connect(icon_size_slider, SIGNAL(valueChanged(int)), this, SLOT(set_icon_view_size(int))); + QSlider* icon_size_slider = new QSlider(Qt::Horizontal); + icon_size_slider->setMinimum(16); + icon_size_slider->setMaximum(120); + icon_view_controls->addWidget(icon_size_slider); + connect(icon_size_slider, SIGNAL(valueChanged(int)), this, SLOT(set_icon_view_size(int))); - icon_view_container_layout->addLayout(icon_view_controls); + icon_view_container_layout->addLayout(icon_view_controls); - icon_view = new SourceIconView(dockWidgetContents); - icon_view->project_parent = this; - icon_view->setModel(sorter); - icon_view->setIconSize(QSize(100, 100)); - icon_view->setViewMode(QListView::IconMode); - icon_view->setUniformItemSizes(true); - icon_view_container_layout->addWidget(icon_view); + icon_view = new SourceIconView(dockWidgetContents); + icon_view->project_parent = this; + icon_view->setModel(sorter); + icon_view->setIconSize(QSize(100, 100)); + icon_view->setViewMode(QListView::IconMode); + icon_view->setUniformItemSizes(true); + icon_view_container_layout->addWidget(icon_view); - icon_size_slider->setValue(icon_view->iconSize().height()); + icon_size_slider->setValue(icon_view->iconSize().height()); - verticalLayout->addWidget(icon_view_container); + verticalLayout->addWidget(icon_view_container); - connect(directory_up, SIGNAL(clicked(bool)), this, SLOT(go_up_dir())); - connect(icon_view, SIGNAL(changed_root()), this, SLOT(set_up_dir_enabled())); + connect(directory_up, SIGNAL(clicked(bool)), this, SLOT(go_up_dir())); + connect(icon_view, SIGNAL(changed_root()), this, SLOT(set_up_dir_enabled())); //retranslateUi(Project); setWindowTitle(QApplication::translate("Project", "Project", nullptr)); - update_view_type(); + update_view_type(); } Project::~Project() { @@ -157,8 +147,8 @@ QString Project::get_next_sequence_name(QString start) { name += "0"; } name += QString::number(n); - for (int i=0;iget_name(), name, Qt::CaseInsensitive) == 0) { + for (int i=0;iget_name(), name, Qt::CaseInsensitive) == 0) { found = true; n++; break; @@ -183,11 +173,11 @@ Sequence* create_sequence_from_media(QVector& media_list) { bool got_video_values = false; bool got_audio_values = false; for (int i=0;iget_type()) { + Media* media = media_list.at(i); + switch (media->get_type()) { case MEDIA_TYPE_FOOTAGE: { - Footage* m = media->to_footage(); + Footage* m = media->to_footage(); if (m->ready) { if (!got_video_values) { for (int j=0;jvideo_tracks.size();j++) { @@ -218,7 +208,7 @@ Sequence* create_sequence_from_media(QVector& media_list) { break; case MEDIA_TYPE_SEQUENCE: { - Sequence* seq = media->to_sequence(); + Sequence* seq = media->to_sequence(); s->width = seq->width; s->height = seq->height; s->frame_rate = seq->frame_rate; @@ -237,28 +227,29 @@ Sequence* create_sequence_from_media(QVector& media_list) { } void Project::duplicate_selected() { - QModelIndexList items = tree_view->selectionModel()->selectedRows(); - bool duped = false; - ComboAction* ca = new ComboAction(); - for (int j=0;jget_type() == MEDIA_TYPE_SEQUENCE) { - new_sequence(ca, i->to_sequence()->copy(), false, item_to_media(items.at(j).parent())); - duped = true; - } - } - if (duped) { - undo_stack.push(ca); - } else { - delete ca; - } + QModelIndexList items = get_current_selected(); + bool duped = false; + ComboAction* ca = new ComboAction(); + for (int j=0;jget_type() == MEDIA_TYPE_SEQUENCE) { + new_sequence(ca, i->to_sequence()->copy(), false, item_to_media(items.at(j).parent())); + duped = true; + } + } + if (duped) { + undo_stack.push(ca); + } else { + delete ca; + } } void Project::replace_selected_file() { - QModelIndexList selected_items = tree_view->selectionModel()->selectedRows(); + QModelIndexList selected_items = get_current_selected(); if (selected_items.size() == 1) { - Media* item = item_to_media(selected_items.at(0)); - if (item->get_type() == MEDIA_TYPE_FOOTAGE) { + Media* item = item_to_media(selected_items.at(0)); + if (item->get_type() == MEDIA_TYPE_FOOTAGE) { replace_media(item, 0); } } @@ -266,7 +257,7 @@ void Project::replace_selected_file() { void Project::replace_media(Media* item, QString filename) { if (filename.isEmpty()) { - filename = QFileDialog::getOpenFileName(this, "Replace '" + item->get_name() + "'", "", "All Files (*)"); + filename = QFileDialog::getOpenFileName(this, "Replace '" + item->get_name() + "'", "", "All Files (*)"); } if (!filename.isEmpty()) { ReplaceMediaCommand* rmc = new ReplaceMediaCommand(item, filename); @@ -277,46 +268,43 @@ void Project::replace_media(Media* item, QString filename) { void Project::replace_clip_media() { if (sequence == NULL) { QMessageBox::critical(this, "No active sequence", "No sequence is active, please open the sequence you want to replace clips from.", QMessageBox::Ok); - } else { - QModelIndexList selected_items = tree_view->selectionModel()->selectedRows(); - if (selected_items.size() == 1) { - Media* item = item_to_media(selected_items.at(0)); - if (item->get_type() == MEDIA_TYPE_SEQUENCE && sequence == item->to_sequence()) { - QMessageBox::critical(this, "Active sequence selected", "You cannot insert a sequence into itself, so no clips of this media would be in this sequence.", QMessageBox::Ok); - } else { - ReplaceClipMediaDialog dialog(this, tree_view, item); - dialog.exec(); - } - } + } else { + QModelIndexList selected_items = get_current_selected(); + if (selected_items.size() == 1) { + Media* item = item_to_media(selected_items.at(0)); + if (item->get_type() == MEDIA_TYPE_SEQUENCE && sequence == item->to_sequence()) { + QMessageBox::critical(this, "Active sequence selected", "You cannot insert a sequence into itself, so no clips of this media would be in this sequence.", QMessageBox::Ok); + } else { + ReplaceClipMediaDialog dialog(this, item); + dialog.exec(); + } + } } } void Project::open_properties() { - QModelIndexList selected_items = tree_view->selectionModel()->selectedRows(); - if (selected_items.size() == 1) { - Media* item = item_to_media(selected_items.at(0)); - switch (item->get_type()) { + QModelIndexList selected_items = get_current_selected(); + if (selected_items.size() == 1) { + Media* item = item_to_media(selected_items.at(0)); + switch (item->get_type()) { case MEDIA_TYPE_FOOTAGE: { - MediaPropertiesDialog mpd(this, item); + MediaPropertiesDialog mpd(this, item); mpd.exec(); } break; case MEDIA_TYPE_SEQUENCE: { - NewSequenceDialog nsd(this); - Sequence* s = item->to_sequence(); - nsd.existing_sequence = s; - nsd.existing_item = item; + NewSequenceDialog nsd(this, item); nsd.exec(); } break; default: { // fall back to renaming - QString new_name = QInputDialog::getText(this, "Rename '" + item->get_name() + "'", "Enter new name:", QLineEdit::Normal, item->get_name()); - if (!new_name.isEmpty()) { - MediaRename* mr = new MediaRename(item, new_name); + QString new_name = QInputDialog::getText(this, "Rename '" + item->get_name() + "'", "Enter new name:", QLineEdit::Normal, item->get_name()); + if (!new_name.isEmpty()) { + MediaRename* mr = new MediaRename(item, new_name); undo_stack.push(mr); } } @@ -325,18 +313,18 @@ void Project::open_properties() { } Media* Project::new_sequence(ComboAction *ca, Sequence *s, bool open, Media* parent) { - if (parent == NULL) parent = project_model.get_root(); - Media* item = new Media(parent); - item->set_sequence(s); + if (parent == NULL) parent = project_model.get_root(); + Media* item = new Media(parent); + item->set_sequence(s); - if (ca != NULL) { - ca->append(new NewSequenceCommand(item, parent)); - if (open) ca->append(new ChangeSequenceAction(s)); - } else { - project_model.appendChild(NULL, item); - if (open) set_sequence(s); + if (ca != NULL) { + ca->append(new NewSequenceCommand(item, parent)); + if (open) ca->append(new ChangeSequenceAction(s)); + } else { + project_model.appendChild(NULL, item); + if (open) set_sequence(s); } - return item; + return item; } QString Project::get_file_name_from_path(const QString& path) { @@ -344,233 +332,229 @@ QString Project::get_file_name_from_path(const QString& path) { } /*Media* Project::new_item() { - Media* item = new Media(0); - //item->setFlags(item->flags() | Qt::ItemIsEditable); - return item; + Media* item = new Media(0); + //item->setFlags(item->flags() | Qt::ItemIsEditable); + return item; }*/ bool Project::is_focused() { - return tree_view->hasFocus(); + return tree_view->hasFocus() || icon_view->hasFocus(); } Media* Project::new_folder(QString name) { - Media* item = new Media(0); - item->set_folder(); - return item; + Media* item = new Media(0); + item->set_folder(); + return item; } Media *Project::item_to_media(const QModelIndex &index) { - return static_cast(sorter->mapToSource(index).internalPointer()); + return static_cast(sorter->mapToSource(index).internalPointer()); // return static_cast(index.internalPointer()); } -void Project::get_all_media_from_table(QList items, QList& list, int search_type) { - for (int i=0;iget_type() == MEDIA_TYPE_FOLDER) { - QList children; - for (int j=0;jchildCount();j++) { - children.append(item->child(j)); - } +void Project::get_all_media_from_table(QList& items, QList& list, int search_type) { + for (int i=0;iget_type() == MEDIA_TYPE_FOLDER) { + QList children; + for (int j=0;jchildCount();j++) { + children.append(item->child(j)); + } get_all_media_from_table(children, list, search_type); - } else if (search_type == item->get_type() || search_type == -1) { - list.append(item); - } - } + } else if (search_type == item->get_type() || search_type == -1) { + list.append(item); + } + } } bool delete_clips_in_clipboard_with_media(ComboAction* ca, Media* m) { - int delete_count = 0; - if (clipboard_type == CLIPBOARD_TYPE_CLIP) { - for (int i=0;i(clipboard.at(i)); - if (c->media == m) { - ca->append(new RemoveClipsFromClipboard(i-delete_count)); - delete_count++; - } - } - } - return (delete_count > 0); + int delete_count = 0; + if (clipboard_type == CLIPBOARD_TYPE_CLIP) { + for (int i=0;i(clipboard.at(i)); + if (c->media == m) { + ca->append(new RemoveClipsFromClipboard(i-delete_count)); + delete_count++; + } + } + } + return (delete_count > 0); } void Project::delete_selected_media() { - ComboAction* ca = new ComboAction(); - QModelIndexList selected_items = tree_view->selectionModel()->selectedRows(); - QList items; - for (int i=0;i items; + for (int i=0;isetSortingEnabled(false); - tree_view->setSortingEnabled(true); - - // check if media is in use - QVector parents; - QList sequence_items; - QList all_top_level_items; - for (int i=0;i parents; + QList sequence_items; + QList all_top_level_items; + for (int i=0;i 0) { - QList media_items; + if (sequence_items.size() > 0) { + QList media_items; get_all_media_from_table(items, media_items, MEDIA_TYPE_FOOTAGE); - for (int i=0;ito_footage(); - bool confirm_delete = false; - for (int j=0;jto_sequence(); - for (int k=0;kclips.size();k++) { - Clip* c = s->clips.at(k); - if (c != NULL && c->media == item) { - if (!confirm_delete) { - // we found a reference, so we know we'll need to ask if the user wants to delete it - QMessageBox confirm(this); - confirm.setWindowTitle("Delete media in use?"); - confirm.setText("The media '" + media->name + "' is currently used in '" + s->name + "'. Deleting it will remove all instances in the sequence. Are you sure you want to do this?"); - QAbstractButton* yes_button = confirm.addButton(QMessageBox::Yes); - QAbstractButton* skip_button = NULL; - if (items.size() > 1) skip_button = confirm.addButton("Skip", QMessageBox::NoRole); - QAbstractButton* abort_button = confirm.addButton(QMessageBox::Cancel); - confirm.exec(); - if (confirm.clickedButton() == yes_button) { - // remove all clips referencing this media - confirm_delete = true; - redraw = true; - } else if (confirm.clickedButton() == skip_button) { - // remove media item and any folders containing it from the remove list - Media* parent = item; - while (parent != NULL) { - parents.append(parent); + for (int i=0;ito_footage(); + bool confirm_delete = false; + for (int j=0;jto_sequence(); + for (int k=0;kclips.size();k++) { + Clip* c = s->clips.at(k); + if (c != NULL && c->media == item) { + if (!confirm_delete) { + // we found a reference, so we know we'll need to ask if the user wants to delete it + QMessageBox confirm(this); + confirm.setWindowTitle("Delete media in use?"); + confirm.setText("The media '" + media->name + "' is currently used in '" + s->name + "'. Deleting it will remove all instances in the sequence. Are you sure you want to do this?"); + QAbstractButton* yes_button = confirm.addButton(QMessageBox::Yes); + QAbstractButton* skip_button = NULL; + if (items.size() > 1) skip_button = confirm.addButton("Skip", QMessageBox::NoRole); + QAbstractButton* abort_button = confirm.addButton(QMessageBox::Cancel); + confirm.exec(); + if (confirm.clickedButton() == yes_button) { + // remove all clips referencing this media + confirm_delete = true; + redraw = true; + } else if (confirm.clickedButton() == skip_button) { + // remove media item and any folders containing it from the remove list + Media* parent = item; + while (parent != NULL) { + parents.append(parent); - // re-add item's siblings - for (int m=0;mchildCount();m++) { - Media* child = parent->child(m); - bool found = false; - for (int n=0;nchildCount();m++) { + Media* child = parent->child(m); + bool found = false; + for (int n=0;nparentItem(); - } + parent = parent->parentItem(); + } - j = sequence_items.size(); - k = s->clips.size(); - } else if (confirm.clickedButton() == abort_button) { - // break out of loop - i = media_items.size(); - j = sequence_items.size(); - k = s->clips.size(); + j = sequence_items.size(); + k = s->clips.size(); + } else if (confirm.clickedButton() == abort_button) { + // break out of loop + i = media_items.size(); + j = sequence_items.size(); + k = s->clips.size(); - remove = false; - } - } - if (confirm_delete) { - ca->append(new DeleteClipAction(s, k)); - } - } - } + remove = false; + } + } + if (confirm_delete) { + ca->append(new DeleteClipAction(s, k)); + } + } + } } if (confirm_delete) { - delete_clips_in_clipboard_with_media(ca, item); + delete_clips_in_clipboard_with_media(ca, item); } - } - } + } + } - // remove - if (remove) { - // remove media and parents - for (int m=0;mappend(new DeleteMediaCommand(items.at(i))); + ca->append(new DeleteMediaCommand(items.at(i))); - if (items.at(i)->get_type() == MEDIA_TYPE_SEQUENCE) { - redraw = true; + if (items.at(i)->get_type() == MEDIA_TYPE_SEQUENCE) { + redraw = true; - Sequence* s = items.at(i)->to_sequence(); + Sequence* s = items.at(i)->to_sequence(); if (s == sequence) { - ca->append(new ChangeSequenceAction(NULL)); - } + ca->append(new ChangeSequenceAction(NULL)); + } if (s == panel_footage_viewer->seq) { - panel_footage_viewer->set_media(NULL); + panel_footage_viewer->set_media(NULL); } - } else if (items.at(i)->get_type() == MEDIA_TYPE_FOOTAGE) { + } else if (items.at(i)->get_type() == MEDIA_TYPE_FOOTAGE) { if (panel_footage_viewer->seq != NULL) { for (int j=0;jseq->clips.size();j++) { Clip* c = panel_footage_viewer->seq->clips.at(j); if (c != NULL) { - if (c->media == items.at(i)->to_object()) { - panel_footage_viewer->set_media(NULL); + if (c->media == items.at(i)->to_object()) { + panel_footage_viewer->set_media(NULL); } break; } } } } - } - undo_stack.push(ca); + } + undo_stack.push(ca); - // redraw clips - if (redraw) { + // redraw clips + if (redraw) { update_ui(true); } - } else { - delete ca; - } + } else { + delete ca; + } } void Project::start_preview_generator(Media* item, bool replacing) { - // set up throbber animation - MediaThrobber* throbber = new MediaThrobber(item); - throbber->moveToThread(QApplication::instance()->thread()); - item->throbber = throbber; - QMetaObject::invokeMethod(throbber, "start", Qt::QueuedConnection); + // set up throbber animation + MediaThrobber* throbber = new MediaThrobber(item); + throbber->moveToThread(QApplication::instance()->thread()); + item->throbber = throbber; + QMetaObject::invokeMethod(throbber, "start", Qt::QueuedConnection); - PreviewGenerator* pg = new PreviewGenerator(item, item->to_footage(), replacing); - item->to_footage()->preview_gen = pg; - connect(pg, SIGNAL(set_icon(int, bool)), throbber, SLOT(stop(int, bool))); - pg->start(QThread::LowPriority); + PreviewGenerator* pg = new PreviewGenerator(item, item->to_footage(), replacing); + item->to_footage()->preview_gen = pg; + connect(pg, SIGNAL(set_icon(int, bool)), throbber, SLOT(stop(int, bool))); + pg->start(QThread::LowPriority); } void Project::process_file_list(QStringList& files, bool recursive, Media* replace, Media* parent) { - bool imported = false; + bool imported = false; - QVector image_sequence_urls; - QVector image_sequence_importassequence; - QStringList image_sequence_formats = config.img_seq_formats.split("|"); + QVector image_sequence_urls; + QVector image_sequence_importassequence; + QStringList image_sequence_formats = config.img_seq_formats.split("|"); if (!recursive) last_imported_media.clear(); bool create_undo_action = (!recursive && replace == NULL); - ComboAction* ca; - if (create_undo_action) ca = new ComboAction(); + ComboAction* ca; + if (create_undo_action) ca = new ComboAction(); for (int i=0;iappend(new AddMediaCommand(folder, parent)); - } else { - project_model.appendChild(parent, folder); + if (create_undo_action) { + ca->append(new AddMediaCommand(folder, parent)); + } else { + project_model.appendChild(parent, folder); } imported = true; @@ -668,80 +652,87 @@ void Project::process_file_list(QStringList& files, bool recursive, Media* repla } if (!skip) { - Media* item; + Media* item; Footage* m; if (replace != NULL) { item = replace; - m = replace->to_footage(); + m = replace->to_footage(); m->reset(); } else { - item = new Media(parent); + item = new Media(parent); m = new Footage(); } - m->using_inout = false; - m->url = file; + m->using_inout = false; + m->url = file; m->name = get_file_name_from_path(files.at(i)); - item->set_footage(m); + item->set_footage(m); - // generate waveform/thumbnail in another thread - start_preview_generator(item, replace != NULL); + // generate waveform/thumbnail in another thread + start_preview_generator(item, replace != NULL); - last_imported_media.append(item); + last_imported_media.append(item); if (replace == NULL) { if (create_undo_action) { - ca->append(new AddMediaCommand(item, parent)); + ca->append(new AddMediaCommand(item, parent)); } else { - project_model.appendChild(parent, item); + project_model.appendChild(parent, item); } } imported = true; } } - } + } if (create_undo_action) { if (imported) { - undo_stack.push(ca); + undo_stack.push(ca); } else { - delete ca; + delete ca; } } } Media* Project::get_selected_folder() { // if one item is selected and it's a folder, return it - QModelIndexList selected_items = tree_view->selectionModel()->selectedRows(); - if (selected_items.size() == 1) { - Media* m = item_to_media(selected_items.at(0)); - if (m->get_type() == MEDIA_TYPE_FOLDER) return m; + QModelIndexList selected_items = get_current_selected(); + if (selected_items.size() == 1) { + Media* m = item_to_media(selected_items.at(0)); + if (m->get_type() == MEDIA_TYPE_FOLDER) return m; } - return NULL; + return NULL; } bool Project::reveal_media(Media *media, QModelIndex parent) { - for (int i=0;iget_type() == MEDIA_TYPE_FOLDER) { + if (m->get_type() == MEDIA_TYPE_FOLDER) { if (reveal_media(media, item)) return true; - } else if (m == media) { + } else if (m == media) { // expand all folders leading to this media - QModelIndex sorted_index = sorter->mapFromSource(item); + QModelIndex sorted_index = sorter->mapFromSource(item); - QModelIndex hierarchy = sorted_index.parent(); - while (hierarchy.isValid()) { - tree_view->setExpanded(hierarchy, true); - hierarchy = hierarchy.parent(); + QModelIndex hierarchy = sorted_index.parent(); + + if (config.project_view_type == PROJECT_VIEW_TREE) { + while (hierarchy.isValid()) { + tree_view->setExpanded(hierarchy, true); + hierarchy = hierarchy.parent(); + } + + // select item + tree_view->selectionModel()->select(sorted_index, QItemSelectionModel::Select); + } else if (config.project_view_type == PROJECT_VIEW_ICON) { + icon_view->setRootIndex(hierarchy); + icon_view->selectionModel()->select(sorted_index, QItemSelectionModel::Select); + set_up_dir_enabled(); } - // select item - tree_view->selectionModel()->select(sorted_index, QItemSelectionModel::Select); - return true; } } @@ -755,7 +746,7 @@ void Project::import_dialog() { if (fd.exec()) { QStringList files = fd.selectedFiles(); - process_file_list(files, false, NULL, get_selected_folder()); + process_file_list(files, false, NULL, get_selected_folder()); } } @@ -763,30 +754,30 @@ void Project::delete_clips_using_selected_media() { if (sequence == NULL) { QMessageBox::critical(this, "No active sequence", "No sequence is active, please open the sequence you want to delete clips from.", QMessageBox::Ok); } else { - ComboAction* ca = new ComboAction(); + ComboAction* ca = new ComboAction(); bool deleted = false; - QModelIndexList items = tree_view->selectionModel()->selectedRows(); - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + QModelIndexList items = get_current_selected(); + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); if (c != NULL) { for (int j=0;jmedia == m) { - ca->append(new DeleteClipAction(sequence, i)); + ca->append(new DeleteClipAction(sequence, i)); deleted = true; } } } } for (int j=0;jclear_effects(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(); - sequences.at(i)->set_sequence(NULL); - } + // 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(); + sequences.at(i)->set_sequence(NULL); + } - // delete everything else - project_model.clear(); + // delete everything else + project_model.clear(); } void Project::new_project() { // clear existing project - set_sequence(NULL); - panel_footage_viewer->set_media(NULL); - clear(); + set_sequence(NULL); + panel_footage_viewer->set_media(NULL); + clear(); mainWindow->setWindowModified(false); } void Project::load_project(bool autorecovery) { - new_project(); + new_project(); - LoadDialog ld(this, autorecovery); - ld.exec(); + LoadDialog ld(this, autorecovery); + ld.exec(); } void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, const QModelIndex& parent) { - bool root = (!parent.parent().isValid()); - for (int i=0;iget_type()) { - if (m->get_type() == MEDIA_TYPE_FOLDER) { - if (set_ids_only) { - m->temp_id = folder_id; // saves a temporary ID for matching in the project file - folder_id++; - } else { - // if we're saving folders, save the folder - stream.writeStartElement("folder"); - stream.writeAttribute("name", m->get_name()); - stream.writeAttribute("id", QString::number(m->temp_id)); - if (!item.parent().isValid()) { - stream.writeAttribute("parent", "0"); - } else { - stream.writeAttribute("parent", QString::number(project_model.getItem(item.parent())->temp_id)); - } - stream.writeEndElement(); - } + if (type == m->get_type()) { + if (m->get_type() == MEDIA_TYPE_FOLDER) { + if (set_ids_only) { + m->temp_id = folder_id; // saves a temporary ID for matching in the project file + folder_id++; + } else { + // if we're saving folders, save the folder + stream.writeStartElement("folder"); + stream.writeAttribute("name", m->get_name()); + stream.writeAttribute("id", QString::number(m->temp_id)); + if (!item.parent().isValid()) { + stream.writeAttribute("parent", "0"); + } else { + stream.writeAttribute("parent", QString::number(project_model.getItem(item.parent())->temp_id)); + } + stream.writeEndElement(); + } // save_folder(stream, item, type, set_ids_only); - } else { - int folder = root ? 0 : project_model.getItem(parent)->temp_id; - if (type == MEDIA_TYPE_FOOTAGE) { - Footage* f = m->to_footage(); - f->save_id = media_id; - stream.writeStartElement("footage"); - stream.writeAttribute("id", QString::number(media_id)); - stream.writeAttribute("folder", QString::number(folder)); - stream.writeAttribute("name", f->name); - stream.writeAttribute("url", proj_dir.relativeFilePath(f->url)); - stream.writeAttribute("duration", QString::number(f->length)); - stream.writeAttribute("using_inout", QString::number(f->using_inout)); - stream.writeAttribute("in", QString::number(f->in)); - stream.writeAttribute("out", QString::number(f->out)); - for (int j=0;jvideo_tracks.size();j++) { - FootageStream* ms = f->video_tracks.at(j); - stream.writeStartElement("video"); - stream.writeAttribute("id", QString::number(ms->file_index)); - stream.writeAttribute("width", QString::number(ms->video_width)); - stream.writeAttribute("height", QString::number(ms->video_height)); + } else { + int folder = root ? 0 : project_model.getItem(parent)->temp_id; + if (type == MEDIA_TYPE_FOOTAGE) { + Footage* f = m->to_footage(); + f->save_id = media_id; + stream.writeStartElement("footage"); + stream.writeAttribute("id", QString::number(media_id)); + stream.writeAttribute("folder", QString::number(folder)); + stream.writeAttribute("name", f->name); + stream.writeAttribute("url", proj_dir.relativeFilePath(f->url)); + stream.writeAttribute("duration", QString::number(f->length)); + stream.writeAttribute("using_inout", QString::number(f->using_inout)); + stream.writeAttribute("in", QString::number(f->in)); + stream.writeAttribute("out", QString::number(f->out)); + for (int j=0;jvideo_tracks.size();j++) { + FootageStream* ms = f->video_tracks.at(j); + stream.writeStartElement("video"); + stream.writeAttribute("id", QString::number(ms->file_index)); + stream.writeAttribute("width", QString::number(ms->video_width)); + stream.writeAttribute("height", QString::number(ms->video_height)); stream.writeAttribute("framerate", QString::number(ms->video_frame_rate, 'f', 10)); - stream.writeAttribute("infinite", QString::number(ms->infinite_length)); - stream.writeEndElement(); - } - for (int j=0;jaudio_tracks.size();j++) { - FootageStream* ms = f->audio_tracks.at(j); - stream.writeStartElement("audio"); - stream.writeAttribute("id", QString::number(ms->file_index)); - stream.writeAttribute("channels", QString::number(ms->audio_channels)); - stream.writeAttribute("layout", QString::number(ms->audio_layout)); - stream.writeAttribute("frequency", QString::number(ms->audio_frequency)); - stream.writeEndElement(); - } - stream.writeEndElement(); - media_id++; - } else if (type == MEDIA_TYPE_SEQUENCE) { - Sequence* s = m->to_sequence(); - if (set_ids_only) { - s->save_id = sequence_id; - sequence_id++; - } else { - stream.writeStartElement("sequence"); - stream.writeAttribute("id", QString::number(s->save_id)); - stream.writeAttribute("folder", QString::number(folder)); - stream.writeAttribute("name", s->name); - stream.writeAttribute("width", QString::number(s->width)); - stream.writeAttribute("height", QString::number(s->height)); + stream.writeAttribute("infinite", QString::number(ms->infinite_length)); + stream.writeEndElement(); + } + for (int j=0;jaudio_tracks.size();j++) { + FootageStream* ms = f->audio_tracks.at(j); + stream.writeStartElement("audio"); + stream.writeAttribute("id", QString::number(ms->file_index)); + stream.writeAttribute("channels", QString::number(ms->audio_channels)); + stream.writeAttribute("layout", QString::number(ms->audio_layout)); + stream.writeAttribute("frequency", QString::number(ms->audio_frequency)); + stream.writeEndElement(); + } + stream.writeEndElement(); + media_id++; + } else if (type == MEDIA_TYPE_SEQUENCE) { + Sequence* s = m->to_sequence(); + if (set_ids_only) { + s->save_id = sequence_id; + sequence_id++; + } else { + stream.writeStartElement("sequence"); + stream.writeAttribute("id", QString::number(s->save_id)); + stream.writeAttribute("folder", QString::number(folder)); + stream.writeAttribute("name", s->name); + stream.writeAttribute("width", QString::number(s->width)); + stream.writeAttribute("height", QString::number(s->height)); stream.writeAttribute("framerate", QString::number(s->frame_rate, 'f', 10)); - stream.writeAttribute("afreq", QString::number(s->audio_frequency)); - stream.writeAttribute("alayout", QString::number(s->audio_layout)); - if (s == sequence) { - stream.writeAttribute("open", "1"); + stream.writeAttribute("afreq", QString::number(s->audio_frequency)); + stream.writeAttribute("alayout", QString::number(s->audio_layout)); + if (s == sequence) { + stream.writeAttribute("open", "1"); } stream.writeAttribute("workarea", QString::number(s->using_workarea)); stream.writeAttribute("workareaIn", QString::number(s->workarea_in)); stream.writeAttribute("workareaOut", QString::number(s->workarea_out)); - for (int j=0;jtransitions.size();j++) { - Transition* t = s->transitions.at(j); - if (t != NULL) { - stream.writeStartElement("transition"); - stream.writeAttribute("id", QString::number(j)); - stream.writeAttribute("length", QString::number(t->get_true_length())); - t->save(stream); - stream.writeEndElement(); // transition - } - } + for (int j=0;jtransitions.size();j++) { + Transition* t = s->transitions.at(j); + if (t != NULL) { + stream.writeStartElement("transition"); + stream.writeAttribute("id", QString::number(j)); + stream.writeAttribute("length", QString::number(t->get_true_length())); + t->save(stream); + stream.writeEndElement(); // transition + } + } - for (int j=0;jclips.size();j++) { - Clip* c = s->clips.at(j); - if (c != NULL) { - stream.writeStartElement("clip"); // clip - stream.writeAttribute("id", QString::number(j)); + for (int j=0;jclips.size();j++) { + Clip* c = s->clips.at(j); + if (c != NULL) { + stream.writeStartElement("clip"); // clip + stream.writeAttribute("id", QString::number(j)); stream.writeAttribute("enabled", QString::number(c->enabled)); - stream.writeAttribute("name", c->name); - stream.writeAttribute("clipin", QString::number(c->clip_in)); - stream.writeAttribute("in", QString::number(c->timeline_in)); - stream.writeAttribute("out", QString::number(c->timeline_out)); - stream.writeAttribute("track", QString::number(c->track)); - stream.writeAttribute("opening", QString::number(c->opening_transition)); - stream.writeAttribute("closing", QString::number(c->closing_transition)); + stream.writeAttribute("name", c->name); + stream.writeAttribute("clipin", QString::number(c->clip_in)); + stream.writeAttribute("in", QString::number(c->timeline_in)); + stream.writeAttribute("out", QString::number(c->timeline_out)); + stream.writeAttribute("track", QString::number(c->track)); + stream.writeAttribute("opening", QString::number(c->opening_transition)); + stream.writeAttribute("closing", QString::number(c->closing_transition)); - stream.writeAttribute("r", QString::number(c->color_r)); - stream.writeAttribute("g", QString::number(c->color_g)); - stream.writeAttribute("b", QString::number(c->color_b)); + stream.writeAttribute("r", QString::number(c->color_r)); + stream.writeAttribute("g", QString::number(c->color_g)); + stream.writeAttribute("b", QString::number(c->color_b)); - stream.writeAttribute("autoscale", QString::number(c->autoscale)); + stream.writeAttribute("autoscale", QString::number(c->autoscale)); stream.writeAttribute("speed", QString::number(c->speed, 'f', 10)); - stream.writeAttribute("maintainpitch", QString::number(c->maintain_audio_pitch)); - stream.writeAttribute("reverse", QString::number(c->reverse)); + stream.writeAttribute("maintainpitch", QString::number(c->maintain_audio_pitch)); + stream.writeAttribute("reverse", QString::number(c->reverse)); if (c->media != NULL) { stream.writeAttribute("type", QString::number(c->media->get_type())); @@ -949,186 +940,193 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, } } - stream.writeStartElement("linked"); // linked - for (int k=0;klinked.size();k++) { - stream.writeStartElement("link"); // link - stream.writeAttribute("id", QString::number(c->linked.at(k))); - stream.writeEndElement(); // link - } - stream.writeEndElement(); // linked + stream.writeStartElement("linked"); // linked + for (int k=0;klinked.size();k++) { + stream.writeStartElement("link"); // link + stream.writeAttribute("id", QString::number(c->linked.at(k))); + stream.writeEndElement(); // link + } + stream.writeEndElement(); // linked - for (int k=0;keffects.size();k++) { + for (int k=0;keffects.size();k++) { stream.writeStartElement("effect"); // effect c->effects.at(k)->save(stream); stream.writeEndElement(); // effect - } + } - stream.writeEndElement(); // clip - } - } + stream.writeEndElement(); // clip + } + } for (int j=0;jmarkers.size();j++) { stream.writeStartElement("marker"); stream.writeAttribute("frame", QString::number(s->markers.at(j).frame)); stream.writeAttribute("name", s->markers.at(j).name); stream.writeEndElement(); } - stream.writeEndElement(); - } - } - } - } - - if (m->get_type() == MEDIA_TYPE_FOLDER) { - save_folder(stream, type, set_ids_only, item); + stream.writeEndElement(); + } + } + } } - } + + if (m->get_type() == MEDIA_TYPE_FOLDER) { + save_folder(stream, type, set_ids_only, item); + } + } } void Project::save_project(bool autorecovery) { - folder_id = 1; - media_id = 1; - sequence_id = 1; + folder_id = 1; + media_id = 1; + sequence_id = 1; - QFile file(autorecovery ? autorecovery_filename : project_url); - if (!file.open(QIODevice::WriteOnly/* | QIODevice::Text*/)) { + QFile file(autorecovery ? autorecovery_filename : project_url); + if (!file.open(QIODevice::WriteOnly/* | QIODevice::Text*/)) { dout << "[ERROR] Could not open file"; - return; - } + return; + } - QXmlStreamWriter stream(&file); - stream.setAutoFormatting(true); - stream.writeStartDocument(); // doc + QXmlStreamWriter stream(&file); + stream.setAutoFormatting(true); + stream.writeStartDocument(); // doc - stream.writeStartElement("project"); // project + stream.writeStartElement("project"); // project stream.writeTextElement("version", QString::number(SAVE_VERSION)); - stream.writeTextElement("url", project_url); - proj_dir = QFileInfo(project_url).absoluteDir(); + stream.writeTextElement("url", project_url); + proj_dir = QFileInfo(project_url).absoluteDir(); - save_folder(stream, MEDIA_TYPE_FOLDER, true); + save_folder(stream, MEDIA_TYPE_FOLDER, true); - stream.writeStartElement("folders"); // folders - save_folder(stream, MEDIA_TYPE_FOLDER, false); - stream.writeEndElement(); // folders + stream.writeStartElement("folders"); // folders + save_folder(stream, MEDIA_TYPE_FOLDER, false); + stream.writeEndElement(); // folders - stream.writeStartElement("media"); // media - save_folder(stream, MEDIA_TYPE_FOOTAGE, false); - stream.writeEndElement(); // media + stream.writeStartElement("media"); // media + save_folder(stream, MEDIA_TYPE_FOOTAGE, false); + stream.writeEndElement(); // media - save_folder(stream, MEDIA_TYPE_SEQUENCE, true); + save_folder(stream, MEDIA_TYPE_SEQUENCE, true); - stream.writeStartElement("sequences"); // sequences - save_folder(stream, MEDIA_TYPE_SEQUENCE, false); - stream.writeEndElement();// sequences + stream.writeStartElement("sequences"); // sequences + save_folder(stream, MEDIA_TYPE_SEQUENCE, false); + stream.writeEndElement();// sequences - stream.writeEndElement(); // project + stream.writeEndElement(); // project - stream.writeEndDocument(); // doc + stream.writeEndDocument(); // doc - file.close(); + file.close(); - if (!autorecovery) { - add_recent_project(project_url); + if (!autorecovery) { + add_recent_project(project_url); mainWindow->setWindowModified(false); - } + } } void Project::update_view_type() { - tree_view->setVisible(config.project_view_type == PROJECT_VIEW_TREE); - icon_view_container->setVisible(config.project_view_type == PROJECT_VIEW_ICON); + tree_view->setVisible(config.project_view_type == PROJECT_VIEW_TREE); + icon_view_container->setVisible(config.project_view_type == PROJECT_VIEW_ICON); - switch (config.project_view_type) { - case PROJECT_VIEW_TREE: - sources_common->view = tree_view; - break; - case PROJECT_VIEW_ICON: - sources_common->view = icon_view; - break; - } + switch (config.project_view_type) { + case PROJECT_VIEW_TREE: + sources_common->view = tree_view; + break; + case PROJECT_VIEW_ICON: + sources_common->view = icon_view; + break; + } } void Project::set_icon_view() { - config.project_view_type = PROJECT_VIEW_ICON; - update_view_type(); + config.project_view_type = PROJECT_VIEW_ICON; + update_view_type(); } void Project::set_tree_view() { - config.project_view_type = PROJECT_VIEW_TREE; - update_view_type(); + config.project_view_type = PROJECT_VIEW_TREE; + update_view_type(); } void Project::save_recent_projects() { - // save to file - QFile f(recent_proj_file); - if (f.open(QFile::WriteOnly | QFile::Truncate | QFile::Text)) { - QTextStream out(&f); - for (int i=0;i 0) { - out << "\n"; - } - out << recent_projects.at(i); - } - f.close(); - } else { + // save to file + QFile f(recent_proj_file); + if (f.open(QFile::WriteOnly | QFile::Truncate | QFile::Text)) { + QTextStream out(&f); + for (int i=0;i 0) { + out << "\n"; + } + out << recent_projects.at(i); + } + f.close(); + } else { dout << "[WARNING] Could not save recent projects"; - } + } } void Project::clear_recent_projects() { - recent_projects.clear(); - save_recent_projects(); + recent_projects.clear(); + save_recent_projects(); } void Project::set_icon_view_size(int s) { - icon_view->setIconSize(QSize(s, s)); + icon_view->setIconSize(QSize(s, s)); } void Project::set_up_dir_enabled() { - directory_up->setEnabled(icon_view->rootIndex().isValid()); + directory_up->setEnabled(icon_view->rootIndex().isValid()); } void Project::go_up_dir() { - icon_view->setRootIndex(icon_view->rootIndex().parent()); - set_up_dir_enabled(); + icon_view->setRootIndex(icon_view->rootIndex().parent()); + set_up_dir_enabled(); } void Project::add_recent_project(QString url) { - bool found = false; - for (int i=0;i MAXIMUM_RECENT_PROJECTS) { - recent_projects.removeLast(); - } - } - save_recent_projects(); + bool found = false; + for (int i=0;i MAXIMUM_RECENT_PROJECTS) { + recent_projects.removeLast(); + } + } + save_recent_projects(); } void Project::list_all_sequences_worker(QVector* list, Media* parent) { - for (int i=0;iget_type()) { - case MEDIA_TYPE_SEQUENCE: - list->append(item); - break; - case MEDIA_TYPE_FOLDER: - list_all_sequences_worker(list, item); - break; - } - } + for (int i=0;iget_type()) { + case MEDIA_TYPE_SEQUENCE: + list->append(item); + break; + case MEDIA_TYPE_FOLDER: + list_all_sequences_worker(list, item); + break; + } + } } QVector Project::list_all_project_sequences() { - QVector list; - list_all_sequences_worker(&list, NULL); - return list; + QVector list; + list_all_sequences_worker(&list, NULL); + return list; +} + +QModelIndexList Project::get_current_selected() { + if (config.project_view_type == PROJECT_VIEW_TREE) { + return panel_project->tree_view->selectionModel()->selectedRows(); + } + return panel_project->icon_view->selectionModel()->selectedIndexes(); } #define THROBBER_LIMIT 20 @@ -1137,51 +1135,51 @@ QVector Project::list_all_project_sequences() { MediaThrobber::MediaThrobber(Media *i) : pixmap(":/icons/throbber.png"), animation(0), item(i), animator(NULL) {} void MediaThrobber::start() { - // set up throbber - animation_update(); - animator = new QTimer(this); - animator->setInterval(20); - connect(animator, SIGNAL(timeout()), this, SLOT(animation_update())); - animator->start(); + // set up throbber + animation_update(); + animator = new QTimer(this); + animator->setInterval(20); + connect(animator, SIGNAL(timeout()), this, SLOT(animation_update())); + animator->start(); } void MediaThrobber::animation_update() { - if (animation == THROBBER_LIMIT) { - animation = 0; - } - project_model.set_icon(item, QIcon(pixmap.copy(THROBBER_SIZE*animation, 0, THROBBER_SIZE, THROBBER_SIZE))); + if (animation == THROBBER_LIMIT) { + animation = 0; + } + project_model.set_icon(item, QIcon(pixmap.copy(THROBBER_SIZE*animation, 0, THROBBER_SIZE, THROBBER_SIZE))); animation++; } void MediaThrobber::stop(int icon_type, bool replace) { - if (animator != NULL) { - animator->stop(); - delete animator; - } - - switch (icon_type) { - case ICON_TYPE_VIDEO: project_model.set_icon(item, QIcon(":/icons/videosource.png")); break; - case ICON_TYPE_AUDIO: project_model.set_icon(item, QIcon(":/icons/audiosource.png")); break; - case ICON_TYPE_IMAGE: project_model.set_icon(item, QIcon(":/icons/imagesource.png")); break; - case ICON_TYPE_ERROR: project_model.set_icon(item, QIcon(":/icons/error.png")); break; - } - - // refresh all clips - QVector sequences = panel_project->list_all_project_sequences(); - for (int i=0;ito_sequence(); - for (int j=0;jclips.size();j++) { - Clip* c = s->clips.at(j); - if (c != NULL) { - c->refresh(); - } - } + if (animator != NULL) { + animator->stop(); + delete animator; } - // redraw clips + switch (icon_type) { + case ICON_TYPE_VIDEO: project_model.set_icon(item, QIcon(":/icons/videosource.png")); break; + case ICON_TYPE_AUDIO: project_model.set_icon(item, QIcon(":/icons/audiosource.png")); break; + case ICON_TYPE_IMAGE: project_model.set_icon(item, QIcon(":/icons/imagesource.png")); break; + case ICON_TYPE_ERROR: project_model.set_icon(item, QIcon(":/icons/error.png")); break; + } + + // refresh all clips + QVector sequences = panel_project->list_all_project_sequences(); + for (int i=0;ito_sequence(); + for (int j=0;jclips.size();j++) { + Clip* c = s->clips.at(j); + if (c != NULL) { + c->refresh(); + } + } + } + + // redraw clips update_ui(replace); - panel_project->tree_view->viewport()->update(); - item->throbber = NULL; - deleteLater(); + panel_project->tree_view->viewport()->update(); + item->throbber = NULL; + deleteLater(); } diff --git a/panels/project.h b/panels/project.h index 71fdd0137..395b7f991 100644 --- a/panels/project.h +++ b/panels/project.h @@ -27,10 +27,6 @@ class SourcesCommon; #define LOAD_TYPE_VERSION 69 #define LOAD_TYPE_URL 70 -namespace Ui { -class Project; -} - extern QString autorecovery_filename; extern QString project_url; extern QStringList recent_projects; @@ -48,81 +44,81 @@ class Project : public QDockWidget { public: explicit Project(QWidget *parent = 0); ~Project(); - bool is_focused(); + bool is_focused(); void clear(); - Media* new_sequence(ComboAction *ca, Sequence* s, bool open, Media* parent); - QString get_next_sequence_name(QString start = 0); - void process_file_list(QStringList& files, bool recursive = false, Media* replace = NULL, Media *parent = NULL); - void replace_media(Media* item, QString filename); - Media *get_selected_folder(); - bool reveal_media(Media *media, QModelIndex parent = QModelIndex()); - void add_recent_project(QString url); + Media* new_sequence(ComboAction *ca, Sequence* s, bool open, Media* parent); + QString get_next_sequence_name(QString start = 0); + void process_file_list(QStringList& files, bool recursive = false, Media* replace = NULL, Media *parent = NULL); + void replace_media(Media* item, QString filename); + Media *get_selected_folder(); + bool reveal_media(Media *media, QModelIndex parent = QModelIndex()); + void add_recent_project(QString url); - void new_project(); - void load_project(bool autorecovery); - void save_project(bool autorecovery); + void new_project(); + void load_project(bool autorecovery); + void save_project(bool autorecovery); - Media* new_folder(QString name); - Media* item_to_media(const QModelIndex& index); + Media* new_folder(QString name); + Media* item_to_media(const QModelIndex& index); - void save_recent_projects(); + void save_recent_projects(); - QVector list_all_project_sequences(); + QVector list_all_project_sequences(); - SourceTable* tree_view; - SourceIconView* icon_view; - SourcesCommon* sources_common; + SourceTable* tree_view; + SourceIconView* icon_view; + SourcesCommon* sources_common; - QSortFilterProxyModel* sorter; + QSortFilterProxyModel* sorter; - QVector last_imported_media; + QVector last_imported_media; - //Media *new_item(); + QModelIndexList get_current_selected(); void start_preview_generator(Media* item, bool replacing); + void get_all_media_from_table(QList &items, QList &list, int type = -1); public slots: void import_dialog(); - void delete_selected_media(); - void duplicate_selected(); + void delete_selected_media(); + void duplicate_selected(); void delete_clips_using_selected_media(); void replace_selected_file(); void replace_clip_media(); void open_properties(); private: - void save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, const QModelIndex &parent = QModelIndex()); - int folder_id; - int media_id; - int sequence_id; - void get_all_media_from_table(QList items, QList &list, int type); - void list_all_sequences_worker(QVector *list, Media* parent); + void save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, const QModelIndex &parent = QModelIndex()); + int folder_id; + int media_id; + int sequence_id; + void list_all_sequences_worker(QVector *list, Media* parent); QString get_file_name_from_path(const QString &path); - QDir proj_dir; - QWidget* icon_view_container; - QPushButton* directory_up; + QDir proj_dir; + QWidget* icon_view_container; + QPushButton* directory_up; private slots: - void update_view_type(); - void set_icon_view(); - void set_tree_view(); + void update_view_type(); + void set_icon_view(); + void set_tree_view(); void clear_recent_projects(); - void set_icon_view_size(int); - void set_up_dir_enabled(); - void go_up_dir(); + void set_icon_view_size(int); + void set_up_dir_enabled(); + void go_up_dir(); }; class MediaThrobber : public QObject { - Q_OBJECT + Q_OBJECT public: - MediaThrobber(Media*); + MediaThrobber(Media*); public slots: - void start(); + void start(); void stop(int, bool replace); private slots: - void animation_update(); + void animation_update(); private: - QPixmap pixmap; - int animation; - Media* item; - QTimer* animator; + QPixmap pixmap; + int animation; + Media* item; + QTimer* animator; }; #endif // PROJECT_H diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 9b61aa6d8..432fb6996 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -1,5 +1,4 @@ #include "timeline.h" -#include "ui_timeline.h" #include "panels/panels.h" #include "panels/project.h" @@ -12,7 +11,6 @@ #include "panels/viewer.h" #include "playback/cacher.h" #include "playback/playback.h" -#include "ui_viewer.h" #include "project/undo.h" #include "project/media.h" #include "io/config.h" @@ -20,6 +18,10 @@ #include "project/transition.h" #include "project/footage.h" #include "io/clipboard.h" +#include "ui/timelineheader.h" +#include "ui/resizablescrollbar.h" +#include "ui/audiomonitor.h" +#include "mainwindow.h" #include "debug.h" #include @@ -32,6 +34,10 @@ #include #include #include +#include +#include +#include +#include long refactor_frame_number(long framenumber, double source_frame_rate, double target_frame_rate) { return qRound(((double)framenumber/source_frame_rate)*target_frame_rate); @@ -45,122 +51,110 @@ void draw_selection_rectangle(QPainter& painter, const QRect& rect) { Timeline::Timeline(QWidget *parent) : QDockWidget(parent), - cursor_frame(0), - cursor_track(0), - zoom(1.0), - zoom_just_changed(false), - showing_all(false), - snapping(true), - snapped(false), - snap_point(0), - selecting(false), - rect_select_init(false), - rect_select_proc(false), - moving_init(false), - moving_proc(false), - move_insert(false), - trim_target(-1), - trim_in_point(false), - splitting(false), - importing(false), + cursor_frame(0), + cursor_track(0), + zoom(1.0), + zoom_just_changed(false), + showing_all(false), + snapping(true), + snapped(false), + snap_point(0), + selecting(false), + rect_select_init(false), + rect_select_proc(false), + moving_init(false), + moving_proc(false), + move_insert(false), + trim_target(-1), + trim_in_point(false), + splitting(false), + importing(false), importing_files(false), - creating(false), - transition_tool_init(false), - transition_tool_proc(false), - transition_tool_pre_clip(-1), - transition_tool_post_clip(-1), - hand_moving(false), - block_repaints(false), - ui(new Ui::Timeline), - last_frame(0), - scroll(0) + creating(false), + transition_tool_init(false), + transition_tool_proc(false), + transition_tool_pre_clip(-1), + transition_tool_post_clip(-1), + hand_moving(false), + block_repaints(false), + last_frame(0), + scroll(0) { + setup_ui(); + default_track_height = (QGuiApplication::primaryScreen()->logicalDotsPerInch() / 96) * TRACK_DEFAULT_HEIGHT; - ui->setupUi(this); + headers->viewer = panel_sequence_viewer; - ui->headers->viewer = panel_sequence_viewer; + video_area->bottom_align = true; + video_area->scrollBar = videoScrollbar; + audio_area->scrollBar = audioScrollbar; - /* --- TEMPORARY --- - * I feel like the rolling edit tool is unnecessary, but just - * in case I change my mind, I'm leaving all the functionality - * intact and only hiding the UI to get to it. Still deciding - * on this one but the pointer tool literally does the same - * functionality. - */ - ui->toolRollingButton->setVisible(false); - ui->toolRollingButton->setEnabled(false); - /* --- */ + tool_buttons.append(toolArrowButton); + tool_buttons.append(toolEditButton); + tool_buttons.append(toolRippleButton); + tool_buttons.append(toolRazorButton); + tool_buttons.append(toolSlipButton); + tool_buttons.append(toolSlideButton); + tool_buttons.append(toolTransitionButton); + tool_buttons.append(toolHandButton); - ui->video_area->bottom_align = true; - ui->video_area->scrollBar = ui->videoScrollbar; - ui->audio_area->scrollBar = ui->audioScrollbar; + toolArrowButton->click(); - tool_buttons.append(ui->toolArrowButton); - tool_buttons.append(ui->toolEditButton); - tool_buttons.append(ui->toolRippleButton); - tool_buttons.append(ui->toolRazorButton); - tool_buttons.append(ui->toolSlipButton); - tool_buttons.append(ui->toolRollingButton); - tool_buttons.append(ui->toolSlideButton); - tool_buttons.append(ui->toolTransitionButton); - tool_buttons.append(ui->toolHandButton); - - ui->toolArrowButton->click(); - - connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(setScroll(int))); - connect(ui->videoScrollbar, SIGNAL(valueChanged(int)), ui->video_area, SLOT(setScroll(int))); - connect(ui->audioScrollbar, SIGNAL(valueChanged(int)), ui->audio_area, SLOT(setScroll(int))); - connect(ui->horizontalScrollBar, SIGNAL(resize_move(double)), this, SLOT(resize_move(double))); + connect(horizontalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(setScroll(int))); + connect(videoScrollbar, SIGNAL(valueChanged(int)), video_area, SLOT(setScroll(int))); + connect(audioScrollbar, SIGNAL(valueChanged(int)), audio_area, SLOT(setScroll(int))); + connect(horizontalScrollBar, SIGNAL(resize_move(double)), this, SLOT(resize_move(double))); update_sequence(); } -Timeline::~Timeline() -{ - delete ui; -} +Timeline::~Timeline() {} void Timeline::previous_cut() { if (sequence->playhead > 0) { - long p_cut = 0; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL) { + long p_cut = 0; + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL) { if (c->timeline_out > p_cut && c->timeline_out < sequence->playhead) { - p_cut = c->timeline_out; + p_cut = c->timeline_out; } else if (c->timeline_in > p_cut && c->timeline_in < sequence->playhead) { - p_cut = c->timeline_in; - } - } - } + p_cut = c->timeline_in; + } + } + } panel_sequence_viewer->seek(p_cut); - } + } } void Timeline::next_cut() { - bool seek_enabled = false; - long n_cut = LONG_MAX; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL) { + bool seek_enabled = false; + long n_cut = LONG_MAX; + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL) { if (c->timeline_in < n_cut && c->timeline_in > sequence->playhead) { - n_cut = c->timeline_in; - seek_enabled = true; + n_cut = c->timeline_in; + seek_enabled = true; } else if (c->timeline_out < n_cut && c->timeline_out > sequence->playhead) { - n_cut = c->timeline_out; - seek_enabled = true; - } - } - } + n_cut = c->timeline_out; + seek_enabled = true; + } + } + } if (seek_enabled) panel_sequence_viewer->seek(n_cut); } +void ripple_clips(ComboAction* ca, Sequence *s, long point, long length, const QVector& ignore) { + ca->append(new RippleAction(s, point, length, ignore)); +} + void Timeline::toggle_show_all() { showing_all = !showing_all; if (showing_all) { old_zoom = zoom; - set_zoom_value((double) (ui->timeline_area->width() - 200) / (double) sequence->getEndFrame()); + set_zoom_value((double) (timeline_area->width() - 200) / (double) sequence->getEndFrame()); } else { set_zoom_value(old_zoom); } @@ -173,28 +167,28 @@ void Timeline::create_ghosts_from_media(Sequence* seq, long entry_point, QVector for (int i=0;iget_type()) { + switch (medium->get_type()) { case MEDIA_TYPE_FOOTAGE: - m = medium->to_footage(); + m = medium->to_footage(); media = m; can_import = m->ready; if (m->using_inout) { double source_fr = 30; - if (m->video_tracks.size() > 0 && !qIsNull(m->video_tracks.at(0)->video_frame_rate)) source_fr = m->video_tracks.at(0)->video_frame_rate; + if (m->video_tracks.size() > 0 && !qIsNull(m->video_tracks.at(0)->video_frame_rate)) source_fr = m->video_tracks.at(0)->video_frame_rate; default_clip_in = refactor_frame_number(m->in, source_fr, seq->frame_rate); default_clip_out = refactor_frame_number(m->out, source_fr, seq->frame_rate); } break; case MEDIA_TYPE_SEQUENCE: - s = medium->to_sequence(); + s = medium->to_sequence(); sequence_length = s->getEndFrame(); if (seq != NULL) sequence_length = refactor_frame_number(sequence_length, s->frame_rate, seq->frame_rate); media = s; @@ -210,14 +204,14 @@ void Timeline::create_ghosts_from_media(Sequence* seq, long entry_point, QVector if (can_import) { Ghost g; - g.clip = -1; + g.clip = -1; g.trimming = false; g.old_clip_in = g.clip_in = default_clip_in; - g.media = medium; + g.media = medium; g.in = entry_point; g.transition = NULL; - switch (medium->get_type()) { + switch (medium->get_type()) { case MEDIA_TYPE_FOOTAGE: // is video source a still image? if (m->video_tracks.size() > 0 && m->video_tracks[0]->infinite_length && m->audio_tracks.size() == 0) { @@ -280,14 +274,14 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, Sequence* s) { earliest_point = qMin(earliest_point, g.in); Clip* c = new Clip(s); - c->media = g.media; + c->media = g.media; c->media_stream = g.media_stream; c->timeline_in = g.in; c->timeline_out = g.out; c->clip_in = g.clip_in; c->track = g.track; - if (c->media->get_type() == MEDIA_TYPE_FOOTAGE) { - Footage* m = c->media->to_footage(); + if (c->media->get_type() == MEDIA_TYPE_FOOTAGE) { + Footage* m = c->media->to_footage(); if (m->video_tracks.size() == 0) { // audio only (greenish) c->color_r = 128; @@ -305,13 +299,13 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, Sequence* s) { c->color_b = 192; } c->name = m->name; - } else if (c->media->get_type() == MEDIA_TYPE_SEQUENCE) { + } else if (c->media->get_type() == MEDIA_TYPE_SEQUENCE) { // sequence (red?ish?) c->color_r = 192; c->color_g = 128; c->color_b = 128; - Sequence* media = c->media->to_sequence(); + Sequence* media = c->media->to_sequence(); c->name = media->name; } c->recalculateMaxLength(); @@ -331,11 +325,11 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, Sequence* s) { if (c->track < 0) { // add default video effects - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TRANSFORM, EFFECT_TYPE_EFFECT))); + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TRANSFORM, EFFECT_TYPE_EFFECT))); } else { // add default audio effects - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_VOLUME, EFFECT_TYPE_EFFECT))); - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_PAN, EFFECT_TYPE_EFFECT))); + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_VOLUME, EFFECT_TYPE_EFFECT))); + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_PAN, EFFECT_TYPE_EFFECT))); } } if (config.enable_seek_to_import) { @@ -347,64 +341,64 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, Sequence* s) { } int Timeline::get_track_height_size(bool video) { - if (video) { - return video_track_heights.size(); - } else { - return audio_track_heights.size(); - } + if (video) { + return video_track_heights.size(); + } else { + return audio_track_heights.size(); + } } void Timeline::add_transition() { - ComboAction* ca = new ComboAction(); + ComboAction* ca = new ComboAction(); bool adding = false; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL && is_clip_selected(c, true)) { - if (c->get_opening_transition() == NULL) { - ca->append(new AddTransitionCommand(c, NULL, NULL, get_internal_meta(TRANSITION_INTERNAL_LINEARFADE, EFFECT_TYPE_TRANSITION), TA_OPENING_TRANSITION, 30)); + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL && is_clip_selected(c, true)) { + if (c->get_opening_transition() == NULL) { + ca->append(new AddTransitionCommand(c, NULL, NULL, get_internal_meta(TRANSITION_INTERNAL_LINEARFADE, EFFECT_TYPE_TRANSITION), TA_OPENING_TRANSITION, 30)); adding = true; - } - if (c->get_closing_transition() == NULL) { - ca->append(new AddTransitionCommand(c, NULL, NULL, get_internal_meta(TRANSITION_INTERNAL_LINEARFADE, EFFECT_TYPE_TRANSITION), TA_OPENING_TRANSITION, 30)); + } + if (c->get_closing_transition() == NULL) { + ca->append(new AddTransitionCommand(c, NULL, NULL, get_internal_meta(TRANSITION_INTERNAL_LINEARFADE, EFFECT_TYPE_TRANSITION), TA_OPENING_TRANSITION, 30)); adding = true; - } - } - } + } + } + } if (adding) { - undo_stack.push(ca); + undo_stack.push(ca); } else { - delete ca; + delete ca; } update_ui(true); } int Timeline::calculate_track_height(int track, int value) { - int index = (track < 0) ? qAbs(track + 1) : track; - QVector& vector = (track < 0) ? video_track_heights : audio_track_heights; - while (vector.size() < index+1) { + int index = (track < 0) ? qAbs(track + 1) : track; + QVector& vector = (track < 0) ? video_track_heights : audio_track_heights; + while (vector.size() < index+1) { vector.append(default_track_height); - } - if (value > -1) { - vector[index] = value; - } - return vector.at(index); + } + if (value > -1) { + vector[index] = value; + } + return vector.at(index); } void Timeline::update_sequence() { - bool null_sequence = (sequence == NULL); + bool null_sequence = (sequence == NULL); for (int i=0;isetEnabled(!null_sequence); } - ui->snappingButton->setEnabled(!null_sequence); - ui->pushButton_4->setEnabled(!null_sequence); - ui->pushButton_5->setEnabled(!null_sequence); - ui->recordButton->setEnabled(!null_sequence); - ui->addButton->setEnabled(!null_sequence); - ui->headers->setEnabled(!null_sequence); + snappingButton->setEnabled(!null_sequence); + zoomInButton->setEnabled(!null_sequence); + zoomOutButton->setEnabled(!null_sequence); + recordButton->setEnabled(!null_sequence); + addButton->setEnabled(!null_sequence); + headers->setEnabled(!null_sequence); if (null_sequence) { setWindowTitle("Timeline: "); @@ -419,56 +413,56 @@ int Timeline::get_snap_range() { } bool Timeline::focused() { - return (sequence != NULL && (ui->headers->hasFocus() || ui->video_area->hasFocus() || ui->audio_area->hasFocus())); + return (sequence != NULL && (headers->hasFocus() || video_area->hasFocus() || audio_area->hasFocus())); } void Timeline::repaint_timeline() { - if (!block_repaints) { - bool draw = true; + if (!block_repaints) { + bool draw = true; - if (sequence != NULL - && !ui->horizontalScrollBar->isSliderDown() - && !ui->horizontalScrollBar->is_resizing() - && panel_sequence_viewer->playing - && !zoom_just_changed) { - // auto scroll - if (config.autoscroll == AUTOSCROLL_PAGE_SCROLL) { - int playhead_x = panel_timeline->getTimelineScreenPointFromFrame(sequence->playhead); - if (playhead_x < 0 || playhead_x > (ui->editAreas->width() - ui->videoScrollbar->width())) { - ui->horizontalScrollBar->setValue(getScreenPointFromFrame(zoom, sequence->playhead)); - draw = false; - } - } else if (config.autoscroll == AUTOSCROLL_SMOOTH_SCROLL) { - if (center_scroll_to_playhead(ui->horizontalScrollBar, zoom, sequence->playhead)) { - draw = false; - } - } - } + if (sequence != NULL + && !horizontalScrollBar->isSliderDown() + && !horizontalScrollBar->is_resizing() + && panel_sequence_viewer->playing + && !zoom_just_changed) { + // auto scroll + if (config.autoscroll == AUTOSCROLL_PAGE_SCROLL) { + int playhead_x = panel_timeline->getTimelineScreenPointFromFrame(sequence->playhead); + if (playhead_x < 0 || playhead_x > (editAreas->width() - videoScrollbar->width())) { + horizontalScrollBar->setValue(getScreenPointFromFrame(zoom, sequence->playhead)); + draw = false; + } + } else if (config.autoscroll == AUTOSCROLL_SMOOTH_SCROLL) { + if (center_scroll_to_playhead(horizontalScrollBar, zoom, sequence->playhead)) { + draw = false; + } + } + } - zoom_just_changed = false; + zoom_just_changed = false; - if (draw) { - ui->headers->update(); - ui->video_area->update(); - ui->audio_area->update(); + if (draw) { + headers->update(); + video_area->update(); + audio_area->update(); - if (sequence != NULL) { - set_sb_max(); + if (sequence != NULL) { + set_sb_max(); - if (last_frame != sequence->playhead) { - ui->audio_monitor->update(); - last_frame = sequence->playhead; - } - } - } - } + if (last_frame != sequence->playhead) { + audio_monitor->update(); + last_frame = sequence->playhead; + } + } + } + } } void Timeline::select_all() { if (sequence != NULL) { sequence->selections.clear(); - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); if (c != NULL) { Selection s; s.in = c->timeline_in; @@ -478,39 +472,39 @@ void Timeline::select_all() { } } repaint_timeline(); - } + } } void Timeline::resizeEvent(QResizeEvent *event) { - if (sequence != NULL) set_sb_max(); + if (sequence != NULL) set_sb_max(); } void Timeline::delete_in_out(bool ripple) { - if (sequence != NULL && sequence->using_workarea) { - QVector areas; - int video_tracks = 0, audio_tracks = 0; - sequence->getTrackLimits(&video_tracks, &audio_tracks); - for (int i=video_tracks;i<=audio_tracks;i++) { - Selection s; - s.in = sequence->workarea_in; - s.out = sequence->workarea_out; - s.track = i; - areas.append(s); - } - ComboAction* ca = new ComboAction(); - delete_areas_and_relink(ca, areas); - if (ripple) ca->append(new RippleCommand(sequence, sequence->workarea_in, sequence->workarea_in - sequence->workarea_out)); - ca->append(new SetTimelineInOutCommand(sequence, false, 0, 0)); - undo_stack.push(ca); + if (sequence != NULL && sequence->using_workarea) { + QVector areas; + int video_tracks = 0, audio_tracks = 0; + sequence->getTrackLimits(&video_tracks, &audio_tracks); + for (int i=video_tracks;i<=audio_tracks;i++) { + Selection s; + s.in = sequence->workarea_in; + s.out = sequence->workarea_out; + s.track = i; + areas.append(s); + } + ComboAction* ca = new ComboAction(); + delete_areas_and_relink(ca, areas); + if (ripple) ripple_clips(ca, sequence, sequence->workarea_in, sequence->workarea_in - sequence->workarea_out); + ca->append(new SetTimelineInOutCommand(sequence, false, 0, 0)); + undo_stack.push(ca); update_ui(true); - } + } } void Timeline::delete_selection(QVector& selections, bool ripple_delete) { if (selections.size() > 0) { - panel_effect_controls->clear_effects(true); + panel_effect_controls->clear_effects(true); - ComboAction* ca = new ComboAction(); + ComboAction* ca = new ComboAction(); delete_areas_and_relink(ca, selections); @@ -518,54 +512,54 @@ void Timeline::delete_selection(QVector& selections, bool ripple_dele long ripple_point = selections.at(0).in; long ripple_length = selections.at(0).out - selections.at(0).in; - // retrieve ripple_point and ripple_length from current selection + // retrieve ripple_point and ripple_length from current selection for (int i=1;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + bool can_ripple = true; + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); if (c != NULL && c->timeline_in < ripple_point && c->timeline_out > ripple_point) { - // conflict detected, but this clip may be getting deleted so let's check - bool deleted = false; + // conflict detected, but this clip may be getting deleted so let's check + bool deleted = false; for (int j=0;jtrack - && !(c->timeline_in < s.in && c->timeline_out < s.in) - && !(c->timeline_in > s.out && c->timeline_out > s.out)) { - deleted = true; - break; - } - } - if (!deleted) { - for (int j=0;jclips.size();j++) { - Clip* cc = sequence->clips.at(j); + if (s.track == c->track + && !(c->timeline_in < s.in && c->timeline_out < s.in) + && !(c->timeline_in > s.out && c->timeline_out > s.out)) { + deleted = true; + break; + } + } + if (!deleted) { + for (int j=0;jclips.size();j++) { + Clip* cc = sequence->clips.at(j); if (cc != NULL && cc->track == c->track - && cc->timeline_in > c->timeline_out - && cc->timeline_in < c->timeline_out + ripple_length) { - ripple_length = cc->timeline_in - c->timeline_out; - } - } - } - } + && cc->timeline_in > c->timeline_out + && cc->timeline_in < c->timeline_out + ripple_length) { + ripple_length = cc->timeline_in - c->timeline_out; + } + } + } + } } if (can_ripple) { - ca->append(new RippleCommand(sequence, ripple_point, -ripple_length)); + ripple_clips(ca, sequence, ripple_point, -ripple_length); panel_sequence_viewer->seek(ripple_point-1); } } selections.clear(); - undo_stack.push(ca); + undo_stack.push(ca); update_ui(true); } @@ -573,14 +567,14 @@ void Timeline::delete_selection(QVector& selections, bool ripple_dele void Timeline::set_zoom_value(double v) { zoom = v; - zoom_just_changed = true; - ui->headers->update_zoom(zoom); + zoom_just_changed = true; + headers->update_zoom(zoom); - repaint_timeline(); + repaint_timeline(); - // TODO find a way to gradually move towards target_scroll instead of just centering it? - if (!ui->horizontalScrollBar->is_resizing()) - center_scroll_to_playhead(ui->horizontalScrollBar, zoom, sequence->playhead); + // TODO find a way to gradually move towards target_scroll instead of just centering it? + if (!horizontalScrollBar->is_resizing()) + center_scroll_to_playhead(horizontalScrollBar, zoom, sequence->playhead); } void Timeline::set_zoom(bool in) { @@ -590,677 +584,691 @@ void Timeline::set_zoom(bool in) { void Timeline::decheck_tool_buttons(QObject* sender) { for (int i=0;isetChecked(tool_buttons.at(i) == sender); + tool_buttons[i]->setChecked(tool_buttons.at(i) == sender); } } QVector Timeline::get_tracks_of_linked_clips(int i) { - QVector tracks; - Clip* clip = sequence->clips.at(i); - for (int j=0;jlinked.size();j++) { - tracks.append(sequence->clips.at(clip->linked.at(j))->track); - } - return tracks; + QVector tracks; + Clip* clip = sequence->clips.at(i); + for (int j=0;jlinked.size();j++) { + tracks.append(sequence->clips.at(clip->linked.at(j))->track); + } + return tracks; } -void Timeline::on_pushButton_4_clicked() -{ - set_zoom(true); +void Timeline::zoom_in() { + set_zoom(true); } -void Timeline::on_pushButton_5_clicked() -{ - set_zoom(false); +void Timeline::zoom_out() { + set_zoom(false); } bool Timeline::is_clip_selected(Clip* clip, bool containing) { for (int i=0;isequence->selections.size();i++) { const Selection& s = clip->sequence->selections.at(i); - if (clip->track == s.track && ((clip->timeline_in >= s.in && clip->timeline_out <= s.out && containing) || - (!containing && !(clip->timeline_in < s.in && clip->timeline_out < s.in) && !(clip->timeline_in > s.in && clip->timeline_out > s.in)))) { + if (clip->track == s.track && ((clip->timeline_in >= s.in && clip->timeline_out <= s.out && containing) || + (!containing && !(clip->timeline_in < s.in && clip->timeline_out < s.in) && !(clip->timeline_in > s.in && clip->timeline_out > s.in)))) { return true; } } return false; } -void Timeline::on_snappingButton_toggled(bool checked) { +void Timeline::snapping_clicked(bool checked) { snapping = checked; } Clip* Timeline::split_clip(ComboAction* ca, int p, long frame) { - return split_clip(ca, p, frame, frame); + return split_clip(ca, p, frame, frame); } Clip* Timeline::split_clip(ComboAction* ca, int p, long frame, long post_in) { - Clip* pre = sequence->clips.at(p); - if (pre != NULL && pre->timeline_in < frame && pre->timeline_out > frame) { // guard against attempts to split at in/out points - Clip* post = pre->copy(sequence); + Clip* pre = sequence->clips.at(p); + if (pre != NULL && pre->timeline_in < frame && pre->timeline_out > frame) { // guard against attempts to split at in/out points + Clip* post = pre->copy(sequence); long new_clip_length = frame - pre->timeline_in; post->timeline_in = post_in; post->clip_in = pre->clip_in + (post->timeline_in - pre->timeline_in); - move_clip(ca, pre, pre->timeline_in, frame, pre->clip_in, pre->track); + move_clip(ca, pre, pre->timeline_in, frame, pre->clip_in, pre->track); - if (pre->get_opening_transition() != NULL) { - /*if (frame < pre->timeline_in + pre->get_opening_transition()->length && pre->get_opening_transition()->secondary_clip != NULL) { - // separate shared transition - ca->append(new SetPointer((void**) &pre->get_opening_transition()->secondary_clip, NULL)); - pre->get_opening_transition()->secondary_clip->closing_transition = pre->get_opening_transition()->copy(pre->get_opening_transition()->secondary_clip, NULL); - }*/ + if (pre->get_opening_transition() != NULL) { + /*if (frame < pre->timeline_in + pre->get_opening_transition()->length && pre->get_opening_transition()->secondary_clip != NULL) { + // separate shared transition + ca->append(new SetPointer((void**) &pre->get_opening_transition()->secondary_clip, NULL)); + pre->get_opening_transition()->secondary_clip->closing_transition = pre->get_opening_transition()->copy(pre->get_opening_transition()->secondary_clip, NULL); + }*/ - if (pre->get_opening_transition()->get_true_length() > new_clip_length) { - ca->append(new ModifyTransitionCommand(pre, TA_OPENING_TRANSITION, new_clip_length)); + if (pre->get_opening_transition()->get_true_length() > new_clip_length) { + ca->append(new ModifyTransitionCommand(pre, TA_OPENING_TRANSITION, new_clip_length)); } - post->sequence->hard_delete_transition(post, TA_OPENING_TRANSITION); + post->sequence->hard_delete_transition(post, TA_OPENING_TRANSITION); } - if (pre->get_closing_transition() != NULL) { - ca->append(new DeleteTransitionCommand(pre->sequence, pre->closing_transition)); - if (pre->get_closing_transition()->secondary_clip == NULL) post->get_closing_transition()->set_length(qMin((long) post->get_closing_transition()->get_true_length(), post->getLength())); + if (pre->get_closing_transition() != NULL) { + ca->append(new DeleteTransitionCommand(pre->sequence, pre->closing_transition)); + if (pre->get_closing_transition()->secondary_clip == NULL) post->get_closing_transition()->set_length(qMin((long) post->get_closing_transition()->get_true_length(), post->getLength())); } - return post; - } - return NULL; + return post; + } + return NULL; } bool Timeline::has_clip_been_split(int c) { - for (int i=0;iclips.at(clip); - if (c != NULL) { - QVector pre_clips; - QVector post_clips; + Clip* c = sequence->clips.at(clip); + if (c != NULL) { + QVector pre_clips; + QVector post_clips; - Clip* post = split_clip(ca, clip, frame); + Clip* post = split_clip(ca, clip, frame); - // if alt is not down, split clips links too - if (post == NULL) { - return false; - } else { - post_clips.append(post); - if (relink) { - pre_clips.append(clip); + // if alt is not down, split clips links too + if (post == NULL) { + return false; + } else { + post_clips.append(post); + if (relink) { + pre_clips.append(clip); - bool original_clip_is_selected = is_clip_selected(c, true); + bool original_clip_is_selected = is_clip_selected(c, true); - // find linked clips of old clip - for (int i=0;ilinked.size();i++) { - int l = c->linked.at(i); - if (!has_clip_been_split(l)) { - Clip* link = sequence->clips.at(l); - if ((original_clip_is_selected && is_clip_selected(link, true)) || !original_clip_is_selected) { - split_cache.append(l); - Clip* s = split_clip(ca, l, frame); - if (s != NULL) { - pre_clips.append(l); - post_clips.append(s); - } - } - } - } + // find linked clips of old clip + for (int i=0;ilinked.size();i++) { + int l = c->linked.at(i); + if (!has_clip_been_split(l)) { + Clip* link = sequence->clips.at(l); + if ((original_clip_is_selected && is_clip_selected(link, true)) || !original_clip_is_selected) { + split_cache.append(l); + Clip* s = split_clip(ca, l, frame); + if (s != NULL) { + pre_clips.append(l); + post_clips.append(s); + } + } + } + } - relink_clips_using_ids(pre_clips, post_clips); - } - ca->append(new AddClipCommand(sequence, post_clips)); - return true; - } - } - return false; + relink_clips_using_ids(pre_clips, post_clips); + } + ca->append(new AddClipCommand(sequence, post_clips)); + return true; + } + } + return false; } void Timeline::clean_up_selections(QVector& areas) { - for (int i=0;i ss.out) { - // do nothing - } else if (s.in >= ss.in && s.out <= ss.out) { - remove = true; - } else if (s.in <= ss.out && s.out > ss.out) { - ss.out = s.out; - remove = true; - } else if (s.out >= ss.in && s.in < ss.in) { - ss.in = s.in; - remove = true; - } - if (remove) { - areas.removeAt(i); - i--; - break; - } - } - } - } - } + for (int i=0;i ss.out) { + // do nothing + } else if (s.in >= ss.in && s.out <= ss.out) { + remove = true; + } else if (s.in <= ss.out && s.out > ss.out) { + ss.out = s.out; + remove = true; + } else if (s.out >= ss.in && s.in < ss.in) { + ss.in = s.in; + remove = true; + } + if (remove) { + areas.removeAt(i); + i--; + break; + } + } + } + } + } } bool selection_contains_transition(const Selection& s, Clip* c, int type) { - if (type == TA_OPENING_TRANSITION) { - return c->get_opening_transition() != NULL - && s.out == c->timeline_in + c->get_opening_transition()->get_true_length() - && ((c->get_opening_transition()->secondary_clip == NULL && s.in == c->timeline_in) - || (c->get_opening_transition()->secondary_clip != NULL && s.in == c->timeline_in - c->get_opening_transition()->get_true_length())); - } else { - return c->get_closing_transition() != NULL - && s.in == c->timeline_out - c->get_closing_transition()->get_true_length() - && ((c->get_closing_transition()->secondary_clip == NULL && s.out == c->timeline_out) - || (c->get_closing_transition()->secondary_clip != NULL && s.out == c->timeline_out + c->get_closing_transition()->get_true_length())); - } + if (type == TA_OPENING_TRANSITION) { + return c->get_opening_transition() != NULL + && s.out == c->timeline_in + c->get_opening_transition()->get_true_length() + && ((c->get_opening_transition()->secondary_clip == NULL && s.in == c->timeline_in) + || (c->get_opening_transition()->secondary_clip != NULL && s.in == c->timeline_in - c->get_opening_transition()->get_true_length())); + } else { + return c->get_closing_transition() != NULL + && s.in == c->timeline_out - c->get_closing_transition()->get_true_length() + && ((c->get_closing_transition()->secondary_clip == NULL && s.out == c->timeline_out) + || (c->get_closing_transition()->secondary_clip != NULL && s.out == c->timeline_out + c->get_closing_transition()->get_true_length())); + } } void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& areas) { - clean_up_selections(areas); + clean_up_selections(areas); - QVector pre_clips; - QVector post_clips; + QVector pre_clips; + QVector post_clips; - for (int i=0;iclips.size();j++) { - Clip* c = sequence->clips.at(j); - if (c != NULL && c->track == s.track && !c->undeletable) { - if (selection_contains_transition(s, c, TA_OPENING_TRANSITION)) { + for (int i=0;iclips.size();j++) { + Clip* c = sequence->clips.at(j); + if (c != NULL && c->track == s.track && !c->undeletable) { + if (selection_contains_transition(s, c, TA_OPENING_TRANSITION)) { // delete opening transition - ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); - } else if (selection_contains_transition(s, c, TA_CLOSING_TRANSITION)) { + ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); + } else if (selection_contains_transition(s, c, TA_CLOSING_TRANSITION)) { // delete closing transition - ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); + ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); } else if (c->timeline_in >= s.in && c->timeline_out <= s.out) { - // clips falls entirely within deletion area - ca->append(new DeleteClipAction(sequence, j)); - } else if (c->timeline_in < s.in && c->timeline_out > s.out) { - // middle of clip is within deletion area + // clips falls entirely within deletion area + ca->append(new DeleteClipAction(sequence, j)); + } else if (c->timeline_in < s.in && c->timeline_out > s.out) { + // middle of clip is within deletion area - // duplicate clip - Clip* post = split_clip(ca, j, s.in, s.out); + // duplicate clip + Clip* post = split_clip(ca, j, s.in, s.out); pre_clips.append(j); post_clips.append(post); - } else if (c->timeline_in < s.in && c->timeline_out > s.in) { - // only out point is in deletion area - move_clip(ca, c, c->timeline_in, s.in, c->clip_in, c->track); + } else if (c->timeline_in < s.in && c->timeline_out > s.in) { + // only out point is in deletion area + move_clip(ca, c, c->timeline_in, s.in, c->clip_in, c->track); - if (c->get_closing_transition() != NULL) { - if (s.in < c->timeline_out - c->get_closing_transition()->get_true_length()) { - ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); + if (c->get_closing_transition() != NULL) { + if (s.in < c->timeline_out - c->get_closing_transition()->get_true_length()) { + ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); } else { - ca->append(new ModifyTransitionCommand(c, TA_CLOSING_TRANSITION, c->get_closing_transition()->get_true_length() - (c->timeline_out - s.in))); + ca->append(new ModifyTransitionCommand(c, TA_CLOSING_TRANSITION, c->get_closing_transition()->get_true_length() - (c->timeline_out - s.in))); } } - } else if (c->timeline_in < s.out && c->timeline_out > s.out) { - // only in point is in deletion area - move_clip(ca, c, s.out, c->timeline_out, c->clip_in + (s.out - c->timeline_in), c->track); + } else if (c->timeline_in < s.out && c->timeline_out > s.out) { + // only in point is in deletion area + move_clip(ca, c, s.out, c->timeline_out, c->clip_in + (s.out - c->timeline_in), c->track); - if (c->get_opening_transition() != NULL) { - if (s.out > c->timeline_in + c->get_opening_transition()->get_true_length()) { - ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); + if (c->get_opening_transition() != NULL) { + if (s.out > c->timeline_in + c->get_opening_transition()->get_true_length()) { + ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); } else { - ca->append(new ModifyTransitionCommand(c, TA_OPENING_TRANSITION, c->get_opening_transition()->get_true_length() - (s.out - c->timeline_in))); + ca->append(new ModifyTransitionCommand(c, TA_OPENING_TRANSITION, c->get_opening_transition()->get_true_length() - (s.out - c->timeline_in))); } } - } - } - } - } - relink_clips_using_ids(pre_clips, post_clips); - ca->append(new AddClipCommand(sequence, post_clips)); + } + } + } + } + relink_clips_using_ids(pre_clips, post_clips); + ca->append(new AddClipCommand(sequence, post_clips)); } void Timeline::copy(bool del) { - bool cleared = false; - bool copied = false; + bool cleared = false; + bool copied = false; - long min_in = 0; + long min_in = 0; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL) { + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL) { for (int j=0;jselections.size();j++) { const Selection& s = sequence->selections.at(j); - if (s.track == c->track && !((c->timeline_in <= s.in && c->timeline_out <= s.in) || (c->timeline_in >= s.out && c->timeline_out >= s.out))) { - if (!cleared) { - clear_clipboard(); - cleared = true; - clipboard_type = CLIPBOARD_TYPE_CLIP; - } + if (s.track == c->track && !((c->timeline_in <= s.in && c->timeline_out <= s.in) || (c->timeline_in >= s.out && c->timeline_out >= s.out))) { + if (!cleared) { + clear_clipboard(); + cleared = true; + clipboard_type = CLIPBOARD_TYPE_CLIP; + } - Clip* copied_clip = c->copy(NULL); + Clip* copied_clip = c->copy(NULL); - copied_clip->cached_fr = sequence->frame_rate; + // copy linked IDs (we correct these later in paste()) + copied_clip->linked = c->linked; - // copy linked IDs (we correct these later in paste()) - copied_clip->linked = c->linked; + if (copied_clip->timeline_in < s.in) { + copied_clip->clip_in += (s.in - copied_clip->timeline_in); + copied_clip->timeline_in = s.in; + } - if (copied_clip->timeline_in < s.in) { - copied_clip->clip_in += (s.in - copied_clip->timeline_in); - copied_clip->timeline_in = s.in; - } + if (copied_clip->timeline_out > s.out) { + copied_clip->timeline_out = s.out; + } - if (copied_clip->timeline_out > s.out) { - copied_clip->timeline_out = s.out; - } + if (copied) { + min_in = qMin(min_in, s.in); + } else { + min_in = s.in; + copied = true; + } - if (copied) { - min_in = qMin(min_in, s.in); - } else { - min_in = s.in; - copied = true; - } + copied_clip->load_id = i; - copied_clip->load_id = i; + clipboard.append(copied_clip); + } + } + } + } - clipboard.append(copied_clip); - } - } - } - } + for (int i=0;i(clipboard.at(i))->timeline_in -= min_in; + static_cast(clipboard.at(i))->timeline_out -= min_in; + } - for (int i=0;i(clipboard.at(i))->timeline_in -= min_in; - static_cast(clipboard.at(i))->timeline_out -= min_in; - } - - if (del && copied) { + if (del && copied) { delete_selection(sequence->selections, false); - } + } } void Timeline::relink_clips_using_ids(QVector& old_clips, QVector& new_clips) { - // relink pasted clips - for (int i=0;iclips.at(old_clips.at(i)); - for (int j=0;jlinked.size();j++) { - for (int k=0;klinked.at(j) == old_clips.at(k)) { - new_clips.at(i)->linked.append(k); - } - } - } - } + // relink pasted clips + for (int i=0;iclips.at(old_clips.at(i)); + for (int j=0;jlinked.size();j++) { + for (int k=0;klinked.at(j) == old_clips.at(k)) { + new_clips.at(i)->linked.append(k); + } + } + } + } } void Timeline::paste(bool insert) { - if (clipboard.size() > 0) { - if (clipboard_type == CLIPBOARD_TYPE_CLIP) { - ComboAction* ca = new ComboAction(); + if (clipboard.size() > 0) { + if (clipboard_type == CLIPBOARD_TYPE_CLIP) { + ComboAction* ca = new ComboAction(); - // create copies and delete areas that we'll be pasting to - QVector delete_areas; - QVector pasted_clips; - long paste_start = LONG_MAX; - long paste_end = LONG_MIN; - for (int i=0;i(clipboard.at(i)); + // create copies and delete areas that we'll be pasting to + QVector delete_areas; + QVector pasted_clips; + long paste_start = LONG_MAX; + long paste_end = LONG_MIN; + for (int i=0;i(clipboard.at(i)); - // create copy of clip and offset by playhead - Clip* cc = c->copy(sequence); + // create copy of clip and offset by playhead + Clip* cc = c->copy(sequence); - // convert frame rates - cc->timeline_in = refactor_frame_number(cc->timeline_in, c->cached_fr, sequence->frame_rate); - cc->timeline_out = refactor_frame_number(cc->timeline_out, c->cached_fr, sequence->frame_rate); - cc->clip_in = refactor_frame_number(cc->clip_in, c->cached_fr, sequence->frame_rate); + // convert frame rates + cc->timeline_in = refactor_frame_number(cc->timeline_in, c->cached_fr, sequence->frame_rate); + cc->timeline_out = refactor_frame_number(cc->timeline_out, c->cached_fr, sequence->frame_rate); + cc->clip_in = refactor_frame_number(cc->clip_in, c->cached_fr, sequence->frame_rate); - cc->timeline_in += sequence->playhead; - cc->timeline_out += sequence->playhead; - cc->track = c->track; + cc->timeline_in += sequence->playhead; + cc->timeline_out += sequence->playhead; + cc->track = c->track; - paste_start = qMin(paste_start, cc->timeline_in); - paste_end = qMax(paste_end, cc->timeline_out); + paste_start = qMin(paste_start, cc->timeline_in); + paste_end = qMax(paste_end, cc->timeline_out); - pasted_clips.append(cc); + pasted_clips.append(cc); - if (!insert) { - Selection s; - s.in = cc->timeline_in; - s.out = cc->timeline_out; - s.track = c->track; - delete_areas.append(s); - } - } - if (insert) { - split_cache.clear(); - split_all_clips_at_point(ca, sequence->playhead); - ca->append(new RippleCommand(sequence, paste_start, paste_end - paste_start)); - } else { - delete_areas_and_relink(ca, delete_areas); - } + if (!insert) { + Selection s; + s.in = cc->timeline_in; + s.out = cc->timeline_out; + s.track = c->track; + delete_areas.append(s); + } + } + if (insert) { + split_cache.clear(); + split_all_clips_at_point(ca, sequence->playhead); + ripple_clips(ca, sequence, paste_start, paste_end - paste_start); + } else { + delete_areas_and_relink(ca, delete_areas); + } - // correct linked clips - for (int i=0;i(clipboard.at(i)); + // correct linked clips + for (int i=0;i(clipboard.at(i)); - for (int j=0;jlinked.size();j++) { - for (int k=0;k(clipboard.at(k)); - if (comp->load_id == oc->linked.at(j)) { - pasted_clips.at(i)->linked.append(k); - } - } - } - } + for (int j=0;jlinked.size();j++) { + for (int k=0;k(clipboard.at(k)); + if (comp->load_id == oc->linked.at(j)) { + pasted_clips.at(i)->linked.append(k); + } + } + } + } - ca->append(new AddClipCommand(sequence, pasted_clips)); + ca->append(new AddClipCommand(sequence, pasted_clips)); - undo_stack.push(ca); + undo_stack.push(ca); - update_ui(true); + update_ui(true); - if (config.paste_seeks) { - panel_sequence_viewer->seek(paste_end); - } - } else if (clipboard_type == CLIPBOARD_TYPE_EFFECT) { - ComboAction* ca = new ComboAction(); - bool push = false; + if (config.paste_seeks) { + panel_sequence_viewer->seek(paste_end); + } + } else if (clipboard_type == CLIPBOARD_TYPE_EFFECT) { + ComboAction* ca = new ComboAction(); + bool push = false; - bool replace = false; - bool skip = false; - bool ask_conflict = true; + bool replace = false; + bool skip = false; + bool ask_conflict = true; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL && is_clip_selected(c, true)) { - for (int j=0;j(clipboard.at(j)); - if ((c->track < 0) == (e->meta->subtype == EFFECT_TYPE_VIDEO)) { - int found = -1; - if (ask_conflict) { - replace = false; - skip = false; - } - for (int k=0;keffects.size();k++) { - if (c->effects.at(k)->meta == e->meta) { - found = k; - break; - } - } - if (found >= 0 && ask_conflict) { - QMessageBox box(this); - box.setWindowTitle("Effect already exists"); - box.setText("Clip '" + c->name + "' already contains a '" + e->meta->name + "' effect. Would you like to replace it with the pasted one or add it as a separate effect?"); - box.setIcon(QMessageBox::Icon::Question); + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL && is_clip_selected(c, true)) { + for (int j=0;j(clipboard.at(j)); + if ((c->track < 0) == (e->meta->subtype == EFFECT_TYPE_VIDEO)) { + int found = -1; + if (ask_conflict) { + replace = false; + skip = false; + } + for (int k=0;keffects.size();k++) { + if (c->effects.at(k)->meta == e->meta) { + found = k; + break; + } + } + if (found >= 0 && ask_conflict) { + QMessageBox box(this); + box.setWindowTitle("Effect already exists"); + box.setText("Clip '" + c->name + "' already contains a '" + e->meta->name + "' effect. Would you like to replace it with the pasted one or add it as a separate effect?"); + box.setIcon(QMessageBox::Icon::Question); - box.addButton("Add", QMessageBox::YesRole); - QPushButton* replace_button = box.addButton("Replace", QMessageBox::NoRole); - QPushButton* skip_button = box.addButton("Skip", QMessageBox::RejectRole); + box.addButton("Add", QMessageBox::YesRole); + QPushButton* replace_button = box.addButton("Replace", QMessageBox::NoRole); + QPushButton* skip_button = box.addButton("Skip", QMessageBox::RejectRole); - QCheckBox* future_box = new QCheckBox("Do this for all conflicts found"); - box.setCheckBox(future_box); + QCheckBox* future_box = new QCheckBox("Do this for all conflicts found"); + box.setCheckBox(future_box); - box.exec(); + box.exec(); - if (box.clickedButton() == replace_button) { - replace = true; - } else if (box.clickedButton() == skip_button) { - skip = true; - } - ask_conflict = !future_box->isChecked(); - } + if (box.clickedButton() == replace_button) { + replace = true; + } else if (box.clickedButton() == skip_button) { + skip = true; + } + ask_conflict = !future_box->isChecked(); + } - 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); + 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 AddEffectCommand(c, e->copy(c), NULL, found)); - push = true; - } else { - ca->append(new AddEffectCommand(c, e->copy(c), NULL)); - push = true; - } - } - } - } - } - if (push) { - ca->appendPost(new ReloadEffectsCommand()); - undo_stack.push(ca); - } else { - delete ca; - } - update_ui(true); - } - } + ca->append(new AddEffectCommand(c, e->copy(c), NULL, found)); + push = true; + } else { + ca->append(new AddEffectCommand(c, e->copy(c), NULL)); + push = true; + } + } + } + } + } + if (push) { + ca->appendPost(new ReloadEffectsCommand()); + undo_stack.push(ca); + } else { + delete ca; + } + update_ui(true); + } + } } void Timeline::ripple_to_in_point(bool in, bool ripple) { - if (sequence != NULL) { - // get track count - int track_min = 0; - int track_max = 0; + if (sequence != NULL) { + if (sequence->clips.size() > 0) { + if (!in && sequence->playhead == 0) return; - bool one_frame_mode = false; + // get track count + int track_min = INT_MAX; + int track_max = INT_MIN; + long sequence_end = 0; - // find closest in point to playhead - long in_point = in ? 0 : LONG_MAX; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL) { - track_min = qMin(track_min, c->track); - track_max = qMax(track_max, c->track); - if ((in && c->timeline_in > in_point && c->timeline_in <= sequence->playhead) - || (!in && c->timeline_in < in_point && c->timeline_in >= sequence->playhead)) { - in_point = c->timeline_in; - if (sequence->playhead == in_point) { - one_frame_mode = true; - break; - } - } - if ((in && c->timeline_out > in_point && c->timeline_out <= sequence->playhead) - || (!in && c->timeline_out < in_point && c->timeline_out > sequence->playhead)) { - in_point = c->timeline_out; - if (sequence->playhead == in_point) { - one_frame_mode = true; - break; + // find closest in point to playhead + long in_point = in ? LONG_MIN : LONG_MAX; + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL) { + track_min = qMin(track_min, c->track); + track_max = qMax(track_max, c->track); + + sequence_end = qMax(c->timeline_out, sequence_end); + + if (sequence->playhead != in_point) { + if ((in && c->timeline_in > in_point && c->timeline_in <= sequence->playhead) + || (!in && c->timeline_in < in_point && c->timeline_in >= sequence->playhead)) { + in_point = c->timeline_in; + } + if ((in && c->timeline_out > in_point && c->timeline_out <= sequence->playhead) + || (!in && c->timeline_out < in_point && c->timeline_out >= sequence->playhead)) { + in_point = c->timeline_out; + } } } } - } - QVector areas; - ComboAction* ca = new ComboAction(); + if (in && sequence->playhead == sequence_end) return; - if (one_frame_mode) { - // set up deletion areas based on track count - if (in) { - in_point = sequence->playhead; + QVector areas; + ComboAction* ca = new ComboAction(); + bool push_undo = true; + + if (sequence->playhead == in_point) { // one frame mode + if (ripple) { + // set up deletion areas based on track count + if (in) { + in_point = sequence->playhead; + } else { + in_point = sequence->playhead - 1; + } + + if (in_point >= 0) { + Selection s; + s.in = in_point; + s.out = in_point + 1; + for (int i=track_min;i<=track_max;i++) { + s.track = i; + areas.append(s); + } + + // trim and move clips around the in point + delete_areas_and_relink(ca, areas); + + if (ripple) ripple_clips(ca, sequence, in_point, -1); + } else { + push_undo = false; + } + } else { + push_undo = false; + } } else { - in_point = sequence->playhead - 1; - } - - for (int i=track_min;i<=track_max;i++) { + // set up deletion areas based on track count Selection s; - s.in = in_point; - s.out = in_point + 1; - s.track = i; - areas.append(s); - } - - // trim and move clips around the in point - delete_areas_and_relink(ca, areas); - if (ripple) ca->append(new RippleCommand(sequence, in_point, -1)); - } else { - // set up deletion areas based on track count - for (int i=track_min;i<=track_max;i++) { - Selection s; s.in = qMin(in_point, sequence->playhead); s.out = qMax(in_point, sequence->playhead); - s.track = i; - areas.append(s); + for (int i=track_min;i<=track_max;i++) { + s.track = i; + areas.append(s); + } + + // trim and move clips around the in point + delete_areas_and_relink(ca, areas); + if (ripple) ripple_clips(ca, sequence, in_point, (in) ? (in_point - sequence->playhead) : (sequence->playhead - in_point)); } - // trim and move clips around the in point - delete_areas_and_relink(ca, areas); - if (ripple) ca->append(new RippleCommand(sequence, in_point, (in) ? (in_point - sequence->playhead) : (sequence->playhead - in_point))); - } + if (push_undo) { + undo_stack.push(ca); - undo_stack.push(ca); + update_ui(true); - update_ui(true); - - if (in_point < sequence->playhead && ripple) panel_sequence_viewer->seek(in_point); - } + if (in_point < sequence->playhead && ripple) panel_sequence_viewer->seek(in_point); + } else { + delete ca; + } + } else { + panel_sequence_viewer->seek(0); + } + } } bool Timeline::split_selection(ComboAction* ca) { - bool split = false; + bool split = false; - // temporary relinking vectors - QVector pre_splits; - QVector post_splits; - QVector secondary_post_splits; + // temporary relinking vectors + QVector pre_splits; + QVector post_splits; + QVector secondary_post_splits; - // find clips within selection and split - for (int j=0;jclips.size();j++) { - Clip* clip = sequence->clips.at(j); - if (clip != NULL) { + // find clips within selection and split + for (int j=0;jclips.size();j++) { + Clip* clip = sequence->clips.at(j); + if (clip != NULL) { for (int i=0;iselections.size();i++) { const Selection& s = sequence->selections.at(i); - if (s.track == clip->track) { + if (s.track == clip->track) { if (clip->timeline_in < s.in && clip->timeline_out > s.out) { - Clip* split_A = clip->copy(sequence); - split_A->clip_in += (s.in - clip->timeline_in); - split_A->timeline_in = s.in; - split_A->timeline_out = s.out; - pre_splits.append(j); + Clip* split_A = clip->copy(sequence); + split_A->clip_in += (s.in - clip->timeline_in); + split_A->timeline_in = s.in; + split_A->timeline_out = s.out; + pre_splits.append(j); post_splits.append(split_A); - Clip* split_B = clip->copy(sequence); - split_B->clip_in += (s.out - clip->timeline_in); - split_B->timeline_in = s.out; - secondary_post_splits.append(split_B); + Clip* split_B = clip->copy(sequence); + split_B->clip_in += (s.out - clip->timeline_in); + split_B->timeline_in = s.out; + secondary_post_splits.append(split_B); - if (clip->get_opening_transition() != NULL) { - split_B->sequence->hard_delete_transition(split_B, TA_OPENING_TRANSITION); - split_A->sequence->hard_delete_transition(split_A, TA_OPENING_TRANSITION); + if (clip->get_opening_transition() != NULL) { + split_B->sequence->hard_delete_transition(split_B, TA_OPENING_TRANSITION); + split_A->sequence->hard_delete_transition(split_A, TA_OPENING_TRANSITION); } - if (clip->get_closing_transition() != NULL) { - ca->append(new DeleteTransitionCommand(clip->sequence, clip->closing_transition)); + if (clip->get_closing_transition() != NULL) { + ca->append(new DeleteTransitionCommand(clip->sequence, clip->closing_transition)); - split_A->sequence->hard_delete_transition(split_A, TA_CLOSING_TRANSITION); + split_A->sequence->hard_delete_transition(split_A, TA_CLOSING_TRANSITION); } - move_clip(ca, clip, clip->timeline_in, s.in, clip->clip_in, clip->track); - split = true; - } else { - Clip* post_a = split_clip(ca, j, s.in); - Clip* post_b = split_clip(ca, j, s.out); - if (post_a != NULL) { - pre_splits.append(j); - post_splits.append(post_a); - split = true; - } - if (post_b != NULL) { - if (post_a != NULL) { - pre_splits.append(j); - post_splits.append(post_b); - } else { - secondary_post_splits.append(post_b); - } - split = true; - } - } - } - } - } - } + move_clip(ca, clip, clip->timeline_in, s.in, clip->clip_in, clip->track); + split = true; + } else { + Clip* post_a = split_clip(ca, j, s.in); + Clip* post_b = split_clip(ca, j, s.out); + if (post_a != NULL) { + pre_splits.append(j); + post_splits.append(post_a); + split = true; + } + if (post_b != NULL) { + if (post_a != NULL) { + pre_splits.append(j); + post_splits.append(post_b); + } else { + secondary_post_splits.append(post_b); + } + split = true; + } + } + } + } + } + } - if (split) { - // relink after splitting - relink_clips_using_ids(pre_splits, post_splits); - relink_clips_using_ids(pre_splits, secondary_post_splits); - ca->append(new AddClipCommand(sequence, post_splits)); - ca->append(new AddClipCommand(sequence, secondary_post_splits)); + if (split) { + // relink after splitting + relink_clips_using_ids(pre_splits, post_splits); + relink_clips_using_ids(pre_splits, secondary_post_splits); + ca->append(new AddClipCommand(sequence, post_splits)); + ca->append(new AddClipCommand(sequence, secondary_post_splits)); - return true; - } - return false; + return true; + } + return false; } bool Timeline::split_all_clips_at_point(ComboAction* ca, long point) { - bool split = false; - for (int j=0;jclips.size();j++) { - Clip* c = sequence->clips.at(j); - if (c != NULL) { - // always relinks - if (split_clip_and_relink(ca, j, point, true)) { - split = true; - } - } - } - return split; + bool split = false; + for (int j=0;jclips.size();j++) { + Clip* c = sequence->clips.at(j); + if (c != NULL) { + // always relinks + if (split_clip_and_relink(ca, j, point, true)) { + split = true; + } + } + } + return split; } void Timeline::split_at_playhead() { - ComboAction* ca = new ComboAction(); - bool split_selected = false; - split_cache.clear(); + ComboAction* ca = new ComboAction(); + bool split_selected = false; + split_cache.clear(); if (sequence->selections.size() > 0) { - // see if whole clips are selected - QVector pre_clips; - QVector post_clips; - for (int j=0;jclips.size();j++) { - Clip* clip = sequence->clips.at(j); - if (clip != NULL && is_clip_selected(clip, true)) { + // see if whole clips are selected + QVector pre_clips; + QVector post_clips; + for (int j=0;jclips.size();j++) { + Clip* clip = sequence->clips.at(j); + if (clip != NULL && is_clip_selected(clip, true)) { Clip* s = split_clip(ca, j, sequence->playhead); - if (s != NULL) { - pre_clips.append(j); - post_clips.append(s); - split_selected = true; - } - } - } + if (s != NULL) { + pre_clips.append(j); + post_clips.append(s); + split_selected = true; + } + } + } - if (split_selected) { - // relink clips if we split - relink_clips_using_ids(pre_clips, post_clips); - ca->append(new AddClipCommand(sequence, post_clips)); - } else { - // split a selection if not - split_selected = split_selection(ca); - } - } + if (split_selected) { + // relink clips if we split + relink_clips_using_ids(pre_clips, post_clips); + ca->append(new AddClipCommand(sequence, post_clips)); + } else { + // split a selection if not + split_selected = split_selection(ca); + } + } - // if nothing was selected or no selections fell within playhead, simply split at playhead - if (!split_selected) { - split_selected = split_all_clips_at_point(ca, sequence->playhead); - } + // if nothing was selected or no selections fell within playhead, simply split at playhead + if (!split_selected) { + split_selected = split_all_clips_at_point(ca, sequence->playhead); + } - if (split_selected) { - undo_stack.push(ca); + if (split_selected) { + undo_stack.push(ca); update_ui(true); - } else { - delete ca; - } + } else { + delete ca; + } } void Timeline::deselect_area(long in, long out, int track) { @@ -1294,18 +1302,18 @@ void Timeline::deselect_area(long in, long out, int track) { } bool Timeline::snap_to_point(long point, long* l) { - int limit = get_snap_range(); - if (*l > point-limit-1 && *l < point+limit+1) { - snap_point = point; - *l = point; - snapped = true; - return true; - } - return false; + int limit = get_snap_range(); + if (*l > point-limit-1 && *l < point+limit+1) { + snap_point = point; + *l = point; + snapped = true; + return true; + } + return false; } bool Timeline::snap_to_timeline(long* l, bool use_playhead, bool use_markers, bool use_workarea) { - snapped = false; + snapped = false; if (snapping) { if (use_playhead && !panel_sequence_viewer->playing) { // snap to playhead @@ -1333,11 +1341,11 @@ bool Timeline::snap_to_timeline(long* l, bool use_playhead, bool use_markers, bo return true; } else if (snap_to_point(c->timeline_out, l)) { return true; - } else if (c->get_opening_transition() != NULL - && snap_to_point(c->timeline_in + c->get_opening_transition()->get_true_length(), l)) { + } else if (c->get_opening_transition() != NULL + && snap_to_point(c->timeline_in + c->get_opening_transition()->get_true_length(), l)) { return true; - } else if (c->get_closing_transition() != NULL - && snap_to_point(c->timeline_out - c->get_closing_transition()->get_true_length(), l)) { + } else if (c->get_closing_transition() != NULL + && snap_to_point(c->timeline_out - c->get_closing_transition()->get_true_length(), l)) { return true; } } @@ -1357,50 +1365,50 @@ void Timeline::set_marker() { } void Timeline::toggle_links() { - LinkCommand* command = new LinkCommand(); + LinkCommand* command = new LinkCommand(); command->s = sequence; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL && is_clip_selected(c, true)) { + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL && is_clip_selected(c, true)) { command->clips.append(i); - if (c->linked.size() > 0) { - command->link = false; // prioritize unlinking + if (c->linked.size() > 0) { + command->link = false; // prioritize unlinking for (int j=0;jlinked.size();j++) { // add links to the command if (!command->clips.contains(c->linked.at(j))) { command->clips.append(c->linked.at(j)); } - } - } - } - } - if (command->clips.size() > 0) { - undo_stack.push(command); + } + } + } + } + if (command->clips.size() > 0) { + undo_stack.push(command); repaint_timeline(); - } else { - delete command; - } + } else { + delete command; + } } void Timeline::increase_track_height() { - for (int i=0;itimeline_area->setCursor(Qt::ArrowCursor); - tool = TIMELINE_TOOL_POINTER; - creating = false; -} - -void Timeline::on_toolEditButton_clicked() { - decheck_tool_buttons(sender()); - ui->timeline_area->setCursor(Qt::IBeamCursor); - tool = TIMELINE_TOOL_EDIT; - creating = false; -} - -void Timeline::on_toolRippleButton_clicked() { - decheck_tool_buttons(sender()); - ui->timeline_area->setCursor(Qt::ArrowCursor); - tool = TIMELINE_TOOL_RIPPLE; - creating = false; -} - -void Timeline::on_toolRollingButton_clicked() { - decheck_tool_buttons(sender()); - ui->timeline_area->setCursor(Qt::ArrowCursor); - tool = TIMELINE_TOOL_ROLLING; - creating = false; -} - -void Timeline::on_toolRazorButton_clicked() -{ - decheck_tool_buttons(sender()); - ui->timeline_area->setCursor(Qt::IBeamCursor); - tool = TIMELINE_TOOL_RAZOR; - creating = false; -} - -void Timeline::on_toolSlipButton_clicked() -{ - decheck_tool_buttons(sender()); - ui->timeline_area->setCursor(Qt::ArrowCursor); - tool = TIMELINE_TOOL_SLIP; - creating = false; -} - -void Timeline::on_toolSlideButton_clicked() -{ - decheck_tool_buttons(sender()); - ui->timeline_area->setCursor(Qt::ArrowCursor); - tool = TIMELINE_TOOL_SLIDE; - creating = false; -} - -void Timeline::on_addButton_clicked() { +void Timeline::add_btn_click() { QMenu add_menu(this); QAction* titleMenuItem = new QAction(&add_menu); @@ -1511,39 +1467,40 @@ void Timeline::on_addButton_clicked() { noiseMenuItem->setData(ADD_OBJ_NOISE); add_menu.addAction(noiseMenuItem); - connect(&add_menu, SIGNAL(triggered(QAction*)), this, SLOT(addMenuItem(QAction*))); + connect(&add_menu, SIGNAL(triggered(QAction*)), this, SLOT(add_menu_item(QAction*))); add_menu.exec(QCursor::pos()); } -void Timeline::addMenuItem(QAction* action) { +void Timeline::add_menu_item(QAction* action) { creating = true; creating_object = action->data().toInt(); } void Timeline::setScroll(int s) { scroll = s; - ui->headers->set_scroll(s); + headers->set_scroll(s); repaint_timeline(); } -void Timeline::on_recordButton_clicked() { +void Timeline::record_btn_click() { if (project_url.isEmpty()) { QMessageBox::critical(this, "Unsaved Project", "You must save this project before you can record audio in it.", QMessageBox::Ok); } else { creating = true; creating_object = ADD_OBJ_AUDIO; + mainWindow->statusBar()->showMessage("Click on the timeline where you want to start recording (drag to limit the recording to a certain timeframe)", 10000); } } -void Timeline::on_toolTransitionButton_clicked() { +void Timeline::transition_tool_click() { creating = false; QMenu transition_menu(this); - for (int i=0;isetObjectName("v"); a->setData(reinterpret_cast(&em)); @@ -1552,9 +1509,9 @@ void Timeline::on_toolTransitionButton_clicked() { transition_menu.addSeparator(); - for (int i=0;isetObjectName("a"); a->setData(reinterpret_cast(&em)); @@ -1563,7 +1520,7 @@ void Timeline::on_toolTransitionButton_clicked() { connect(&transition_menu, SIGNAL(triggered(QAction*)), this, SLOT(transition_menu_select(QAction*))); - ui->toolTransitionButton->setChecked(false); + toolTransitionButton->setChecked(false); transition_menu.exec(QCursor::pos()); } @@ -1578,40 +1535,281 @@ void Timeline::transition_menu_select(QAction* a) { } decheck_tool_buttons(sender()); - ui->timeline_area->setCursor(Qt::CrossCursor); + timeline_area->setCursor(Qt::CrossCursor); tool = TIMELINE_TOOL_TRANSITION; - ui->toolTransitionButton->setChecked(true); + toolTransitionButton->setChecked(true); } void Timeline::resize_move(double z) { - set_zoom_value(zoom * z); + set_zoom_value(zoom * z); } void Timeline::set_sb_max() { - ui->headers->set_scrollbar_max(ui->horizontalScrollBar, sequence->getEndFrame(), ui->editAreas->width() - getScreenPointFromFrame(zoom, 200)); + headers->set_scrollbar_max(horizontalScrollBar, sequence->getEndFrame(), editAreas->width() - getScreenPointFromFrame(zoom, 200)); } -void move_clip(ComboAction* ca, Clip *c, long iin, long iout, long iclip_in, int itrack, bool verify_transitions) { - ca->append(new MoveClipAction(c, iin, iout, iclip_in, itrack)); +void Timeline::setup_ui() { + QWidget* dockWidgetContents = new QWidget(); - if (verify_transitions) { - if (c->get_opening_transition() != NULL && c->get_opening_transition()->secondary_clip != NULL && c->get_opening_transition()->secondary_clip->timeline_out != iin) { - // separate transition - ca->append(new SetPointer((void**) &c->get_opening_transition()->secondary_clip, NULL)); - ca->append(new AddTransitionCommand(c->get_opening_transition()->secondary_clip, NULL, c->get_opening_transition(), NULL, TA_CLOSING_TRANSITION, 0)); - } + QHBoxLayout* horizontalLayout = new QHBoxLayout(dockWidgetContents); + horizontalLayout->setSpacing(0); + horizontalLayout->setContentsMargins(0, 0, 0, 0); - if (c->get_closing_transition() != NULL && c->get_closing_transition()->secondary_clip != NULL && c->get_closing_transition()->parent_clip->timeline_in != iout) { - // separate transition - ca->append(new SetPointer((void**) &c->get_closing_transition()->secondary_clip, NULL)); - ca->append(new AddTransitionCommand(c, NULL, c->get_closing_transition(), NULL, TA_CLOSING_TRANSITION, 0)); - } - } + QWidget* tool_buttons = new QWidget(dockWidgetContents); + tool_buttons->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum); + + QVBoxLayout* tool_buttons_layout = new QVBoxLayout(tool_buttons); + tool_buttons_layout->setSpacing(4); + tool_buttons_layout->setContentsMargins(0, 0, 0, 0); + + toolArrowButton = new QPushButton(tool_buttons); + QIcon arrow_icon; + arrow_icon.addFile(QStringLiteral(":/icons/arrow.png"), QSize(), QIcon::Normal, QIcon::Off); + arrow_icon.addFile(QStringLiteral(":/icons/arrow-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + toolArrowButton->setIcon(arrow_icon); + toolArrowButton->setCheckable(true); + toolArrowButton->setToolTip("Pointer Tool (V)"); + toolArrowButton->setProperty("tool", TIMELINE_TOOL_POINTER); + connect(toolArrowButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); + tool_buttons_layout->addWidget(toolArrowButton); + + toolEditButton = new QPushButton(tool_buttons); + QIcon icon1; + icon1.addFile(QStringLiteral(":/icons/beam.png"), QSize(), QIcon::Normal, QIcon::Off); + icon1.addFile(QStringLiteral(":/icons/beam-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + toolEditButton->setIcon(icon1); + toolEditButton->setCheckable(true); + toolEditButton->setToolTip("Edit Tool (X)"); + toolEditButton->setProperty("tool", TIMELINE_TOOL_EDIT); + connect(toolEditButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); + tool_buttons_layout->addWidget(toolEditButton); + + toolRippleButton = new QPushButton(tool_buttons); + QIcon icon2; + icon2.addFile(QStringLiteral(":/icons/ripple.png"), QSize(), QIcon::Normal, QIcon::Off); + icon2.addFile(QStringLiteral(":/icons/ripple-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + toolRippleButton->setIcon(icon2); + toolRippleButton->setCheckable(true); + toolRippleButton->setToolTip("Ripple Tool (B)"); + toolRippleButton->setProperty("tool", TIMELINE_TOOL_RIPPLE); + connect(toolRippleButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); + tool_buttons_layout->addWidget(toolRippleButton); + + toolRazorButton = new QPushButton(tool_buttons); + QIcon icon4; + icon4.addFile(QStringLiteral(":/icons/razor.png"), QSize(), QIcon::Normal, QIcon::Off); + icon4.addFile(QStringLiteral(":/icons/razor-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + toolRazorButton->setIcon(icon4); + toolRazorButton->setCheckable(true); + toolRazorButton->setToolTip("Razor Tool (C)"); + toolRazorButton->setProperty("tool", TIMELINE_TOOL_RAZOR); + connect(toolRazorButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); + tool_buttons_layout->addWidget(toolRazorButton); + + toolSlipButton = new QPushButton(tool_buttons); + QIcon icon5; + icon5.addFile(QStringLiteral(":/icons/slip.png"), QSize(), QIcon::Normal, QIcon::On); + icon5.addFile(QStringLiteral(":/icons/slip-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolSlipButton->setIcon(icon5); + toolSlipButton->setCheckable(true); + toolSlipButton->setToolTip("Slip Tool (Y)"); + toolSlipButton->setProperty("tool", TIMELINE_TOOL_SLIP); + connect(toolSlipButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); + tool_buttons_layout->addWidget(toolSlipButton); + + toolSlideButton = new QPushButton(tool_buttons); + QIcon icon6; + icon6.addFile(QStringLiteral(":/icons/slide.png"), QSize(), QIcon::Normal, QIcon::On); + icon6.addFile(QStringLiteral(":/icons/slide-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolSlideButton->setIcon(icon6); + toolSlideButton->setCheckable(true); + toolSlideButton->setToolTip("Slide Tool (U)"); + toolSlideButton->setProperty("tool", TIMELINE_TOOL_SLIDE); + connect(toolSlideButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); + tool_buttons_layout->addWidget(toolSlideButton); + + toolHandButton = new QPushButton(tool_buttons); + QIcon icon7; + icon7.addFile(QStringLiteral(":/icons/hand.png"), QSize(), QIcon::Normal, QIcon::On); + icon7.addFile(QStringLiteral(":/icons/hand-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolHandButton->setIcon(icon7); + toolHandButton->setCheckable(true); + toolHandButton->setToolTip("Hand Tool (H)"); + toolHandButton->setProperty("tool", TIMELINE_TOOL_HAND); + connect(toolHandButton, SIGNAL(clicked(bool)), this, SLOT(set_tool())); + tool_buttons_layout->addWidget(toolHandButton); + + toolTransitionButton = new QPushButton(tool_buttons); + QIcon icon8; + icon8.addFile(QStringLiteral(":/icons/transition-tool.png"), QSize(), QIcon::Normal, QIcon::On); + icon8.addFile(QStringLiteral(":/icons/transition-tool-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolTransitionButton->setIcon(icon8); + toolTransitionButton->setCheckable(true); + toolTransitionButton->setToolTip("Transition Tool (T)"); + connect(toolTransitionButton, SIGNAL(clicked(bool)), this, SLOT(transition_tool_click())); + tool_buttons_layout->addWidget(toolTransitionButton); + + snappingButton = new QPushButton(tool_buttons); + QIcon icon9; + icon9.addFile(QStringLiteral(":/icons/magnet.png"), QSize(), QIcon::Normal, QIcon::On); + icon9.addFile(QStringLiteral(":/icons/magnet-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + snappingButton->setIcon(icon9); + snappingButton->setCheckable(true); + snappingButton->setChecked(true); + snappingButton->setToolTip("Snapping (S)"); + connect(snappingButton, SIGNAL(toggled(bool)), this, SLOT(snapping_clicked(bool))); + tool_buttons_layout->addWidget(snappingButton); + + zoomInButton = new QPushButton(tool_buttons); + QIcon icon10; + icon10.addFile(QStringLiteral(":/icons/zoomin.png"), QSize(), QIcon::Normal, QIcon::On); + icon10.addFile(QStringLiteral(":/icons/zoomin-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + zoomInButton->setIcon(icon10); + zoomInButton->setToolTip("Zoom In (=)"); + connect(zoomInButton, SIGNAL(clicked(bool)), this, SLOT(zoom_in())); + tool_buttons_layout->addWidget(zoomInButton); + + zoomOutButton = new QPushButton(tool_buttons); + QIcon icon11; + icon11.addFile(QStringLiteral(":/icons/zoomout.png"), QSize(), QIcon::Normal, QIcon::On); + icon11.addFile(QStringLiteral(":/icons/zoomout-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + zoomOutButton->setIcon(icon11); + zoomOutButton->setToolTip("Zoom Out (-)"); + connect(zoomOutButton, SIGNAL(clicked(bool)), this, SLOT(zoom_out())); + tool_buttons_layout->addWidget(zoomOutButton); + + recordButton = new QPushButton(tool_buttons); + QIcon icon12; + icon12.addFile(QStringLiteral(":/icons/record.png"), QSize(), QIcon::Normal, QIcon::On); + icon12.addFile(QStringLiteral(":/icons/record-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + recordButton->setIcon(icon12); + recordButton->setToolTip("Record audio"); + connect(recordButton, SIGNAL(clicked(bool)), this, SLOT(record_btn_click())); + + tool_buttons_layout->addWidget(recordButton); + + addButton = new QPushButton(tool_buttons); + QIcon icon13; + icon13.addFile(QStringLiteral(":/icons/add-button.png"), QSize(), QIcon::Normal, QIcon::On); + icon13.addFile(QStringLiteral(":/icons/add-button-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + addButton->setIcon(icon13); + addButton->setToolTip("Add title, solid, bars, etc."); + connect(addButton, SIGNAL(clicked()), this, SLOT(add_btn_click())); + tool_buttons_layout->addWidget(addButton); + + tool_buttons_layout->addStretch(); + + horizontalLayout->addWidget(tool_buttons); + + timeline_area = new QWidget(dockWidgetContents); + QSizePolicy sizePolicy2(QSizePolicy::Minimum, QSizePolicy::Minimum); + sizePolicy2.setHorizontalStretch(1); + sizePolicy2.setVerticalStretch(0); + sizePolicy2.setHeightForWidth(timeline_area->sizePolicy().hasHeightForWidth()); + timeline_area->setSizePolicy(sizePolicy2); + QVBoxLayout* timeline_area_layout = new QVBoxLayout(timeline_area); + timeline_area_layout->setSpacing(0); + timeline_area_layout->setContentsMargins(0, 0, 0, 0); + headers = new TimelineHeader(timeline_area); + + timeline_area_layout->addWidget(headers); + + editAreas = new QWidget(timeline_area); + QHBoxLayout* editAreaLayout = new QHBoxLayout(editAreas); + editAreaLayout->setSpacing(0); + editAreaLayout->setContentsMargins(0, 0, 0, 0); + QSplitter* splitter = new QSplitter(editAreas); + splitter->setOrientation(Qt::Vertical); + QWidget* videoContainer = new QWidget(splitter); + QHBoxLayout* videoContainerLayout = new QHBoxLayout(videoContainer); + videoContainerLayout->setSpacing(0); + videoContainerLayout->setContentsMargins(0, 0, 0, 0); + video_area = new TimelineWidget(videoContainer); + video_area->setFocusPolicy(Qt::ClickFocus); + + videoContainerLayout->addWidget(video_area); + + videoScrollbar = new QScrollBar(videoContainer); + videoScrollbar->setMaximum(0); + videoScrollbar->setSingleStep(20); + videoScrollbar->setPageStep(1826); + videoScrollbar->setOrientation(Qt::Vertical); + + videoContainerLayout->addWidget(videoScrollbar); + + splitter->addWidget(videoContainer); + + QWidget* audioContainer = new QWidget(splitter); + QHBoxLayout* audioContainerLayout = new QHBoxLayout(audioContainer); + audioContainerLayout->setSpacing(0); + audioContainerLayout->setContentsMargins(0, 0, 0, 0); + audio_area = new TimelineWidget(audioContainer); + audio_area->setFocusPolicy(Qt::ClickFocus); + + audioContainerLayout->addWidget(audio_area); + + audioScrollbar = new QScrollBar(audioContainer); + audioScrollbar->setMaximum(0); + audioScrollbar->setOrientation(Qt::Vertical); + + audioContainerLayout->addWidget(audioScrollbar); + + splitter->addWidget(audioContainer); + + editAreaLayout->addWidget(splitter); + + timeline_area_layout->addWidget(editAreas); + + horizontalScrollBar = new ResizableScrollBar(timeline_area); + horizontalScrollBar->setMaximum(0); + horizontalScrollBar->setSingleStep(20); + horizontalScrollBar->setPageStep(1826); + horizontalScrollBar->setOrientation(Qt::Horizontal); + + timeline_area_layout->addWidget(horizontalScrollBar); + + horizontalLayout->addWidget(timeline_area); + + audio_monitor = new AudioMonitor(dockWidgetContents); + audio_monitor->setMinimumSize(QSize(50, 0)); + + horizontalLayout->addWidget(audio_monitor); + + setWidget(dockWidgetContents); } -void Timeline::on_toolHandButton_clicked() { - decheck_tool_buttons(sender()); - ui->timeline_area->setCursor(Qt::OpenHandCursor); - tool = TIMELINE_TOOL_HAND; - creating = false; +void move_clip(ComboAction* ca, Clip *c, long iin, long iout, long iclip_in, int itrack, bool verify_transitions, bool relative) { + ca->append(new MoveClipAction(c, iin, iout, iclip_in, itrack, relative)); + + if (verify_transitions) { + if (c->get_opening_transition() != NULL && c->get_opening_transition()->secondary_clip != NULL && c->get_opening_transition()->secondary_clip->timeline_out != iin) { + // separate transition + ca->append(new SetPointer((void**) &c->get_opening_transition()->secondary_clip, NULL)); + ca->append(new AddTransitionCommand(c->get_opening_transition()->secondary_clip, NULL, c->get_opening_transition(), NULL, TA_CLOSING_TRANSITION, 0)); + } + + if (c->get_closing_transition() != NULL && c->get_closing_transition()->secondary_clip != NULL && c->get_closing_transition()->parent_clip->timeline_in != iout) { + // separate transition + ca->append(new SetPointer((void**) &c->get_closing_transition()->secondary_clip, NULL)); + ca->append(new AddTransitionCommand(c, NULL, c->get_closing_transition(), NULL, TA_CLOSING_TRANSITION, 0)); + } + } +} + +void Timeline::set_tool() { + QPushButton* button = static_cast(sender()); + decheck_tool_buttons(button); + tool = button->property("tool").toInt(); + creating = false; + switch (tool) { + case TIMELINE_TOOL_EDIT: + case TIMELINE_TOOL_RAZOR: + timeline_area->setCursor(Qt::IBeamCursor); + break; + case TIMELINE_TOOL_HAND: + timeline_area->setCursor(Qt::OpenHandCursor); + break; + default: + timeline_area->setCursor(Qt::ArrowCursor); + } } diff --git a/panels/timeline.h b/panels/timeline.h index d3ae3a7d1..a76adc3a9 100644 --- a/panels/timeline.h +++ b/panels/timeline.h @@ -24,6 +24,11 @@ class ComboAction; class Effect; class Media; class Transition; +class TimelineHeader; +class TimelineWidget; +class ResizableScrollBar; +class AudioMonitor; +class QScrollBar; struct EffectMeta; struct Sequence; struct Clip; @@ -35,10 +40,11 @@ int getScreenPointFromFrame(double zoom, long frame); long getFrameFromScreenPoint(double zoom, int x); void draw_selection_rectangle(QPainter& painter, const QRect& rect); bool selection_contains_transition(const Selection& s, Clip* c, int type); -void move_clip(ComboAction *ca, Clip *c, long iin, long iout, long iclip_in, int itrack, bool verify_transitions = true); +void move_clip(ComboAction *ca, Clip *c, long iin, long iout, long iclip_in, int itrack, bool verify_transitions = true, bool relative = false); +void ripple_clips(ComboAction *ca, Sequence* s, long point, long length, const QVector& ignore = QVector()); struct Ghost { - int clip; + int clip; long in; long out; int track; @@ -50,23 +56,19 @@ struct Ghost { long old_clip_in; // importing variables - Media* media; - int media_stream; + Media* media; + int media_stream; // other variables long ghost_length; long media_length; - bool trim_in; - bool trimming; + bool trim_in; + bool trimming; // transition trimming - Transition* transition; + Transition* transition; }; -namespace Ui { -class Timeline; -} - class Timeline : public QDockWidget { Q_OBJECT @@ -74,35 +76,31 @@ public: explicit Timeline(QWidget *parent = 0); ~Timeline(); - bool focused(); - void set_zoom(bool in); - void copy(bool del); - void paste(bool insert); - void deselect(); - Clip* split_clip(ComboAction* ca, int p, long frame); - Clip* split_clip(ComboAction* ca, int p, long frame, long post_in); - bool split_selection(ComboAction* ca); - void split_at_playhead(); - bool split_all_clips_at_point(ComboAction *ca, long point); - bool split_clip_and_relink(ComboAction* ca, int clip, long frame, bool relink); - void clean_up_selections(QVector& areas); + bool focused(); + void set_zoom(bool in); + void copy(bool del); + void paste(bool insert); + Clip* split_clip(ComboAction* ca, int p, long frame); + Clip* split_clip(ComboAction* ca, int p, long frame, long post_in); + bool split_selection(ComboAction* ca); + bool split_all_clips_at_point(ComboAction *ca, long point); + bool split_clip_and_relink(ComboAction* ca, int clip, long frame, bool relink); + void clean_up_selections(QVector& areas); void deselect_area(long in, long out, int track); - void delete_areas_and_relink(ComboAction *ca, QVector& areas); - void relink_clips_using_ids(QVector& old_clips, QVector& new_clips); - void update_sequence(); - void increase_track_height(); - void decrease_track_height(); - void add_transition(); - QVector get_tracks_of_linked_clips(int i); - bool has_clip_been_split(int c); - void toggle_links(); + void delete_areas_and_relink(ComboAction *ca, QVector& areas); + void relink_clips_using_ids(QVector& old_clips, QVector& new_clips); + void update_sequence(); + void increase_track_height(); + void decrease_track_height(); + void add_transition(); + QVector get_tracks_of_linked_clips(int i); + bool has_clip_been_split(int c); void ripple_to_in_point(bool in, bool ripple); - void delete_in_out(bool ripple); + void delete_in_out(bool ripple); void previous_cut(); void next_cut(); - void toggle_show_all(); - void create_ghosts_from_media(Sequence *seq, long entry_point, QVector &media_list); + 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); @@ -111,141 +109,145 @@ public: long getDisplayFrameFromScreenPoint(int x); int get_snap_range(); - bool snap_to_point(long point, long* l); + bool snap_to_point(long point, long* l); bool snap_to_timeline(long* l, bool use_playhead, bool use_markers, bool use_workarea); void set_marker(); - // shared information + // shared information int tool; - long cursor_frame; - int cursor_track; - double zoom; - bool zoom_just_changed; + long cursor_frame; + int cursor_track; + double zoom; + bool zoom_just_changed; long drag_frame_start; int drag_track_start; void update_effect_controls(); bool showing_all; double old_zoom; - QVector video_track_heights; - QVector audio_track_heights; - int get_track_height_size(bool video); - int calculate_track_height(int track, int height); + QVector video_track_heights; + QVector audio_track_heights; + int get_track_height_size(bool video); + int calculate_track_height(int track, int height); - // snapping - bool snapping; - bool snapped; - long snap_point; + // snapping + bool snapping; + bool snapped; + long snap_point; // selecting functions bool selecting; - int selection_offset; - bool is_clip_selected(Clip* clip, bool containing); + int selection_offset; + bool is_clip_selected(Clip* clip, bool containing); void delete_selection(QVector &selections, bool ripple); void select_all(); - bool rect_select_init; - bool rect_select_proc; - int rect_select_x; - int rect_select_y; - int rect_select_w; - int rect_select_h; + bool rect_select_init; + bool rect_select_proc; + int rect_select_x; + int rect_select_y; + int rect_select_w; + int rect_select_h; // moving bool moving_init; bool moving_proc; - QVector ghosts; - bool video_ghosts; - bool audio_ghosts; + QVector ghosts; + bool video_ghosts; + bool audio_ghosts; bool move_insert; // trimming int trim_target; - bool trim_in_point; + bool trim_in_point; int transition_select; // splitting bool splitting; - QVector split_tracks; - QVector split_cache; + QVector split_tracks; + QVector split_cache; // importing - bool importing; + bool importing; bool importing_files; // creating variables bool creating; int creating_object; - // transition variables - bool transition_tool_init; - bool transition_tool_proc; - int transition_tool_pre_clip; - int transition_tool_post_clip; - int transition_tool_type; + // transition variables + bool transition_tool_init; + bool transition_tool_proc; + int transition_tool_pre_clip; + int transition_tool_post_clip; + int transition_tool_type; const EffectMeta* transition_tool_meta; int transition_tool_side; - // hand tool variables - bool hand_moving; - int drag_x_start; - int drag_y_start; + // hand tool variables + bool hand_moving; + int drag_x_start; + int drag_y_start; - bool block_repaints; + bool block_repaints; - Ui::Timeline *ui; + TimelineHeader* headers; + AudioMonitor* audio_monitor; + ResizableScrollBar* horizontalScrollBar; - void resizeEvent(QResizeEvent *event); + QPushButton* toolArrowButton; + QPushButton* toolEditButton; + QPushButton* toolRippleButton; + QPushButton* toolRazorButton; + QPushButton* toolSlipButton; + QPushButton* toolSlideButton; + QPushButton* toolHandButton; + QPushButton* toolTransitionButton; + QPushButton* snappingButton; + + void resizeEvent(QResizeEvent *event); public slots: void repaint_timeline(); + void toggle_show_all(); + void deselect(); + void toggle_links(); + void split_at_playhead(); private slots: - - void on_pushButton_4_clicked(); - - void on_pushButton_5_clicked(); - - void on_snappingButton_toggled(bool checked); - - void on_toolSlideButton_clicked(); - - void on_toolArrowButton_clicked(); - - void on_toolEditButton_clicked(); - - void on_toolRippleButton_clicked(); - - void on_toolRollingButton_clicked(); - - void on_toolRazorButton_clicked(); - - void on_toolSlipButton_clicked(); - - void on_addButton_clicked(); - - void addMenuItem(QAction*); - + void zoom_in(); + void zoom_out(); + void snapping_clicked(bool checked); + void add_btn_click(); + void add_menu_item(QAction*); void setScroll(int); - - void on_recordButton_clicked(); - - void on_toolTransitionButton_clicked(); - + void record_btn_click(); + void transition_tool_click(); void transition_menu_select(QAction*); - - void resize_move(double d); - - void on_toolHandButton_clicked(); + void resize_move(double d); + void set_tool(); private: void set_zoom_value(double v); QVector tool_buttons; void decheck_tool_buttons(QObject* sender); - void set_tool(int tool); + void set_tool(int tool); long last_frame; - int scroll; - void set_sb_max(); + int scroll; + void set_sb_max(); + + void setup_ui(); int default_track_height; + + QWidget* timeline_area; + TimelineWidget* video_area; + TimelineWidget* audio_area; + QWidget* editAreas; + QScrollBar* videoScrollbar; + QScrollBar* audioScrollbar; + QPushButton* zoomInButton; + QPushButton* zoomOutButton; + QPushButton* recordButton; + QPushButton* addButton; }; #endif // TIMELINE_H diff --git a/panels/timeline.ui b/panels/timeline.ui deleted file mode 100644 index 7cf0a5ce7..000000000 --- a/panels/timeline.ui +++ /dev/null @@ -1,538 +0,0 @@ - - - Timeline - - - - 0 - 0 - 901 - 592 - - - - - 0 - 0 - - - - Timeline - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 4 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Pointer Tool (V) - - - - - - - :/icons/arrow.png - :/icons/arrow-disabled.png:/icons/arrow.png - - - true - - - - - - - Edit Tool (X) - - - - - - - :/icons/beam.png - :/icons/beam-disabled.png:/icons/beam.png - - - true - - - - - - - Ripple Tool (B) - - - - - - - :/icons/ripple.png - :/icons/ripple-disabled.png:/icons/ripple.png - - - true - - - - - - - Rolling Tool (N) - - - - - - - :/icons/rolling.png - :/icons/rolling-disabled.png:/icons/rolling.png - - - true - - - - - - - Razor Tool (C) - - - - - - - :/icons/razor.png - :/icons/razor-disabled.png:/icons/razor.png - - - true - - - - - - - Slip Tool (Y) - - - - - - - :/icons/slip.png - :/icons/slip-disabled.png - - - - true - - - - - - - Slide Tool (U) - - - - - - - :/icons/slide.png - :/icons/slide-disabled.png - - - - true - - - - - - - Hand Tool (H) - - - - - - - :/icons/hand.png - :/icons/hand-disabled.png - - - - true - - - - - - - Transition Tool (T) - - - - - - - :/icons/transition-tool.png - :/icons/transition-tool-disabled.png - - - - true - - - - - - - - - - - :/icons/magnet.png - :/icons/magnet-disabled.png - - - - true - - - true - - - - - - - Zoom In (=) - - - - - - - :/icons/zoomin.png - :/icons/zoomin-disabled.png - - - - - - - - Zoom Out (-) - - - - - - - :/icons/zoomout.png - :/icons/zoomout-disabled.png - - - - - - - - Record audio - - - - :/icons/record.png - :/icons/record-disabled.png - - - - - - - - Add title, solid, bars, etc. - - - - - - - :/icons/add-button.png - :/icons/add-button-disabled.png - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - 1 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Vertical - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::ClickFocus - - - - - - - 0 - - - 20 - - - 1826 - - - Qt::Vertical - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::ClickFocus - - - - - - - 0 - - - 20 - - - 1826 - - - Qt::Vertical - - - - - - - - - - - - - - 0 - - - 20 - - - 1826 - - - Qt::Horizontal - - - - - - - - - - - 50 - 0 - - - - - - - - - - TimelineHeader - QWidget -
ui/timelineheader.h
- 1 -
- - TimelineWidget - QWidget -
ui/timelinewidget.h
- 1 -
- - AudioMonitor - QWidget -
ui/audiomonitor.h
- 1 -
- - ResizableScrollBar - QScrollBar -
ui/resizablescrollbar.h
-
-
- - - - -
diff --git a/panels/viewer.cpp b/panels/viewer.cpp index 1fb1c318a..01e488079 100644 --- a/panels/viewer.cpp +++ b/panels/viewer.cpp @@ -1,5 +1,4 @@ #include "viewer.h" -#include "ui_viewer.h" #include "playback/audio.h" #include "timeline.h" @@ -12,9 +11,12 @@ #include "project/media.h" #include "project/undo.h" #include "ui/audiomonitor.h" -#include "ui_timeline.h" #include "playback/playback.h" #include "ui/viewerwidget.h" +#include "ui/viewercontainer.h" +#include "ui/labelslider.h" +#include "ui/timelineheader.h" +#include "ui/resizablescrollbar.h" #include "debug.h" #define FRAMES_IN_ONE_MINUTE 1798 // 1800 - 2 @@ -30,64 +32,64 @@ extern "C" { #include #include #include +#include +#include Viewer::Viewer(QWidget *parent) : - QDockWidget(parent), + QDockWidget(parent), playing(false), - just_played(false), - media(NULL), - seq(NULL), - ui(new Ui::Viewer), - created_sequence(false), - cue_recording_internal(false), - panel_name("Viewer: "), - minimum_zoom(1.0) + just_played(false), + media(NULL), + seq(NULL), + created_sequence(false), + cue_recording_internal(false), + panel_name("Viewer: "), + minimum_zoom(1.0) { - ui->setupUi(this); - ui->headers->viewer = this; - ui->headers->snapping = false; - ui->headers->show_text(false); - ui->glViewerPane->viewer = this; - viewer_widget = ui->glViewerPane->child; - viewer_widget->viewer = this; - set_media(NULL); + setup_ui(); - ui->currentTimecode->setEnabled(false); - ui->currentTimecode->set_minimum_value(0); - ui->currentTimecode->set_default_value(qSNaN()); - ui->currentTimecode->set_value(0, false); - ui->currentTimecode->set_display_type(LABELSLIDER_FRAMENUMBER); - connect(ui->currentTimecode, SIGNAL(valueChanged()), this, SLOT(update_playhead())); + headers->viewer = this; + headers->snapping = false; + headers->show_text(false); + glViewerPane->viewer = this; + viewer_widget = glViewerPane->child; + viewer_widget->viewer = this; + set_media(NULL); + + currentTimecode->setEnabled(false); + currentTimecode->set_minimum_value(0); + currentTimecode->set_default_value(qSNaN()); + currentTimecode->set_value(0, false); + currentTimecode->set_display_type(LABELSLIDER_FRAMENUMBER); + connect(currentTimecode, SIGNAL(valueChanged()), this, SLOT(update_playhead())); recording_flasher.setInterval(500); connect(&playback_updater, SIGNAL(timeout()), this, SLOT(timer_update())); connect(&recording_flasher, SIGNAL(timeout()), this, SLOT(recording_flasher_update())); - connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), ui->headers, SLOT(set_scroll(int))); - connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), viewer_widget, SLOT(set_waveform_scroll(int))); - connect(ui->horizontalScrollBar, SIGNAL(resize_move(double)), this, SLOT(resize_move(double))); + connect(horizontalScrollBar, SIGNAL(valueChanged(int)), headers, SLOT(set_scroll(int))); + connect(horizontalScrollBar, SIGNAL(valueChanged(int)), viewer_widget, SLOT(set_waveform_scroll(int))); + connect(horizontalScrollBar, SIGNAL(resize_move(double)), this, SLOT(resize_move(double))); - update_playhead_timecode(0); - update_end_timecode(); + update_playhead_timecode(0); + update_end_timecode(); } -Viewer::~Viewer() { - delete ui; -} +Viewer::~Viewer() {} bool Viewer::is_focused() { - return ui->headers->hasFocus() - || viewer_widget->hasFocus() - || ui->btnSkipToStart->hasFocus() - || ui->btnRewind->hasFocus() - || ui->btnPlay->hasFocus() - || ui->btnFastForward->hasFocus() - || ui->btnSkipToEnd->hasFocus(); + return headers->hasFocus() + || viewer_widget->hasFocus() + || btnSkipToStart->hasFocus() + || btnRewind->hasFocus() + || btnPlay->hasFocus() + || btnFastForward->hasFocus() + || btnSkipToEnd->hasFocus(); } void Viewer::set_main_sequence() { clean_created_seq(); - set_sequence(true, sequence); + set_sequence(true, sequence); } void Viewer::reset_all_audio() { @@ -101,43 +103,43 @@ void Viewer::reset_all_audio() { if (c != NULL) c->reset_audio(); } } - clear_audio_ibuffer(); + clear_audio_ibuffer(); } long timecode_to_frame(const QString& s, int view, double frame_rate) { - QList list = s.split(QRegExp("[:;]")); + QList list = s.split(QRegExp("[:;]")); - if (view == TIMECODE_FRAMES || (list.size() == 1 && view != TIMECODE_MILLISECONDS)) { + if (view == TIMECODE_FRAMES || (list.size() == 1 && view != TIMECODE_MILLISECONDS)) { return s.toLong(); } int frRound = qRound(frame_rate); - int hours, minutes, seconds, frames; + int hours, minutes, seconds, frames; - if (view == TIMECODE_MILLISECONDS) { - long milliseconds = s.toLong(); + if (view == TIMECODE_MILLISECONDS) { + long milliseconds = s.toLong(); - hours = milliseconds/3600000; - milliseconds -= (hours*3600000); - minutes = milliseconds/60000; - milliseconds -= (minutes*60000); - seconds = milliseconds/1000; - milliseconds -= (seconds*1000); - frames = qRound64((milliseconds*0.001)*frame_rate); + hours = milliseconds/3600000; + milliseconds -= (hours*3600000); + minutes = milliseconds/60000; + milliseconds -= (minutes*60000); + seconds = milliseconds/1000; + milliseconds -= (seconds*1000); + frames = qRound64((milliseconds*0.001)*frame_rate); - seconds = qRound64(seconds * frame_rate); - minutes = qRound64(minutes * frame_rate * 60); - hours = qRound64(hours * frame_rate * 3600); - } else { - hours = ((list.size() > 0) ? list.at(0).toInt() : 0) * frRound * 3600; - minutes = ((list.size() > 1) ? list.at(1).toInt() : 0) * frRound * 60; - seconds = ((list.size() > 2) ? list.at(2).toInt() : 0) * frRound; - frames = (list.size() > 3) ? list.at(3).toInt() : 0; - } + seconds = qRound64(seconds * frame_rate); + minutes = qRound64(minutes * frame_rate * 60); + hours = qRound64(hours * frame_rate * 3600); + } else { + hours = ((list.size() > 0) ? list.at(0).toInt() : 0) * frRound * 3600; + minutes = ((list.size() > 1) ? list.at(1).toInt() : 0) * frRound * 60; + seconds = ((list.size() > 2) ? list.at(2).toInt() : 0) * frRound; + frames = (list.size() > 3) ? list.at(3).toInt() : 0; + } int f = (frames + seconds + minutes + hours); - if ((view == TIMECODE_DROP || view == TIMECODE_MILLISECONDS) && frame_rate_is_droppable(frame_rate)) { + if ((view == TIMECODE_DROP || view == TIMECODE_MILLISECONDS) && frame_rate_is_droppable(frame_rate)) { // return drop int d; int m; @@ -161,69 +163,69 @@ long timecode_to_frame(const QString& s, int view, double frame_rate) { } QString frame_to_timecode(long f, int view, double frame_rate) { - if (view == TIMECODE_FRAMES) { - return QString::number(f); - } + if (view == TIMECODE_FRAMES) { + return QString::number(f); + } - // return timecode - int hours = 0; - int mins = 0; - int secs = 0; - int frames = 0; - QString token = ":"; + // return timecode + int hours = 0; + int mins = 0; + int secs = 0; + int frames = 0; + QString token = ":"; - if ((view == TIMECODE_DROP || view == TIMECODE_MILLISECONDS) && frame_rate_is_droppable(frame_rate)) { - //CONVERT A FRAME NUMBER TO DROP FRAME TIMECODE - //Code by David Heidelberger, adapted from Andrew Duncan, further adapted for Olive by Olive Team - //Given an int called framenumber and a double called framerate - //Framerate should be 29.97, 59.94, or 23.976, otherwise the calculations will be off. + if ((view == TIMECODE_DROP || view == TIMECODE_MILLISECONDS) && frame_rate_is_droppable(frame_rate)) { + //CONVERT A FRAME NUMBER TO DROP FRAME TIMECODE + //Code by David Heidelberger, adapted from Andrew Duncan, further adapted for Olive by Olive Team + //Given an int called framenumber and a double called framerate + //Framerate should be 29.97, 59.94, or 23.976, otherwise the calculations will be off. - int d; - int m; + int d; + int m; - int dropFrames = round(frame_rate * .066666); //Number of frames to drop on the minute marks is the nearest integer to 6% of the framerate - int framesPerHour = round(frame_rate*60*60); //Number of frqRound64ames in an hour - int framesPer24Hours = framesPerHour*24; //Number of frames in a day - timecode rolls over after 24 hours - int framesPer10Minutes = round(frame_rate * 60 * 10); //Number of frames per ten minutes - int framesPerMinute = (round(frame_rate)*60)- dropFrames; //Number of frames per minute is the round of the framerate * 60 minus the number of dropped frames + int dropFrames = round(frame_rate * .066666); //Number of frames to drop on the minute marks is the nearest integer to 6% of the framerate + int framesPerHour = round(frame_rate*60*60); //Number of frqRound64ames in an hour + int framesPer24Hours = framesPerHour*24; //Number of frames in a day - timecode rolls over after 24 hours + int framesPer10Minutes = round(frame_rate * 60 * 10); //Number of frames per ten minutes + int framesPerMinute = (round(frame_rate)*60)- dropFrames; //Number of frames per minute is the round of the framerate * 60 minus the number of dropped frames - //If framenumber is greater than 24 hrs, next operation will rollover clock - f = f % framesPer24Hours; //% is the modulus operator, which returns a remainder. a % b = the remainder of a/b + //If framenumber is greater than 24 hrs, next operation will rollover clock + f = f % framesPer24Hours; //% is the modulus operator, which returns a remainder. a % b = the remainder of a/b - d = f / framesPer10Minutes; // \ means integer division, which is a/b without a remainder. Some languages you could use floor(a/b) - m = f % framesPer10Minutes; + d = f / framesPer10Minutes; // \ means integer division, which is a/b without a remainder. Some languages you could use floor(a/b) + m = f % framesPer10Minutes; - //In the original post, the next line read m>1, which only worked for 29.97. Jean-Baptiste Mardelle correctly pointed out that m should be compared to dropFrames. - if (m > dropFrames) { - f = f + (dropFrames*9*d) + dropFrames * ((m - dropFrames) / framesPerMinute); - } else { - f = f + dropFrames*9*d; - } + //In the original post, the next line read m>1, which only worked for 29.97. Jean-Baptiste Mardelle correctly pointed out that m should be compared to dropFrames. + if (m > dropFrames) { + f = f + (dropFrames*9*d) + dropFrames * ((m - dropFrames) / framesPerMinute); + } else { + f = f + dropFrames*9*d; + } - int frRound = round(frame_rate); - frames = f % frRound; - secs = (f / frRound) % 60; - mins = ((f / frRound) / 60) % 60; - hours = (((f / frRound) / 60) / 60); + int frRound = round(frame_rate); + frames = f % frRound; + secs = (f / frRound) % 60; + mins = ((f / frRound) / 60) % 60; + hours = (((f / frRound) / 60) / 60); - token = ";"; - } else { + token = ";"; + } else { // non-drop timecode - int int_fps = qRound(frame_rate); + int int_fps = qRound(frame_rate); hours = f / (3600 * int_fps); - mins = f / (60*int_fps) % 60; - secs = f/int_fps % 60; - frames = f%int_fps; - } - if (view == TIMECODE_MILLISECONDS) { - return QString::number((hours*3600000)+(mins*60000)+(secs*1000)+qCeil(frames*1000/frame_rate)); - } - return QString(QString::number(hours).rightJustified(2, '0') + - ":" + QString::number(mins).rightJustified(2, '0') + - ":" + QString::number(secs).rightJustified(2, '0') + - token + QString::number(frames).rightJustified(2, '0') - ); + mins = f / (60*int_fps) % 60; + secs = f/int_fps % 60; + frames = f%int_fps; + } + if (view == TIMECODE_MILLISECONDS) { + return QString::number((hours*3600000)+(mins*60000)+(secs*1000)+qCeil(frames*1000/frame_rate)); + } + return QString(QString::number(hours).rightJustified(2, '0') + + ":" + QString::number(mins).rightJustified(2, '0') + + ":" + QString::number(secs).rightJustified(2, '0') + + token + QString::number(frames).rightJustified(2, '0') + ); } bool frame_rate_is_droppable(float rate) { @@ -234,8 +236,8 @@ void Viewer::seek(long p) { pause(); seq->playhead = p; update_parents(); - reset_all_audio(); - audio_scrub = true; + reset_all_audio(); + audio_scrub = true; } void Viewer::go_to_start() { @@ -278,7 +280,7 @@ void Viewer::cue_recording(long start, long end, int track) { void Viewer::uncue_recording() { cue_recording_internal = false; recording_flasher.stop(); - ui->btnPlay->setStyleSheet(QString()); + btnPlay->setStyleSheet(QString()); } bool Viewer::is_recording_cued() { @@ -298,7 +300,7 @@ void Viewer::play() { if (panel_footage_viewer->playing) panel_footage_viewer->pause(); if (seq != NULL) { - reset_all_audio(); + reset_all_audio(); if (is_recording_cued() && !start_recording()) { dout << "[ERROR] Failed to record audio"; return; @@ -316,7 +318,7 @@ void Viewer::play_wake() { if (just_played) { start_msecs = QDateTime::currentMSecsSinceEpoch(); playback_updater.start(); - if (audio_thread != NULL) audio_thread->notifyReceiver(); + if (audio_thread != NULL) audio_thread->notifyReceiver(); just_played = false; } } @@ -336,27 +338,27 @@ void Viewer::pause() { // import audio QStringList file_list; file_list.append(get_recorded_audio_filename()); - panel_project->process_file_list(file_list); + panel_project->process_file_list(file_list); // add it to the sequence Clip* c = new Clip(seq); - Media* m = panel_project->last_imported_media.at(0); - Footage* f = m->to_footage(); + Media* m = panel_project->last_imported_media.at(0); + Footage* f = m->to_footage(); - f->ready_lock.lock(); + f->ready_lock.lock(); - c->media = m; // latest media + c->media = m; // latest media c->media_stream = 0; c->timeline_in = recording_start; - c->timeline_out = f->get_length_in_frames(seq->frame_rate); + c->timeline_out = recording_start + f->get_length_in_frames(seq->frame_rate); c->clip_in = 0; c->track = recording_track; c->color_r = 128; c->color_g = 192; c->color_b = 128; - c->name = m->get_name(); + c->name = m->get_name(); - f->ready_lock.unlock(); + f->ready_lock.unlock(); QVector add_clips; add_clips.append(c); @@ -366,24 +368,24 @@ void Viewer::pause() { } void Viewer::update_playhead_timecode(long p) { - ui->currentTimecode->set_value(p, false); + currentTimecode->set_value(p, false); } void Viewer::update_end_timecode() { - ui->endTimecode->setText((seq == NULL) ? frame_to_timecode(0, config.timecode_view, 30) : frame_to_timecode(seq->getEndFrame(), config.timecode_view, seq->frame_rate)); + endTimecode->setText((seq == NULL) ? frame_to_timecode(0, config.timecode_view, 30) : frame_to_timecode(seq->getEndFrame(), config.timecode_view, seq->frame_rate)); } void Viewer::update_header_zoom() { if (seq != NULL) { long sequenceEndFrame = seq->getEndFrame(); - if (cached_end_frame != sequenceEndFrame) { - minimum_zoom = (sequenceEndFrame > 0) ? ((double) ui->headers->width() / (double) sequenceEndFrame) : 1; - ui->headers->update_zoom(qMax(ui->headers->get_zoom(), minimum_zoom)); - set_sb_max(); - viewer_widget->waveform_zoom = ui->headers->get_zoom(); - } else { - ui->headers->update(); - } + if (cached_end_frame != sequenceEndFrame) { + minimum_zoom = (sequenceEndFrame > 0) ? ((double) headers->width() / (double) sequenceEndFrame) : 1; + headers->update_zoom(qMax(headers->get_zoom(), minimum_zoom)); + set_sb_max(); + viewer_widget->waveform_zoom = headers->get_zoom(); + } else { + headers->update(); + } } } @@ -392,137 +394,238 @@ void Viewer::update_parents() { update_ui(false); } else { update_viewer(); - } + } } void Viewer::resizeEvent(QResizeEvent *event) { - if (seq != NULL) { - set_sb_max(); - } + if (seq != NULL) { + set_sb_max(); + } } void Viewer::update_viewer() { - update_header_zoom(); + update_header_zoom(); viewer_widget->update(); if (seq != NULL) update_playhead_timecode(seq->playhead); - update_end_timecode(); + update_end_timecode(); } void Viewer::clear_inout_point() { - if (seq->using_workarea) { - undo_stack.push(new SetTimelineInOutCommand(seq, false, 0, 0)); - update_parents(); - } + if (seq->using_workarea) { + undo_stack.push(new SetTimelineInOutCommand(seq, false, 0, 0)); + update_parents(); + } } void Viewer::set_in_point() { - ui->headers->set_in_point(seq->playhead); + headers->set_in_point(seq->playhead); } void Viewer::set_out_point() { - ui->headers->set_out_point(seq->playhead); + headers->set_out_point(seq->playhead); } void Viewer::set_zoom(bool in) { - if (seq != NULL) { - set_zoom_value(in ? ui->headers->get_zoom()*2 : qMax(minimum_zoom, ui->headers->get_zoom()*0.5)); - } + if (seq != NULL) { + set_zoom_value(in ? headers->get_zoom()*2 : qMax(minimum_zoom, headers->get_zoom()*0.5)); + } } void Viewer::set_zoom_value(double d) { - ui->headers->update_zoom(d); - if (viewer_widget->waveform) { - viewer_widget->waveform_zoom = d; - viewer_widget->update(); - } - if (seq != NULL) { - set_sb_max(); - if (!ui->horizontalScrollBar->is_resizing()) - center_scroll_to_playhead(ui->horizontalScrollBar, ui->headers->get_zoom(), seq->playhead); - } + headers->update_zoom(d); + if (viewer_widget->waveform) { + viewer_widget->waveform_zoom = d; + viewer_widget->update(); + } + if (seq != NULL) { + set_sb_max(); + if (!horizontalScrollBar->is_resizing()) + center_scroll_to_playhead(horizontalScrollBar, headers->get_zoom(), seq->playhead); + } } void Viewer::set_sb_max() { - ui->headers->set_scrollbar_max(ui->horizontalScrollBar, seq->getEndFrame(), ui->headers->width()); + headers->set_scrollbar_max(horizontalScrollBar, seq->getEndFrame(), headers->width()); +} + +void Viewer::setup_ui() { + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + + QWidget* contents = new QWidget(); + + QVBoxLayout* layout = new QVBoxLayout(contents); + layout->setSpacing(0); + layout->setMargin(0); + + glViewerPane = new ViewerContainer(contents); + glViewerPane->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + layout->addWidget(glViewerPane); + + headers = new TimelineHeader(contents); + layout->addWidget(headers); + + horizontalScrollBar = new ResizableScrollBar(contents); + horizontalScrollBar->setSingleStep(20); + horizontalScrollBar->setOrientation(Qt::Horizontal); + layout->addWidget(horizontalScrollBar); + + QWidget* lower_controls = new QWidget(contents); + + QHBoxLayout* lower_control_layout = new QHBoxLayout(lower_controls); + lower_control_layout->setMargin(0); + + // current time code + QWidget* current_timecode_container = new QWidget(lower_controls); + QHBoxLayout* current_timecode_container_layout = new QHBoxLayout(current_timecode_container); + current_timecode_container_layout->setSpacing(0); + current_timecode_container_layout->setMargin(0); + currentTimecode = new LabelSlider(current_timecode_container); + current_timecode_container_layout->addWidget(currentTimecode); + lower_control_layout->addWidget(current_timecode_container); + + QWidget* playback_controls = new QWidget(lower_controls); + + QHBoxLayout* playback_control_layout = new QHBoxLayout(playback_controls); + playback_control_layout->setSpacing(0); + playback_control_layout->setMargin(0); + + btnSkipToStart = new QPushButton(playback_controls); + QIcon goToStartIcon; + goToStartIcon.addFile(QStringLiteral(":/icons/prev.png"), QSize(), QIcon::Normal, QIcon::Off); + goToStartIcon.addFile(QStringLiteral(":/icons/prev-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + btnSkipToStart->setIcon(goToStartIcon); + connect(btnSkipToStart, SIGNAL(clicked(bool)), this, SLOT(go_to_start())); + playback_control_layout->addWidget(btnSkipToStart); + + btnRewind = new QPushButton(playback_controls); + QIcon rewindIcon; + rewindIcon.addFile(QStringLiteral(":/icons/rew.png"), QSize(), QIcon::Normal, QIcon::Off); + rewindIcon.addFile(QStringLiteral(":/icons/rew-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + btnRewind->setIcon(rewindIcon); + connect(btnRewind, SIGNAL(clicked(bool)), this, SLOT(previous_frame())); + playback_control_layout->addWidget(btnRewind); + + btnPlay = new QPushButton(playback_controls); + QIcon playIcon; + playIcon.addFile(QStringLiteral(":/icons/play.png"), QSize(), QIcon::Normal, QIcon::Off); + playIcon.addFile(QStringLiteral(":/icons/play-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + btnPlay->setIcon(playIcon); + connect(btnPlay, SIGNAL(clicked(bool)), this, SLOT(toggle_play())); + playback_control_layout->addWidget(btnPlay); + + btnFastForward = new QPushButton(playback_controls); + QIcon ffIcon; + ffIcon.addFile(QStringLiteral(":/icons/ff.png"), QSize(), QIcon::Normal, QIcon::On); + ffIcon.addFile(QStringLiteral(":/icons/ff-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + btnFastForward->setIcon(ffIcon); + connect(btnFastForward, SIGNAL(clicked(bool)), this, SLOT(next_frame())); + playback_control_layout->addWidget(btnFastForward); + + btnSkipToEnd = new QPushButton(playback_controls); + QIcon nextIcon; + nextIcon.addFile(QStringLiteral(":/icons/next.png"), QSize(), QIcon::Normal, QIcon::Off); + nextIcon.addFile(QStringLiteral(":/icons/next-disabled.png"), QSize(), QIcon::Disabled, QIcon::Off); + btnSkipToEnd->setIcon(nextIcon); + connect(btnSkipToEnd, SIGNAL(clicked(bool)), this, SLOT(go_to_end())); + playback_control_layout->addWidget(btnSkipToEnd); + + lower_control_layout->addWidget(playback_controls); + + QWidget* end_timecode_container = new QWidget(lower_controls); + + QHBoxLayout* end_timecode_layout = new QHBoxLayout(end_timecode_container); + end_timecode_layout->setSpacing(0); + end_timecode_layout->setMargin(0); + + endTimecode = new QLabel(end_timecode_container); + endTimecode->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + + end_timecode_layout->addWidget(endTimecode); + + lower_control_layout->addWidget(end_timecode_container); + + layout->addWidget(lower_controls); + + setWidget(contents); } void Viewer::set_media(Media* m) { main_sequence = false; - media = m; - clean_created_seq(); - if (media != NULL) { - switch (media->get_type()) { - case MEDIA_TYPE_FOOTAGE: - { - Footage* footage = media->to_footage(); + media = m; + clean_created_seq(); + if (media != NULL) { + switch (media->get_type()) { + case MEDIA_TYPE_FOOTAGE: + { + Footage* footage = media->to_footage(); - seq = new Sequence(); - created_sequence = true; - seq->wrapper_sequence = true; - seq->name = footage->name; + seq = new Sequence(); + created_sequence = true; + seq->wrapper_sequence = true; + seq->name = footage->name; - seq->using_workarea = footage->using_inout; - if (footage->using_inout) { - seq->workarea_in = footage->in; - seq->workarea_out = footage->out; - } + seq->using_workarea = footage->using_inout; + if (footage->using_inout) { + seq->workarea_in = footage->in; + seq->workarea_out = footage->out; + } - seq->frame_rate = 30; + seq->frame_rate = 30; - if (footage->video_tracks.size() > 0) { - FootageStream* video_stream = footage->video_tracks.at(0); - seq->width = video_stream->video_width; - 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; + if (footage->video_tracks.size() > 0) { + FootageStream* video_stream = footage->video_tracks.at(0); + seq->width = video_stream->video_width; + 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; - Clip* c = new Clip(seq); - c->media = media; - c->media_stream = video_stream->file_index; - c->timeline_in = 0; - c->timeline_out = footage->get_length_in_frames(seq->frame_rate); - if (c->timeline_out <= 0) c->timeline_out = 150; - c->track = -1; - c->clip_in = 0; - c->recalculateMaxLength(); - seq->clips.append(c); - } else { - seq->width = 1920; - seq->height = 1080; - } + Clip* c = new Clip(seq); + c->media = media; + c->media_stream = video_stream->file_index; + c->timeline_in = 0; + c->timeline_out = footage->get_length_in_frames(seq->frame_rate); + if (c->timeline_out <= 0) c->timeline_out = 150; + c->track = -1; + c->clip_in = 0; + c->recalculateMaxLength(); + seq->clips.append(c); + } else { + seq->width = 1920; + seq->height = 1080; + } - if (footage->audio_tracks.size() > 0) { - FootageStream* audio_stream = footage->audio_tracks.at(0); - seq->audio_frequency = audio_stream->audio_frequency; + if (footage->audio_tracks.size() > 0) { + FootageStream* audio_stream = footage->audio_tracks.at(0); + seq->audio_frequency = audio_stream->audio_frequency; - Clip* c = new Clip(seq); - c->media = media; - c->media_stream = audio_stream->file_index; - c->timeline_in = 0; - c->timeline_out = footage->get_length_in_frames(seq->frame_rate); - c->track = 0; - c->clip_in = 0; - c->recalculateMaxLength(); - seq->clips.append(c); + Clip* c = new Clip(seq); + c->media = media; + c->media_stream = audio_stream->file_index; + c->timeline_in = 0; + c->timeline_out = footage->get_length_in_frames(seq->frame_rate); + c->track = 0; + c->clip_in = 0; + c->recalculateMaxLength(); + seq->clips.append(c); - if (footage->video_tracks.size() == 0) { - viewer_widget->waveform = true; - viewer_widget->waveform_clip = c; - viewer_widget->waveform_ms = audio_stream; - viewer_widget->update(); - } - } else { - seq->audio_frequency = 48000; - } + if (footage->video_tracks.size() == 0) { + viewer_widget->waveform = true; + viewer_widget->waveform_clip = c; + viewer_widget->waveform_ms = audio_stream; + viewer_widget->update(); + } + } else { + seq->audio_frequency = 48000; + } - seq->audio_layout = AV_CH_LAYOUT_STEREO; - } - break; - case MEDIA_TYPE_SEQUENCE: - seq = media->to_sequence(); - break; - } - } - set_sequence(false, seq); + seq->audio_layout = AV_CH_LAYOUT_STEREO; + } + break; + case MEDIA_TYPE_SEQUENCE: + seq = media->to_sequence(); + break; + } + } + set_sequence(false, seq); } void Viewer::on_btnSkipToStart_clicked() { @@ -546,45 +649,45 @@ void Viewer::on_btnPlay_clicked() { } void Viewer::update_playhead() { - seek(ui->currentTimecode->value()); + seek(currentTimecode->value()); } void Viewer::timer_update() { - long previous_playhead = seq->playhead; + long previous_playhead = seq->playhead; - seq->playhead = qRound(playhead_start + ((QDateTime::currentMSecsSinceEpoch()-start_msecs) * 0.001 * seq->frame_rate)); + seq->playhead = qRound(playhead_start + ((QDateTime::currentMSecsSinceEpoch()-start_msecs) * 0.001 * seq->frame_rate)); update_parents(); - long end_frame = (seq->using_workarea && previous_playhead < seq->workarea_out) ? seq->workarea_out : seq->getEndFrame(); - if ((!recording - && playing - && seq->playhead >= end_frame - && previous_playhead < end_frame) - || (recording && recording_start != recording_end && seq->playhead >= recording_end)) { - pause(); - } + long end_frame = (seq->using_workarea && previous_playhead < seq->workarea_out) ? seq->workarea_out : seq->getEndFrame(); + if ((!recording + && playing + && seq->playhead >= end_frame + && previous_playhead < end_frame) + || (recording && recording_start != recording_end && seq->playhead >= recording_end)) { + pause(); + } } void Viewer::recording_flasher_update() { - if (ui->btnPlay->styleSheet().isEmpty()) { - ui->btnPlay->setStyleSheet("background: red;"); + if (btnPlay->styleSheet().isEmpty()) { + btnPlay->setStyleSheet("background: red;"); } else { - ui->btnPlay->setStyleSheet(QString()); - } + btnPlay->setStyleSheet(QString()); + } } void Viewer::resize_move(double d) { - set_zoom_value(ui->headers->get_zoom()*d); + set_zoom_value(headers->get_zoom()*d); } void Viewer::clean_created_seq() { viewer_widget->waveform = false; if (created_sequence) { - // TODO delete undo commands referencing this sequence to avoid crashes - /*for (int i=0;iheaders->setEnabled(!null_sequence); - ui->currentTimecode->setEnabled(!null_sequence); - viewer_widget->setEnabled(!null_sequence); - viewer_widget->setVisible(!null_sequence); - ui->btnSkipToStart->setEnabled(!null_sequence); - ui->btnRewind->setEnabled(!null_sequence); - ui->btnPlay->setEnabled(!null_sequence); - ui->btnFastForward->setEnabled(!null_sequence); - ui->btnSkipToEnd->setEnabled(!null_sequence); + headers->setEnabled(!null_sequence); + currentTimecode->setEnabled(!null_sequence); + viewer_widget->setEnabled(!null_sequence); + viewer_widget->setVisible(!null_sequence); + btnSkipToStart->setEnabled(!null_sequence); + btnRewind->setEnabled(!null_sequence); + btnPlay->setEnabled(!null_sequence); + btnFastForward->setEnabled(!null_sequence); + btnSkipToEnd->setEnabled(!null_sequence); - if (!null_sequence) { - ui->currentTimecode->set_frame_rate(seq->frame_rate); + if (!null_sequence) { + currentTimecode->set_frame_rate(seq->frame_rate); playback_updater.setInterval(qFloor(1000 / seq->frame_rate)); - update_playhead_timecode(seq->playhead); - update_end_timecode(); + update_playhead_timecode(seq->playhead); + update_end_timecode(); - ui->glViewerPane->adjust(); + glViewerPane->adjust(); - setWindowTitle(panel_name + seq->name); - } else { - update_playhead_timecode(0); - update_end_timecode(); + setWindowTitle(panel_name + seq->name); + } else { + update_playhead_timecode(0); + update_end_timecode(); - setWindowTitle(panel_name + "(none)"); - } + setWindowTitle(panel_name + "(none)"); + } update_header_zoom(); viewer_widget->update(); - update(); + update(); } void Viewer::set_playpause_icon(bool play) { - ui->btnPlay->setIcon(QIcon((play) ? ":/icons/play.png" : ":/icons/pause.png")); + btnPlay->setIcon(QIcon((play) ? ":/icons/play.png" : ":/icons/pause.png")); } diff --git a/panels/viewer.h b/panels/viewer.h index 8ca343b3c..d46ba94c4 100644 --- a/panels/viewer.h +++ b/panels/viewer.h @@ -8,10 +8,12 @@ class Timeline; class ViewerWidget; class Media; struct Sequence; - -namespace Ui { -class Viewer; -} +class TimelineHeader; +class ResizableScrollBar; +class ViewerContainer; +class LabelSlider; +class QPushButton; +class QLabel; bool frame_rate_is_droppable(float rate); long timecode_to_frame(const QString& s, int view, double frame_rate); @@ -26,28 +28,23 @@ public: ~Viewer(); bool is_focused(); - void set_main_sequence(); - void set_media(Media *m); + void set_main_sequence(); + void set_media(Media *m); void compose(); - void set_playpause_icon(bool play); - void update_playhead_timecode(long p); - void update_end_timecode(); + void set_playpause_icon(bool play); + void update_playhead_timecode(long p); + void update_end_timecode(); void update_header_zoom(); void update_viewer(); - void clear_inout_point(); + void clear_inout_point(); void set_in_point(); void set_out_point(); - void set_zoom(bool in); + void set_zoom(bool in); // playback functions - void go_to_start(); - void previous_frame(); - void next_frame(); void seek(long p); - void toggle_play(); void play(); void pause(); - void go_to_end(); bool playing; long playhead_start; qint64 start_msecs; @@ -56,51 +53,68 @@ public: void cue_recording(long start, long end, int track); void uncue_recording(); - bool is_recording_cued(); + bool is_recording_cued(); long recording_start; long recording_end; - int recording_track; + int recording_track; - void reset_all_audio(); + void reset_all_audio(); void update_parents(); ViewerWidget* viewer_widget; - Media* media; + Media* media; Sequence* seq; - Ui::Viewer *ui; - - void resizeEvent(QResizeEvent *event); + void resizeEvent(QResizeEvent *event); public slots: void play_wake(); + void go_to_start(); + void previous_frame(); + void toggle_play(); + void next_frame(); + void go_to_end(); private slots: - void on_btnSkipToStart_clicked(); - void on_btnRewind_clicked(); - void on_btnPlay_clicked(); - void on_btnFastForward_clicked(); - void on_btnSkipToEnd_clicked(); + void on_btnSkipToStart_clicked(); + void on_btnRewind_clicked(); + void on_btnPlay_clicked(); + void on_btnFastForward_clicked(); + void on_btnSkipToEnd_clicked(); void update_playhead(); void timer_update(); void recording_flasher_update(); - void resize_move(double d); + void resize_move(double d); private: void clean_created_seq(); - void set_sequence(bool main, Sequence* s); + void set_sequence(bool main, Sequence* s); bool main_sequence; bool created_sequence; - long cached_end_frame; - QString panel_name; - double minimum_zoom; - void set_zoom_value(double d); - void set_sb_max(); + long cached_end_frame; + QString panel_name; + double minimum_zoom; + void set_zoom_value(double d); + void set_sb_max(); + + void setup_ui(); + + TimelineHeader* headers; + ResizableScrollBar* horizontalScrollBar; + ViewerContainer* glViewerPane; + LabelSlider* currentTimecode; + QLabel* endTimecode; + + QPushButton* btnSkipToStart; + QPushButton* btnRewind; + QPushButton* btnPlay; + QPushButton* btnFastForward; + QPushButton* btnSkipToEnd; bool cue_recording_internal; - QTimer recording_flasher; + QTimer recording_flasher; }; #endif // VIEWER_H diff --git a/panels/viewer.ui b/panels/viewer.ui deleted file mode 100644 index 69011823f..000000000 --- a/panels/viewer.ui +++ /dev/null @@ -1,259 +0,0 @@ - - - Viewer - - - - 0 - 0 - 583 - 396 - - - - - 0 - 0 - - - - Viewer - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - - - - - - - 0 - - - 20 - - - 1826 - - - Qt::Horizontal - - - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - true - - - - :/icons/prev.png - :/icons/prev-disabled.png:/icons/prev.png - - - - - - - - :/icons/rew.png - :/icons/rew-disabled.png:/icons/rew.png - - - - - - - - :/icons/play.png - :/icons/play-disabled.png:/icons/play.png - - - - - - - - :/icons/ff.png - :/icons/ff-disabled.png - - - - - - - - - :/icons/next.png - :/icons/next-disabled.png:/icons/next.png - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - - - - - - TimelineHeader - QWidget -
ui/timelineheader.h
- 1 -
- - ResizableScrollBar - QScrollBar -
ui/resizablescrollbar.h
-
- - ViewerContainer - QWidget -
ui/viewercontainer.h
- 1 -
- - LabelSlider - QLabel -
ui/labelslider.h
-
-
- - - - -
diff --git a/playback/audio.cpp b/playback/audio.cpp index 8d04cedce..e5e90601e 100644 --- a/playback/audio.cpp +++ b/playback/audio.cpp @@ -7,9 +7,10 @@ #include "panels/panels.h" #include "panels/timeline.h" #include "panels/viewer.h" -#include "ui_timeline.h" +#include "ui/audiomonitor.h" #include "debug.h" +#include #include #include #include @@ -43,49 +44,49 @@ bool is_audio_device_set() { void init_audio() { stop_audio(); - QAudioFormat audio_format; - audio_format.setSampleRate(config.audio_rate); - audio_format.setChannelCount(2); - audio_format.setSampleSize(16); - audio_format.setCodec("audio/pcm"); - audio_format.setByteOrder(QAudioFormat::LittleEndian); - audio_format.setSampleType(QAudioFormat::SignedInt); + QAudioFormat audio_format; + audio_format.setSampleRate(config.audio_rate); + audio_format.setChannelCount(2); + audio_format.setSampleSize(16); + audio_format.setCodec("audio/pcm"); + audio_format.setByteOrder(QAudioFormat::LittleEndian); + audio_format.setSampleType(QAudioFormat::SignedInt); - QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice()); - QList devs = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); - dout << "[INFO] Found the following audio devices:"; - for (int i=0;i 0) { - dout << "[WARNING] Default audio returned NULL, attempting to use first device found..."; - info = devs.at(0); - } - dout << "[INFO] Using audio device" << info.deviceName(); + QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice()); + QList devs = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); + dout << "[INFO] Found the following audio devices:"; + for (int i=0;i 0) { + dout << "[WARNING] Default audio returned NULL, attempting to use first device found..."; + info = devs.at(0); + } + dout << "[INFO] Using audio device" << info.deviceName(); - if (!info.isFormatSupported(audio_format)) { - qWarning() << "[WARNING] Audio format is not supported by backend, using nearest"; - audio_format = info.nearestFormat(audio_format); - } + if (!info.isFormatSupported(audio_format)) { + qWarning() << "[WARNING] Audio format is not supported by backend, using nearest"; + audio_format = info.nearestFormat(audio_format); + } - audio_output = new QAudioOutput(info, audio_format); - audio_output->moveToThread(QApplication::instance()->thread()); - audio_output->setNotifyInterval(5); + audio_output = new QAudioOutput(info, audio_format); + audio_output->moveToThread(QApplication::instance()->thread()); + audio_output->setNotifyInterval(5); - // connect - audio_io_device = audio_output->start(); - if (audio_io_device == NULL) { - dout << "[WARNING] Received NULL audio device. No compatible audio output was found."; - } else { - audio_device_set = true; + // connect + audio_io_device = audio_output->start(); + if (audio_io_device == NULL) { + dout << "[WARNING] Received NULL audio device. No compatible audio output was found."; + } else { + audio_device_set = true; - // start sender thread - audio_thread = new AudioSenderThread(); - QObject::connect(audio_output, SIGNAL(notify()), audio_thread, SLOT(notifyReceiver())); - audio_thread->start(QThread::TimeCriticalPriority); + // start sender thread + audio_thread = new AudioSenderThread(); + QObject::connect(audio_output, SIGNAL(notify()), audio_thread, SLOT(notifyReceiver())); + audio_thread->start(QThread::TimeCriticalPriority); - clear_audio_ibuffer(); - } + clear_audio_ibuffer(); + } } void stop_audio() { @@ -100,12 +101,12 @@ void stop_audio() { void clear_audio_ibuffer() { memset(audio_ibuffer, 0, audio_ibuffer_size); - audio_ibuffer_read = 0; + audio_ibuffer_read = 0; } int get_buffer_offset_from_frame(double framerate, long frame) { if (frame >= audio_ibuffer_frame) { - return qFloor(((double) (frame - audio_ibuffer_frame)/framerate)*audio_output->format().sampleRate())*av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)*av_get_channel_layout_nb_channels(AV_CH_LAYOUT_STEREO); + return qFloor(((double) (frame - audio_ibuffer_frame)/framerate)*audio_output->format().sampleRate())*av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)*av_get_channel_layout_nb_channels(AV_CH_LAYOUT_STEREO); } else { dout << "[WARNING] Invalid values passed to get_buffer_offset_from_frame"; return 0; @@ -135,7 +136,7 @@ void AudioSenderThread::run() { cond.wait(&lock); if (close) { break; - } else if (panel_sequence_viewer->playing || panel_footage_viewer->playing || audio_scrub) { + } else if (panel_sequence_viewer->playing || panel_footage_viewer->playing || audio_scrub) { int written_bytes = 0; int adjusted_read_index = audio_ibuffer_read%audio_ibuffer_size; @@ -147,7 +148,7 @@ void AudioSenderThread::run() { written_bytes += send_audio_to_output(0, audio_ibuffer_size); } - audio_scrub = false; + audio_scrub = false; } } lock.unlock(); @@ -163,26 +164,26 @@ int AudioSenderThread::send_audio_to_output(int offset, int max) { // TODO make this work for the footage viewer - currently, enabling it causes crash due to an ASSERT Sequence* s = NULL; /*if (panel_footage_viewer->playing) { - s = panel_footage_viewer->seq; + s = panel_footage_viewer->seq; }*/ - if (panel_sequence_viewer->playing) { - s = panel_sequence_viewer->seq; - } - if (s != NULL) { - if (panel_timeline->ui->audio_monitor->sample_cache_offset == -1) { - panel_timeline->ui->audio_monitor->sample_cache_offset = s->playhead; + if (panel_sequence_viewer->playing) { + s = panel_sequence_viewer->seq; + } + if (s != NULL) { + if (panel_timeline->audio_monitor->sample_cache_offset == -1) { + panel_timeline->audio_monitor->sample_cache_offset = s->playhead; } - int channel_count = av_get_channel_layout_nb_channels(s->audio_layout); - long sample_cache_playhead = panel_timeline->ui->audio_monitor->sample_cache_offset + (panel_timeline->ui->audio_monitor->sample_cache.size()/channel_count); + int channel_count = av_get_channel_layout_nb_channels(s->audio_layout); + long sample_cache_playhead = panel_timeline->audio_monitor->sample_cache_offset + (panel_timeline->audio_monitor->sample_cache.size()/channel_count); int next_buffer_offset, buffer_offset_adjusted, i; - int buffer_offset = get_buffer_offset_from_frame(s->frame_rate, sample_cache_playhead); + int buffer_offset = get_buffer_offset_from_frame(s->frame_rate, sample_cache_playhead); if (samples.size() != channel_count) samples.resize(channel_count); samples.fill(0); // TODO: I don't like this, but i'm not sure if there's a smarter way to do it while (buffer_offset < audio_ibuffer_limit) { sample_cache_playhead++; - next_buffer_offset = qMin(get_buffer_offset_from_frame(s->frame_rate, sample_cache_playhead), audio_ibuffer_limit); + next_buffer_offset = qMin(get_buffer_offset_from_frame(s->frame_rate, sample_cache_playhead), audio_ibuffer_limit); while (buffer_offset < next_buffer_offset) { for (i=0;iui->audio_monitor->sample_cache.append(samples); + panel_timeline->audio_monitor->sample_cache.append(samples); buffer_offset = next_buffer_offset; } } diff --git a/project/clip.cpp b/project/clip.cpp index 65fbdb50a..213a53858 100644 --- a/project/clip.cpp +++ b/project/clip.cpp @@ -10,6 +10,7 @@ #include "project/sequence.h" #include "panels/timeline.h" #include "project/media.h" +#include "io/clipboard.h" #include "undo.h" extern "C" { @@ -17,69 +18,70 @@ extern "C" { } Clip::Clip(Sequence* s) : - sequence(s), - enabled(true), - clip_in(0), - timeline_in(0), - timeline_out(0), - track(0), - media(NULL), - speed(1.0), - reverse(false), - maintain_audio_pitch(false), - autoscale(config.autoscale_by_default), - opening_transition(-1), - closing_transition(-1), - undeletable(false), - replaced(false), - ignore_reverse(false), - use_existing_frame(false), + sequence(s), + enabled(true), + clip_in(0), + timeline_in(0), + timeline_out(0), + track(0), + media(NULL), + speed(1.0), + reverse(false), + maintain_audio_pitch(false), + autoscale(config.autoscale_by_default), + opening_transition(-1), + closing_transition(-1), + undeletable(false), + replaced(false), + ignore_reverse(false), + use_existing_frame(false), filter_graph(NULL), - fbo(NULL), - opts(NULL) + fbo(NULL), + opts(NULL) { pkt = av_packet_alloc(); - reset(); + reset(); } Clip* Clip::copy(Sequence* s) { - Clip* copy = new Clip(s); + Clip* copy = new Clip(s); - copy->enabled = enabled; - copy->name = QString(name); - copy->clip_in = clip_in; - copy->timeline_in = timeline_in; - copy->timeline_out = timeline_out; - copy->track = track; - copy->color_r = color_r; - copy->color_g = color_g; + copy->enabled = enabled; + copy->name = QString(name); + copy->clip_in = clip_in; + copy->timeline_in = timeline_in; + copy->timeline_out = timeline_out; + copy->track = track; + copy->color_r = color_r; + copy->color_g = color_g; copy->color_b = color_b; - copy->media = media; - copy->media_stream = media_stream; - copy->autoscale = autoscale; + copy->media = media; + copy->media_stream = media_stream; + copy->autoscale = autoscale; copy->speed = speed; copy->maintain_audio_pitch = maintain_audio_pitch; copy->reverse = reverse; - for (int i=0;ieffects.append(effects.at(i)->copy(copy)); - } + for (int i=0;ieffects.append(effects.at(i)->copy(copy)); + } - // TODO make a replacemennt for this somehow - if (get_opening_transition() != NULL && get_opening_transition()->secondary_clip == NULL) copy->opening_transition = get_opening_transition()->copy(copy, NULL); - if (get_closing_transition() != NULL && get_closing_transition()->secondary_clip == NULL) copy->closing_transition = get_closing_transition()->copy(copy, NULL); + copy->cached_fr = (this->sequence == NULL) ? cached_fr : this->sequence->frame_rate; + + if (get_opening_transition() != NULL && get_opening_transition()->secondary_clip == NULL) copy->opening_transition = get_opening_transition()->copy(copy, NULL); + if (get_closing_transition() != NULL && get_closing_transition()->secondary_clip == NULL) copy->closing_transition = get_closing_transition()->copy(copy, NULL); copy->recalculateMaxLength(); - return copy; + return copy; } void Clip::reset() { - audio_just_reset = false; - open = false; - finished_opening = false; + audio_just_reset = false; + open = false; + finished_opening = false; pkt_written = false; - audio_reset = false; + audio_reset = false; frame_sample_index = -1; audio_buffer_write = false; texture_frame = -1; @@ -88,42 +90,42 @@ void Clip::reset() { codec = NULL; codecCtx = NULL; texture = NULL; - last_invalid_ts = -1; + last_invalid_ts = -1; } void Clip::reset_audio() { - if (media == NULL || media->get_type() == MEDIA_TYPE_FOOTAGE) { - audio_reset = true; - frame_sample_index = -1; - audio_buffer_write = 0; - } else if (media->get_type() == MEDIA_TYPE_SEQUENCE) { - Sequence* nested_sequence = media->to_sequence(); - for (int i=0;iclips.size();i++) { - Clip* c = nested_sequence->clips.at(i); - if (c != NULL) c->reset_audio(); - } - } + if (media == NULL || media->get_type() == MEDIA_TYPE_FOOTAGE) { + audio_reset = true; + frame_sample_index = -1; + audio_buffer_write = 0; + } else if (media->get_type() == MEDIA_TYPE_SEQUENCE) { + Sequence* nested_sequence = media->to_sequence(); + for (int i=0;iclips.size();i++) { + Clip* c = nested_sequence->clips.at(i); + if (c != NULL) c->reset_audio(); + } + } } void Clip::refresh() { // validates media if it was replaced - if (replaced && media != NULL && media->get_type() == MEDIA_TYPE_FOOTAGE) { - Footage* m = media->to_footage(); + if (replaced && media != NULL && media->get_type() == MEDIA_TYPE_FOOTAGE) { + Footage* m = media->to_footage(); - if (track < 0 && m->video_tracks.size() > 0) { - media_stream = m->video_tracks.at(0)->file_index; - } else if (track >= 0 && m->audio_tracks.size() > 0) { - media_stream = m->audio_tracks.at(0)->file_index; - } + if (track < 0 && m->video_tracks.size() > 0) { + media_stream = m->video_tracks.at(0)->file_index; + } else if (track >= 0 && m->audio_tracks.size() > 0) { + media_stream = m->audio_tracks.at(0)->file_index; + } } replaced = false; - // reinitializes all effects... just in case - for (int i=0;irefresh(); } - recalculateMaxLength(); + recalculateMaxLength(); } void Clip::queue_clear() { @@ -142,79 +144,87 @@ void Clip::queue_remove_earliest() { } } av_frame_free(&queue[earliest_frame]); - queue.removeAt(earliest_frame); + queue.removeAt(earliest_frame); } Transition* Clip::get_opening_transition() { - if (opening_transition > -1) { - return this->sequence->transitions.at(opening_transition); - } - return NULL; + if (opening_transition > -1) { + if (this->sequence == NULL) { + return clipboard_transitions.at(opening_transition); + } else { + return this->sequence->transitions.at(opening_transition); + } + } + return NULL; } Transition* Clip::get_closing_transition() { - if (closing_transition > -1) { - return this->sequence->transitions.at(closing_transition); - } - return NULL; + if (closing_transition > -1) { + if (this->sequence == NULL) { + return clipboard_transitions.at(closing_transition); + } else { + return this->sequence->transitions.at(closing_transition); + } + } + return NULL; } Clip::~Clip() { - if (open) { + if (open) { close_clip(this); - // make sure clip has closed before clip is destroyed - if (multithreaded && media != NULL && media->get_type() == MEDIA_TYPE_FOOTAGE) { - cacher->wait(); - } - } + // make sure clip has closed before clip is destroyed + if (multithreaded && media != NULL && media->get_type() == MEDIA_TYPE_FOOTAGE) { + cacher->wait(); + } + } - if (opening_transition != -1) this->sequence->hard_delete_transition(this, TA_OPENING_TRANSITION); - if (closing_transition != -1) this->sequence->hard_delete_transition(this, TA_CLOSING_TRANSITION); + if (opening_transition != -1) this->sequence->hard_delete_transition(this, TA_OPENING_TRANSITION); + if (closing_transition != -1) this->sequence->hard_delete_transition(this, TA_CLOSING_TRANSITION); - for (int i=0;isecondary_clip != NULL) { - // we must be the secondary clip, so return (timeline in - length) - return clip_in - get_opening_transition()->get_true_length(); - } - return clip_in; + if (get_opening_transition() != NULL && get_opening_transition()->secondary_clip != NULL) { + // we must be the secondary clip, so return (timeline in - length) + return clip_in - get_opening_transition()->get_true_length(); + } + return clip_in; } long Clip::get_timeline_in_with_transition() { - if (get_opening_transition() != NULL && get_opening_transition()->secondary_clip != NULL) { - // we must be the secondary clip, so return (timeline in - length) - return timeline_in - get_opening_transition()->get_true_length(); - } - return timeline_in; + if (get_opening_transition() != NULL && get_opening_transition()->secondary_clip != NULL) { + // we must be the secondary clip, so return (timeline in - length) + return timeline_in - get_opening_transition()->get_true_length(); + } + return timeline_in; } long Clip::get_timeline_out_with_transition() { - if (get_closing_transition() != NULL && get_closing_transition()->secondary_clip != NULL) { - // we must be the primary clip, so return (timeline out + length2) - return timeline_out + get_closing_transition()->get_true_length(); - } else { - return timeline_out; - } + if (get_closing_transition() != NULL && get_closing_transition()->secondary_clip != NULL) { + // we must be the primary clip, so return (timeline out + length2) + return timeline_out + get_closing_transition()->get_true_length(); + } else { + return timeline_out; + } } // timeline functions long Clip::getLength() { - return timeline_out - timeline_in; + return timeline_out - timeline_in; } double Clip::getMediaFrameRate() { - Q_ASSERT(track < 0); - if (media != NULL) { - double rate = media->get_frame_rate(media_stream); - if (!qIsNaN(rate)) return rate; - } - if (sequence != NULL) return sequence->frame_rate; + Q_ASSERT(track < 0); + if (media != NULL) { + double rate = media->get_frame_rate(media_stream); + if (!qIsNaN(rate)) return rate; + } + if (sequence != NULL) return sequence->frame_rate; return qSNaN(); } @@ -224,29 +234,29 @@ void Clip::recalculateMaxLength() { fr /= speed; - calculated_length = LONG_MAX; + calculated_length = LONG_MAX; - if (media != NULL) { - switch (media->get_type()) { - case MEDIA_TYPE_FOOTAGE: - { - Footage* m = media->to_footage(); - FootageStream* ms = m->get_stream_from_file_index(track < 0, media_stream); - if (ms != NULL && ms->infinite_length) { - calculated_length = LONG_MAX; - } else { - calculated_length = m->get_length_in_frames(fr); - } - } - break; - case MEDIA_TYPE_SEQUENCE: - { - Sequence* s = media->to_sequence(); - calculated_length = refactor_frame_number(s->getEndFrame(), s->frame_rate, fr); - } - break; - } - } + if (media != NULL) { + switch (media->get_type()) { + case MEDIA_TYPE_FOOTAGE: + { + Footage* m = media->to_footage(); + FootageStream* ms = m->get_stream_from_file_index(track < 0, media_stream); + if (ms != NULL && ms->infinite_length) { + calculated_length = LONG_MAX; + } else { + calculated_length = m->get_length_in_frames(fr); + } + } + break; + case MEDIA_TYPE_SEQUENCE: + { + Sequence* s = media->to_sequence(); + calculated_length = refactor_frame_number(s->getEndFrame(), s->frame_rate, fr); + } + break; + } + } } } @@ -256,16 +266,16 @@ long Clip::getMaximumLength() { int Clip::getWidth() { if (media == NULL && sequence != NULL) return sequence->width; - switch (media->get_type()) { + switch (media->get_type()) { case MEDIA_TYPE_FOOTAGE: { - FootageStream* ms = media->to_footage()->get_stream_from_file_index(track < 0, media_stream); + FootageStream* ms = media->to_footage()->get_stream_from_file_index(track < 0, media_stream); if (ms != NULL) return ms->video_width; - if (sequence != NULL) return sequence->width; + if (sequence != NULL) return sequence->width; } case MEDIA_TYPE_SEQUENCE: { - Sequence* s = media->to_sequence(); + Sequence* s = media->to_sequence(); return s->width; } } @@ -274,16 +284,16 @@ int Clip::getWidth() { int Clip::getHeight() { if (media == NULL && sequence != NULL) return sequence->height; - switch (media->get_type()) { + switch (media->get_type()) { case MEDIA_TYPE_FOOTAGE: { - FootageStream* ms = media->to_footage()->get_stream_from_file_index(track < 0, media_stream); + FootageStream* ms = media->to_footage()->get_stream_from_file_index(track < 0, media_stream); if (ms != NULL) return ms->video_height; - if (sequence != NULL) return sequence->height; + if (sequence != NULL) return sequence->height; } case MEDIA_TYPE_SEQUENCE: { - Sequence* s = media->to_sequence(); + Sequence* s = media->to_sequence(); return s->height; } } @@ -292,11 +302,11 @@ int Clip::getHeight() { void Clip::refactor_frame_rate(ComboAction* ca, double multiplier, bool change_timeline_points) { if (change_timeline_points) { - move_clip(ca, this, - qRound((double) timeline_in * multiplier), - qRound((double) timeline_out * multiplier), - qRound((double) clip_in * multiplier), - track); + move_clip(ca, this, + qRound((double) timeline_in * multiplier), + qRound((double) timeline_out * multiplier), + qRound((double) clip_in * multiplier), + track); } for (int i=0;iroot = true; + root_item = new Media(0); + root_item->root = true; } -ProjectModel::~ProjectModel() { - destroy_root(); +ProjectModel::~ProjectModel() { + destroy_root(); } void ProjectModel::destroy_root() { - if (panel_sequence_viewer != NULL) panel_sequence_viewer->viewer_widget->delete_function(); - if (panel_footage_viewer != NULL) panel_footage_viewer->viewer_widget->delete_function(); + if (panel_sequence_viewer != NULL) panel_sequence_viewer->viewer_widget->delete_function(); + if (panel_footage_viewer != NULL) panel_footage_viewer->viewer_widget->delete_function(); - if (root_item != NULL) { - delete root_item; - } + if (root_item != NULL) { + delete root_item; + } } void ProjectModel::clear() { - beginResetModel(); - destroy_root(); - root_item = new Media(0); - root_item->root = true; - endResetModel(); + beginResetModel(); + destroy_root(); + root_item = new Media(0); + root_item->root = true; + endResetModel(); } Media *ProjectModel::get_root() { - return root_item; + return root_item; } QVariant ProjectModel::data(const QModelIndex &index, int role) const { - if (!index.isValid()) - return QVariant(); + if (!index.isValid()) + return QVariant(); - return static_cast(index.internalPointer())->data(index.column(), role); + return static_cast(index.internalPointer())->data(index.column(), role); } Qt::ItemFlags ProjectModel::flags(const QModelIndex &index) const { - if (!index.isValid()) - return Qt::ItemIsDropEnabled; + if (!index.isValid()) + return Qt::ItemIsDropEnabled; - return QAbstractItemModel::flags(index) | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEditable; + return QAbstractItemModel::flags(index) | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEditable; } QVariant ProjectModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (orientation == Qt::Horizontal && role == Qt::DisplayRole) - return root_item->data(section, role); + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) + return root_item->data(section, role); - return QVariant(); + return QVariant(); } QModelIndex ProjectModel::index(int row, int column, const QModelIndex &parent) const { - if (!hasIndex(row, column, parent)) - return QModelIndex(); + if (!hasIndex(row, column, parent)) + return QModelIndex(); - Media *parentItem; + Media *parentItem; - if (!parent.isValid()) - parentItem = root_item; - else - parentItem = static_cast(parent.internalPointer()); + if (!parent.isValid()) + parentItem = root_item; + else + parentItem = static_cast(parent.internalPointer()); - Media *childItem = parentItem->child(row); - if (childItem) - return createIndex(row, column, childItem); - else - return QModelIndex(); + Media *childItem = parentItem->child(row); + if (childItem) + return createIndex(row, column, childItem); + else + return QModelIndex(); +} + +QModelIndex ProjectModel::create_index(int arow, int acolumn, void* aid) { + return createIndex(arow, acolumn, aid); } QModelIndex ProjectModel::parent(const QModelIndex &index) const { - if (!index.isValid()) - return QModelIndex(); + if (!index.isValid()) + return QModelIndex(); - Media *childItem = static_cast(index.internalPointer()); - Media *parentItem = childItem->parentItem(); + Media *childItem = static_cast(index.internalPointer()); + Media *parentItem = childItem->parentItem(); - if (parentItem == root_item) - return QModelIndex(); + if (parentItem == root_item) + return QModelIndex(); - return createIndex(parentItem->row(), 0, parentItem); + return createIndex(parentItem->row(), 0, parentItem); } bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int role) { - if (role != Qt::EditRole) - return false; + if (role != Qt::EditRole) + return false; - Media *item = static_cast(index.internalPointer()); - bool result = item->setData(index.column(), value); + Media *item = static_cast(index.internalPointer()); + bool result = item->setData(index.column(), value); - if (result) - emit dataChanged(index, index); + if (result) + emit dataChanged(index, index); - return result; + return result; } int ProjectModel::rowCount(const QModelIndex &parent) const { - Media *parentItem; - if (parent.column() > 0) - return 0; + Media *parentItem; + if (parent.column() > 0) + return 0; - if (!parent.isValid()) { - parentItem = root_item; - } else { - parentItem = static_cast(parent.internalPointer()); - } + if (!parent.isValid()) { + parentItem = root_item; + } else { + parentItem = static_cast(parent.internalPointer()); + } - return parentItem->childCount(); + return parentItem->childCount(); } int ProjectModel::columnCount(const QModelIndex &parent) const { - if (parent.isValid()) - return static_cast(parent.internalPointer())->columnCount(); - else - return root_item->columnCount(); + if (parent.isValid()) + return static_cast(parent.internalPointer())->columnCount(); + else + return root_item->columnCount(); } Media *ProjectModel::getItem(const QModelIndex &index) const { - if (index.isValid()) { - Media *item = static_cast(index.internalPointer()); - if (item) - return item; - } - return root_item; + if (index.isValid()) { + Media *item = static_cast(index.internalPointer()); + if (item) + return item; + } + return root_item; } void ProjectModel::set_icon(Media* m, const QIcon &ico) { - QModelIndex index = createIndex(m->row(), 0, m); - m->set_icon(ico); - emit dataChanged(index, index); + QModelIndex index = createIndex(m->row(), 0, m); + m->set_icon(ico); + emit dataChanged(index, index); } void ProjectModel::appendChild(Media *parent, Media *child) { - if (parent == NULL) parent = root_item; - beginInsertRows(parent == root_item ? QModelIndex() : createIndex(parent->row(), 0, parent), parent->childCount(), parent->childCount()); - parent->appendChild(child); - endInsertRows(); + if (parent == NULL) parent = root_item; + beginInsertRows(parent == root_item ? QModelIndex() : createIndex(parent->row(), 0, parent), parent->childCount(), parent->childCount()); + parent->appendChild(child); + endInsertRows(); } void ProjectModel::moveChild(Media *child, Media *to) { - if (to == NULL) to = root_item; - Media* from = child->parentItem(); - beginMoveRows( - from == root_item ? QModelIndex() : createIndex(from->row(), 0, from), - child->row(), - child->row(), - to == root_item ? QModelIndex() : createIndex(to->row(), 0, to), - to->childCount() - ); - from->removeChild(child->row()); - to->appendChild(child); - endMoveRows(); + if (to == NULL) to = root_item; + Media* from = child->parentItem(); + beginMoveRows( + from == root_item ? QModelIndex() : createIndex(from->row(), 0, from), + child->row(), + child->row(), + to == root_item ? QModelIndex() : createIndex(to->row(), 0, to), + to->childCount() + ); + from->removeChild(child->row()); + to->appendChild(child); + endMoveRows(); } void ProjectModel::removeChild(Media* parent, Media* m) { - if (parent == NULL) parent = root_item; - beginRemoveRows(parent == root_item ? QModelIndex() : createIndex(parent->row(), 0, parent), m->row(), m->row()); - parent->removeChild(m->row()); - endRemoveRows(); + if (parent == NULL) parent = root_item; + beginRemoveRows(parent == root_item ? QModelIndex() : createIndex(parent->row(), 0, parent), m->row(), m->row()); + parent->removeChild(m->row()); + endRemoveRows(); } Media* ProjectModel::child(int i, Media* parent) { - if (parent == NULL) parent = root_item; - return parent->child(i); + if (parent == NULL) parent = root_item; + return parent->child(i); } int ProjectModel::childCount(Media *parent) { - if (parent == NULL) parent = root_item; - return parent->childCount(); + if (parent == NULL) parent = root_item; + return parent->childCount(); } diff --git a/project/projectmodel.h b/project/projectmodel.h index 42709b848..b37836f6b 100644 --- a/project/projectmodel.h +++ b/project/projectmodel.h @@ -7,35 +7,36 @@ class Media; class ProjectModel : public QAbstractItemModel { - Q_OBJECT + Q_OBJECT public: - ProjectModel(QObject* parent = 0); - ~ProjectModel() override; + ProjectModel(QObject* parent = 0); + ~ProjectModel() override; - void destroy_root(); - void clear(); - Media* get_root(); - QVariant data(const QModelIndex &index, int role) const override; - Qt::ItemFlags flags(const QModelIndex &index) const override; - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const override; - QModelIndex index(int row, int column, - const QModelIndex &parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &index) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - Media *getItem(const QModelIndex &index) const; + void destroy_root(); + void clear(); + Media* get_root(); + QVariant data(const QModelIndex &index, int role) const override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const override; + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const override; + QModelIndex create_index(int arow, int acolumn, void *aid); + QModelIndex parent(const QModelIndex &index) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + Media *getItem(const QModelIndex &index) const; - void appendChild(Media* parent, Media* child); - void moveChild(Media *child, Media *to); - void removeChild(Media *parent, Media* m); - Media *child(int i, Media* parent = NULL); - int childCount(Media* parent = NULL); - void set_icon(Media* m, const QIcon &ico); + void appendChild(Media* parent, Media* child); + void moveChild(Media *child, Media *to); + void removeChild(Media *parent, Media* m); + Media *child(int i, Media* parent = NULL); + int childCount(Media* parent = NULL); + void set_icon(Media* m, const QIcon &ico); private: - Media* root_item; + Media* root_item; }; #endif // PROJECTMODEL_H diff --git a/project/sequence.cpp b/project/sequence.cpp index f454243a7..4450df41f 100644 --- a/project/sequence.cpp +++ b/project/sequence.cpp @@ -7,94 +7,102 @@ Sequence::Sequence() : playhead(0), - using_workarea(false), - workarea_in(0), - workarea_out(0), - wrapper_sequence(false) + using_workarea(false), + workarea_in(0), + workarea_out(0), + wrapper_sequence(false) { } Sequence::~Sequence() { - // dealloc all clips - for (int i=0;iname = name + " (copy)"; - s->width = width; - s->height = height; - s->frame_rate = frame_rate; - s->audio_frequency = audio_frequency; - s->audio_layout = audio_layout; - s->clips.resize(clips.size()); - for (int i=0;iclips[i] = NULL; - } else { - Clip* copy = c->copy(s); - copy->linked = c->linked; - s->clips[i] = copy; - } - } - return s; + Sequence* s = new Sequence(); + s->name = name + " (copy)"; + s->width = width; + s->height = height; + s->frame_rate = frame_rate; + s->audio_frequency = audio_frequency; + s->audio_layout = audio_layout; + s->clips.resize(clips.size()); + for (int i=0;iclips[i] = NULL; + } else { + Clip* copy = c->copy(s); + copy->linked = c->linked; + s->clips[i] = copy; + } + } + return s; } long Sequence::getEndFrame() { - long end = 0; - for (int j=0;jtimeline_out > end) { - end = c->timeline_out; - } - } - return end; + long end = 0; + for (int j=0;jtimeline_out > end) { + end = c->timeline_out; + } + } + return end; } void Sequence::hard_delete_transition(Clip *c, int type) { - int transition_index = (type == TA_OPENING_TRANSITION) ? c->opening_transition : c->closing_transition; - if (transition_index > -1) { - bool del = true; - for (int i=0;iopening_transition == transition_index - || cc->closing_transition == transition_index)) { - // another clip is using this, don't delete just yet - del = false; - break; - } - } + int transition_index = (type == TA_OPENING_TRANSITION) ? c->opening_transition : c->closing_transition; + if (transition_index > -1) { + bool del = true; - if (del) { - delete transitions.at(transition_index); - transitions[transition_index] = NULL; - } + Transition* t = transitions.at(transition_index); + if (t->secondary_clip != NULL) { + for (int i=0;iopening_transition == transition_index + || c->closing_transition == transition_index)) { + if (type == TA_OPENING_TRANSITION) { + // convert to closing transition + t->parent_clip = t->secondary_clip; + } - if (type == TA_OPENING_TRANSITION) { - c->opening_transition = -1; - } else { - c->closing_transition = -1; - } - } + del = false; + t->secondary_clip = NULL; + } + } + } + + if (del) { + delete transitions.at(transition_index); + transitions[transition_index] = NULL; + } + + if (type == TA_OPENING_TRANSITION) { + c->opening_transition = -1; + } else { + c->closing_transition = -1; + } + } } void Sequence::getTrackLimits(int* video_tracks, int* audio_tracks) { int vt = 0; int at = 0; - for (int j=0;jtrack < 0 && c->track < vt) { // video clip - vt = c->track; - } else if (c->track > at) { - at = c->track; - } - } + for (int j=0;jtrack < 0 && c->track < vt) { // video clip + vt = c->track; + } else if (c->track > at) { + at = c->track; + } + } } if (video_tracks != NULL) *video_tracks = vt; if (audio_tracks != NULL) *audio_tracks = at; diff --git a/project/sequence.h b/project/sequence.h index bd5d20cd6..9ab5c03d9 100644 --- a/project/sequence.h +++ b/project/sequence.h @@ -8,35 +8,36 @@ struct Clip; class Transition; +class Media; struct Sequence { Sequence(); ~Sequence(); - Sequence* copy(); - QString name; - void getTrackLimits(int* video_tracks, int* audio_tracks); + Sequence* copy(); + QString name; + void getTrackLimits(int* video_tracks, int* audio_tracks); long getEndFrame(); - void hard_delete_transition(Clip *c, int type); + void hard_delete_transition(Clip *c, int type); int width; int height; - double frame_rate; + double frame_rate; int audio_frequency; - int audio_layout; + int audio_layout; QVector selections; long playhead; - bool using_workarea; - long workarea_in; - long workarea_out; + bool using_workarea; + long workarea_in; + long workarea_out; - bool wrapper_sequence; + bool wrapper_sequence; - int save_id; + int save_id; - QVector markers; + QVector markers; QVector clips; - QVector transitions; + QVector transitions; }; // static variable for the currently active sequence diff --git a/project/sourcescommon.cpp b/project/sourcescommon.cpp index dd1bd3da2..b5272c8cd 100644 --- a/project/sourcescommon.cpp +++ b/project/sourcescommon.cpp @@ -18,263 +18,263 @@ #include SourcesCommon::SourcesCommon(Project* parent) : - project_parent(parent), - editing_item(NULL) + project_parent(parent), + editing_item(NULL) { - rename_timer.setInterval(1000); - connect(&rename_timer, SIGNAL(timeout()), this, SLOT(rename_interval())); + rename_timer.setInterval(1000); + connect(&rename_timer, SIGNAL(timeout()), this, SLOT(rename_interval())); } void SourcesCommon::create_seq_from_selected() { - if (!selected_items.isEmpty()) { - QVector media_list; - for (int i=0;iitem_to_media(selected_items.at(i))); - } + if (!selected_items.isEmpty()) { + QVector media_list; + for (int i=0;iitem_to_media(selected_items.at(i))); + } - ComboAction* ca = new ComboAction(); - Sequence* s = create_sequence_from_media(media_list); + ComboAction* ca = new ComboAction(); + Sequence* 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); + // add clips to it + panel_timeline->create_ghosts_from_media(s, 0, media_list); + panel_timeline->add_clips_from_ghosts(ca, s); - project_parent->new_sequence(ca, s, true, NULL); - undo_stack.push(ca); - } + project_parent->new_sequence(ca, s, true, NULL); + undo_stack.push(ca); + } } void SourcesCommon::show_context_menu(QWidget* parent, const QModelIndexList& items) { - QMenu menu(parent); + QMenu menu(parent); - selected_items = items; + selected_items = items; - QAction* import_action = menu.addAction("Import..."); - QObject::connect(import_action, SIGNAL(triggered(bool)), project_parent, SLOT(import_dialog())); + QAction* import_action = menu.addAction("Import..."); + QObject::connect(import_action, SIGNAL(triggered(bool)), project_parent, SLOT(import_dialog())); - QAction* new_folder_action = menu.addAction("New Folder..."); - QObject::connect(new_folder_action, SIGNAL(triggered(bool)), mainWindow, SLOT(on_actionFolder_triggered())); + QMenu* new_menu = menu.addMenu("New"); + mainWindow->make_new_menu(new_menu); - if (items.size() > 0) { - Media* m = project_parent->item_to_media(items.at(0)); + if (items.size() > 0) { + Media* m = project_parent->item_to_media(items.at(0)); - if (items.size() == 1) { - // replace footage - int type = m->get_type(); - if (type == MEDIA_TYPE_FOOTAGE) { - QAction* replace_action = menu.addAction("Replace/Relink Media"); - QObject::connect(replace_action, SIGNAL(triggered(bool)), project_parent, SLOT(replace_selected_file())); + if (items.size() == 1) { + // replace footage + int type = m->get_type(); + if (type == MEDIA_TYPE_FOOTAGE) { + QAction* replace_action = menu.addAction("Replace/Relink Media"); + QObject::connect(replace_action, SIGNAL(triggered(bool)), project_parent, SLOT(replace_selected_file())); #if defined(Q_OS_WIN) - QAction* reveal_in_explorer = menu.addAction("Reveal in Explorer"); + QAction* reveal_in_explorer = menu.addAction("Reveal in Explorer"); #elif defined(Q_OS_MAC) - QAction* reveal_in_explorer = menu.addAction("Reveal in Finder"); + QAction* reveal_in_explorer = menu.addAction("Reveal in Finder"); #else - QAction* reveal_in_explorer = menu.addAction("Reveal in File Manager"); + QAction* reveal_in_explorer = menu.addAction("Reveal in File Manager"); #endif - QObject::connect(reveal_in_explorer, SIGNAL(triggered(bool)), this, SLOT(reveal_in_browser())); - } - if (type != MEDIA_TYPE_FOLDER) { - QAction* replace_clip_media = menu.addAction("Replace Clips Using This Media"); - QObject::connect(replace_clip_media, SIGNAL(triggered(bool)), project_parent, SLOT(replace_clip_media())); - } - } + QObject::connect(reveal_in_explorer, SIGNAL(triggered(bool)), this, SLOT(reveal_in_browser())); + } + if (type != MEDIA_TYPE_FOLDER) { + QAction* replace_clip_media = menu.addAction("Replace Clips Using This Media"); + QObject::connect(replace_clip_media, SIGNAL(triggered(bool)), project_parent, SLOT(replace_clip_media())); + } + } - // duplicate item - bool all_sequences = true; - bool all_footage = true; - for (int i=0;iget_type() != MEDIA_TYPE_SEQUENCE) { - all_sequences = false; - } - if (m->get_type() != MEDIA_TYPE_FOOTAGE) { - all_footage = false; - } - } + // duplicate item + bool all_sequences = true; + bool all_footage = true; + for (int i=0;iget_type() != MEDIA_TYPE_SEQUENCE) { + all_sequences = false; + } + if (m->get_type() != MEDIA_TYPE_FOOTAGE) { + all_footage = false; + } + } - // create sequence from - QAction* create_seq_from = menu.addAction("Create Sequence With This Media"); - QObject::connect(create_seq_from, SIGNAL(triggered(bool)), this, SLOT(create_seq_from_selected())); + // create sequence from + QAction* create_seq_from = menu.addAction("Create Sequence With This Media"); + QObject::connect(create_seq_from, SIGNAL(triggered(bool)), this, SLOT(create_seq_from_selected())); - // ONLY sequences are selected - if (all_sequences) { - // ONLY sequences are selected - QAction* duplicate_action = menu.addAction("Duplicate"); - QObject::connect(duplicate_action, SIGNAL(triggered(bool)), project_parent, SLOT(duplicate_selected())); - } + // ONLY sequences are selected + if (all_sequences) { + // ONLY sequences are selected + QAction* duplicate_action = menu.addAction("Duplicate"); + QObject::connect(duplicate_action, SIGNAL(triggered(bool)), project_parent, SLOT(duplicate_selected())); + } - // ONLY footage is selected - if (all_footage) { - QAction* delete_footage_from_sequences = menu.addAction("Delete All Clips Using This Media"); - QObject::connect(delete_footage_from_sequences, SIGNAL(triggered(bool)), project_parent, SLOT(delete_clips_using_selected_media())); - } + // ONLY footage is selected + if (all_footage) { + QAction* delete_footage_from_sequences = menu.addAction("Delete All Clips Using This Media"); + QObject::connect(delete_footage_from_sequences, SIGNAL(triggered(bool)), project_parent, SLOT(delete_clips_using_selected_media())); + } - // delete media - QAction* delete_action = menu.addAction("Delete"); - QObject::connect(delete_action, SIGNAL(triggered(bool)), project_parent, SLOT(delete_selected_media())); + // delete media + QAction* delete_action = menu.addAction("Delete"); + QObject::connect(delete_action, SIGNAL(triggered(bool)), project_parent, SLOT(delete_selected_media())); - if (items.size() == 1) { - QAction* properties_action = menu.addAction("Properties..."); - QObject::connect(properties_action, SIGNAL(triggered(bool)), project_parent, SLOT(open_properties())); - } - } + if (items.size() == 1) { + QAction* properties_action = menu.addAction("Properties..."); + QObject::connect(properties_action, SIGNAL(triggered(bool)), project_parent, SLOT(open_properties())); + } + } - menu.addSeparator(); + menu.addSeparator(); - QAction* tree_view_action = menu.addAction("Tree View"); - connect(tree_view_action, SIGNAL(triggered(bool)), project_parent, SLOT(set_tree_view())); + QAction* tree_view_action = menu.addAction("Tree View"); + connect(tree_view_action, SIGNAL(triggered(bool)), project_parent, SLOT(set_tree_view())); - QAction* icon_view_action = menu.addAction("Icon View"); - connect(icon_view_action, SIGNAL(triggered(bool)), project_parent, SLOT(set_icon_view())); + QAction* icon_view_action = menu.addAction("Icon View"); + connect(icon_view_action, SIGNAL(triggered(bool)), project_parent, SLOT(set_icon_view())); - menu.exec(QCursor::pos()); + menu.exec(QCursor::pos()); } void SourcesCommon::mousePressEvent(QMouseEvent *) { - stop_rename_timer(); + stop_rename_timer(); } void SourcesCommon::item_click(Media *m, const QModelIndex& index) { - if (editing_item == m) { - rename_timer.start(); - } else { - editing_item = m; - editing_index = index; - } + if (editing_item == m) { + rename_timer.start(); + } else { + editing_item = m; + editing_index = index; + } } void SourcesCommon::mouseDoubleClickEvent(QMouseEvent *e, const QModelIndexList& selected_items) { - stop_rename_timer(); - if (selected_items.size() == 0) { - project_parent->import_dialog(); - } else if (selected_items.size() == 1) { - Media* item = project_parent->item_to_media(selected_items.at(0)); - switch (item->get_type()) { - case MEDIA_TYPE_FOOTAGE: - panel_footage_viewer->set_media(item); - panel_footage_viewer->setFocus(); - break; - case MEDIA_TYPE_SEQUENCE: - undo_stack.push(new ChangeSequenceAction(item->to_sequence())); - break; - } - } + stop_rename_timer(); + if (selected_items.size() == 0) { + project_parent->import_dialog(); + } else if (selected_items.size() == 1) { + Media* item = project_parent->item_to_media(selected_items.at(0)); + switch (item->get_type()) { + case MEDIA_TYPE_FOOTAGE: + panel_footage_viewer->set_media(item); + panel_footage_viewer->setFocus(); + break; + case MEDIA_TYPE_SEQUENCE: + undo_stack.push(new ChangeSequenceAction(item->to_sequence())); + break; + } + } } void SourcesCommon::dropEvent(QWidget* parent, QDropEvent *event, const QModelIndex& drop_item, const QModelIndexList& items) { - const QMimeData* mimeData = event->mimeData(); - Media* m = project_parent->item_to_media(drop_item); - if (mimeData->hasUrls()) { - // drag files in from outside - QList urls = mimeData->urls(); - if (!urls.isEmpty()) { - QStringList paths; - for (int i=0;iget_type() == MEDIA_TYPE_FOOTAGE - && !QFileInfo(paths.at(0)).isDir() - && config.drop_on_media_to_replace - && QMessageBox::question(parent, "Replace Media", "You dropped a file onto '" + m->get_name() + "'. Would you like to replace it with the dropped file?", QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes) { - replace = true; - project_parent->replace_media(m, paths.at(0)); - } - if (!replace) { - QModelIndex parent; - if (drop_item.isValid()) { - if (m->get_type() == MEDIA_TYPE_FOLDER) { - parent = drop_item; - } else { - parent = drop_item.parent(); - } - } - project_parent->process_file_list(paths, false, NULL, panel_project->item_to_media(parent)); - } - } - event->acceptProposedAction(); - } else { - event->ignore(); + const QMimeData* mimeData = event->mimeData(); + Media* m = project_parent->item_to_media(drop_item); + if (mimeData->hasUrls()) { + // drag files in from outside + QList urls = mimeData->urls(); + if (!urls.isEmpty()) { + QStringList paths; + for (int i=0;iget_type() == MEDIA_TYPE_FOOTAGE + && !QFileInfo(paths.at(0)).isDir() + && config.drop_on_media_to_replace + && QMessageBox::question(parent, "Replace Media", "You dropped a file onto '" + m->get_name() + "'. Would you like to replace it with the dropped file?", QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes) { + replace = true; + project_parent->replace_media(m, paths.at(0)); + } + if (!replace) { + QModelIndex parent; + if (drop_item.isValid()) { + if (m->get_type() == MEDIA_TYPE_FOLDER) { + parent = drop_item; + } else { + parent = drop_item.parent(); + } + } + project_parent->process_file_list(paths, false, NULL, panel_project->item_to_media(parent)); + } + } + event->acceptProposedAction(); + } else { + event->ignore(); - // dragging files within project - // if we dragged to the root OR dragged to a folder - if (!drop_item.isValid() || (drop_item.isValid() && m->get_type() == MEDIA_TYPE_FOLDER)) { - QVector move_items; - for (int i=0;iitem_to_media(item); - if (parent != drop_item && item != drop_item) { - bool ignore = false; - if (parent.isValid()) { - // if child belongs to a selected parent, assume the user is just moving the parent and ignore the child - QModelIndex par = parent; - while (par.isValid() && !ignore) { - for (int j=0;j 0) { - MediaMove* mm = new MediaMove(); - mm->to = m; - mm->items = move_items; - undo_stack.push(mm); - } - } - } + // dragging files within project + // if we dragged to the root OR dragged to a folder + if (!drop_item.isValid() || (drop_item.isValid() && m->get_type() == MEDIA_TYPE_FOLDER)) { + QVector move_items; + for (int i=0;iitem_to_media(item); + if (parent != drop_item && item != drop_item) { + bool ignore = false; + if (parent.isValid()) { + // if child belongs to a selected parent, assume the user is just moving the parent and ignore the child + QModelIndex par = parent; + while (par.isValid() && !ignore) { + for (int j=0;j 0) { + MediaMove* mm = new MediaMove(); + mm->to = m; + mm->items = move_items; + undo_stack.push(mm); + } + } + } } void SourcesCommon::reveal_in_browser() { - Media* media = project_parent->item_to_media(selected_items.at(0)); - Footage* m = media->to_footage(); + Media* media = project_parent->item_to_media(selected_items.at(0)); + Footage* m = media->to_footage(); #if defined(Q_OS_WIN) - QStringList args; - args << "/select," << QDir::toNativeSeparators(m->url); - QProcess::startDetached("explorer", args); + QStringList args; + args << "/select," << QDir::toNativeSeparators(m->url); + QProcess::startDetached("explorer", args); #elif defined(Q_OS_MAC) - QStringList args; - args << "-e"; - args << "tell application \"Finder\""; - args << "-e"; - args << "activate"; - args << "-e"; - args << "select POSIX file \""+m->url+"\""; - args << "-e"; - args << "end tell"; - QProcess::startDetached("osascript", args); + QStringList args; + args << "-e"; + args << "tell application \"Finder\""; + args << "-e"; + args << "activate"; + args << "-e"; + args << "select POSIX file \""+m->url+"\""; + args << "-e"; + args << "end tell"; + QProcess::startDetached("osascript", args); #else - QDesktopServices::openUrl(QUrl::fromLocalFile(m->url.left(m->url.lastIndexOf('/')))); + QDesktopServices::openUrl(QUrl::fromLocalFile(m->url.left(m->url.lastIndexOf('/')))); #endif } void SourcesCommon::stop_rename_timer() { - rename_timer.stop(); + rename_timer.stop(); } void SourcesCommon::rename_interval() { - stop_rename_timer(); - if (view->hasFocus() && editing_item != NULL) { - view->edit(editing_index); - } + stop_rename_timer(); + if (view->hasFocus() && editing_item != NULL) { + view->edit(editing_index); + } } void SourcesCommon::item_renamed(Media* item) { - if (editing_item == item) { - MediaRename* mr = new MediaRename(item, "idk"); - undo_stack.push(mr); - editing_item = NULL; - } + if (editing_item == item) { + MediaRename* mr = new MediaRename(item, "idk"); + undo_stack.push(mr); + editing_item = NULL; + } } diff --git a/project/transition.cpp b/project/transition.cpp index 440ae7729..63490797d 100644 --- a/project/transition.cpp +++ b/project/transition.cpp @@ -5,6 +5,8 @@ #include "sequence.h" #include "debug.h" +#include "io/clipboard.h" + #include "effects/internal/crossdissolvetransition.h" #include "effects/internal/linearfadetransition.h" #include "effects/internal/exponentialfadetransition.h" @@ -19,71 +21,71 @@ #include Transition::Transition(Clip* c, Clip* s, const EffectMeta* em) : - Effect(c, em), secondary_clip(s), - length(30) + Effect(c, em), secondary_clip(s), + length(30) { - length_field = add_row("Length:", false)->add_field(EFFECT_FIELD_DOUBLE, "length"); - connect(length_field, SIGNAL(changed()), this, SLOT(set_length_from_slider())); - length_field->set_double_default_value(30); - length_field->set_double_minimum_value(0); + length_field = add_row("Length:", false)->add_field(EFFECT_FIELD_DOUBLE, "length"); + connect(length_field, SIGNAL(changed()), this, SLOT(set_length_from_slider())); + length_field->set_double_default_value(30); + length_field->set_double_minimum_value(0); - LabelSlider* length_ui_ele = static_cast(length_field->ui_element); - length_ui_ele->set_display_type(LABELSLIDER_FRAMENUMBER); - length_ui_ele->set_frame_rate(parent_clip->sequence->frame_rate); + LabelSlider* length_ui_ele = static_cast(length_field->ui_element); + length_ui_ele->set_display_type(LABELSLIDER_FRAMENUMBER); + length_ui_ele->set_frame_rate(parent_clip->sequence == NULL ? parent_clip->cached_fr : parent_clip->sequence->frame_rate); } int Transition::copy(Clip *c, Clip* s) { - int copy_index = create_transition(c, s, meta); - c->sequence->transitions.at(copy_index)->length = length; - return copy_index; + return create_transition(c, s, meta, length); } void Transition::set_length(long l) { - length = l; - length_field->set_double_value(l); + length = l; + length_field->set_double_value(l); } long Transition::get_true_length() { - return length; + return length; } long Transition::get_length() { - if (secondary_clip != NULL) { - return length * 2; - } - return length; + if (secondary_clip != NULL) { + return length * 2; + } + return length; } void Transition::set_length_from_slider() { - set_length(length_field->get_double_value(0)); - update_ui(false); + set_length(length_field->get_double_value(0)); + update_ui(false); } Transition* get_transition_from_meta(Clip* c, Clip* s, const EffectMeta* em) { - if (!em->filename.isEmpty()) { - // load effect from file - return new Transition(c, s, em); - } else if (em->internal >= 0 && em->internal < TRANSITION_INTERNAL_COUNT) { - // must be an internal effect - switch (em->internal) { - case TRANSITION_INTERNAL_CROSSDISSOLVE: return new CrossDissolveTransition(c, s, em); - case TRANSITION_INTERNAL_LINEARFADE: return new LinearFadeTransition(c, s, em); - case TRANSITION_INTERNAL_EXPONENTIALFADE: return new ExponentialFadeTransition(c, s, em); - case TRANSITION_INTERNAL_LOGARITHMICFADE: return new LogarithmicFadeTransition(c, s, em); - case TRANSITION_INTERNAL_CUBE: return new CubeTransition(c, s, em); - } - } else { - dout << "[ERROR] Invalid transition data"; - QMessageBox::critical(mainWindow, "Invalid transition", "No candidate for transition '" + em->name + "'. This transition may be corrupt. Try reinstalling it or Olive."); - } - return NULL; + if (!em->filename.isEmpty()) { + // load effect from file + return new Transition(c, s, em); + } else if (em->internal >= 0 && em->internal < TRANSITION_INTERNAL_COUNT) { + // must be an internal effect + switch (em->internal) { + case TRANSITION_INTERNAL_CROSSDISSOLVE: return new CrossDissolveTransition(c, s, em); + case TRANSITION_INTERNAL_LINEARFADE: return new LinearFadeTransition(c, s, em); + case TRANSITION_INTERNAL_EXPONENTIALFADE: return new ExponentialFadeTransition(c, s, em); + case TRANSITION_INTERNAL_LOGARITHMICFADE: return new LogarithmicFadeTransition(c, s, em); + case TRANSITION_INTERNAL_CUBE: return new CubeTransition(c, s, em); + } + } else { + dout << "[ERROR] Invalid transition data"; + QMessageBox::critical(mainWindow, "Invalid transition", "No candidate for transition '" + em->name + "'. This transition may be corrupt. Try reinstalling it or Olive."); + } + return NULL; } -int create_transition(Clip* c, Clip* s, const EffectMeta* em) { - Transition* t = get_transition_from_meta(c, s, em); - if (t != NULL) { - c->sequence->transitions.append(t); - return c->sequence->transitions.size() - 1; - } - return -1; +int create_transition(Clip* c, Clip* s, const EffectMeta* em, long length) { + Transition* t = get_transition_from_meta(c, s, em); + if (length >= 0) t->set_length(length); + if (t != NULL) { + QVector& transition_list = (c->sequence == NULL) ? clipboard_transitions : c->sequence->transitions; + transition_list.append(t); + return transition_list.size() - 1; + } + return -1; } diff --git a/project/transition.h b/project/transition.h index 2f9df63f4..29e2e2493 100644 --- a/project/transition.h +++ b/project/transition.h @@ -14,22 +14,22 @@ #define TRANSITION_INTERNAL_CUBE 4 #define TRANSITION_INTERNAL_COUNT 5 -int create_transition(Clip* c, Clip* s, const EffectMeta* em); +int create_transition(Clip* c, Clip* s, const EffectMeta* em, long length = -1); class Transition : public Effect { - Q_OBJECT + Q_OBJECT public: - Transition(Clip* c, Clip* s, const EffectMeta* em); - int copy(Clip* c, Clip* s); - Clip* secondary_clip; - void set_length(long l); - long get_true_length(); - long get_length(); + Transition(Clip* c, Clip* s, const EffectMeta* em); + int copy(Clip* c, Clip* s); + Clip* secondary_clip; + void set_length(long l); + long get_true_length(); + long get_length(); private slots: - void set_length_from_slider(); + void set_length_from_slider(); private: - long length; // used only for transitions - EffectField* length_field; + long length; // used only for transitions + EffectField* length_field; }; #endif // TRANSITION_H diff --git a/project/undo.cpp b/project/undo.cpp index 8e9132d82..e67c38941 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -30,98 +30,142 @@ QUndoStack undo_stack; ComboAction::ComboAction() {} ComboAction::~ComboAction() { - for (int i=0;i=0;i--) { - commands.at(i)->undo(); - } + for (int i=commands.size()-1;i>=0;i--) { + commands.at(i)->undo(); + } for (int i=0;iundo(); } } void ComboAction::redo() { - for (int i=0;iredo(); - } + for (int i=0;iredo(); + } for (int i=0;iredo(); } } void ComboAction::append(QUndoCommand* u) { - commands.append(u); + commands.append(u); } void ComboAction::appendPost(QUndoCommand* u) { post_commands.append(u); } -MoveClipAction::MoveClipAction(Clip *c, long iin, long iout, long iclip_in, int itrack) : - clip(c), +MoveClipAction::MoveClipAction(Clip *c, long iin, long iout, long iclip_in, int itrack, bool irelative) : + clip(c), old_in(c->timeline_in), old_out(c->timeline_out), old_clip_in(c->clip_in), old_track(c->track), - new_in(iin), - new_out(iout), - new_clip_in(iclip_in), + new_in(iin), + new_out(iout), + new_clip_in(iclip_in), new_track(itrack), + relative(irelative), old_project_changed(mainWindow->isWindowModified()) {} void MoveClipAction::undo() { - clip->timeline_in = old_in; - clip->timeline_out = old_out; - clip->clip_in = old_clip_in; - clip->track = old_track; + if (relative) { + clip->timeline_in -= new_in; + clip->timeline_out -= new_out; + clip->clip_in -= new_clip_in; + clip->track -= new_track; + } else { + clip->timeline_in = old_in; + clip->timeline_out = old_out; + clip->clip_in = old_clip_in; + clip->track = old_track; + } mainWindow->setWindowModified(old_project_changed); } void MoveClipAction::redo() { - clip->timeline_in = new_in; - clip->timeline_out = new_out; - clip->clip_in = new_clip_in; - clip->track = new_track; + if (relative) { + clip->timeline_in += new_in; + clip->timeline_out += new_out; + clip->clip_in += new_clip_in; + clip->track += new_track; + } else { + clip->timeline_in = new_in; + clip->timeline_out = new_out; + clip->clip_in = new_clip_in; + clip->track = new_track; + } mainWindow->setWindowModified(true); } DeleteClipAction::DeleteClipAction(Sequence* s, int clip) : - seq(s), + seq(s), index(clip), + opening_transition(-1), + closing_transition(-1), old_project_changed(mainWindow->isWindowModified()) {} DeleteClipAction::~DeleteClipAction() { - if (ref != NULL) delete ref; + if (ref != NULL) delete ref; } void DeleteClipAction::undo() { // restore ref to clip - seq->clips[index] = ref; - ref = NULL; + seq->clips[index] = ref; + + // restore shared transitions + if (opening_transition > -1) { + seq->transitions.at(opening_transition)->secondary_clip = seq->transitions.at(opening_transition)->parent_clip; + seq->transitions.at(opening_transition)->parent_clip = ref; + ref->opening_transition = opening_transition; + opening_transition = -1; + } + if (closing_transition > -1) { + seq->transitions.at(closing_transition)->secondary_clip = ref; + ref->closing_transition = closing_transition; + closing_transition = -1; + } // restore links to this clip for (int i=linkClipIndex.size()-1;i>=0;i--) { seq->clips.at(linkClipIndex.at(i))->linked.insert(linkLinkIndex.at(i), index); } + ref = NULL; + mainWindow->setWindowModified(old_project_changed); } void DeleteClipAction::redo() { // remove ref to clip - ref = seq->clips.at(index); - if (ref->open) { - close_clip(ref); - } - seq->clips[index] = NULL; + ref = seq->clips.at(index); + if (ref->open) { + close_clip(ref); + } + seq->clips[index] = NULL; + + // save shared transitions + if (ref->opening_transition > -1 && ref->get_opening_transition()->secondary_clip != NULL) { + opening_transition = ref->opening_transition; + ref->get_opening_transition()->parent_clip = ref->get_opening_transition()->secondary_clip; + ref->get_opening_transition()->secondary_clip = NULL; + ref->opening_transition = -1; + } + if (ref->closing_transition > -1 && ref->get_closing_transition()->secondary_clip != NULL) { + closing_transition = ref->closing_transition; + ref->get_closing_transition()->secondary_clip = NULL; + ref->closing_transition = -1; + } // delete link to this clip linkClipIndex.clear(); @@ -143,261 +187,261 @@ void DeleteClipAction::redo() { } ChangeSequenceAction::ChangeSequenceAction(Sequence* s) : - new_sequence(s) + new_sequence(s) {} void ChangeSequenceAction::undo() { - set_sequence(old_sequence); + set_sequence(old_sequence); } void ChangeSequenceAction::redo() { - old_sequence = sequence; - set_sequence(new_sequence); + old_sequence = sequence; + set_sequence(new_sequence); } SetTimelineInOutCommand::SetTimelineInOutCommand(Sequence *s, bool enabled, long in, long out) : - seq(s), - new_enabled(enabled), - new_in(in), + seq(s), + new_enabled(enabled), + new_in(in), new_out(out), old_project_changed(mainWindow->isWindowModified()) {} void SetTimelineInOutCommand::undo() { - seq->using_workarea = old_enabled; - seq->workarea_in = old_in; - seq->workarea_out = old_out; + seq->using_workarea = old_enabled; + seq->workarea_in = old_in; + seq->workarea_out = old_out; - // footage viewer functions - if (seq->wrapper_sequence) { - Footage* m = seq->clips.at(0)->media->to_footage(); - m->using_inout = old_enabled; - m->in = old_in; - m->out = old_out; - } + // footage viewer functions + if (seq->wrapper_sequence) { + Footage* m = seq->clips.at(0)->media->to_footage(); + m->using_inout = old_enabled; + m->in = old_in; + m->out = old_out; + } mainWindow->setWindowModified(old_project_changed); } void SetTimelineInOutCommand::redo() { - old_enabled = seq->using_workarea; - old_in = seq->workarea_in; - old_out = seq->workarea_out; + old_enabled = seq->using_workarea; + old_in = seq->workarea_in; + old_out = seq->workarea_out; - seq->using_workarea = new_enabled; - seq->workarea_in = new_in; - seq->workarea_out = new_out; + seq->using_workarea = new_enabled; + seq->workarea_in = new_in; + seq->workarea_out = new_out; - // footage viewer functions - if (seq->wrapper_sequence) { - Footage* m = seq->clips.at(0)->media->to_footage(); - m->using_inout = new_enabled; - m->in = new_in; - m->out = new_out; - } + // footage viewer functions + if (seq->wrapper_sequence) { + Footage* m = seq->clips.at(0)->media->to_footage(); + m->using_inout = new_enabled; + m->in = new_in; + m->out = new_out; + } mainWindow->setWindowModified(true); } AddEffectCommand::AddEffectCommand(Clip* c, Effect* e, const EffectMeta *m, int insert_pos) : - clip(c), - meta(m), - ref(e), - pos(insert_pos), + clip(c), + meta(m), + ref(e), + pos(insert_pos), done(false), old_project_changed(mainWindow->isWindowModified()) {} AddEffectCommand::~AddEffectCommand() { - if (!done && ref != NULL) delete ref; + if (!done && ref != NULL) delete ref; } void AddEffectCommand::undo() { - clip->effects.last()->close(); - if (pos < 0) { - clip->effects.removeLast(); - } else { - clip->effects.removeAt(pos); - } - done = false; + clip->effects.last()->close(); + if (pos < 0) { + clip->effects.removeLast(); + } else { + clip->effects.removeAt(pos); + } + done = false; mainWindow->setWindowModified(old_project_changed); } void AddEffectCommand::redo() { - if (ref == NULL) { + if (ref == NULL) { ref = create_effect(clip, meta); - } - if (pos < 0) { - clip->effects.append(ref); - } else { - clip->effects.insert(pos, ref); - } - done = true; + } + if (pos < 0) { + clip->effects.append(ref); + } else { + clip->effects.insert(pos, ref); + } + done = true; mainWindow->setWindowModified(true); } AddTransitionCommand::AddTransitionCommand(Clip* c, Clip *s, Transition* copy, const EffectMeta *itransition, int itype, int ilength) : - clip(c), - secondary(s), - transition_to_copy(copy), - transition(itransition), + clip(c), + secondary(s), + transition_to_copy(copy), + transition(itransition), type(itype), - length(ilength), + length(ilength), old_project_changed(mainWindow->isWindowModified()) {} void AddTransitionCommand::undo() { - clip->sequence->hard_delete_transition(clip, type); - if (secondary != NULL) secondary->sequence->hard_delete_transition(secondary, (type == TA_OPENING_TRANSITION) ? TA_CLOSING_TRANSITION : TA_OPENING_TRANSITION); + clip->sequence->hard_delete_transition(clip, type); + if (secondary != NULL) secondary->sequence->hard_delete_transition(secondary, (type == TA_OPENING_TRANSITION) ? TA_CLOSING_TRANSITION : TA_OPENING_TRANSITION); - if (type == TA_OPENING_TRANSITION) { - clip->opening_transition = old_ptransition; - if (secondary != NULL) secondary->closing_transition = old_stransition; - } else { - clip->closing_transition = old_ptransition; - if (secondary != NULL) secondary->opening_transition = old_stransition; - } + if (type == TA_OPENING_TRANSITION) { + clip->opening_transition = old_ptransition; + if (secondary != NULL) secondary->closing_transition = old_stransition; + } else { + clip->closing_transition = old_ptransition; + if (secondary != NULL) secondary->opening_transition = old_stransition; + } mainWindow->setWindowModified(old_project_changed); } void AddTransitionCommand::redo() { - if (type == TA_OPENING_TRANSITION) { - old_ptransition = clip->opening_transition; - clip->opening_transition = (transition_to_copy == NULL) ? create_transition(clip, secondary, transition) : transition_to_copy->copy(clip, NULL); - if (secondary != NULL) { - old_stransition = secondary->closing_transition; - secondary->closing_transition = clip->opening_transition; - } - if (length > 0) { - clip->get_opening_transition()->set_length(length); - } - } else { - old_ptransition = clip->closing_transition; - clip->closing_transition = (transition_to_copy == NULL) ? create_transition(clip, secondary, transition) : transition_to_copy->copy(clip, NULL); - if (secondary != NULL) { - old_stransition = secondary->opening_transition; - secondary->opening_transition = clip->closing_transition; - } - if (length > 0) { - clip->get_closing_transition()->set_length(length); - } - } + if (type == TA_OPENING_TRANSITION) { + old_ptransition = clip->opening_transition; + clip->opening_transition = (transition_to_copy == NULL) ? create_transition(clip, secondary, transition) : transition_to_copy->copy(clip, NULL); + if (secondary != NULL) { + old_stransition = secondary->closing_transition; + secondary->closing_transition = clip->opening_transition; + } + if (length > 0) { + clip->get_opening_transition()->set_length(length); + } + } else { + old_ptransition = clip->closing_transition; + clip->closing_transition = (transition_to_copy == NULL) ? create_transition(clip, secondary, transition) : transition_to_copy->copy(clip, NULL); + if (secondary != NULL) { + old_stransition = secondary->opening_transition; + secondary->opening_transition = clip->closing_transition; + } + if (length > 0) { + clip->get_closing_transition()->set_length(length); + } + } mainWindow->setWindowModified(true); } ModifyTransitionCommand::ModifyTransitionCommand(Clip* c, int itype, long ilength) : - clip(c), - type(itype), + clip(c), + type(itype), new_length(ilength), old_project_changed(mainWindow->isWindowModified()) {} void ModifyTransitionCommand::undo() { - Transition* t = (type == TA_OPENING_TRANSITION) ? clip->get_opening_transition() : clip->get_closing_transition(); - t->set_length(old_length); + Transition* t = (type == TA_OPENING_TRANSITION) ? clip->get_opening_transition() : clip->get_closing_transition(); + t->set_length(old_length); mainWindow->setWindowModified(old_project_changed); } void ModifyTransitionCommand::redo() { - Transition* t = (type == TA_OPENING_TRANSITION) ? clip->get_opening_transition() : clip->get_closing_transition(); - old_length = t->get_true_length(); - t->set_length(new_length); + Transition* t = (type == TA_OPENING_TRANSITION) ? clip->get_opening_transition() : clip->get_closing_transition(); + old_length = t->get_true_length(); + t->set_length(new_length); mainWindow->setWindowModified(true); } DeleteTransitionCommand::DeleteTransitionCommand(Sequence* s, int transition_index) : - seq(s), - index(transition_index), + seq(s), + index(transition_index), transition(NULL), - otc(NULL), - ctc(NULL), + otc(NULL), + ctc(NULL), old_project_changed(mainWindow->isWindowModified()) {} DeleteTransitionCommand::~DeleteTransitionCommand() { - if (transition != NULL) delete transition; + if (transition != NULL) delete transition; } void DeleteTransitionCommand::undo() { - seq->transitions[index] = transition; + seq->transitions[index] = transition; - if (otc != NULL) otc->opening_transition = index; - if (ctc != NULL) ctc->closing_transition = index; + if (otc != NULL) otc->opening_transition = index; + if (ctc != NULL) ctc->closing_transition = index; - transition = NULL; + transition = NULL; mainWindow->setWindowModified(old_project_changed); } void DeleteTransitionCommand::redo() { - for (int i=0;iclips.size();i++) { - Clip* c = seq->clips.at(i); - if (c != NULL) { - if (c->opening_transition == index) { - otc = c; - c->opening_transition = -1; - } - if (c->closing_transition == index) { - ctc = c; - c->closing_transition = -1; - } - } - } + for (int i=0;iclips.size();i++) { + Clip* c = seq->clips.at(i); + if (c != NULL) { + if (c->opening_transition == index) { + otc = c; + c->opening_transition = -1; + } + if (c->closing_transition == index) { + ctc = c; + c->closing_transition = -1; + } + } + } - transition = seq->transitions.at(index); - seq->transitions[index] = NULL; + transition = seq->transitions.at(index); + seq->transitions[index] = NULL; mainWindow->setWindowModified(true); } NewSequenceCommand::NewSequenceCommand(Media *s, Media* iparent) : - seq(s), - parent(iparent), + seq(s), + parent(iparent), done(false), old_project_changed(mainWindow->isWindowModified()) { - if (parent == NULL) parent = project_model.get_root(); + if (parent == NULL) parent = project_model.get_root(); } NewSequenceCommand::~NewSequenceCommand() { - if (!done) delete seq; + if (!done) delete seq; } void NewSequenceCommand::undo() { - project_model.removeChild(parent, seq); + project_model.removeChild(parent, seq); - done = false; + done = false; mainWindow->setWindowModified(old_project_changed); } void NewSequenceCommand::redo() { - project_model.appendChild(parent, seq); + project_model.appendChild(parent, seq); - done = true; + done = true; mainWindow->setWindowModified(true); } AddMediaCommand::AddMediaCommand(Media* iitem, Media *iparent) : - item(iitem), - parent(iparent), + item(iitem), + parent(iparent), done(false), old_project_changed(mainWindow->isWindowModified()) {} AddMediaCommand::~AddMediaCommand() { - if (!done) { - delete item; - } + if (!done) { + delete item; + } } void AddMediaCommand::undo() { - project_model.removeChild(parent, item); - done = false; + project_model.removeChild(parent, item); + done = false; mainWindow->setWindowModified(old_project_changed); } void AddMediaCommand::redo() { - project_model.appendChild(parent, item); + project_model.appendChild(parent, item); done = true; mainWindow->setWindowModified(true); @@ -405,92 +449,53 @@ void AddMediaCommand::redo() { DeleteMediaCommand::DeleteMediaCommand(Media* i) : item(i), - parent(i->parentItem()), + parent(i->parentItem()), old_project_changed(mainWindow->isWindowModified()) {} DeleteMediaCommand::~DeleteMediaCommand() { - if (done) { - delete item; + if (done) { + delete item; } } void DeleteMediaCommand::undo() { - project_model.appendChild(parent, item); + project_model.appendChild(parent, item); mainWindow->setWindowModified(old_project_changed); done = false; } void DeleteMediaCommand::redo() { - project_model.removeChild(parent, item); + project_model.removeChild(parent, item); mainWindow->setWindowModified(true); done = true; } -RippleCommand::RippleCommand(Sequence *s, long ipoint, long ilength) : - seq(s), - point(ipoint), - length(ilength), - old_project_changed(mainWindow->isWindowModified()) -{} - -void RippleCommand::undo() { - for (int i=0;itimeline_in -= length; - c->timeline_out -= length; - } - mainWindow->setWindowModified(old_project_changed); -} - -void RippleCommand::redo() { - rippled.clear(); - for (int j=0;jclips.size();j++) { - Clip* c = seq->clips.at(j); - bool found = false; - for (int i=0;itimeline_in >= point) { - c->timeline_in += length; - c->timeline_out += length; - rippled.append(c); - } - } - } - mainWindow->setWindowModified(true); -} - AddClipCommand::AddClipCommand(Sequence* s, QVector& add) : - seq(s), + seq(s), clips(add), old_project_changed(mainWindow->isWindowModified()) {} AddClipCommand::~AddClipCommand() { - for (int i=0;iclips.last(); panel_timeline->deselect_area(c->timeline_in, c->timeline_out, c->track); undone_clips.prepend(c); - if (c->open) close_clip(c); - seq->clips.removeLast(); - } + if (c->open) close_clip(c); + seq->clips.removeLast(); + } mainWindow->setWindowModified(old_project_changed); } @@ -509,8 +514,8 @@ void AddClipCommand::redo() { for (int j=0;jlinked.size();j++) { copy->linked[j] = original->linked.at(j) + linkOffset; } - if (original->opening_transition > -1) copy->opening_transition = original->get_opening_transition()->copy(copy, NULL); - if (original->closing_transition > -1) copy->closing_transition = original->get_closing_transition()->copy(copy, NULL); + if (original->opening_transition > -1) copy->opening_transition = original->get_opening_transition()->copy(copy, NULL); + if (original->closing_transition > -1) copy->closing_transition = original->get_closing_transition()->copy(copy, NULL); seq->clips.append(copy); } } @@ -520,32 +525,32 @@ void AddClipCommand::redo() { LinkCommand::LinkCommand() : link(true), old_project_changed(mainWindow->isWindowModified()) {} void LinkCommand::undo() { - for (int i=0;iclips.at(clips.at(i)); - if (link) { - c->linked.clear(); - } else { - c->linked = old_links.at(i); - } - } + if (link) { + c->linked.clear(); + } else { + c->linked = old_links.at(i); + } + } mainWindow->setWindowModified(old_project_changed); } void LinkCommand::redo() { - old_links.clear(); - for (int i=0;iclips.at(clips.at(i)); - if (link) { - for (int j=0;jlinked.append(clips.at(j)); - } - } - } else { - old_links.append(c->linked); - c->linked.clear(); - } - } + } + } + } else { + old_links.append(c->linked); + c->linked.clear(); + } + } mainWindow->setWindowModified(true); } @@ -554,15 +559,15 @@ CheckboxCommand::CheckboxCommand(QCheckBox* b) : box(b), checked(box->isChecked( CheckboxCommand::~CheckboxCommand() {} void CheckboxCommand::undo() { - box->setChecked(!checked); - done = false; + box->setChecked(!checked); + done = false; mainWindow->setWindowModified(old_project_changed); } void CheckboxCommand::redo() { - if (!done) { - box->setChecked(checked); - } + if (!done) { + box->setChecked(checked); + } mainWindow->setWindowModified(true); } @@ -571,19 +576,19 @@ ReplaceMediaCommand::ReplaceMediaCommand(Media* i, QString s) : new_filename(s), old_project_changed(mainWindow->isWindowModified()) { - old_filename = item->to_footage()->url; + old_filename = item->to_footage()->url; } void ReplaceMediaCommand::replace(QString& filename) { // close any clips currently using this media - QVector all_sequences = panel_project->list_all_project_sequences(); + QVector all_sequences = panel_project->list_all_project_sequences(); for (int i=0;ito_sequence(); - for (int j=0;jclips.size();j++) { - Clip* c = s->clips.at(j); - if (c != NULL && c->media == item && c->open) { + Sequence* s = all_sequences.at(i)->to_sequence(); + for (int j=0;jclips.size();j++) { + Clip* c = s->clips.at(j); + if (c != NULL && c->media == item && c->open) { close_clip(c); - if (c->media != NULL && c->media->get_type() == MEDIA_TYPE_FOOTAGE) c->cacher->wait(); + if (c->media != NULL && c->media->get_type() == MEDIA_TYPE_FOOTAGE) c->cacher->wait(); c->replaced = true; } } @@ -592,8 +597,8 @@ void ReplaceMediaCommand::replace(QString& filename) { // replace media QStringList files; files.append(filename); - item->to_footage()->ready_lock.lock(); - panel_project->process_file_list(files, false, item, NULL); + item->to_footage()->ready_lock.lock(); + panel_project->process_file_list(files, false, item, NULL); } void ReplaceMediaCommand::undo() { @@ -610,7 +615,7 @@ void ReplaceMediaCommand::redo() { ReplaceClipMediaCommand::ReplaceClipMediaCommand(Media *a, Media *b, bool e) : old_media(a), - new_media(b), + new_media(b), preserve_clip_ins(e), old_project_changed(mainWindow->isWindowModified()) {} @@ -624,7 +629,7 @@ void ReplaceClipMediaCommand::replace(bool undo) { Clip* c = clips.at(i); if (c->open) { close_clip(c); - if (c->media != NULL && c->media->get_type() == MEDIA_TYPE_FOOTAGE) c->cacher->wait(); + if (c->media != NULL && c->media->get_type() == MEDIA_TYPE_FOOTAGE) c->cacher->wait(); } if (undo) { @@ -632,14 +637,14 @@ void ReplaceClipMediaCommand::replace(bool undo) { c->clip_in = old_clip_ins.at(i); } - c->media = old_media; + c->media = old_media; } else { if (!preserve_clip_ins) { old_clip_ins.append(c->clip_in); c->clip_in = 0; } - c->media = new_media; + c->media = new_media; } c->replaced = true; @@ -656,7 +661,7 @@ void ReplaceClipMediaCommand::undo() { void ReplaceClipMediaCommand::redo() { replace(false); - update_ui(true); + update_ui(true); mainWindow->setWindowModified(true); } @@ -685,9 +690,9 @@ void EffectDeleteCommand::redo() { for (int i=0;ieffects.at(fx_id); - e->close(); - deleted_objects.append(e); + Effect* e = c->effects.at(fx_id); + e->close(); + deleted_objects.append(e); c->effects.removeAt(fx_id); } panel_effect_controls->reload_clips(); @@ -699,37 +704,37 @@ MediaMove::MediaMove() : old_project_changed(mainWindow->isWindowModified()) {} void MediaMove::undo() { for (int i=0;isetWindowModified(old_project_changed); } void MediaMove::redo() { - if (to == NULL) to = project_model.get_root(); + if (to == NULL) to = project_model.get_root(); froms.resize(items.size()); for (int i=0;iparentItem(); + Media* parent = items.at(i)->parentItem(); froms[i] = parent; - project_model.moveChild(items.at(i), to); - } + project_model.moveChild(items.at(i), to); + } mainWindow->setWindowModified(true); } MediaRename::MediaRename(Media* iitem, QString ito) : - item(iitem), - from(iitem->get_name()), - to(ito), - old_project_changed(mainWindow->isWindowModified()) + item(iitem), + from(iitem->get_name()), + to(ito), + old_project_changed(mainWindow->isWindowModified()) {} void MediaRename::undo() { - item->set_name(from); - mainWindow->setWindowModified(old_project_changed); + item->set_name(from); + mainWindow->setWindowModified(old_project_changed); } void MediaRename::redo() { - item->set_name(to); - mainWindow->setWindowModified(true); + item->set_name(to); + mainWindow->setWindowModified(true); } KeyframeMove::KeyframeMove() : old_project_changed(mainWindow->isWindowModified()) {} @@ -749,9 +754,9 @@ void KeyframeMove::redo() { } KeyframeDelete::KeyframeDelete() : - disable_keyframes_on_row(NULL), - old_project_changed(mainWindow->isWindowModified()), - sorted(false) + disable_keyframes_on_row(NULL), + old_project_changed(mainWindow->isWindowModified()), + sorted(false) {} void KeyframeDelete::undo() { @@ -828,7 +833,7 @@ KeyframeSet::KeyframeSet(EffectRow* r, int i, long t, bool justMadeKeyframe) : EffectField* field = row->field(i); if (index != -1) { if (field->type == EFFECT_FIELD_DOUBLE) { - old_values[i] = static_cast(field->ui_element)->getPreviousValue(); + old_values[i] = static_cast(field->ui_element)->getPreviousValue(); } else { old_values[i] = field->keyframe_data.at(index); } @@ -903,17 +908,17 @@ SetAutoscaleAction::SetAutoscaleAction() : {} void SetAutoscaleAction::undo() { - for (int i=0;iautoscale = !clips.at(i)->autoscale; - } + for (int i=0;iautoscale = !clips.at(i)->autoscale; + } panel_sequence_viewer->viewer_widget->update(); mainWindow->setWindowModified(old_project_changed); } void SetAutoscaleAction::redo() { - for (int i=0;iautoscale = !clips.at(i)->autoscale; - } + for (int i=0;iautoscale = !clips.at(i)->autoscale; + } panel_sequence_viewer->viewer_widget->update(); mainWindow->setWindowModified(true); } @@ -927,9 +932,9 @@ AddMarkerAction::AddMarkerAction(Sequence* s, long t, QString n) : void AddMarkerAction::undo() { if (index == -1) { - seq->markers.removeLast(); + seq->markers.removeLast(); } else { - seq->markers[index].name = old_name; + seq->markers[index].name = old_name; } mainWindow->setWindowModified(old_project_changed); @@ -937,8 +942,8 @@ void AddMarkerAction::undo() { void AddMarkerAction::redo() { index = -1; - for (int i=0;imarkers.size();i++) { - if (seq->markers.at(i).frame == time) { + for (int i=0;imarkers.size();i++) { + if (seq->markers.at(i).frame == time) { index = i; break; } @@ -947,10 +952,10 @@ void AddMarkerAction::redo() { if (index == -1) { Marker m; m.frame = time; - seq->markers.append(m); + seq->markers.append(m); } else { - old_name = seq->markers.at(index).name; - seq->markers[index].name = name; + old_name = seq->markers.at(index).name; + seq->markers[index].name = name; } mainWindow->setWindowModified(true); @@ -1040,22 +1045,22 @@ void SetBool::redo() { } SetSelectionsCommand::SetSelectionsCommand(Sequence* s) : - seq(s), + seq(s), done(true), old_project_changed(mainWindow->isWindowModified()) {} void SetSelectionsCommand::undo() { - seq->selections = old_data; - done = false; + seq->selections = old_data; + done = false; mainWindow->setWindowModified(old_project_changed); } void SetSelectionsCommand::redo() { - if (!done) { - seq->selections = new_data; - done = true; - } + if (!done) { + seq->selections = new_data; + done = true; + } mainWindow->setWindowModified(true); } @@ -1114,7 +1119,7 @@ void EditSequenceCommand::redo() { void EditSequenceCommand::update() { // update tooltip - item->set_sequence(seq); + item->set_sequence(seq); for (int i=0;iclips.size();i++) { // TODO shift in/out/clipin points to match new frame rate @@ -1131,36 +1136,36 @@ void EditSequenceCommand::update() { } SetInt::SetInt(int* pointer, int new_value) : - p(pointer), - oldval(*pointer), + p(pointer), + oldval(*pointer), newval(new_value), old_project_changed(mainWindow->isWindowModified()) {} void SetInt::undo() { - *p = oldval; + *p = oldval; mainWindow->setWindowModified(old_project_changed); } void SetInt::redo() { - *p = newval; + *p = newval; mainWindow->setWindowModified(true); } SetString::SetString(QString* pointer, QString new_value) : - p(pointer), - oldval(*pointer), + p(pointer), + oldval(*pointer), newval(new_value), old_project_changed(mainWindow->isWindowModified()) {} void SetString::undo() { - *p = oldval; + *p = oldval; mainWindow->setWindowModified(old_project_changed); } void SetString::redo() { - *p = newval; + *p = newval; mainWindow->setWindowModified(true); } @@ -1173,7 +1178,7 @@ void CloseAllClipsCommand::redo() { } UpdateFootageTooltip::UpdateFootageTooltip(Media *i) : - item(i) + item(i) {} void UpdateFootageTooltip::undo() { @@ -1181,7 +1186,7 @@ void UpdateFootageTooltip::undo() { } void UpdateFootageTooltip::redo() { - item->update_tooltip(); + item->update_tooltip(); } MoveEffectCommand::MoveEffectCommand() : @@ -1211,13 +1216,13 @@ RemoveClipsFromClipboard::~RemoveClipsFromClipboard() { } void RemoveClipsFromClipboard::undo() { - clipboard.insert(pos, clip); + clipboard.insert(pos, clip); done = false; } void RemoveClipsFromClipboard::redo() { - clip = static_cast(clipboard.at(pos)); - clipboard.removeAt(pos); + clip = static_cast(clipboard.at(pos)); + clipboard.removeAt(pos); done = true; } @@ -1240,26 +1245,53 @@ void RenameClipCommand::redo() { } SetPointer::SetPointer(void **pointer, void *data) : - p(pointer), - new_data(data), - old_changed(mainWindow->isWindowModified()) + p(pointer), + new_data(data), + old_changed(mainWindow->isWindowModified()) {} void SetPointer::undo() { - *p = old_data; - mainWindow->setWindowModified(old_changed); + *p = old_data; + mainWindow->setWindowModified(old_changed); } void SetPointer::redo() { - old_data = *p; - *p = new_data; - mainWindow->setWindowModified(true); + old_data = *p; + *p = new_data; + mainWindow->setWindowModified(true); } void ReloadEffectsCommand::undo() { - redo(); + redo(); } void ReloadEffectsCommand::redo() { - panel_effect_controls->reload_clips(); + panel_effect_controls->reload_clips(); +} + +RippleAction::RippleAction(Sequence *is, long ipoint, long ilength, const QVector &iignore) : + s(is), + point(ipoint), + length(ilength), + ignore(iignore) +{} + +void RippleAction::undo() { + ca->undo(); + delete ca; +} + +void RippleAction::redo() { + ca = new ComboAction(); + for (int i=0;iclips.size();i++) { + if (!ignore.contains(i)) { + Clip* c = s->clips.at(i); + if (c != NULL) { + if (c->timeline_in >= point) { + move_clip(ca, c, length, length, 0, 0, true, true); + } + } + } + } + ca->redo(); } diff --git a/project/undo.h b/project/undo.h index 36be97d59..a1f79212f 100644 --- a/project/undo.h +++ b/project/undo.h @@ -28,48 +28,66 @@ extern QUndoStack undo_stack; class ComboAction : public QUndoCommand { public: - ComboAction(); - ~ComboAction(); - void undo(); - void redo(); - void append(QUndoCommand* u); + ComboAction(); + ~ComboAction(); + void undo(); + void redo(); + void append(QUndoCommand* u); void appendPost(QUndoCommand* u); private: - QVector commands; + QVector commands; QVector post_commands; }; class MoveClipAction : public QUndoCommand { public: - MoveClipAction(Clip* c, long iin, long iout, long iclip_in, int itrack); - void undo(); - void redo(); + MoveClipAction(Clip* c, long iin, long iout, long iclip_in, int itrack, bool irelative); + void undo(); + void redo(); private: - Clip* clip; + Clip* clip; - long old_in; - long old_out; - long old_clip_in; - int old_track; + long old_in; + long old_out; + long old_clip_in; + int old_track; - long new_in; - long new_out; - long new_clip_in; - int new_track; + long new_in; + long new_out; + long new_clip_in; + int new_track; + + bool relative; bool old_project_changed; }; +class RippleAction : public QUndoCommand { +public: + RippleAction(Sequence *is, long ipoint, long ilength, const QVector& iignore); + void undo(); + void redo(); +private: + Sequence *s; + long point; + long length; + QVector ignore; + ComboAction* ca; +}; + class DeleteClipAction : public QUndoCommand { public: - DeleteClipAction(Sequence* s, int clip); - ~DeleteClipAction(); - void undo(); - void redo(); + DeleteClipAction(Sequence* s, int clip); + ~DeleteClipAction(); + void undo(); + void redo(); private: - Sequence* seq; - Clip* ref; - int index; + Sequence* seq; + Clip* ref; + int index; + + int opening_transition; + int closing_transition; QVector linkClipIndex; QVector linkLinkIndex; @@ -79,207 +97,193 @@ private: class ChangeSequenceAction : public QUndoCommand { public: - ChangeSequenceAction(Sequence* s); - void undo(); - void redo(); + ChangeSequenceAction(Sequence* s); + void undo(); + void redo(); private: - Sequence* old_sequence; - Sequence* new_sequence; + Sequence* old_sequence; + Sequence* new_sequence; }; class AddEffectCommand : public QUndoCommand { public: - AddEffectCommand(Clip* c, Effect *e, const EffectMeta* m, int insert_pos = -1); - ~AddEffectCommand(); - void undo(); - void redo(); + AddEffectCommand(Clip* c, Effect *e, const EffectMeta* m, int insert_pos = -1); + ~AddEffectCommand(); + void undo(); + void redo(); private: - Clip* clip; + Clip* clip; const EffectMeta* meta; - Effect* ref; - int pos; - bool done; + Effect* ref; + int pos; + bool done; bool old_project_changed; }; class AddTransitionCommand : public QUndoCommand { public: - AddTransitionCommand(Clip* c, Clip* s, Transition *copy, const EffectMeta* itransition, int itype, int ilength); - void undo(); - void redo(); + AddTransitionCommand(Clip* c, Clip* s, Transition *copy, const EffectMeta* itransition, int itype, int ilength); + void undo(); + void redo(); private: - Clip* clip; - Clip* secondary; - Transition* transition_to_copy; + Clip* clip; + Clip* secondary; + Transition* transition_to_copy; const EffectMeta* transition; - int type; - int length; + int type; + int length; bool old_project_changed; - int old_ptransition; - int old_stransition; + int old_ptransition; + int old_stransition; }; class ModifyTransitionCommand : public QUndoCommand { public: - ModifyTransitionCommand(Clip* c, int itype, long ilength); - void undo(); - void redo(); + ModifyTransitionCommand(Clip* c, int itype, long ilength); + void undo(); + void redo(); private: - Clip* clip; - int type; - long new_length; - long old_length; + Clip* clip; + int type; + long new_length; + long old_length; bool old_project_changed; }; class DeleteTransitionCommand : public QUndoCommand { public: - DeleteTransitionCommand(Sequence* s, int transition_index); - ~DeleteTransitionCommand(); - void undo(); - void redo(); + DeleteTransitionCommand(Sequence* s, int transition_index); + ~DeleteTransitionCommand(); + void undo(); + void redo(); private: - Sequence* seq; - int index; - Transition* transition; - Clip* otc; - Clip* ctc; + Sequence* seq; + int index; + Transition* transition; + Clip* otc; + Clip* ctc; bool old_project_changed; }; class SetTimelineInOutCommand : public QUndoCommand { public: - SetTimelineInOutCommand(Sequence* s, bool enabled, long in, long out); - void undo(); - void redo(); + SetTimelineInOutCommand(Sequence* s, bool enabled, long in, long out); + void undo(); + void redo(); private: - Sequence* seq; + Sequence* seq; - bool old_enabled; - long old_in; - long old_out; + bool old_enabled; + long old_in; + long old_out; - bool new_enabled; - long new_in; - long new_out; + bool new_enabled; + long new_in; + long new_out; bool old_project_changed; }; class NewSequenceCommand : public QUndoCommand { public: - NewSequenceCommand(Media *s, Media* iparent); - ~NewSequenceCommand(); - void undo(); - void redo(); + NewSequenceCommand(Media *s, Media* iparent); + ~NewSequenceCommand(); + void undo(); + void redo(); private: - Media* seq; - Media* parent; - bool done; + Media* seq; + Media* parent; + bool done; bool old_project_changed; }; class AddMediaCommand : public QUndoCommand { public: - AddMediaCommand(Media* iitem, Media* iparent); - ~AddMediaCommand(); - void undo(); - void redo(); + AddMediaCommand(Media* iitem, Media* iparent); + ~AddMediaCommand(); + void undo(); + void redo(); private: - Media* item; - Media* parent; - bool done; + Media* item; + Media* parent; + bool done; bool old_project_changed; }; class DeleteMediaCommand : public QUndoCommand { public: - DeleteMediaCommand(Media *i); - ~DeleteMediaCommand(); - void undo(); - void redo(); + DeleteMediaCommand(Media *i); + ~DeleteMediaCommand(); + void undo(); + void redo(); private: - Media* item; - Media* parent; + Media* item; + Media* parent; bool old_project_changed; bool done; }; -class RippleCommand : public QUndoCommand { -public: - RippleCommand(Sequence* s, long ipoint, long ilength); - QVector ignore; - void undo(); - void redo(); -private: - Sequence* seq; - long point; - long length; - QVector rippled; - bool old_project_changed; -}; - class AddClipCommand : public QUndoCommand { public: - AddClipCommand(Sequence* s, QVector& add); - ~AddClipCommand(); - void undo(); - void redo(); + AddClipCommand(Sequence* s, QVector& add); + ~AddClipCommand(); + void undo(); + void redo(); private: - Sequence* seq; - QVector clips; + Sequence* seq; + QVector clips; QVector undone_clips; bool old_project_changed; }; class LinkCommand : public QUndoCommand { public: - LinkCommand(); - void undo(); + LinkCommand(); + void undo(); void redo(); Sequence* s; QVector clips; - bool link; + bool link; private: - QVector< QVector > old_links; + QVector< QVector > old_links; bool old_project_changed; }; class CheckboxCommand : public QUndoCommand { public: - CheckboxCommand(QCheckBox* b); - ~CheckboxCommand(); - void undo(); - void redo(); + CheckboxCommand(QCheckBox* b); + ~CheckboxCommand(); + void undo(); + void redo(); private: - QCheckBox* box; - bool checked; - bool done; + QCheckBox* box; + bool checked; + bool done; bool old_project_changed; }; class ReplaceMediaCommand : public QUndoCommand { public: - ReplaceMediaCommand(Media*, QString); + ReplaceMediaCommand(Media*, QString); void undo(); void redo(); private: - Media *item; + Media *item; QString old_filename; QString new_filename; - bool old_project_changed; + bool old_project_changed; void replace(QString& filename); }; class ReplaceClipMediaCommand : public QUndoCommand { public: - ReplaceClipMediaCommand(Media *, Media *, bool); + ReplaceClipMediaCommand(Media *, Media *, bool); void undo(); void redo(); QVector clips; private: - Media* old_media; - Media* new_media; + Media* old_media; + Media* new_media; bool preserve_clip_ins; bool old_project_changed; QVector old_clip_ins; @@ -302,26 +306,26 @@ private: class MediaMove : public QUndoCommand { public: - MediaMove(); - QVector items; - Media* to; + MediaMove(); + QVector items; + Media* to; void undo(); void redo(); private: - QVector froms; + QVector froms; bool old_project_changed; }; class MediaRename : public QUndoCommand { public: - MediaRename(Media* iitem, QString to); - void undo(); - void redo(); + MediaRename(Media* iitem, QString to); + void undo(); + void redo(); private: - bool old_project_changed; - Media* item; - QString from; - QString to; + bool old_project_changed; + Media* item; + QString from; + QString to; }; class KeyframeMove : public QUndoCommand { @@ -386,9 +390,9 @@ private: class SetAutoscaleAction : public QUndoCommand { public: SetAutoscaleAction(); - void undo(); - void redo(); - QVector clips; + void undo(); + void redo(); + QVector clips; private: bool old_project_changed; }; @@ -458,14 +462,14 @@ private: class SetSelectionsCommand : public QUndoCommand { public: - SetSelectionsCommand(Sequence *s); - void undo(); - void redo(); - QVector old_data; - QVector new_data; + SetSelectionsCommand(Sequence *s); + void undo(); + void redo(); + QVector old_data; + QVector new_data; private: - Sequence* seq; - bool done; + Sequence* seq; + bool done; bool old_project_changed; }; @@ -483,7 +487,7 @@ private: class EditSequenceCommand : public QUndoCommand { public: - EditSequenceCommand(Media *i, Sequence* s); + EditSequenceCommand(Media *i, Sequence* s); void undo(); void redo(); void update(); @@ -495,7 +499,7 @@ public: int audio_frequency; int audio_layout; private: - Media* item; + Media* item; Sequence* seq; bool old_project_changed; @@ -509,25 +513,25 @@ private: class SetInt : public QUndoCommand { public: - SetInt(int* pointer, int new_value); - void undo(); - void redo(); + SetInt(int* pointer, int new_value); + void undo(); + void redo(); private: - int* p; - int oldval; - int newval; + int* p; + int oldval; + int newval; bool old_project_changed; }; class SetString : public QUndoCommand { public: - SetString(QString* pointer, QString new_value); - void undo(); - void redo(); + SetString(QString* pointer, QString new_value); + void undo(); + void redo(); private: - QString* p; - QString oldval; - QString newval; + QString* p; + QString oldval; + QString newval; bool old_project_changed; }; @@ -539,11 +543,11 @@ public: class UpdateFootageTooltip : public QUndoCommand { public: - UpdateFootageTooltip(Media* i); + UpdateFootageTooltip(Media* i); void undo(); void redo(); private: - Media* item; + Media* item; }; class MoveEffectCommand : public QUndoCommand { @@ -585,20 +589,20 @@ private: class SetPointer : public QUndoCommand { public: - SetPointer(void** pointer, void* data); - void undo(); - void redo(); + SetPointer(void** pointer, void* data); + void undo(); + void redo(); private: - bool old_changed; - void** p; - void* new_data; - void* old_data; + bool old_changed; + void** p; + void* new_data; + void* old_data; }; class ReloadEffectsCommand : public QUndoCommand { public: - void undo(); - void redo(); + void undo(); + void redo(); }; #endif // UNDO_H diff --git a/ui/keyframeview.cpp b/ui/keyframeview.cpp index c46dcb0c2..914b979b3 100644 --- a/ui/keyframeview.cpp +++ b/ui/keyframeview.cpp @@ -11,7 +11,7 @@ #include "panels/viewer.h" #include "ui/viewerwidget.h" #include "project/sequence.h" -#include "ui_effectcontrols.h" +#include "ui/resizablescrollbar.h" #include #include @@ -27,44 +27,44 @@ long KeyframeView::adjust_row_keyframe(EffectRow* row, long time) { KeyframeView::KeyframeView(QWidget *parent) : QWidget(parent), - visible_in(0), - visible_out(0), + visible_in(0), + visible_out(0), mousedown(false), dragging(false), keys_selected(false), - select_rect(false), + select_rect(false), x_scroll(0), - y_scroll(0), - scroll_drag(false) + y_scroll(0), + scroll_drag(false) { setFocusPolicy(Qt::ClickFocus); setMouseTracking(true); - setContextMenuPolicy(Qt::CustomContextMenu); - connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu(const QPoint&))); + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu(const QPoint&))); } void KeyframeView::show_context_menu(const QPoint& pos) { - if (selected_rows.size() > 0) { - QMenu menu(this); - QAction* linear = menu.addAction("Linear"); - linear->setData(KEYFRAME_TYPE_LINEAR); - QAction* smooth = menu.addAction("Smooth"); - smooth->setData(KEYFRAME_TYPE_SMOOTH); - /*QAction* bezier = menu.addAction("Bezier"); - bezier->setData(KEYFRAME_TYPE_BEZIER);*/ - connect(&menu, SIGNAL(triggered(QAction*)), this, SLOT(menu_set_key_type(QAction*))); - menu.exec(mapToGlobal(pos)); - } + if (selected_rows.size() > 0) { + QMenu menu(this); + QAction* linear = menu.addAction("Linear"); + linear->setData(KEYFRAME_TYPE_LINEAR); + QAction* smooth = menu.addAction("Smooth"); + smooth->setData(KEYFRAME_TYPE_SMOOTH); + /*QAction* bezier = menu.addAction("Bezier"); + bezier->setData(KEYFRAME_TYPE_BEZIER);*/ + connect(&menu, SIGNAL(triggered(QAction*)), this, SLOT(menu_set_key_type(QAction*))); + menu.exec(mapToGlobal(pos)); + } } void KeyframeView::menu_set_key_type(QAction* a) { - ComboAction* ca = new ComboAction(); - for (int i=0;iappend(new SetInt(&selected_rows.at(i)->keyframe_types[selected_keyframes.at(i)], a->data().toInt())); - } - undo_stack.push(ca); - update(); + ComboAction* ca = new ComboAction(); + for (int i=0;iappend(new SetInt(&selected_rows.at(i)->keyframe_types[selected_keyframes.at(i)], a->data().toInt())); + } + undo_stack.push(ca); + update(); } void KeyframeView::paintEvent(QPaintEvent*) { @@ -99,7 +99,7 @@ void KeyframeView::paintEvent(QPaintEvent*) { bool keyframe_selected = keyframeIsSelected(row, k); long keyframe_frame = adjust_row_keyframe(row, row->keyframe_times.at(k)); if (dragging && keyframe_selected) keyframe_frame += frame_diff; - draw_keyframe(p, row->keyframe_types.at(k), getScreenPointFromFrame(panel_effect_controls->zoom, keyframe_frame) - x_scroll, keyframe_y, keyframe_selected); + draw_keyframe(p, row->keyframe_types.at(k), getScreenPointFromFrame(panel_effect_controls->zoom, keyframe_frame) - x_scroll, keyframe_y, keyframe_selected); } rows.append(row); @@ -113,7 +113,7 @@ void KeyframeView::paintEvent(QPaintEvent*) { if (max_width < width()) { p.fillRect(QRect(max_width, 0, width(), height()), QColor(0, 0, 0, 64)); } - panel_effect_controls->ui->horizontalScrollBar->setMaximum(qMax(max_width - width(), 0)); + panel_effect_controls->horizontalScrollBar->setMaximum(qMax(max_width - width(), 0)); header->set_visible_in(visible_in); int playhead_x = getScreenPointFromFrame(panel_effect_controls->zoom, sequence->playhead-visible_in) - x_scroll; @@ -129,9 +129,9 @@ void KeyframeView::paintEvent(QPaintEvent*) { draw_selection_rectangle(p, QRect(rect_select_x, rect_select_y, rect_select_w, rect_select_h)); } - /*if (mouseover && mouseover_row < rowY.size()) { + /*if (mouseover && mouseover_row < rowY.size()) { draw_keyframe(p, getScreenPointFromFrame(panel_effect_controls->zoom, mouseover_frame - visible_in), rowY.at(mouseover_row), true); - }*/ + }*/ } bool KeyframeView::keyframeIsSelected(EffectRow *row, int keyframe) { @@ -173,98 +173,98 @@ void KeyframeView::set_y_scroll(int s) { } void KeyframeView::draw_keyframe(QPainter &p, int type, int x, int y, bool darker) { - int color = (darker) ? 100 : 160; - p.setPen(QColor(0, 0, 0)); - p.setBrush(QColor(color, color, color)); + int color = (darker) ? 100 : 160; + p.setPen(QColor(0, 0, 0)); + p.setBrush(QColor(color, color, color)); - switch (type) { - case KEYFRAME_TYPE_LINEAR: - { - QPoint points[KEYFRAME_POINT_COUNT] = {QPoint(x-KEYFRAME_SIZE, y), QPoint(x, y-KEYFRAME_SIZE), QPoint(x+KEYFRAME_SIZE, y), QPoint(x, y+KEYFRAME_SIZE)}; - p.drawPolygon(points, KEYFRAME_POINT_COUNT); - } - break; - case KEYFRAME_TYPE_SMOOTH: - p.drawEllipse(QPoint(x, y), KEYFRAME_SIZE, KEYFRAME_SIZE); - break; - } + switch (type) { + case KEYFRAME_TYPE_LINEAR: + { + QPoint points[KEYFRAME_POINT_COUNT] = {QPoint(x-KEYFRAME_SIZE, y), QPoint(x, y-KEYFRAME_SIZE), QPoint(x+KEYFRAME_SIZE, y), QPoint(x, y+KEYFRAME_SIZE)}; + p.drawPolygon(points, KEYFRAME_POINT_COUNT); + } + break; + case KEYFRAME_TYPE_SMOOTH: + p.drawEllipse(QPoint(x, y), KEYFRAME_SIZE, KEYFRAME_SIZE); + break; + } } void KeyframeView::resize_move(double d) { - header->update_zoom(header->get_zoom()*d); + header->update_zoom(header->get_zoom()*d); } void KeyframeView::mousePressEvent(QMouseEvent *event) { - rect_select_x = event->x(); - rect_select_y = event->y(); + rect_select_x = event->x(); + rect_select_y = event->y(); - if (panel_timeline->tool == TIMELINE_TOOL_HAND || event->buttons() & Qt::MiddleButton) { - scroll_drag = true; - return; - } + if (panel_timeline->tool == TIMELINE_TOOL_HAND || event->buttons() & Qt::MiddleButton) { + scroll_drag = true; + return; + } - int mouse_x = event->x() + x_scroll; - int mouse_y = event->y(); - int row_index = -1; - int keyframe_index = -1; - long frame_diff = 0; - long frame_min = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x-KEYFRAME_SIZE); - drag_frame_start = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x); - long frame_max = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x+KEYFRAME_SIZE); - for (int i=0;i rowY.at(i)-KEYFRAME_SIZE-KEYFRAME_SIZE && mouse_y < rowY.at(i)+KEYFRAME_SIZE+KEYFRAME_SIZE) { - EffectRow* row = rows.at(i); - for (int j=0;jkeyframe_times.size();j++) { - long eval_keyframe_time = row->keyframe_times.at(j)-row->parent_effect->parent_clip->clip_in+(row->parent_effect->parent_clip->timeline_in-visible_in); - if (eval_keyframe_time >= frame_min && eval_keyframe_time <= frame_max) { - long eval_frame_diff = qAbs(eval_keyframe_time - drag_frame_start); - if (keyframe_index == -1 || eval_frame_diff < frame_diff) { - row_index = i; - keyframe_index = j; - frame_diff = eval_frame_diff; - } - } - } - break; - } - } - bool already_selected = false; - keys_selected = false; - if (keyframe_index > -1) already_selected = keyframeIsSelected(rows.at(row_index), keyframe_index); - if (!already_selected) { - if (!(event->modifiers() & Qt::ShiftModifier)) { - selected_rows.clear(); - selected_keyframes.clear(); - } - if (keyframe_index > -1) { - selected_rows.append(rows.at(row_index)); - selected_keyframes.append(keyframe_index); - } - } + int mouse_x = event->x() + x_scroll; + int mouse_y = event->y(); + int row_index = -1; + int keyframe_index = -1; + long frame_diff = 0; + long frame_min = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x-KEYFRAME_SIZE); + drag_frame_start = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x); + long frame_max = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x+KEYFRAME_SIZE); + for (int i=0;i rowY.at(i)-KEYFRAME_SIZE-KEYFRAME_SIZE && mouse_y < rowY.at(i)+KEYFRAME_SIZE+KEYFRAME_SIZE) { + EffectRow* row = rows.at(i); + for (int j=0;jkeyframe_times.size();j++) { + long eval_keyframe_time = row->keyframe_times.at(j)-row->parent_effect->parent_clip->clip_in+(row->parent_effect->parent_clip->timeline_in-visible_in); + if (eval_keyframe_time >= frame_min && eval_keyframe_time <= frame_max) { + long eval_frame_diff = qAbs(eval_keyframe_time - drag_frame_start); + if (keyframe_index == -1 || eval_frame_diff < frame_diff) { + row_index = i; + keyframe_index = j; + frame_diff = eval_frame_diff; + } + } + } + break; + } + } + bool already_selected = false; + keys_selected = false; + if (keyframe_index > -1) already_selected = keyframeIsSelected(rows.at(row_index), keyframe_index); + if (!already_selected) { + if (!(event->modifiers() & Qt::ShiftModifier)) { + selected_rows.clear(); + selected_keyframes.clear(); + } + if (keyframe_index > -1) { + selected_rows.append(rows.at(row_index)); + selected_keyframes.append(keyframe_index); + } + } - if (selected_rows.size() > 0) { - keys_selected = true; - } + if (selected_rows.size() > 0) { + keys_selected = true; + } - update(); + update(); - if (event->button() == Qt::LeftButton) { - mousedown = true; - } + if (event->button() == Qt::LeftButton) { + mousedown = true; + } } void KeyframeView::mouseMoveEvent(QMouseEvent* event) { - if (panel_timeline->tool == TIMELINE_TOOL_HAND) { - setCursor(Qt::OpenHandCursor); - } else { - unsetCursor(); - } - if (scroll_drag) { - panel_effect_controls->ui->horizontalScrollBar->setValue(panel_effect_controls->ui->horizontalScrollBar->value() + rect_select_x - event->pos().x()); - panel_effect_controls->ui->verticalScrollBar->setValue(panel_effect_controls->ui->verticalScrollBar->value() + rect_select_y - event->pos().y()); - rect_select_x = event->pos().x(); - rect_select_y = event->pos().y(); - } else if (mousedown) { + if (panel_timeline->tool == TIMELINE_TOOL_HAND) { + setCursor(Qt::OpenHandCursor); + } else { + unsetCursor(); + } + if (scroll_drag) { + panel_effect_controls->horizontalScrollBar->setValue(panel_effect_controls->horizontalScrollBar->value() + rect_select_x - event->pos().x()); + panel_effect_controls->verticalScrollBar->setValue(panel_effect_controls->verticalScrollBar->value() + rect_select_y - event->pos().y()); + rect_select_x = event->pos().x(); + rect_select_y = event->pos().y(); + } else if (mousedown) { int mouse_x = event->x() + x_scroll; if (keys_selected) { // move keyframes @@ -333,7 +333,7 @@ void KeyframeView::mouseMoveEvent(QMouseEvent* event) { select_rect = true; } update(); - } + } } void KeyframeView::mouseReleaseEvent(QMouseEvent*) { @@ -347,8 +347,8 @@ void KeyframeView::mouseReleaseEvent(QMouseEvent*) { select_rect = false; dragging = false; - mousedown = false; - scroll_drag = false; + mousedown = false; + scroll_drag = false; panel_timeline->snapped = false; update(); } diff --git a/ui/resizablescrollbar.cpp b/ui/resizablescrollbar.cpp index 0bde2cfeb..f08bba77e 100644 --- a/ui/resizablescrollbar.cpp +++ b/ui/resizablescrollbar.cpp @@ -9,96 +9,98 @@ #define RESIZE_HANDLE_SIZE 10 ResizableScrollBar::ResizableScrollBar(QWidget *parent) : - QScrollBar(parent), - resize_init(false), - resize_proc(false) + QScrollBar(parent), + resize_init(false), + resize_proc(false) { - setMouseTracking(true); + setSingleStep(20); + setMaximum(0); + setMouseTracking(true); } bool ResizableScrollBar::is_resizing() { - return resize_proc; + return resize_proc; } void ResizableScrollBar::resizeEvent(QResizeEvent *event) { - setPageStep(event->size().width()); + setPageStep(event->size().width()); } void ResizableScrollBar::mousePressEvent(QMouseEvent *e) { - if (resize_init) { - QStyleOptionSlider opt; - initStyleOption(&opt); + if (resize_init) { + QStyleOptionSlider opt; + initStyleOption(&opt); - QRect sr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, - QStyle::SC_ScrollBarSlider, this); + QRect sr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, + QStyle::SC_ScrollBarSlider, this); - resize_proc = true; - resize_start = e->pos().x(); + resize_proc = true; + resize_start = e->pos().x(); - resize_start_max = maximum(); - resize_start_width = sr.width(); - } else { - QScrollBar::mousePressEvent(e); - } + resize_start_max = maximum(); + resize_start_width = sr.width(); + } else { + QScrollBar::mousePressEvent(e); + } } void ResizableScrollBar::mouseMoveEvent(QMouseEvent *e) { - QStyleOptionSlider opt; - initStyleOption(&opt); + QStyleOptionSlider opt; + initStyleOption(&opt); - QRect sr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, - QStyle::SC_ScrollBarSlider, this); - QRect gr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, - QStyle::SC_ScrollBarGroove, this); + QRect sr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, + QStyle::SC_ScrollBarSlider, this); + QRect gr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, + QStyle::SC_ScrollBarGroove, this); - if (resize_proc) { - int diff = (e->pos().x() - resize_start); - if (resize_top) diff = -diff; - double scale = double(sr.width())/double(sr.width()+diff); - if (!qIsInf(scale) && !qIsNull(scale)) { - emit resize_move(scale); - resize_start = e->pos().x(); + if (resize_proc) { + int diff = (e->pos().x() - resize_start); + if (resize_top) diff = -diff; + double scale = double(sr.width())/double(sr.width()+diff); + if (!qIsInf(scale) && !qIsNull(scale)) { + emit resize_move(scale); + resize_start = e->pos().x(); - if (resize_top) { - int slider_min = gr.x(); - int slider_max = gr.right() - (sr.width()+diff); - int val = QStyle::sliderValueFromPosition(minimum(), maximum(), e->pos().x() - slider_min, slider_max - slider_min, opt.upsideDown); + if (resize_top) { + int slider_min = gr.x(); + int slider_max = gr.right() - (sr.width()+diff); + int val = QStyle::sliderValueFromPosition(minimum(), maximum(), e->pos().x() - slider_min, slider_max - slider_min, opt.upsideDown); - setValue(val); - } else { - setValue(qRound(value() * scale)); - } - } - } else { - bool new_resize_init = false; + setValue(val); + } else { + setValue(qRound(value() * scale)); + } + } + } else { + bool new_resize_init = false; - if ((orientation() == Qt::Horizontal && e->pos().x() > sr.left()-RESIZE_HANDLE_SIZE && e->pos().x() < sr.left()+RESIZE_HANDLE_SIZE) - || (orientation() == Qt::Vertical && e->pos().y() > sr.top()-RESIZE_HANDLE_SIZE && e->pos().y() < sr.top()+RESIZE_HANDLE_SIZE)) { - new_resize_init = true; - resize_top = true; - } else if ((orientation() == Qt::Horizontal && e->pos().x() > sr.right()-RESIZE_HANDLE_SIZE && e->pos().x() < sr.right()+RESIZE_HANDLE_SIZE) - || (orientation() == Qt::Vertical && e->pos().y() > sr.bottom()-RESIZE_HANDLE_SIZE && e->pos().y() < sr.bottom()+RESIZE_HANDLE_SIZE)) { - new_resize_init = true; - resize_top = false; - } + if ((orientation() == Qt::Horizontal && e->pos().x() > sr.left()-RESIZE_HANDLE_SIZE && e->pos().x() < sr.left()+RESIZE_HANDLE_SIZE) + || (orientation() == Qt::Vertical && e->pos().y() > sr.top()-RESIZE_HANDLE_SIZE && e->pos().y() < sr.top()+RESIZE_HANDLE_SIZE)) { + new_resize_init = true; + resize_top = true; + } else if ((orientation() == Qt::Horizontal && e->pos().x() > sr.right()-RESIZE_HANDLE_SIZE && e->pos().x() < sr.right()+RESIZE_HANDLE_SIZE) + || (orientation() == Qt::Vertical && e->pos().y() > sr.bottom()-RESIZE_HANDLE_SIZE && e->pos().y() < sr.bottom()+RESIZE_HANDLE_SIZE)) { + new_resize_init = true; + resize_top = false; + } - if (resize_init != new_resize_init) { - if (new_resize_init) { - setCursor(Qt::SizeHorCursor); - } else { - unsetCursor(); - } - resize_init = new_resize_init; - } + if (resize_init != new_resize_init) { + if (new_resize_init) { + setCursor(Qt::SizeHorCursor); + } else { + unsetCursor(); + } + resize_init = new_resize_init; + } - QScrollBar::mouseMoveEvent(e); - } + QScrollBar::mouseMoveEvent(e); + } } void ResizableScrollBar::mouseReleaseEvent(QMouseEvent *e) { - if (resize_proc) { - resize_proc = false; - } else { - QScrollBar::mouseReleaseEvent(e); - } + if (resize_proc) { + resize_proc = false; + } else { + QScrollBar::mouseReleaseEvent(e); + } } diff --git a/ui/sourceiconview.cpp b/ui/sourceiconview.cpp index 9617adc24..83aed6176 100644 --- a/ui/sourceiconview.cpp +++ b/ui/sourceiconview.cpp @@ -8,60 +8,62 @@ #include "debug.h" SourceIconView::SourceIconView(QWidget *parent) : QListView(parent) { - setContextMenuPolicy(Qt::CustomContextMenu); - connect(this, SIGNAL(clicked(const QModelIndex&)), this, SLOT(item_click(const QModelIndex&))); - connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu())); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setResizeMode(QListView::Adjust); + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(clicked(const QModelIndex&)), this, SLOT(item_click(const QModelIndex&))); + connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu())); } void SourceIconView::show_context_menu() { - project_parent->sources_common->show_context_menu(this, selectedIndexes()); + project_parent->sources_common->show_context_menu(this, selectedIndexes()); } void SourceIconView::item_click(const QModelIndex& index) { - if (selectionModel()->selectedRows().size() == 1 && index.column() == 0) { - project_parent->sources_common->item_click(project_parent->item_to_media(index), index); - } + if (selectedIndexes().size() == 1 && index.column() == 0) { + project_parent->sources_common->item_click(project_parent->item_to_media(index), index); + } } void SourceIconView::mousePressEvent(QMouseEvent* event) { - project_parent->sources_common->mousePressEvent(event); - if (!indexAt(event->pos()).isValid()) selectionModel()->clear(); - QListView::mousePressEvent(event); + project_parent->sources_common->mousePressEvent(event); + if (!indexAt(event->pos()).isValid()) selectionModel()->clear(); + QListView::mousePressEvent(event); } void SourceIconView::dragEnterEvent(QDragEnterEvent *event) { - if (event->mimeData()->hasUrls()) { - event->acceptProposedAction(); - } else { - QListView::dragEnterEvent(event); - } + if (event->mimeData()->hasUrls()) { + event->acceptProposedAction(); + } else { + QListView::dragEnterEvent(event); + } } void SourceIconView::dragMoveEvent(QDragMoveEvent *event) { - if (event->mimeData()->hasUrls()) { - event->acceptProposedAction(); - } else { - QListView::dragMoveEvent(event); - } + if (event->mimeData()->hasUrls()) { + event->acceptProposedAction(); + } else { + QListView::dragMoveEvent(event); + } } void SourceIconView::dropEvent(QDropEvent* event) { - QModelIndex drop_item = indexAt(event->pos()); - if (!drop_item.isValid()) drop_item = rootIndex(); - project_parent->sources_common->dropEvent(this, event, drop_item, selectedIndexes()); + QModelIndex drop_item = indexAt(event->pos()); + if (!drop_item.isValid()) drop_item = rootIndex(); + project_parent->sources_common->dropEvent(this, event, drop_item, selectedIndexes()); } void SourceIconView::mouseDoubleClickEvent(QMouseEvent *event) { - bool default_behavior = true; - if (selectedIndexes().size() == 1) { - Media* m = project_parent->item_to_media(selectedIndexes().at(0)); - if (m->get_type() == MEDIA_TYPE_FOLDER) { - default_behavior = false; - setRootIndex(selectedIndexes().at(0)); - emit changed_root(); - } - } - if (default_behavior) { - project_parent->sources_common->mouseDoubleClickEvent(event, selectedIndexes()); - } + bool default_behavior = true; + if (selectedIndexes().size() == 1) { + Media* m = project_parent->item_to_media(selectedIndexes().at(0)); + if (m->get_type() == MEDIA_TYPE_FOLDER) { + default_behavior = false; + setRootIndex(selectedIndexes().at(0)); + emit changed_root(); + } + } + if (default_behavior) { + project_parent->sources_common->mouseDoubleClickEvent(event, selectedIndexes()); + } } diff --git a/ui/sourcetable.cpp b/ui/sourcetable.cpp index 75586e8b4..d439c0f04 100644 --- a/ui/sourcetable.cpp +++ b/ui/sourcetable.cpp @@ -27,47 +27,51 @@ SourceTable::SourceTable(QWidget* parent) : QTreeView(parent) { setSortingEnabled(true); - sortByColumn(0, Qt::AscendingOrder); - setContextMenuPolicy(Qt::CustomContextMenu); - connect(this, SIGNAL(clicked(const QModelIndex&)), this, SLOT(item_click(const QModelIndex&))); - connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu())); + setAcceptDrops(true); + sortByColumn(0, Qt::AscendingOrder); + setContextMenuPolicy(Qt::CustomContextMenu); + setEditTriggers(QAbstractItemView::NoEditTriggers); + setDragDropMode(QAbstractItemView::DragDrop); + setSelectionMode(QAbstractItemView::ExtendedSelection); + connect(this, SIGNAL(clicked(const QModelIndex&)), this, SLOT(item_click(const QModelIndex&))); + connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu())); } void SourceTable::show_context_menu() { - project_parent->sources_common->show_context_menu(this, selectionModel()->selectedRows()); + project_parent->sources_common->show_context_menu(this, selectionModel()->selectedRows()); } void SourceTable::item_click(const QModelIndex& index) { - if (selectionModel()->selectedRows().size() == 1 && index.column() == 0) { - project_parent->sources_common->item_click(project_parent->item_to_media(index), index); - } + if (selectionModel()->selectedRows().size() == 1 && index.column() == 0) { + project_parent->sources_common->item_click(project_parent->item_to_media(index), index); + } } void SourceTable::mousePressEvent(QMouseEvent* event) { - project_parent->sources_common->mousePressEvent(event); - QTreeView::mousePressEvent(event); + project_parent->sources_common->mousePressEvent(event); + QTreeView::mousePressEvent(event); } void SourceTable::mouseDoubleClickEvent(QMouseEvent* event) { - project_parent->sources_common->mouseDoubleClickEvent(event, selectionModel()->selectedRows()); + project_parent->sources_common->mouseDoubleClickEvent(event, selectionModel()->selectedRows()); } void SourceTable::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasUrls()) { - event->acceptProposedAction(); - } else { - QTreeView::dragEnterEvent(event); - } + event->acceptProposedAction(); + } else { + QTreeView::dragEnterEvent(event); + } } void SourceTable::dragMoveEvent(QDragMoveEvent *event) { - if (event->mimeData()->hasUrls()) { - event->acceptProposedAction(); - } else { - QTreeView::dragMoveEvent(event); - } + if (event->mimeData()->hasUrls()) { + event->acceptProposedAction(); + } else { + QTreeView::dragMoveEvent(event); + } } void SourceTable::dropEvent(QDropEvent* event) { - project_parent->sources_common->dropEvent(this, event, indexAt(event->pos()), selectionModel()->selectedRows()); + project_parent->sources_common->dropEvent(this, event, indexAt(event->pos()), selectionModel()->selectedRows()); } diff --git a/ui/timelineheader.cpp b/ui/timelineheader.cpp index b4269eb3a..7ea79ac2c 100644 --- a/ui/timelineheader.cpp +++ b/ui/timelineheader.cpp @@ -23,34 +23,34 @@ #define MARKER_SIZE 4 bool center_scroll_to_playhead(QScrollBar* bar, double zoom, long playhead) { - // returns true is the scroll was changed, false if not - int target_scroll = qMin(bar->maximum(), qMax(0, getScreenPointFromFrame(zoom, playhead)-(bar->width()>>1))); - if (target_scroll == bar->value()) { - return false; - } - bar->setValue(target_scroll); - return true; + // returns true is the scroll was changed, false if not + int target_scroll = qMin(bar->maximum(), qMax(0, getScreenPointFromFrame(zoom, playhead)-(bar->width()>>1))); + if (target_scroll == bar->value()) { + return false; + } + bar->setValue(target_scroll); + return true; } TimelineHeader::TimelineHeader(QWidget *parent) : QWidget(parent), - snapping(true), + snapping(true), dragging(false), resizing_workarea(false), zoom(1), - in_visible(0), + in_visible(0), fm(font()), dragging_markers(false), scroll(0) { height_actual = fm.height(); - setCursor(Qt::ArrowCursor); - setMouseTracking(true); + setCursor(Qt::ArrowCursor); + setMouseTracking(true); setFocusPolicy(Qt::ClickFocus); show_text(true); - setContextMenuPolicy(Qt::CustomContextMenu); - connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(show_context_menu(const QPoint &))); + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(show_context_menu(const QPoint &))); } void TimelineHeader::set_scroll(int s) { @@ -81,11 +81,11 @@ void TimelineHeader::set_visible_in(long i) { void TimelineHeader::set_in_point(long new_in) { long new_out = viewer->seq->workarea_out; - if (new_out == new_in) { - new_in--; - } else if (new_out < new_in) { + if (new_out == new_in) { + new_in--; + } else if (new_out < new_in) { new_out = viewer->seq->getEndFrame(); - } + } undo_stack.push(new SetTimelineInOutCommand(viewer->seq, true, new_in, new_out)); update_parents(); @@ -93,18 +93,18 @@ void TimelineHeader::set_in_point(long new_in) { void TimelineHeader::set_out_point(long new_out) { long new_in = viewer->seq->workarea_in; - if (new_out == new_in) { - new_out++; - } else if (new_in > new_out || new_in < 0) { - new_in = 0; - } + if (new_out == new_in) { + new_out++; + } else if (new_in > new_out || new_in < 0) { + new_in = 0; + } undo_stack.push(new SetTimelineInOutCommand(viewer->seq, true, new_in, new_out)); update_parents(); } void TimelineHeader::set_scrollbar_max(QScrollBar* bar, long sequence_end_frame, int offset) { - bar->setMaximum(qMax(0, getScreenPointFromFrame(zoom, sequence_end_frame) - offset)); + bar->setMaximum(qMax(0, getScreenPointFromFrame(zoom, sequence_end_frame) - offset)); } void TimelineHeader::show_text(bool enable) { @@ -118,7 +118,7 @@ void TimelineHeader::show_text(bool enable) { } void TimelineHeader::mousePressEvent(QMouseEvent* event) { - if (viewer->seq != NULL) { + if (viewer->seq != NULL && event->buttons() & Qt::LeftButton) { if (resizing_workarea) { sequence_end = viewer->seq->getEndFrame(); } else { @@ -275,11 +275,11 @@ void TimelineHeader::update_parents() { void TimelineHeader::update_zoom(double z) { zoom = z; - update(); + update(); } double TimelineHeader::get_zoom() { - return zoom; + return zoom; } void TimelineHeader::delete_markers() { @@ -295,72 +295,83 @@ void TimelineHeader::delete_markers() { void TimelineHeader::paintEvent(QPaintEvent*) { if (viewer->seq != NULL && zoom > 0) { - QPainter p(this); + QPainter p(this); int yoff = (text_enabled) ? height()/2 : 0; double interval = viewer->seq->frame_rate; - int textWidth = 0; + int textWidth = 0; int lastTextBoundary = INT_MIN; - int i = 0; + int i = 0; int lastLineX = INT_MIN; - int sublineCount = 1; - int sublineTest = qRound(interval*zoom); - int sublineInterval = 1; + int sublineCount = 1; + int sublineTest = qRound(interval*zoom); + int sublineInterval = 1; while (sublineTest > SUBLINE_MIN_PADDING - && sublineInterval >= 1) { - sublineCount *= 2; - sublineInterval = (interval/sublineCount); - sublineTest = qRound(sublineInterval*zoom); - } - sublineCount = qMin(sublineCount, qRound(interval)); + && sublineInterval >= 1) { + sublineCount *= 2; + sublineInterval = (interval/sublineCount); + sublineTest = qRound(sublineInterval*zoom); + } + sublineCount = qMin(sublineCount, qRound(interval)); - while (true) { - long frame = qRound(interval*i); + int text_x, fullTextWidth; + QString timecode; + + while (true) { + long frame = qRound(interval*i); int lineX = qRound(frame*zoom) - scroll; int next_lineX = qRound(qRound(interval*(i+1))*zoom) - scroll; - if (lineX > width()) break; - if (next_lineX > 0 && lineX > lastLineX+LINE_MIN_PADDING) { - // draw text - if (text_enabled && lineX-textWidth > lastTextBoundary) { + if (lineX > width()) break; + + // draw text + bool draw_text = false; + if (text_enabled && lineX-textWidth > lastTextBoundary) { + timecode = frame_to_timecode(frame + in_visible, config.timecode_view, viewer->seq->frame_rate); + fullTextWidth = fm.width(timecode); + textWidth = fullTextWidth>>1; + text_x = lineX-textWidth; + lastTextBoundary = lineX+textWidth; + if (lastTextBoundary >= 0) { + draw_text = true; + } + } + + if (lineX > lastLineX+LINE_MIN_PADDING) { + if (draw_text) { p.setPen(Qt::white); - QString timecode = frame_to_timecode(frame + in_visible, config.timecode_view, viewer->seq->frame_rate); - int fullTextWidth = fm.width(timecode); - textWidth = fullTextWidth>>1; - int text_x = lineX-textWidth; - lastTextBoundary = lineX+textWidth; - if (lastTextBoundary >= 0) { - p.drawText(QRect(text_x, 0, fullTextWidth, yoff), timecode); - } + p.drawText(QRect(text_x, 0, fullTextWidth, yoff), timecode); } // draw line markers p.setPen(Qt::gray); p.drawLine(lineX, yoff, lineX, height()); - lastLineX = lineX; - // draw sub-line markers for (int j=1;jseq->using_workarea) { in_x = getHeaderScreenPointFromFrame((resizing_workarea ? temp_workarea_in : viewer->seq->workarea_in)); int out_x = getHeaderScreenPointFromFrame((resizing_workarea ? temp_workarea_out : viewer->seq->workarea_out)); - p.fillRect(QRect(in_x, 0, out_x-in_x, height()), QColor(0, 192, 255, 128)); - p.setPen(Qt::white); - p.drawLine(in_x, 0, in_x, height()); - p.drawLine(out_x, 0, out_x, height()); - } + p.fillRect(QRect(in_x, 0, out_x-in_x, height()), QColor(0, 192, 255, 128)); + p.setPen(Qt::white); + p.drawLine(in_x, 0, in_x, height()); + p.drawLine(out_x, 0, out_x, height()); + } // draw markers for (int i=0;iseq->markers.size();i++) { @@ -389,30 +400,28 @@ void TimelineHeader::paintEvent(QPaintEvent*) { p.drawPolygon(points, 5); } - // draw playhead triangle - p.setRenderHint(QPainter::Antialiasing); + // draw playhead triangle + p.setRenderHint(QPainter::Antialiasing); - in_x = getHeaderScreenPointFromFrame(viewer->seq->playhead); - QPoint start(in_x, height()+2); - QPainterPath path; - path.moveTo(start + QPoint(1,0)); - path.lineTo(in_x-PLAYHEAD_SIZE, yoff); - path.lineTo(in_x+PLAYHEAD_SIZE+1, yoff); - path.lineTo(start); - p.fillPath(path, Qt::red); + in_x = getHeaderScreenPointFromFrame(viewer->seq->playhead); + QPoint start(in_x, height()+2); + QPainterPath path; + path.moveTo(start + QPoint(1,0)); + path.lineTo(in_x-PLAYHEAD_SIZE, yoff); + path.lineTo(in_x+PLAYHEAD_SIZE+1, yoff); + path.lineTo(start); + p.fillPath(path, Qt::red); } } void TimelineHeader::show_context_menu(const QPoint &pos) { - QMenu contextMenu(tr("Context menu"), this); + QMenu menu(this); - QAction clear_in_out("Clear In/Out Points", this); - if (!viewer->seq->using_workarea) clear_in_out.setEnabled(false); - connect(&clear_in_out, SIGNAL(triggered()), mainWindow, SLOT(on_actionClear_In_Out_triggered())); - contextMenu.addAction(&clear_in_out); - contextMenu.exec(mapToGlobal(pos)); + mainWindow->make_inout_menu(&menu); + + menu.exec(mapToGlobal(pos)); } void TimelineHeader::resized_scroll_listener(double d) { - update_zoom(zoom * d); + update_zoom(zoom * d); } diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index 7a8ee4fbe..da2d3b738 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -14,11 +14,13 @@ #include "panels/effectcontrols.h" #include "panels/viewer.h" #include "project/undo.h" -#include "ui_timeline.h" #include "mainwindow.h" #include "ui/viewerwidget.h" #include "dialogs/stabilizerdialog.h" #include "project/media.h" +#include "ui/resizablescrollbar.h" +#include "dialogs/newsequencedialog.h" +#include "mainwindow.h" #include "debug.h" #include "project/effect.h" @@ -39,26 +41,27 @@ #include #include #include +#include #define MAX_TEXT_WIDTH 20 #define TRANSITION_BETWEEN_RANGE 40 TimelineWidget::TimelineWidget(QWidget *parent) : QWidget(parent) { - selection_command = NULL; + selection_command = NULL; self_created_sequence = NULL; scroll = 0; bottom_align = false; - track_resizing = false; - setMouseTracking(true); + track_resizing = false; + setMouseTracking(true); - setAcceptDrops(true); + setAcceptDrops(true); - setContextMenuPolicy(Qt::CustomContextMenu); - connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu(const QPoint&))); + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu(const QPoint&))); - tooltip_timer.setInterval(500); - connect(&tooltip_timer, SIGNAL(timeout()), this, SLOT(tooltip_timer_timeout())); + tooltip_timer.setInterval(500); + connect(&tooltip_timer, SIGNAL(timeout()), this, SLOT(tooltip_timer_timeout())); } void TimelineWidget::right_click_ripple() { @@ -75,143 +78,144 @@ void TimelineWidget::right_click_ripple() { } void TimelineWidget::show_context_menu(const QPoint& pos) { - if (sequence != NULL) { - // hack because sometimes right clicking doesn't trigger mouse release event - panel_timeline->rect_select_init = false; - panel_timeline->rect_select_proc = false; + if (sequence != NULL) { + // hack because sometimes right clicking doesn't trigger mouse release event + panel_timeline->rect_select_init = false; + panel_timeline->rect_select_proc = false; - QMenu menu(this); + QMenu menu(this); - QAction* undoAction = menu.addAction("&Undo"); - QAction* redoAction = menu.addAction("&Redo"); - connect(undoAction, SIGNAL(triggered(bool)), mainWindow, SLOT(undo())); - connect(redoAction, SIGNAL(triggered(bool)), mainWindow, SLOT(redo())); - undoAction->setEnabled(undo_stack.canUndo()); - redoAction->setEnabled(undo_stack.canRedo()); - menu.addSeparator(); + QAction* undoAction = menu.addAction("&Undo"); + QAction* redoAction = menu.addAction("&Redo"); + connect(undoAction, SIGNAL(triggered(bool)), mainWindow, SLOT(undo())); + connect(redoAction, SIGNAL(triggered(bool)), mainWindow, SLOT(redo())); + undoAction->setEnabled(undo_stack.canUndo()); + redoAction->setEnabled(undo_stack.canRedo()); + menu.addSeparator(); - // collect all the selected clips - QVector selected_clips; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL && panel_timeline->is_clip_selected(c, true)) { - selected_clips.append(c); - } - } + // collect all the selected clips + QVector selected_clips; + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL && panel_timeline->is_clip_selected(c, true)) { + selected_clips.append(c); + } + } - if (selected_clips.isEmpty()) { - // no clips are selected - panel_timeline->cursor_frame = panel_timeline->getTimelineFrameFromScreenPoint(pos.x()); - panel_timeline->cursor_track = getTrackFromScreenPoint(pos.y()); + if (selected_clips.isEmpty()) { + // no clips are selected + panel_timeline->cursor_frame = panel_timeline->getTimelineFrameFromScreenPoint(pos.x()); + panel_timeline->cursor_track = getTrackFromScreenPoint(pos.y()); - bool can_ripple_delete = true; - bool at_end_of_sequence = true; - rc_ripple_min = 0; - rc_ripple_max = LONG_MAX; + bool can_ripple_delete = true; + bool at_end_of_sequence = true; + rc_ripple_min = 0; + rc_ripple_max = LONG_MAX; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL) { - if (c->timeline_in > panel_timeline->cursor_frame || c->timeline_out > panel_timeline->cursor_frame) { - at_end_of_sequence = false; - } - if (c->track == panel_timeline->cursor_track) { - if (c->timeline_in <= panel_timeline->cursor_frame && c->timeline_out >= panel_timeline->cursor_frame) { - can_ripple_delete = false; - break; - } else if (c->timeline_out < panel_timeline->cursor_frame) { - rc_ripple_min = qMax(rc_ripple_min, c->timeline_out); - } else if (c->timeline_in > panel_timeline->cursor_frame) { - rc_ripple_max = qMin(rc_ripple_max, c->timeline_in); - } - } - } - } + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL) { + if (c->timeline_in > panel_timeline->cursor_frame || c->timeline_out > panel_timeline->cursor_frame) { + at_end_of_sequence = false; + } + if (c->track == panel_timeline->cursor_track) { + if (c->timeline_in <= panel_timeline->cursor_frame && c->timeline_out >= panel_timeline->cursor_frame) { + can_ripple_delete = false; + break; + } else if (c->timeline_out < panel_timeline->cursor_frame) { + rc_ripple_min = qMax(rc_ripple_min, c->timeline_out); + } else if (c->timeline_in > panel_timeline->cursor_frame) { + rc_ripple_max = qMin(rc_ripple_max, c->timeline_in); + } + } + } + } - if (can_ripple_delete && !at_end_of_sequence) { - QAction* ripple_delete_action = menu.addAction("R&ipple Delete"); - connect(ripple_delete_action, SIGNAL(triggered(bool)), this, SLOT(right_click_ripple())); - } + if (can_ripple_delete && !at_end_of_sequence) { + QAction* ripple_delete_action = menu.addAction("R&ipple Delete"); + connect(ripple_delete_action, SIGNAL(triggered(bool)), this, SLOT(right_click_ripple())); + } - menu.addAction("Sequence settings coming soon..."); - } else { - // clips are selected - QAction* cutAction = menu.addAction("C&ut"); - connect(cutAction, SIGNAL(triggered(bool)), mainWindow, SLOT(cut())); - QAction* copyAction = menu.addAction("Cop&y"); - connect(copyAction, SIGNAL(triggered(bool)), mainWindow, SLOT(copy())); - QAction* pasteAction = menu.addAction("&Paste"); - connect(pasteAction, SIGNAL(triggered(bool)), mainWindow, SLOT(paste())); - menu.addSeparator(); - QAction* speedAction = menu.addAction("&Speed/Duration"); - connect(speedAction, SIGNAL(triggered(bool)), mainWindow, SLOT(openSpeedDialog())); - QAction* autoscaleAction = menu.addAction("Auto-s&cale"); - autoscaleAction->setCheckable(true); - connect(autoscaleAction, SIGNAL(triggered(bool)), this, SLOT(toggle_autoscale())); + QAction* seq_settings = menu.addAction("Sequence Settings"); + connect(seq_settings, SIGNAL(triggered(bool)), this, SLOT(open_sequence_properties())); + } else { + // clips are selected + QAction* cutAction = menu.addAction("C&ut"); + connect(cutAction, SIGNAL(triggered(bool)), mainWindow, SLOT(cut())); + QAction* copyAction = menu.addAction("Cop&y"); + connect(copyAction, SIGNAL(triggered(bool)), mainWindow, SLOT(copy())); + QAction* pasteAction = menu.addAction("&Paste"); + connect(pasteAction, SIGNAL(triggered(bool)), mainWindow, SLOT(paste())); + menu.addSeparator(); + QAction* speedAction = menu.addAction("&Speed/Duration"); + connect(speedAction, SIGNAL(triggered(bool)), mainWindow, SLOT(open_speed_dialog())); + QAction* autoscaleAction = menu.addAction("Auto-s&cale"); + autoscaleAction->setCheckable(true); + connect(autoscaleAction, SIGNAL(triggered(bool)), this, SLOT(toggle_autoscale())); - QAction* nestAction = menu.addAction("&Nest"); - connect(nestAction, SIGNAL(triggered(bool)), mainWindow, SLOT(on_actionNest_triggered())); + QAction* nestAction = menu.addAction("&Nest"); + connect(nestAction, SIGNAL(triggered(bool)), mainWindow, SLOT(nest())); - // stabilizer option - int video_clip_count = 0; - bool all_video_is_footage = true; - for (int i=0;itrack < 0) { - video_clip_count++; - if (selected_clips.at(i)->media == NULL - || selected_clips.at(i)->media->get_type() != MEDIA_TYPE_FOOTAGE) { - all_video_is_footage = false; - } - } - } - if (video_clip_count == 1 && all_video_is_footage) { - QAction* stabilizerAction = menu.addAction("S&tabilizer"); - connect(stabilizerAction, SIGNAL(triggered(bool)), this, SLOT(show_stabilizer_diag())); - } + // stabilizer option + /*int video_clip_count = 0; + bool all_video_is_footage = true; + for (int i=0;itrack < 0) { + video_clip_count++; + if (selected_clips.at(i)->media == NULL + || selected_clips.at(i)->media->get_type() != MEDIA_TYPE_FOOTAGE) { + all_video_is_footage = false; + } + } + } + if (video_clip_count == 1 && all_video_is_footage) { + QAction* stabilizerAction = menu.addAction("S&tabilizer"); + connect(stabilizerAction, SIGNAL(triggered(bool)), this, SLOT(show_stabilizer_diag())); + }*/ - // set autoscale arbitrarily to the first selected clip - autoscaleAction->setChecked(selected_clips.at(0)->autoscale); + // set autoscale arbitrarily to the first selected clip + autoscaleAction->setChecked(selected_clips.at(0)->autoscale); - // check if all selected clips have the same media for a "Reveal In Project" - bool same_media = true; - rc_reveal_media = selected_clips.at(0)->media; - for (int i=1;imedia != rc_reveal_media) { - same_media = false; - break; - } - } + // check if all selected clips have the same media for a "Reveal In Project" + bool same_media = true; + rc_reveal_media = selected_clips.at(0)->media; + for (int i=1;imedia != rc_reveal_media) { + same_media = false; + break; + } + } - if (same_media) { - QAction* revealInProjectAction = menu.addAction("&Reveal in Project"); - connect(revealInProjectAction, SIGNAL(triggered(bool)), this, SLOT(reveal_media())); - } + if (same_media) { + QAction* revealInProjectAction = menu.addAction("&Reveal in Project"); + connect(revealInProjectAction, SIGNAL(triggered(bool)), this, SLOT(reveal_media())); + } - QAction* rename = menu.addAction("R&ename"); - connect(rename, SIGNAL(triggered(bool)), this, SLOT(rename_clip())); - } + QAction* rename = menu.addAction("R&ename"); + connect(rename, SIGNAL(triggered(bool)), this, SLOT(rename_clip())); + } - menu.exec(mapToGlobal(pos)); - } + menu.exec(mapToGlobal(pos)); + } } void TimelineWidget::toggle_autoscale() { - SetAutoscaleAction* action = new SetAutoscaleAction(); - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL && panel_timeline->is_clip_selected(c, true)) { - action->clips.append(c); - } - } - if (action->clips.size() > 0) { - undo_stack.push(action); - } else { - delete action; - } + SetAutoscaleAction* action = new SetAutoscaleAction(); + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL && panel_timeline->is_clip_selected(c, true)) { + action->clips.append(c); + } + } + if (action->clips.size() > 0) { + undo_stack.push(action); + } else { + delete action; + } } void TimelineWidget::tooltip_timer_timeout() { - if (sequence != NULL) { + if (sequence != NULL) { if (tooltip_clip < sequence->clips.size()) { Clip* c = sequence->clips.at(tooltip_clip); if (c != NULL) { @@ -222,7 +226,7 @@ void TimelineWidget::tooltip_timer_timeout() { + "\nDuration: " + frame_to_timecode(c->getLength(), config.timecode_view, sequence->frame_rate)); } } - } + } tooltip_timer.stop(); } @@ -234,7 +238,7 @@ void TimelineWidget::rename_clip() { selected_clips.append(c); } } - if (selected_clips.size() > 0) { + if (selected_clips.size() > 0) { QString s = QInputDialog::getText(this, (selected_clips.size() == 1) ? "Rename '" + selected_clips.at(0)->name + "'" : "Rename multiple clips", "Enter a new name for this clip:", @@ -248,12 +252,29 @@ void TimelineWidget::rename_clip() { undo_stack.push(rcc); update_ui(true); } - } + } } void TimelineWidget::show_stabilizer_diag() { - StabilizerDialog sd; - sd.exec(); + StabilizerDialog sd; + sd.exec(); +} + +void TimelineWidget::open_sequence_properties() { + QList sequence_items; + QList all_top_level_items; + for (int i=0;iget_all_media_from_table(all_top_level_items, sequence_items, MEDIA_TYPE_SEQUENCE); // find all sequences in project + for (int i=0;ito_sequence() == sequence) { + NewSequenceDialog nsd(this, sequence_items.at(i)); + nsd.exec(); + return; + } + } + QMessageBox::critical(this, "Error", "Couldn't locate media wrapper for sequence."); } bool same_sign(int a, int b) { @@ -263,16 +284,14 @@ bool same_sign(int a, int b) { void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { bool import_init = false; - QVector media_list; + QVector media_list; panel_timeline->importing_files = false; - if (event->source() == panel_project->tree_view || event->source() == panel_project->icon_view) { - QModelIndexList items = (event->source() == panel_project->tree_view) - ? panel_project->tree_view->selectionModel()->selectedRows() - : panel_project->icon_view->selectionModel()->selectedIndexes(); - media_list.resize(items.size()); - for (int i=0;iitem_to_media(items.at(i)); + if (event->source() == panel_project->tree_view || event->source() == panel_project->icon_view) { + QModelIndexList items = panel_project->get_current_selected(); + media_list.resize(items.size()); + for (int i=0;iitem_to_media(items.at(i)); } import_init = true; } @@ -280,7 +299,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { if (event->source() == panel_footage_viewer->viewer_widget) { Sequence* proposed_seq = panel_footage_viewer->seq; if (proposed_seq != sequence) { // don't allow nesting the same sequence - media_list.append(panel_footage_viewer->media); + media_list.append(panel_footage_viewer->media); import_init = true; } } @@ -294,17 +313,17 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { file_list.append(urls.at(i).toLocalFile()); } - panel_project->process_file_list(file_list); + panel_project->process_file_list(file_list); 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 - Footage* f = panel_project->last_imported_media.at(i)->to_footage(); - f->ready_lock.lock(); - f->ready_lock.unlock(); + Footage* f = panel_project->last_imported_media.at(i)->to_footage(); + f->ready_lock.lock(); + f->ready_lock.unlock(); - if (f->ready) { - media_list.append(panel_project->last_imported_media.at(i)); + if (f->ready) { + media_list.append(panel_project->last_imported_media.at(i)); } } @@ -317,8 +336,8 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { } } - if (import_init) { - event->acceptProposedAction(); + if (import_init) { + event->acceptProposedAction(); long entry_point; Sequence* seq = sequence; @@ -327,7 +346,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { // 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); + self_created_sequence = create_sequence_from_media(media_list); seq = self_created_sequence; } else { entry_point = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x()); @@ -335,22 +354,22 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { panel_timeline->drag_track_start = (bottom_align) ? -1 : 0; } - panel_timeline->create_ghosts_from_media(seq, entry_point, media_list); + panel_timeline->create_ghosts_from_media(seq, entry_point, media_list); panel_timeline->importing = true; - } + } } void TimelineWidget::dragMoveEvent(QDragMoveEvent *event) { - if (panel_timeline->importing) { - event->acceptProposedAction(); + if (panel_timeline->importing) { + event->acceptProposedAction(); - if (sequence != NULL) { - QPoint pos = event->pos(); - update_ghosts(pos, event->keyboardModifiers() & Qt::ShiftModifier); - panel_timeline->move_insert = ((event->keyboardModifiers() & Qt::ControlModifier) && (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->importing)); - update_ui(false); - } + if (sequence != NULL) { + QPoint pos = event->pos(); + update_ghosts(pos, event->keyboardModifiers() & Qt::ShiftModifier); + panel_timeline->move_insert = ((event->keyboardModifiers() & Qt::ControlModifier) && (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->importing)); + update_ui(false); + } } } @@ -363,7 +382,7 @@ void TimelineWidget::wheelEvent(QWheelEvent *event) { if (config.scroll_zooms != shift) { panel_timeline->set_zoom(in); } else { - QScrollBar* bar = alt ? scrollBar : panel_timeline->ui->horizontalScrollBar; + QScrollBar* bar = alt ? scrollBar : panel_timeline->horizontalScrollBar; int step = bar->singleStep(); if (in) step = -step; @@ -373,7 +392,7 @@ void TimelineWidget::wheelEvent(QWheelEvent *event) { } void TimelineWidget::dragLeaveEvent(QDragLeaveEvent* event) { - event->accept(); + event->accept(); if (panel_timeline->importing) { if (panel_timeline->importing_files) { undo_stack.undo(); @@ -385,7 +404,7 @@ void TimelineWidget::dragLeaveEvent(QDragLeaveEvent* event) { } if (self_created_sequence != NULL) { delete self_created_sequence; - self_created_sequence = NULL; + self_created_sequence = NULL; } } @@ -412,7 +431,7 @@ void insert_clips(ComboAction* ca) { long earliest_new_point = LONG_MAX; long latest_new_point = LONG_MIN; - QVector ignore_clips; + QVector ignore_clips; for (int i=0;ighosts.size();i++) { const Ghost& g = panel_timeline->ghosts.at(i); @@ -422,54 +441,50 @@ void insert_clips(ComboAction* ca) { latest_new_point = qMax(latest_new_point, g.out); if (g.clip >= 0) { - ignore_clips.append(sequence->clips.at(g.clip)); + ignore_clips.append(g.clip); } else { - // don't try to close old gap if importing + // don't try to close old gap if importing ripple_old_point = false; } } - panel_timeline->split_cache.clear(); + panel_timeline->split_cache.clear(); for (int i=0;iclips.size();i++) { Clip* c = sequence->clips.at(i); if (c != NULL) { - // don't split any clips that are moving - bool found = false; - for (int j=0;jghosts.size();j++) { - if (panel_timeline->ghosts.at(j).clip == i) { - found = true; - break; - } - } - if (!found) { - if (c->timeline_in < earliest_new_point && c->timeline_out > earliest_new_point) { - panel_timeline->split_clip_and_relink(ca, i, earliest_new_point, true); - } + // don't split any clips that are moving + bool found = false; + for (int j=0;jghosts.size();j++) { + if (panel_timeline->ghosts.at(j).clip == i) { + found = true; + break; + } + } + if (!found) { + if (c->timeline_in < earliest_new_point && c->timeline_out > earliest_new_point) { + panel_timeline->split_clip_and_relink(ca, i, earliest_new_point, true); + } - // determine if we should close the gap the old clips left behind - if (ripple_old_point - && !((c->timeline_in < earliest_old_point && c->timeline_out <= earliest_old_point) || (c->timeline_in >= latest_old_point && c->timeline_out > latest_old_point)) - && !ignore_clips.contains(c)) { - ripple_old_point = false; - } - } + // determine if we should close the gap the old clips left behind + if (ripple_old_point + && !((c->timeline_in < earliest_old_point && c->timeline_out <= earliest_old_point) || (c->timeline_in >= latest_old_point && c->timeline_out > latest_old_point)) + && !ignore_clips.contains(i)) { + ripple_old_point = false; + } + } } } long ripple_length = (latest_new_point - earliest_new_point); - RippleCommand* rc = new RippleCommand(sequence, earliest_new_point, ripple_length); - rc->ignore = ignore_clips; - ca->append(rc); + ripple_clips(ca, sequence, earliest_new_point, ripple_length, ignore_clips); if (ripple_old_point) { // works for moving later clips earlier but not earlier to later long second_ripple_length = (earliest_old_point - latest_old_point); - RippleCommand* rc2 = new RippleCommand(sequence, latest_old_point, second_ripple_length); - rc2->ignore = ignore_clips; - ca->append(rc2); + ripple_clips(ca, sequence, latest_old_point, second_ripple_length, ignore_clips); if (earliest_old_point < earliest_new_point) { for (int i=0;ighosts.size();i++) { @@ -487,15 +502,15 @@ void insert_clips(ComboAction* ca) { } void TimelineWidget::dropEvent(QDropEvent* event) { - if (panel_timeline->importing && panel_timeline->ghosts.size() > 0) { - event->acceptProposedAction(); + if (panel_timeline->importing && panel_timeline->ghosts.size() > 0) { + event->acceptProposedAction(); - ComboAction* ca = new ComboAction(); + ComboAction* ca = new ComboAction(); - Sequence* s = sequence; + Sequence* s = sequence; - // if we're dropping into nothing, create a new sequences based on the clip being dragged - if (s == NULL) { + // if we're dropping into nothing, create a new sequences based on the clip being dragged + if (s == NULL) { s = self_created_sequence; panel_project->new_sequence(ca, self_created_sequence, true, NULL); self_created_sequence = NULL; @@ -507,28 +522,28 @@ void TimelineWidget::dropEvent(QDropEvent* event) { panel_timeline->add_clips_from_ghosts(ca, s); - undo_stack.push(ca); + undo_stack.push(ca); - setFocus(); + setFocus(); update_ui(true); } } void TimelineWidget::mouseDoubleClickEvent(QMouseEvent *event) { - if (panel_timeline->tool == TIMELINE_TOOL_EDIT) { - int clip_index = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); - if (clip_index >= 0) { - Clip* clip = sequence->clips.at(clip_index); + if (panel_timeline->tool == TIMELINE_TOOL_EDIT) { + int clip_index = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); + if (clip_index >= 0) { + Clip* clip = sequence->clips.at(clip_index); if (!(event->modifiers() & Qt::ShiftModifier)) sequence->selections.clear(); - Selection s; - s.in = clip->timeline_in; - s.out = clip->timeline_out; - s.track = clip->track; + Selection s; + s.in = clip->timeline_in; + s.out = clip->timeline_out; + s.track = clip->track; sequence->selections.append(s); update_ui(false); - } - } + } + } } bool isLiveEditing() { @@ -536,7 +551,7 @@ bool isLiveEditing() { } void TimelineWidget::mousePressEvent(QMouseEvent *event) { - if (sequence != NULL) { + if (sequence != NULL) { int tool = panel_timeline->tool; if (event->button() == Qt::RightButton) { tool = TIMELINE_TOOL_MENU; @@ -618,28 +633,28 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track); } } - } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER && panel_timeline->transition_select != TA_NO_TRANSITION) { - panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track); + } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER && panel_timeline->transition_select != TA_NO_TRANSITION) { + panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track); - for (int i=0;ilinked.size();i++) { - Clip* link = sequence->clips.at(clip->linked.at(i)); - panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track); - } + for (int i=0;ilinked.size();i++) { + Clip* link = sequence->clips.at(clip->linked.at(i)); + panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track); + } - Selection s; - s.track = clip->track; + Selection s; + s.track = clip->track; - if (panel_timeline->transition_select == TA_OPENING_TRANSITION && clip->get_opening_transition() != NULL) { - s.in = clip->timeline_in; - if (clip->get_opening_transition()->secondary_clip != NULL) s.in -= clip->get_opening_transition()->get_true_length(); - s.out = clip->timeline_in + clip->get_opening_transition()->get_true_length(); - } else if (panel_timeline->transition_select == TA_CLOSING_TRANSITION && clip->get_closing_transition() != NULL) { - s.in = clip->timeline_out - clip->get_closing_transition()->get_true_length(); - s.out = clip->timeline_out; - if (clip->get_closing_transition()->secondary_clip != NULL) s.out += clip->get_closing_transition()->get_true_length(); - } - sequence->selections.append(s); - } + if (panel_timeline->transition_select == TA_OPENING_TRANSITION && clip->get_opening_transition() != NULL) { + s.in = clip->timeline_in; + if (clip->get_opening_transition()->secondary_clip != NULL) s.in -= clip->get_opening_transition()->get_true_length(); + s.out = clip->timeline_in + clip->get_opening_transition()->get_true_length(); + } else if (panel_timeline->transition_select == TA_CLOSING_TRANSITION && clip->get_closing_transition() != NULL) { + s.in = clip->timeline_out - clip->get_closing_transition()->get_true_length(); + s.out = clip->timeline_out; + if (clip->get_closing_transition()->secondary_clip != NULL) s.out += clip->get_closing_transition()->get_true_length(); + } + sequence->selections.append(s); + } } else { // if "shift" is not down if (!shift) { @@ -651,17 +666,17 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { s.in = clip->timeline_in; s.out = clip->timeline_out; - if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { - if (panel_timeline->transition_select == TA_OPENING_TRANSITION) { - s.out = clip->timeline_in + clip->get_opening_transition()->get_true_length(); - if (clip->get_opening_transition()->secondary_clip != NULL) s.in -= clip->get_opening_transition()->get_true_length(); - } + if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { + if (panel_timeline->transition_select == TA_OPENING_TRANSITION) { + s.out = clip->timeline_in + clip->get_opening_transition()->get_true_length(); + if (clip->get_opening_transition()->secondary_clip != NULL) s.in -= clip->get_opening_transition()->get_true_length(); + } - if (panel_timeline->transition_select == TA_CLOSING_TRANSITION) { - s.in = clip->timeline_out - clip->get_closing_transition()->get_true_length(); - if (clip->get_closing_transition()->secondary_clip != NULL) s.out += clip->get_closing_transition()->get_true_length(); - } - } + if (panel_timeline->transition_select == TA_CLOSING_TRANSITION) { + s.in = clip->timeline_out - clip->get_closing_transition()->get_true_length(); + if (clip->get_closing_transition()->secondary_clip != NULL) s.out += clip->get_closing_transition()->get_true_length(); + } + } s.track = clip->track; sequence->selections.append(s); @@ -698,12 +713,12 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { update_ui(false); } } - break; - case TIMELINE_TOOL_HAND: - panel_timeline->hand_moving = true; - panel_timeline->drag_x_start = pos.x(); - panel_timeline->drag_y_start = pos.y(); - break; + break; + case TIMELINE_TOOL_HAND: + panel_timeline->hand_moving = true; + panel_timeline->drag_x_start = pos.x(); + panel_timeline->drag_y_start = pos.y(); + break; case TIMELINE_TOOL_EDIT: if (config.edit_tool_also_seeks) panel_sequence_viewer->seek(panel_timeline->drag_frame_start); panel_timeline->selecting = true; @@ -715,61 +730,62 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { update_ui(false); } break; - case TIMELINE_TOOL_TRANSITION: - { - if (panel_timeline->transition_tool_pre_clip > -1) { - panel_timeline->transition_tool_init = true; - } - } - break; + case TIMELINE_TOOL_TRANSITION: + { + if (panel_timeline->transition_tool_pre_clip > -1) { + panel_timeline->transition_tool_init = true; + } + } + break; } } - } + } } void make_room_for_transition(ComboAction* ca, Clip* c, int type, long transition_start, long transition_end, bool delete_old_transitions) { - // make room for transition - if (type == TA_OPENING_TRANSITION) { - if (delete_old_transitions && c->get_opening_transition() != NULL) { - ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); - } - if (c->get_closing_transition() != NULL) { - if (transition_end >= c->timeline_out) { - ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); - } else if (transition_end > c->timeline_out - c->get_closing_transition()->get_true_length()) { - ca->append(new ModifyTransitionCommand(c, TA_CLOSING_TRANSITION, c->timeline_out - transition_end)); - } - } - } else { - if (delete_old_transitions && c->get_closing_transition() != NULL) { - ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); - } - if (c->get_opening_transition() != NULL) { - if (transition_start <= c->timeline_in) { - ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); - } else if (transition_start < c->timeline_in + c->get_opening_transition()->get_true_length()) { - ca->append(new ModifyTransitionCommand(c, TA_OPENING_TRANSITION, transition_start - c->timeline_in)); - } - } - } + // make room for transition + if (type == TA_OPENING_TRANSITION) { + if (delete_old_transitions && c->get_opening_transition() != NULL) { + ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); + } + if (c->get_closing_transition() != NULL) { + if (transition_end >= c->timeline_out) { + ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); + } else if (transition_end > c->timeline_out - c->get_closing_transition()->get_true_length()) { + ca->append(new ModifyTransitionCommand(c, TA_CLOSING_TRANSITION, c->timeline_out - transition_end)); + } + } + } else { + if (delete_old_transitions && c->get_closing_transition() != NULL) { + ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); + } + if (c->get_opening_transition() != NULL) { + if (transition_start <= c->timeline_in) { + ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); + } else if (transition_start < c->timeline_in + c->get_opening_transition()->get_true_length()) { + ca->append(new ModifyTransitionCommand(c, TA_OPENING_TRANSITION, transition_start - c->timeline_in)); + } + } + } } void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { QToolTip::hideText(); - if (sequence != NULL) { - bool alt = (event->modifiers() & Qt::AltModifier); + if (sequence != NULL) { + bool alt = (event->modifiers() & Qt::AltModifier); bool shift = (event->modifiers() & Qt::ShiftModifier); bool ctrl = (event->modifiers() & Qt::ControlModifier); if (event->button() == Qt::LeftButton) { - ComboAction* ca = new ComboAction(); - bool push_undo = false; + ComboAction* ca = new ComboAction(); + bool push_undo = false; if (panel_timeline->creating) { if (panel_timeline->ghosts.size() > 0) { const Ghost& g = panel_timeline->ghosts.at(0); if (panel_timeline->creating_object == ADD_OBJ_AUDIO) { + mainWindow->statusBar()->clearMessage(); panel_sequence_viewer->cue_recording(qMin(g.in, g.out), qMax(g.in, g.out), g.track); panel_timeline->creating = false; } else if (g.in != g.out) { @@ -797,46 +813,46 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { QVector add; add.append(c); - ca->append(new AddClipCommand(sequence, add)); + ca->append(new AddClipCommand(sequence, add)); if (c->track < 0) { // default video effects (before custom effects) - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TRANSFORM, EFFECT_TYPE_EFFECT))); - //c->media_type = MEDIA_TYPE_SOLID; + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TRANSFORM, EFFECT_TYPE_EFFECT))); + //c->media_type = MEDIA_TYPE_SOLID; } switch (panel_timeline->creating_object) { case ADD_OBJ_TITLE: c->name = "Title"; - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TEXT, EFFECT_TYPE_EFFECT))); + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TEXT, EFFECT_TYPE_EFFECT))); break; case ADD_OBJ_SOLID: c->name = "Solid Color"; - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_SOLID, EFFECT_TYPE_EFFECT))); + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_SOLID, EFFECT_TYPE_EFFECT))); break; case ADD_OBJ_BARS: - { + { c->name = "Bars"; - Effect* e = create_effect(c, get_internal_meta(EFFECT_INTERNAL_SOLID, EFFECT_TYPE_EFFECT)); - e->row(0)->field(0)->set_combo_index(1); + Effect* e = create_effect(c, get_internal_meta(EFFECT_INTERNAL_SOLID, EFFECT_TYPE_EFFECT)); + e->row(0)->field(0)->set_combo_index(1); c->effects.append(e); - } + } break; case ADD_OBJ_TONE: c->name = "Tone"; - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TONE, EFFECT_TYPE_EFFECT))); + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_TONE, EFFECT_TYPE_EFFECT))); break; case ADD_OBJ_NOISE: c->name = "Noise"; - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_NOISE, EFFECT_TYPE_EFFECT))); + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_NOISE, EFFECT_TYPE_EFFECT))); break; } if (c->track >= 0) { // default audio effects (after custom effects) - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_VOLUME, EFFECT_TYPE_EFFECT))); - c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_PAN, EFFECT_TYPE_EFFECT))); - //c->media_type = MEDIA_TYPE_TONE; + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_VOLUME, EFFECT_TYPE_EFFECT))); + c->effects.append(create_effect(c, get_internal_meta(EFFECT_INTERNAL_PAN, EFFECT_TYPE_EFFECT))); + //c->media_type = MEDIA_TYPE_TONE; } push_undo = true; @@ -848,7 +864,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { } } else if (panel_timeline->moving_proc) { if (panel_timeline->ghosts.size() > 0) { - const Ghost& first_ghost = panel_timeline->ghosts.at(0); + const Ghost& first_ghost = panel_timeline->ghosts.at(0); // if we were RIPPLING, move all the clips if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) { @@ -869,13 +885,13 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { ripple_length = first_ghost.old_out - panel_timeline->ghosts.at(0).out; ripple_point = first_ghost.old_out; } - QVector ignore_clips; + QVector ignore_clips; for (int i=0;ighosts.size();i++) { const Ghost& g = panel_timeline->ghosts.at(i); // push rippled clips forward if necessary if (panel_timeline->trim_in_point) { - ignore_clips.append(sequence->clips.at(g.clip)); + ignore_clips.append(g.clip); panel_timeline->ghosts[i].in += ripple_length; panel_timeline->ghosts[i].out += ripple_length; } @@ -884,9 +900,8 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { ripple_point = qMin(ripple_point, comp_point); } if (!panel_timeline->trim_in_point) ripple_length = -ripple_length; - RippleCommand* rc = new RippleCommand(sequence, ripple_point, ripple_length); - rc->ignore = ignore_clips; - ca->append(rc); + + ripple_clips(ca, sequence, ripple_point, ripple_length, ignore_clips); } if (panel_timeline->tool == TIMELINE_TOOL_POINTER @@ -900,7 +915,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { const Ghost& g = panel_timeline->ghosts.at(i); if (g.old_in != g.in || g.old_out != g.out || g.track != g.old_track || g.clip_in != g.old_clip_in) { // create copy of clip - Clip* c = sequence->clips.at(g.clip)->copy(sequence); + Clip* c = sequence->clips.at(g.clip)->copy(sequence); c->timeline_in = g.in; c->timeline_out = g.out; @@ -917,12 +932,12 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { } } if (new_clips.size() > 0) { - panel_timeline->delete_areas_and_relink(ca, delete_areas); + panel_timeline->delete_areas_and_relink(ca, delete_areas); // relink duplicated clips panel_timeline->relink_clips_using_ids(old_clips, new_clips); - ca->append(new AddClipCommand(sequence, new_clips)); + ca->append(new AddClipCommand(sequence, new_clips)); } } else { // INSERT if holding ctrl @@ -935,11 +950,11 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { // step 1 - set clips that are moving to "undeletable" (to avoid step 2 deleting any part of them) const Ghost& g = panel_timeline->ghosts.at(i); - sequence->clips.at(g.clip)->undeletable = true; - if (g.transition != NULL) { - g.transition->parent_clip->undeletable = true; - if (g.transition->secondary_clip != NULL) g.transition->secondary_clip->undeletable = true; - } + sequence->clips.at(g.clip)->undeletable = true; + if (g.transition != NULL) { + g.transition->parent_clip->undeletable = true; + if (g.transition->secondary_clip != NULL) g.transition->secondary_clip->undeletable = true; + } Selection s; s.in = g.in; @@ -947,238 +962,238 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { s.track = g.track; delete_areas.append(s); } - panel_timeline->delete_areas_and_relink(ca, delete_areas); + panel_timeline->delete_areas_and_relink(ca, delete_areas); for (int i=0;ighosts.size();i++) { - const Ghost& g = panel_timeline->ghosts.at(i); - sequence->clips.at(g.clip)->undeletable = false; - if (g.transition != NULL) { - g.transition->parent_clip->undeletable = false; - if (g.transition->secondary_clip != NULL) g.transition->secondary_clip->undeletable = false; - } + const Ghost& g = panel_timeline->ghosts.at(i); + sequence->clips.at(g.clip)->undeletable = false; + if (g.transition != NULL) { + g.transition->parent_clip->undeletable = false; + if (g.transition->secondary_clip != NULL) g.transition->secondary_clip->undeletable = false; + } } } for (int i=0;ighosts.size();i++) { Ghost& g = panel_timeline->ghosts[i]; // step 3 - move clips - Clip* c = sequence->clips.at(g.clip); + Clip* c = sequence->clips.at(g.clip); if (g.transition == NULL) { - move_clip(ca, c, c->timeline_in + (g.in - g.old_in), c->timeline_out + (g.out - g.old_out), c->clip_in + (g.clip_in - g.old_clip_in), c->track + (g.track - g.old_track)); + move_clip(ca, c, (g.in - g.old_in), (g.out - g.old_out), (g.clip_in - g.old_clip_in), (g.track - g.old_track), true, true); // adjust transitions if we need to long new_clip_length = (g.out - g.in); - if (c->get_opening_transition() != NULL) { + if (c->get_opening_transition() != NULL) { long max_open_length = new_clip_length; - if (c->get_closing_transition() != NULL && !panel_timeline->trim_in_point) { - max_open_length -= c->get_closing_transition()->get_true_length(); + if (c->get_closing_transition() != NULL && !panel_timeline->trim_in_point) { + max_open_length -= c->get_closing_transition()->get_true_length(); } if (max_open_length <= 0) { - ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); - } else if (c->get_opening_transition()->get_true_length() > max_open_length) { - ca->append(new ModifyTransitionCommand(c, TA_OPENING_TRANSITION, max_open_length)); + ca->append(new DeleteTransitionCommand(c->sequence, c->opening_transition)); + } else if (c->get_opening_transition()->get_true_length() > max_open_length) { + ca->append(new ModifyTransitionCommand(c, TA_OPENING_TRANSITION, max_open_length)); } } - if (c->get_closing_transition() != NULL) { + if (c->get_closing_transition() != NULL) { long max_open_length = new_clip_length; - if (c->get_opening_transition() != NULL && panel_timeline->trim_in_point) { - max_open_length -= c->get_opening_transition()->get_true_length(); + if (c->get_opening_transition() != NULL && panel_timeline->trim_in_point) { + max_open_length -= c->get_opening_transition()->get_true_length(); } if (max_open_length <= 0) { - ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); - } else if (c->get_closing_transition()->get_true_length() > max_open_length) { - ca->append(new ModifyTransitionCommand(c, TA_CLOSING_TRANSITION, max_open_length)); + ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); + } else if (c->get_closing_transition()->get_true_length() > max_open_length) { + ca->append(new ModifyTransitionCommand(c, TA_CLOSING_TRANSITION, max_open_length)); } } } else { - bool is_opening_transition = (g.transition == c->get_opening_transition()); + bool is_opening_transition = (g.transition == c->get_opening_transition()); long new_transition_length = g.out - g.in; - if (g.transition->secondary_clip != NULL) new_transition_length >>= 1; - ca->append(new ModifyTransitionCommand(c, is_opening_transition ? TA_OPENING_TRANSITION : TA_CLOSING_TRANSITION, new_transition_length)); + if (g.transition->secondary_clip != NULL) new_transition_length >>= 1; + ca->append(new ModifyTransitionCommand(c, is_opening_transition ? TA_OPENING_TRANSITION : TA_CLOSING_TRANSITION, new_transition_length)); - long clip_length = c->getLength(); + long clip_length = c->getLength(); - if (g.transition->secondary_clip != NULL) { - if (g.in != g.old_in && !g.trimming) { - long movement = g.in - g.old_in; - move_clip(ca, g.transition->parent_clip, g.transition->parent_clip->timeline_in + movement, g.transition->parent_clip->timeline_out, g.transition->parent_clip->clip_in + movement, g.transition->parent_clip->track, false); - move_clip(ca, g.transition->secondary_clip, g.transition->secondary_clip->timeline_in, g.transition->secondary_clip->timeline_out + movement, g.transition->secondary_clip->clip_in, g.transition->secondary_clip->track, false); - } - } else if (is_opening_transition) { - if (g.in != g.old_in) { - // if transition is going to make the clip bigger, make the clip bigger - move_clip(ca, c, c->timeline_in + (g.in - g.old_in), c->timeline_out, c->clip_in + (g.clip_in - g.old_clip_in), c->track); - clip_length -= (g.in - g.old_in); - } + if (g.transition->secondary_clip != NULL) { + if (g.in != g.old_in && !g.trimming) { + long movement = g.in - g.old_in; + move_clip(ca, g.transition->parent_clip, movement, 0, movement, 0, false, true); + move_clip(ca, g.transition->secondary_clip, 0, movement, 0, 0, false, true); + } + } else if (is_opening_transition) { + if (g.in != g.old_in) { + // if transition is going to make the clip bigger, make the clip bigger + move_clip(ca, c, (g.in - g.old_in), 0, (g.clip_in - g.old_clip_in), 0, true, true); + clip_length -= (g.in - g.old_in); + } - make_room_for_transition(ca, c, TA_OPENING_TRANSITION, g.in, g.out, false); - } else { - if (g.out != g.old_out) { - // if transition is going to make the clip bigger, make the clip bigger - move_clip(ca, c, c->timeline_in, c->timeline_out + (g.out - g.old_out), c->clip_in, c->track); - clip_length += (g.out - g.old_out); - } + make_room_for_transition(ca, c, TA_OPENING_TRANSITION, g.in, g.out, false); + } else { + if (g.out != g.old_out) { + // if transition is going to make the clip bigger, make the clip bigger + move_clip(ca, c, 0, (g.out - g.old_out), 0, 0, true, true); + clip_length += (g.out - g.old_out); + } - make_room_for_transition(ca, c, TA_CLOSING_TRANSITION, g.in, g.out, false); - } + make_room_for_transition(ca, c, TA_CLOSING_TRANSITION, g.in, g.out, false); + } } } - } + } push_undo = true; } } else if (panel_timeline->selecting || panel_timeline->rect_select_proc) { - } else if (panel_timeline->transition_tool_proc) { - const Ghost& g = panel_timeline->ghosts.at(0); + } else if (panel_timeline->transition_tool_proc) { + const Ghost& g = panel_timeline->ghosts.at(0); - if (g.in != g.out) { - long transition_start = qMin(g.in, g.out); - long transition_end = qMax(g.in, g.out); + if (g.in != g.out) { + long transition_start = qMin(g.in, g.out); + long transition_end = qMax(g.in, g.out); - Clip* pre = sequence->clips.at(g.clip); - Clip* post = pre; + Clip* pre = sequence->clips.at(g.clip); + Clip* post = pre; - make_room_for_transition(ca, pre, panel_timeline->transition_tool_type, transition_start, transition_end, true); + make_room_for_transition(ca, pre, panel_timeline->transition_tool_type, transition_start, transition_end, true); - if (panel_timeline->transition_tool_post_clip > -1) { - post = sequence->clips.at(panel_timeline->transition_tool_post_clip); - int opposite_type = (panel_timeline->transition_tool_type == TA_OPENING_TRANSITION) ? TA_CLOSING_TRANSITION : TA_OPENING_TRANSITION; - make_room_for_transition( - ca, - post, - opposite_type, - transition_start, - transition_end, - true - ); + if (panel_timeline->transition_tool_post_clip > -1) { + post = sequence->clips.at(panel_timeline->transition_tool_post_clip); + int opposite_type = (panel_timeline->transition_tool_type == TA_OPENING_TRANSITION) ? TA_CLOSING_TRANSITION : TA_OPENING_TRANSITION; + make_room_for_transition( + ca, + post, + opposite_type, + transition_start, + transition_end, + true + ); - if (panel_timeline->transition_tool_type == TA_CLOSING_TRANSITION) { - // swap - Clip* temp = pre; - pre = post; - post = temp; - } - } + if (panel_timeline->transition_tool_type == TA_CLOSING_TRANSITION) { + // swap + Clip* temp = pre; + pre = post; + post = temp; + } + } - if (transition_start < post->timeline_in || transition_end > pre->timeline_out) { - // delete shit over there and extend timeline in - QVector areas; - Selection s; - s.track = post->track; + if (transition_start < post->timeline_in || transition_end > pre->timeline_out) { + // delete shit over there and extend timeline in + QVector areas; + Selection s; + s.track = post->track; - bool move_post = false; - bool move_pre = false; + bool move_post = false; + bool move_pre = false; - if (transition_start < post->timeline_in) { - s.in = transition_start; - s.out = post->timeline_in; - areas.append(s); - move_post = true; - } - if (transition_end > pre->timeline_out) { - s.in = pre->timeline_out; - s.out = transition_end; - areas.append(s); - move_pre = true; - } + if (transition_start < post->timeline_in) { + s.in = transition_start; + s.out = post->timeline_in; + areas.append(s); + move_post = true; + } + if (transition_end > pre->timeline_out) { + s.in = pre->timeline_out; + s.out = transition_end; + areas.append(s); + move_pre = true; + } - panel_timeline->delete_areas_and_relink(ca, areas); + panel_timeline->delete_areas_and_relink(ca, areas); - if (move_post) move_clip(ca, post, qMin(transition_start, post->timeline_in), post->timeline_out, post->clip_in - (post->timeline_in - transition_start), post->track); - if (move_pre) move_clip(ca, pre, pre->timeline_in, qMax(transition_end, pre->timeline_out), pre->clip_in, pre->track); - } + if (move_post) move_clip(ca, post, qMin(transition_start, post->timeline_in), post->timeline_out, post->clip_in - (post->timeline_in - transition_start), post->track); + if (move_pre) move_clip(ca, pre, pre->timeline_in, qMax(transition_end, pre->timeline_out), pre->clip_in, pre->track); + } - if (panel_timeline->transition_tool_post_clip > -1) { - ca->append(new AddTransitionCommand(pre, post, NULL, panel_timeline->transition_tool_meta, TA_OPENING_TRANSITION, transition_end - pre->timeline_in)); - } else { - ca->append(new AddTransitionCommand(pre, NULL, NULL, panel_timeline->transition_tool_meta, panel_timeline->transition_tool_type, transition_end - transition_start)); - } + if (panel_timeline->transition_tool_post_clip > -1) { + ca->append(new AddTransitionCommand(pre, post, NULL, panel_timeline->transition_tool_meta, TA_OPENING_TRANSITION, transition_end - pre->timeline_in)); + } else { + ca->append(new AddTransitionCommand(pre, NULL, NULL, panel_timeline->transition_tool_meta, panel_timeline->transition_tool_type, transition_end - transition_start)); + } - push_undo = true; - } - } else if (panel_timeline->splitting) { - bool split = false; - for (int i=0;isplit_tracks.size();i++) { - int split_index = getClipIndexFromCoords(panel_timeline->drag_frame_start, panel_timeline->split_tracks.at(i)); - if (split_index > -1 && panel_timeline->split_clip_and_relink(ca, split_index, panel_timeline->drag_frame_start, !alt)) { - split = true; - } - } - if (split) { push_undo = true; - } - panel_timeline->split_cache.clear(); - } + } + } else if (panel_timeline->splitting) { + bool split = false; + for (int i=0;isplit_tracks.size();i++) { + int split_index = getClipIndexFromCoords(panel_timeline->drag_frame_start, panel_timeline->split_tracks.at(i)); + if (split_index > -1 && panel_timeline->split_clip_and_relink(ca, split_index, panel_timeline->drag_frame_start, !alt)) { + split = true; + } + } + if (split) { + push_undo = true; + } + panel_timeline->split_cache.clear(); + } - // remove duplicate selections + // remove duplicate selections panel_timeline->clean_up_selections(sequence->selections); - if (selection_command != NULL) { - selection_command->new_data = sequence->selections; - ca->append(selection_command); - selection_command = NULL; - push_undo = true; - } + if (selection_command != NULL) { + selection_command->new_data = sequence->selections; + ca->append(selection_command); + selection_command = NULL; + push_undo = true; + } - if (push_undo) { - undo_stack.push(ca); - } else { - delete ca; - } + if (push_undo) { + undo_stack.push(ca); + } else { + delete ca; + } - // destroy all ghosts - panel_timeline->ghosts.clear(); + // destroy all ghosts + panel_timeline->ghosts.clear(); - // clear split tracks - panel_timeline->split_tracks.clear(); + // clear split tracks + panel_timeline->split_tracks.clear(); - panel_timeline->selecting = false; - panel_timeline->moving_proc = false; - panel_timeline->moving_init = false; - panel_timeline->splitting = false; - panel_timeline->snapped = false; - panel_timeline->rect_select_init = false; - panel_timeline->rect_select_proc = false; - panel_timeline->transition_tool_init = false; - panel_timeline->transition_tool_proc = false; - panel_timeline->hand_moving = false; - pre_clips.clear(); - post_clips.clear(); + panel_timeline->selecting = false; + panel_timeline->moving_proc = false; + panel_timeline->moving_init = false; + panel_timeline->splitting = false; + panel_timeline->snapped = false; + panel_timeline->rect_select_init = false; + panel_timeline->rect_select_proc = false; + panel_timeline->transition_tool_init = false; + panel_timeline->transition_tool_proc = false; + panel_timeline->hand_moving = false; + pre_clips.clear(); + post_clips.clear(); update_ui(true); - } - } + } + } } void TimelineWidget::init_ghosts() { for (int i=0;ighosts.size();i++) { Ghost& g = panel_timeline->ghosts[i]; - Clip* c = sequence->clips.at(g.clip); + Clip* c = sequence->clips.at(g.clip); g.track = g.old_track = c->track; - g.clip_in = g.old_clip_in = c->clip_in; + g.clip_in = g.old_clip_in = c->clip_in; - if (panel_timeline->tool == TIMELINE_TOOL_SLIP) { - g.clip_in = g.old_clip_in = c->get_clip_in_with_transition(); - g.in = g.old_in = c->get_timeline_in_with_transition(); - g.out = g.old_out = c->get_timeline_out_with_transition(); - g.ghost_length = g.old_out - g.old_in; - } else if (g.transition == NULL) { - // this ghost is for a clip - g.in = g.old_in = c->timeline_in; - g.out = g.old_out = c->timeline_out; + if (panel_timeline->tool == TIMELINE_TOOL_SLIP) { + g.clip_in = g.old_clip_in = c->get_clip_in_with_transition(); + g.in = g.old_in = c->get_timeline_in_with_transition(); + g.out = g.old_out = c->get_timeline_out_with_transition(); g.ghost_length = g.old_out - g.old_in; - } else if (g.transition == c->get_opening_transition()) { - g.in = g.old_in = c->get_timeline_in_with_transition(); - g.ghost_length = c->get_opening_transition()->get_length(); - g.out = g.old_out = g.in + g.ghost_length; - } else if (g.transition == c->get_closing_transition()) { - g.out = g.old_out = c->get_timeline_out_with_transition(); - g.ghost_length = c->get_closing_transition()->get_length(); - g.in = g.old_in = g.out - g.ghost_length; - g.clip_in = g.old_clip_in = c->clip_in + c->getLength() - c->get_closing_transition()->get_true_length(); + } else if (g.transition == NULL) { + // this ghost is for a clip + g.in = g.old_in = c->timeline_in; + g.out = g.old_out = c->timeline_out; + g.ghost_length = g.old_out - g.old_in; + } else if (g.transition == c->get_opening_transition()) { + g.in = g.old_in = c->get_timeline_in_with_transition(); + g.ghost_length = c->get_opening_transition()->get_length(); + g.out = g.old_out = g.in + g.ghost_length; + } else if (g.transition == c->get_closing_transition()) { + g.out = g.old_out = c->get_timeline_out_with_transition(); + g.ghost_length = c->get_closing_transition()->get_length(); + g.in = g.old_in = g.out - g.ghost_length; + g.clip_in = g.old_clip_in = c->clip_in + c->getLength() - c->get_closing_transition()->get_true_length(); } // used for trim ops - g.media_length = c->getMaximumLength(); + g.media_length = c->getMaximumLength(); } for (int i=0;iselections.size();i++) { Selection& s = sequence->selections[i]; @@ -1189,48 +1204,48 @@ void TimelineWidget::init_ghosts() { } void validate_transitions(Clip* c, int transition_type, long& frame_diff) { - long validator; + long validator; - if (transition_type == TA_OPENING_TRANSITION) { - // prevent from going below 0 on the timeline - validator = c->timeline_in + frame_diff; - if (validator < 0) frame_diff -= validator; + if (transition_type == TA_OPENING_TRANSITION) { + // prevent from going below 0 on the timeline + validator = c->timeline_in + frame_diff; + if (validator < 0) frame_diff -= validator; - // prevent from going below 0 for the media - validator = c->clip_in + frame_diff; - if (validator < 0) frame_diff -= validator; + // prevent from going below 0 for the media + validator = c->clip_in + frame_diff; + if (validator < 0) frame_diff -= validator; - // prevent transition from exceeding media length - validator -= c->getMaximumLength(); - if (validator > 0) frame_diff -= validator; - } else { - // prevent from going below 0 on the timeline - validator = c->timeline_out + frame_diff; - if (validator < 0) frame_diff -= validator; + // prevent transition from exceeding media length + validator -= c->getMaximumLength(); + if (validator > 0) frame_diff -= validator; + } else { + // prevent from going below 0 on the timeline + validator = c->timeline_out + frame_diff; + if (validator < 0) frame_diff -= validator; - // prevent from going below 0 for the media - validator = c->clip_in + c->getLength() + frame_diff; - if (validator < 0) frame_diff -= validator; + // prevent from going below 0 for the media + validator = c->clip_in + c->getLength() + frame_diff; + if (validator < 0) frame_diff -= validator; - // prevent transition from exceeding media length - validator -= c->getMaximumLength(); - if (validator > 0) frame_diff -= validator; - } + // prevent transition from exceeding media length + validator -= c->getMaximumLength(); + if (validator > 0) frame_diff -= validator; + } } void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { - int mouse_track = getTrackFromScreenPoint(mouse_pos.y()); - long frame_diff = (lock_frame) ? 0 : panel_timeline->getTimelineFrameFromScreenPoint(mouse_pos.x()) - panel_timeline->drag_frame_start; + int mouse_track = getTrackFromScreenPoint(mouse_pos.y()); + long frame_diff = (lock_frame) ? 0 : panel_timeline->getTimelineFrameFromScreenPoint(mouse_pos.x()) - panel_timeline->drag_frame_start; int track_diff = ((panel_timeline->tool == TIMELINE_TOOL_SLIDE || panel_timeline->transition_select != TA_NO_TRANSITION) && !panel_timeline->importing) ? 0 : mouse_track - panel_timeline->drag_track_start; - long validator; + long validator; long earliest_in_point = LONG_MAX; // first try to snap long fm; - if (panel_timeline->tool != TIMELINE_TOOL_SLIP) { - // slipping doesn't move the clips so we don't bother snapping for it - for (int i=0;ighosts.size();i++) { - const Ghost& g = panel_timeline->ghosts.at(i); + if (panel_timeline->tool != TIMELINE_TOOL_SLIP) { + // slipping doesn't move the clips so we don't bother snapping for it + for (int i=0;ighosts.size();i++) { + const Ghost& g = panel_timeline->ghosts.at(i); if (panel_timeline->trim_target == -1 || g.trim_in) { fm = g.old_in + frame_diff; if (panel_timeline->snap_to_timeline(&fm, true, true, true)) { @@ -1245,37 +1260,37 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { break; } } - } - } + } + } - bool clips_are_movable = (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->tool == TIMELINE_TOOL_SLIDE || panel_timeline->importing); + bool clips_are_movable = (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->tool == TIMELINE_TOOL_SLIDE || panel_timeline->importing); - // validate ghosts - long temp_frame_diff = frame_diff; // cache to see if we change it (thus cancelling any snap) + // validate ghosts + long temp_frame_diff = frame_diff; // cache to see if we change it (thus cancelling any snap) for (int i=0;ighosts.size();i++) { - const Ghost& g = panel_timeline->ghosts.at(i); - Clip* c = NULL; - if (g.clip != -1) c = sequence->clips.at(g.clip); + const Ghost& g = panel_timeline->ghosts.at(i); + Clip* c = NULL; + if (g.clip != -1) c = sequence->clips.at(g.clip); FootageStream* ms = NULL; if (g.clip != -1 && c->media != NULL && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { - ms = c->media->to_footage()->get_stream_from_file_index(c->track < 0, c->media_stream); + ms = c->media->to_footage()->get_stream_from_file_index(c->track < 0, c->media_stream); } - // validate ghosts for trimming + // validate ghosts for trimming if (panel_timeline->creating) { // i feel like we might need something here but we haven't so far? } else if (panel_timeline->tool == TIMELINE_TOOL_SLIP) { - if (c->media->get_type() == MEDIA_TYPE_SEQUENCE - || (ms != NULL && !ms->infinite_length)) { - // prevent slip moving a clip below 0 clip_in - validator = g.old_clip_in - frame_diff; - if (validator < 0) frame_diff += validator; + if (c->media->get_type() == MEDIA_TYPE_SEQUENCE + || (ms != NULL && !ms->infinite_length)) { + // prevent slip moving a clip below 0 clip_in + validator = g.old_clip_in - frame_diff; + if (validator < 0) frame_diff += validator; - // prevent slip moving clip beyond media length - validator += g.ghost_length; - if (validator > g.media_length) frame_diff += validator - g.media_length; - } + // prevent slip moving clip beyond media length + validator += g.ghost_length; + if (validator > g.media_length) frame_diff += validator - g.media_length; + } } else if (g.trimming) { if (g.trim_in) { // prevent clip/transition length from being less than 1 frame long @@ -1289,12 +1304,12 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { } // prevent clip_in from going below 0 - if (c->media->get_type() == MEDIA_TYPE_SEQUENCE + if (c->media->get_type() == MEDIA_TYPE_SEQUENCE || (ms != NULL && !ms->infinite_length)) { validator = g.old_clip_in + frame_diff; if (validator < 0) frame_diff -= validator; - } - } else { + } + } else { // prevent clip length from being less than 1 frame long validator = g.ghost_length + frame_diff; if (validator < 1) frame_diff += (1 - validator); @@ -1305,95 +1320,95 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { validator = g.old_clip_in + g.ghost_length + frame_diff; if (validator > g.media_length) frame_diff -= validator - g.media_length; } - } + } - // prevent dual transition from going below 0 on the primary or media length on the secondary - if (g.transition != NULL && g.transition->secondary_clip != NULL) { - Clip* otc = g.transition->parent_clip; - Clip* ctc = g.transition->secondary_clip; + // prevent dual transition from going below 0 on the primary or media length on the secondary + if (g.transition != NULL && g.transition->secondary_clip != NULL) { + Clip* otc = g.transition->parent_clip; + Clip* ctc = g.transition->secondary_clip; - if (g.trim_in) { - frame_diff -= g.transition->get_true_length(); - } else { - frame_diff += g.transition->get_true_length(); - } + if (g.trim_in) { + frame_diff -= g.transition->get_true_length(); + } else { + frame_diff += g.transition->get_true_length(); + } - validate_transitions(otc, TA_OPENING_TRANSITION, frame_diff); - validate_transitions(ctc, TA_CLOSING_TRANSITION, frame_diff); + validate_transitions(otc, TA_OPENING_TRANSITION, frame_diff); + validate_transitions(ctc, TA_CLOSING_TRANSITION, frame_diff); - frame_diff = -frame_diff; - validate_transitions(otc, TA_OPENING_TRANSITION, frame_diff); - validate_transitions(ctc, TA_CLOSING_TRANSITION, frame_diff); - frame_diff = -frame_diff; + frame_diff = -frame_diff; + validate_transitions(otc, TA_OPENING_TRANSITION, frame_diff); + validate_transitions(ctc, TA_CLOSING_TRANSITION, frame_diff); + frame_diff = -frame_diff; - if (g.trim_in) { - frame_diff += g.transition->get_true_length(); - } else { - frame_diff -= g.transition->get_true_length(); - } - } + if (g.trim_in) { + frame_diff += g.transition->get_true_length(); + } else { + frame_diff -= g.transition->get_true_length(); + } + } - // ripple ops - if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) { - for (int j=0;jtool == TIMELINE_TOOL_RIPPLE) { + for (int j=0;jtrim_in_point) { - validator = post->timeline_in - frame_diff; - if (validator < 0) frame_diff += validator; - } + // prevent any rippled clip from going below 0 + if (panel_timeline->trim_in_point) { + validator = post->timeline_in - frame_diff; + if (validator < 0) frame_diff += validator; + } - // prevent any post-clips colliding with pre-clips - for (int k=0;ktrack == post->track) { - if (panel_timeline->trim_in_point) { - validator = post->timeline_in - frame_diff - pre->timeline_out; - if (validator < 0) frame_diff += validator; - } else { - validator = post->timeline_in + frame_diff - pre->timeline_out; - if (validator < 0) frame_diff -= validator; - } - } - } - } - } - } else if (clips_are_movable) { // validate ghosts for moving - // prevent clips from moving below 0 on the timeline - validator = g.old_in + frame_diff; - if (validator < 0) frame_diff -= validator; + // prevent any post-clips colliding with pre-clips + for (int k=0;ktrack == post->track) { + if (panel_timeline->trim_in_point) { + validator = post->timeline_in - frame_diff - pre->timeline_out; + if (validator < 0) frame_diff += validator; + } else { + validator = post->timeline_in + frame_diff - pre->timeline_out; + if (validator < 0) frame_diff -= validator; + } + } + } + } + } + } else if (clips_are_movable) { // validate ghosts for moving + // prevent clips from moving below 0 on the timeline + validator = g.old_in + frame_diff; + if (validator < 0) frame_diff -= validator; if (g.transition != NULL) { - if (g.transition->secondary_clip != NULL) { - // prevent dual transitions from going below 0 on the primary or above media length on the secondary + if (g.transition->secondary_clip != NULL) { + // prevent dual transitions from going below 0 on the primary or above media length on the secondary - validator = g.transition->parent_clip->get_clip_in_with_transition() + frame_diff; - if (validator < 0) frame_diff -= validator; + validator = g.transition->parent_clip->get_clip_in_with_transition() + frame_diff; + if (validator < 0) frame_diff -= validator; - validator = g.transition->secondary_clip->get_timeline_out_with_transition() - g.transition->secondary_clip->get_timeline_in_with_transition() - g.transition->get_length() + g.transition->secondary_clip->get_clip_in_with_transition() + frame_diff; - if (validator < 0) frame_diff -= validator; + validator = g.transition->secondary_clip->get_timeline_out_with_transition() - g.transition->secondary_clip->get_timeline_in_with_transition() - g.transition->get_length() + g.transition->secondary_clip->get_clip_in_with_transition() + frame_diff; + if (validator < 0) frame_diff -= validator; - validator = g.transition->parent_clip->clip_in + frame_diff - g.transition->parent_clip->getMaximumLength() + g.transition->get_true_length(); - if (validator > 0) frame_diff -= validator; + validator = g.transition->parent_clip->clip_in + frame_diff - g.transition->parent_clip->getMaximumLength() + g.transition->get_true_length(); + if (validator > 0) frame_diff -= validator; - validator = g.transition->secondary_clip->get_timeline_out_with_transition() - g.transition->secondary_clip->get_timeline_in_with_transition() + g.transition->secondary_clip->get_clip_in_with_transition() + frame_diff - g.transition->secondary_clip->getMaximumLength(); - if (validator > 0) frame_diff -= validator; - } else { - // prevent clip_in from going below 0 - if (c->media->get_type() == MEDIA_TYPE_SEQUENCE - || (ms != NULL && !ms->infinite_length)) { - validator = g.old_clip_in + frame_diff; - if (validator < 0) frame_diff -= validator; - } + validator = g.transition->secondary_clip->get_timeline_out_with_transition() - g.transition->secondary_clip->get_timeline_in_with_transition() + g.transition->secondary_clip->get_clip_in_with_transition() + frame_diff - g.transition->secondary_clip->getMaximumLength(); + if (validator > 0) frame_diff -= validator; + } else { + // prevent clip_in from going below 0 + if (c->media->get_type() == MEDIA_TYPE_SEQUENCE + || (ms != NULL && !ms->infinite_length)) { + validator = g.old_clip_in + frame_diff; + if (validator < 0) frame_diff -= validator; + } - // prevent clip length exceeding media length - if (c->media->get_type() == MEDIA_TYPE_SEQUENCE - || (ms != NULL && !ms->infinite_length)) { - validator = g.old_clip_in + g.ghost_length + frame_diff; - if (validator > g.media_length) frame_diff -= validator - g.media_length; - } - } + // prevent clip length exceeding media length + if (c->media->get_type() == MEDIA_TYPE_SEQUENCE + || (ms != NULL && !ms->infinite_length)) { + validator = g.old_clip_in + g.ghost_length + frame_diff; + if (validator > g.media_length) frame_diff -= validator - g.media_length; + } + } } // prevent clips from crossing tracks @@ -1406,121 +1421,121 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { } } } - } else if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION) { - if (panel_timeline->transition_tool_post_clip == -1) { - validate_transitions(c, panel_timeline->transition_tool_type, frame_diff); - } else { - Clip* otc = c; // open transition clip - Clip* ctc = sequence->clips.at(panel_timeline->transition_tool_post_clip); // close transition clip + } else if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION) { + if (panel_timeline->transition_tool_post_clip == -1) { + validate_transitions(c, panel_timeline->transition_tool_type, frame_diff); + } else { + Clip* otc = c; // open transition clip + Clip* ctc = sequence->clips.at(panel_timeline->transition_tool_post_clip); // close transition clip - if (panel_timeline->transition_tool_type == TA_CLOSING_TRANSITION) { - // swap - Clip* temp = otc; - otc = ctc; - ctc = temp; - } + if (panel_timeline->transition_tool_type == TA_CLOSING_TRANSITION) { + // swap + Clip* temp = otc; + otc = ctc; + ctc = temp; + } - // always gets a positive frame_diff - validate_transitions(otc, TA_OPENING_TRANSITION, frame_diff); - validate_transitions(ctc, TA_CLOSING_TRANSITION, frame_diff); + // always gets a positive frame_diff + validate_transitions(otc, TA_OPENING_TRANSITION, frame_diff); + validate_transitions(ctc, TA_CLOSING_TRANSITION, frame_diff); - // always gets a negative frame_diff - frame_diff = -frame_diff; - validate_transitions(otc, TA_OPENING_TRANSITION, frame_diff); - validate_transitions(ctc, TA_CLOSING_TRANSITION, frame_diff); - frame_diff = -frame_diff; - } - } - } - if (temp_frame_diff != frame_diff) panel_timeline->snapped = false; + // always gets a negative frame_diff + frame_diff = -frame_diff; + validate_transitions(otc, TA_OPENING_TRANSITION, frame_diff); + validate_transitions(ctc, TA_CLOSING_TRANSITION, frame_diff); + frame_diff = -frame_diff; + } + } + } + if (temp_frame_diff != frame_diff) panel_timeline->snapped = false; - // apply changes to ghosts - for (int i=0;ighosts.size();i++) { - Ghost& g = panel_timeline->ghosts[i]; + // apply changes to ghosts + for (int i=0;ighosts.size();i++) { + Ghost& g = panel_timeline->ghosts[i]; - if (panel_timeline->tool == TIMELINE_TOOL_SLIP) { - g.clip_in = g.old_clip_in - frame_diff; - } else if (g.trimming) { - long ghost_diff = frame_diff; + if (panel_timeline->tool == TIMELINE_TOOL_SLIP) { + g.clip_in = g.old_clip_in - frame_diff; + } else if (g.trimming) { + long ghost_diff = frame_diff; - // prevent trimming clips from overlapping each other - for (int j=0;jghosts.size();j++) { - const Ghost& comp = panel_timeline->ghosts.at(j); - if (i != j && g.track == comp.track) { - long validator; - if (g.trim_in && comp.out < g.out) { - validator = (g.old_in + ghost_diff) - comp.out; - if (validator < 0) ghost_diff -= validator; - } else if (comp.in > g.in) { - validator = (g.old_out + ghost_diff) - comp.in; - if (validator > 0) ghost_diff -= validator; - } - } - } + // prevent trimming clips from overlapping each other + for (int j=0;jghosts.size();j++) { + const Ghost& comp = panel_timeline->ghosts.at(j); + if (i != j && g.track == comp.track) { + long validator; + if (g.trim_in && comp.out < g.out) { + validator = (g.old_in + ghost_diff) - comp.out; + if (validator < 0) ghost_diff -= validator; + } else if (comp.in > g.in) { + validator = (g.old_out + ghost_diff) - comp.in; + if (validator > 0) ghost_diff -= validator; + } + } + } - // apply changes - if (g.transition != NULL && g.transition->secondary_clip != NULL) { - if (g.trim_in) ghost_diff = -ghost_diff; - g.in = g.old_in - ghost_diff; - g.out = g.old_out + ghost_diff; - } else if (g.trim_in) { - g.in = g.old_in + ghost_diff; - g.clip_in = g.old_clip_in + ghost_diff; - } else { - g.out = g.old_out + ghost_diff; - } - } else if (clips_are_movable) { - g.track = g.old_track; - g.in = g.old_in + frame_diff; - g.out = g.old_out + frame_diff; + // apply changes + if (g.transition != NULL && g.transition->secondary_clip != NULL) { + if (g.trim_in) ghost_diff = -ghost_diff; + g.in = g.old_in - ghost_diff; + g.out = g.old_out + ghost_diff; + } else if (g.trim_in) { + g.in = g.old_in + ghost_diff; + g.clip_in = g.old_clip_in + ghost_diff; + } else { + g.out = g.old_out + ghost_diff; + } + } else if (clips_are_movable) { + g.track = g.old_track; + g.in = g.old_in + frame_diff; + g.out = g.old_out + frame_diff; - if (g.transition != NULL && g.transition == sequence->clips.at(g.clip)->get_opening_transition()) { + if (g.transition != NULL && g.transition == sequence->clips.at(g.clip)->get_opening_transition()) { g.clip_in = g.old_clip_in + frame_diff; } - if (panel_timeline->importing) { - if ((panel_timeline->video_ghosts && mouse_track < 0) - || (panel_timeline->audio_ghosts && mouse_track >= 0)) { - int abs_track_diff = abs(track_diff); - if (g.old_track < 0) { // clip is video - g.track -= abs_track_diff; - } else { // clip is audio - g.track += abs_track_diff; - } - } + if (panel_timeline->importing) { + if ((panel_timeline->video_ghosts && mouse_track < 0) + || (panel_timeline->audio_ghosts && mouse_track >= 0)) { + int abs_track_diff = abs(track_diff); + if (g.old_track < 0) { // clip is video + g.track -= abs_track_diff; + } else { // clip is audio + g.track += abs_track_diff; + } + } } else if (same_sign(g.old_track, panel_timeline->drag_track_start)) { - g.track += track_diff; - } - } else if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION) { - if (panel_timeline->transition_tool_post_clip > -1) { - g.in = g.old_in - frame_diff; - g.out = g.old_out + frame_diff; - } else if (panel_timeline->transition_tool_type == TA_OPENING_TRANSITION) { - g.out = g.old_out + frame_diff; - } else { - g.in = g.old_in + frame_diff; - } - } + g.track += track_diff; + } + } else if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION) { + if (panel_timeline->transition_tool_post_clip > -1) { + g.in = g.old_in - frame_diff; + g.out = g.old_out + frame_diff; + } else if (panel_timeline->transition_tool_type == TA_OPENING_TRANSITION) { + g.out = g.old_out + frame_diff; + } else { + g.in = g.old_in + frame_diff; + } + } earliest_in_point = qMin(earliest_in_point, g.in); - } + } - // apply changes to selections - if (panel_timeline->tool != TIMELINE_TOOL_SLIP && !panel_timeline->importing && !panel_timeline->creating) { + // apply changes to selections + if (panel_timeline->tool != TIMELINE_TOOL_SLIP && !panel_timeline->importing && !panel_timeline->creating) { for (int i=0;iselections.size();i++) { Selection& s = sequence->selections[i]; - if (panel_timeline->trim_target > -1) { - if (panel_timeline->trim_in_point) { - s.in = s.old_in + frame_diff; - } else { - s.out = s.old_out + frame_diff; - } + if (panel_timeline->trim_target > -1) { + if (panel_timeline->trim_in_point) { + s.in = s.old_in + frame_diff; + } else { + s.out = s.old_out + frame_diff; + } } else if (clips_are_movable) { for (int i=0;iselections.size();i++) { Selection& s = sequence->selections[i]; - s.in = s.old_in + frame_diff; - s.out = s.old_out + frame_diff; - s.track = s.old_track; + s.in = s.old_in + frame_diff; + s.out = s.old_out + frame_diff; + s.track = s.old_track; if (panel_timeline->importing) { int abs_track_diff = abs(track_diff); @@ -1532,14 +1547,14 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { } else { if (same_sign(s.track, panel_timeline->drag_track_start)) s.track += track_diff; } - } - } - } - } + } + } + } + } if (panel_timeline->importing) { QToolTip::showText(mapToGlobal(mouse_pos), frame_to_timecode(earliest_in_point, config.timecode_view, sequence->frame_rate)); - } else { + } else { QString tip = ((frame_diff < 0) ? "-" : "+") + frame_to_timecode(qAbs(frame_diff), config.timecode_view, sequence->frame_rate); if (panel_timeline->trim_target > -1) { // find which clip is being moved @@ -1567,408 +1582,399 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { } void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { - tooltip_timer.stop(); - if (sequence != NULL) { - bool alt = (event->modifiers() & Qt::AltModifier); + tooltip_timer.stop(); + if (sequence != NULL) { + bool alt = (event->modifiers() & Qt::AltModifier); - panel_timeline->cursor_frame = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x()); - panel_timeline->cursor_track = getTrackFromScreenPoint(event->pos().y()); + panel_timeline->cursor_frame = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x()); + panel_timeline->cursor_track = getTrackFromScreenPoint(event->pos().y()); panel_timeline->move_insert = ((event->modifiers() & Qt::ControlModifier) && (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->importing || panel_timeline->creating)); - if (!panel_timeline->moving_init) track_resizing = false; + if (!panel_timeline->moving_init) track_resizing = false; if (isLiveEditing()) { panel_timeline->snap_to_timeline(&panel_timeline->cursor_frame, !config.edit_tool_also_seeks || !panel_timeline->selecting, true, true); - } - if (panel_timeline->selecting) { - int selection_count = 1 + qMax(panel_timeline->cursor_track, panel_timeline->drag_track_start) - qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start) + panel_timeline->selection_offset; + } + if (panel_timeline->selecting) { + int selection_count = 1 + qMax(panel_timeline->cursor_track, panel_timeline->drag_track_start) - qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start) + panel_timeline->selection_offset; if (sequence->selections.size() != selection_count) { sequence->selections.resize(selection_count); - } - int minimum_selection_track = qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start); - for (int i=panel_timeline->selection_offset;icursor_track, panel_timeline->drag_track_start); + for (int i=panel_timeline->selection_offset;iselections[i]; - s.track = minimum_selection_track + i - panel_timeline->selection_offset; - long in = panel_timeline->drag_frame_start; - long out = panel_timeline->cursor_frame; - s.in = qMin(in, out); - s.out = qMax(in, out); - } + s.track = minimum_selection_track + i - panel_timeline->selection_offset; + long in = panel_timeline->drag_frame_start; + long out = panel_timeline->cursor_frame; + s.in = qMin(in, out); + s.out = qMax(in, out); + } - // select linked clips too - if (config.edit_tool_selects_links) { - for (int j=0;jclips.size();j++) { - Clip* c = sequence->clips.at(j); + // select linked clips too + if (config.edit_tool_selects_links) { + for (int j=0;jclips.size();j++) { + Clip* c = sequence->clips.at(j); for (int k=0;kselections.size();k++) { const Selection& s = sequence->selections.at(k); - if (!(c->timeline_in < s.in && c->timeline_out < s.in) && - !(c->timeline_in > s.out && c->timeline_out > s.out) && - c->track == s.track) { + if (!(c->timeline_in < s.in && c->timeline_out < s.in) && + !(c->timeline_in > s.out && c->timeline_out > s.out) && + c->track == s.track) { - QVector linked_tracks = panel_timeline->get_tracks_of_linked_clips(j); - for (int k=0;k linked_tracks = panel_timeline->get_tracks_of_linked_clips(j); + for (int k=0;kselections.size();l++) { const Selection& test_sel = sequence->selections.at(l); - if (test_sel.track == linked_tracks.at(k) && - test_sel.in == s.in && - test_sel.out == s.out) { - found = true; - break; - } - } - if (!found) { - Selection link_sel; - link_sel.in = s.in; - link_sel.out = s.out; - link_sel.track = linked_tracks.at(k); + if (test_sel.track == linked_tracks.at(k) && + test_sel.in == s.in && + test_sel.out == s.out) { + found = true; + break; + } + } + if (!found) { + Selection link_sel; + link_sel.in = s.in; + link_sel.out = s.out; + link_sel.track = linked_tracks.at(k); sequence->selections.append(link_sel); - } - } + } + } - break; - } - } - } - } + break; + } + } + } + } - if (config.edit_tool_also_seeks) { + if (config.edit_tool_also_seeks) { panel_sequence_viewer->seek(qMin(panel_timeline->drag_frame_start, panel_timeline->cursor_frame)); } else { panel_timeline->repaint_timeline(); - } - } else if (panel_timeline->hand_moving) { - panel_timeline->block_repaints = true; - panel_timeline->ui->horizontalScrollBar->setValue(panel_timeline->ui->horizontalScrollBar->value() + panel_timeline->drag_x_start - event->pos().x()); - scrollBar->setValue(scrollBar->value() + panel_timeline->drag_y_start - event->pos().y()); - panel_timeline->block_repaints = false; + } + } else if (panel_timeline->hand_moving) { + panel_timeline->block_repaints = true; + panel_timeline->horizontalScrollBar->setValue(panel_timeline->horizontalScrollBar->value() + panel_timeline->drag_x_start - event->pos().x()); + scrollBar->setValue(scrollBar->value() + panel_timeline->drag_y_start - event->pos().y()); + panel_timeline->block_repaints = false; - panel_timeline->repaint_timeline(); + panel_timeline->repaint_timeline(); - panel_timeline->drag_x_start = event->pos().x(); - panel_timeline->drag_y_start = event->pos().y(); - } else if (panel_timeline->moving_init) { - if (track_resizing) { - int diff = track_resize_mouse_cache - event->pos().y(); - int new_height = track_resize_old_value; - if (bottom_align) { - new_height += diff; - } else { - new_height -= diff; - } - if (new_height < TRACK_MIN_HEIGHT) new_height = TRACK_MIN_HEIGHT; - panel_timeline->calculate_track_height(track_target, new_height); + panel_timeline->drag_x_start = event->pos().x(); + panel_timeline->drag_y_start = event->pos().y(); + } else if (panel_timeline->moving_init) { + if (track_resizing) { + int diff = track_resize_mouse_cache - event->pos().y(); + int new_height = track_resize_old_value; + if (bottom_align) { + new_height += diff; + } else { + new_height -= diff; + } + if (new_height < TRACK_MIN_HEIGHT) new_height = TRACK_MIN_HEIGHT; + panel_timeline->calculate_track_height(track_target, new_height); update(); - } else if (panel_timeline->moving_proc) { - update_ghosts(event->pos(), event->modifiers() & Qt::ShiftModifier); - } else { - // set up movement - // create ghosts - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + } else if (panel_timeline->moving_proc) { + update_ghosts(event->pos(), event->modifiers() & Qt::ShiftModifier); + } else { + // set up movement + // create ghosts + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); if (c != NULL) { - Ghost g; + Ghost g; g.transition = NULL; bool add = panel_timeline->is_clip_selected(c, true); // if a whole clip is not selected, maybe just a transition is - if (panel_timeline->tool == TIMELINE_TOOL_POINTER && (c->get_opening_transition() != NULL || c->get_closing_transition() != NULL)) { + if (panel_timeline->tool == TIMELINE_TOOL_POINTER && (c->get_opening_transition() != NULL || c->get_closing_transition() != NULL)) { // check if any selections contain the whole clip or transition for (int j=0;jselections.size();j++) { const Selection& s = sequence->selections.at(j); if (s.track == c->track) { - if (selection_contains_transition(s, c, TA_OPENING_TRANSITION)) { - g.transition = c->get_opening_transition(); + if (selection_contains_transition(s, c, TA_OPENING_TRANSITION)) { + g.transition = c->get_opening_transition(); add = true; break; - } else if (selection_contains_transition(s, c, TA_CLOSING_TRANSITION)) { - g.transition = c->get_closing_transition(); + } else if (selection_contains_transition(s, c, TA_CLOSING_TRANSITION)) { + g.transition = c->get_closing_transition(); add = true; break; } } } - } + } - if (add && g.transition != NULL) { - // check for duplicate transitions - for (int j=0;jghosts.size();j++) { - if (panel_timeline->ghosts.at(j).transition == g.transition) { - add = false; - break; - } - } - } + if (add && g.transition != NULL) { + // check for duplicate transitions + for (int j=0;jghosts.size();j++) { + if (panel_timeline->ghosts.at(j).transition == g.transition) { + add = false; + break; + } + } + } - if (add) { + if (add) { g.clip = i; g.trimming = (panel_timeline->trim_target > -1); g.trim_in = panel_timeline->trim_in_point; panel_timeline->ghosts.append(g); } - } - } + } + } - int size = panel_timeline->ghosts.size(); - if (panel_timeline->tool == TIMELINE_TOOL_ROLLING) { - for (int i=0;iclips.at(panel_timeline->ghosts.at(i).clip); + int size = panel_timeline->ghosts.size(); + if (panel_timeline->tool == TIMELINE_TOOL_ROLLING) { + for (int i=0;iclips.at(panel_timeline->ghosts.at(i).clip); - // see if any ghosts are touching, in which case flip them - for (int k=0;kclips.at(panel_timeline->ghosts.at(k).clip); - if ((panel_timeline->trim_in_point && comp_clip->timeline_out == ghost_clip->timeline_in) || - (!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) { - panel_timeline->ghosts[k].trim_in = !panel_timeline->trim_in_point; - } - } - } + // see if any ghosts are touching, in which case flip them + for (int k=0;kclips.at(panel_timeline->ghosts.at(k).clip); + if ((panel_timeline->trim_in_point && comp_clip->timeline_out == ghost_clip->timeline_in) || + (!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) { + panel_timeline->ghosts[k].trim_in = !panel_timeline->trim_in_point; + } + } + } - // then look for other clips we're touching - for (int i=0;ighosts.at(i); - Clip* ghost_clip = sequence->clips.at(g.clip); - for (int j=0;jclips.size();j++) { - Clip* comp_clip = sequence->clips.at(j); - if (comp_clip->track == ghost_clip->track) { - if ((panel_timeline->trim_in_point && comp_clip->timeline_out == ghost_clip->timeline_in) || - (!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) { - // see if this clip is already selected, and if so just switch the trim_in - bool found = false; - int duplicate_ghost_index; - for (duplicate_ghost_index=0;duplicate_ghost_indexghosts.at(duplicate_ghost_index).clip == j) { - found = true; - break; - } - } - if (g.trim_in == panel_timeline->trim_in_point) { - if (!found) { - // add ghost for this clip with opposite trim_in - Ghost gh; + // then look for other clips we're touching + for (int i=0;ighosts.at(i); + Clip* ghost_clip = sequence->clips.at(g.clip); + for (int j=0;jclips.size();j++) { + Clip* comp_clip = sequence->clips.at(j); + if (comp_clip->track == ghost_clip->track) { + if ((panel_timeline->trim_in_point && comp_clip->timeline_out == ghost_clip->timeline_in) || + (!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) { + // see if this clip is already selected, and if so just switch the trim_in + bool found = false; + int duplicate_ghost_index; + for (duplicate_ghost_index=0;duplicate_ghost_indexghosts.at(duplicate_ghost_index).clip == j) { + found = true; + break; + } + } + if (g.trim_in == panel_timeline->trim_in_point) { + if (!found) { + // add ghost for this clip with opposite trim_in + Ghost gh; gh.transition = NULL; - gh.clip = j; - gh.trimming = (panel_timeline->trim_target > -1); - gh.trim_in = !panel_timeline->trim_in_point; - panel_timeline->ghosts.append(gh); - } - } else { - if (found) { - panel_timeline->ghosts.removeAt(duplicate_ghost_index); - size--; - if (duplicate_ghost_index < i) i--; - } - } - } - } - } - } - } else if (panel_timeline->tool == TIMELINE_TOOL_SLIDE) { - for (int i=0;ighosts.at(i); - Clip* ghost_clip = sequence->clips.at(g.clip); - panel_timeline->ghosts[i].trimming = false; - for (int j=0;jclips.size();j++) { - Clip* c = sequence->clips.at(j); + gh.clip = j; + gh.trimming = (panel_timeline->trim_target > -1); + gh.trim_in = !panel_timeline->trim_in_point; + panel_timeline->ghosts.append(gh); + } + } else { + if (found) { + panel_timeline->ghosts.removeAt(duplicate_ghost_index); + size--; + if (duplicate_ghost_index < i) i--; + } + } + } + } + } + } + } else if (panel_timeline->tool == TIMELINE_TOOL_SLIDE) { + for (int i=0;ighosts.at(i); + Clip* ghost_clip = sequence->clips.at(g.clip); + panel_timeline->ghosts[i].trimming = false; + for (int j=0;jclips.size();j++) { + Clip* c = sequence->clips.at(j); if (c != NULL && c->track == ghost_clip->track) { - bool found = false; - for (int k=0;kghosts.at(k).clip == j) { - found = true; - break; - } - } - if (!found) { - bool is_in = (c->timeline_in == ghost_clip->timeline_out); - if (is_in || c->timeline_out == ghost_clip->timeline_in) { - Ghost gh; + bool found = false; + for (int k=0;kghosts.at(k).clip == j) { + found = true; + break; + } + } + if (!found) { + bool is_in = (c->timeline_in == ghost_clip->timeline_out); + if (is_in || c->timeline_out == ghost_clip->timeline_in) { + Ghost gh; gh.transition = NULL; - gh.clip = j; - gh.trimming = true; - gh.trim_in = is_in; - panel_timeline->ghosts.append(gh); - } - } - } - } - } - } + gh.clip = j; + gh.trimming = true; + gh.trim_in = is_in; + panel_timeline->ghosts.append(gh); + } + } + } + } + } + } - init_ghosts(); + init_ghosts(); - // ripple edit prep - if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) { - QVector axis_ghosts; - for (int i=0;ighosts.size();i++) { - Clip* c = sequence->clips.at(panel_timeline->ghosts.at(i).clip); - bool found = false; - for (int j=0;jtrack == cc->track && - ((panel_timeline->trim_in_point && c->timeline_in < cc->timeline_in) || - (!panel_timeline->trim_in_point && c->timeline_out > cc->timeline_out))) { - axis_ghosts[j] = c; - found = true; - break; - } - } - if (!found) { - axis_ghosts.append(c); - } - } + // ripple edit prep + if (panel_timeline->tool == TIMELINE_TOOL_RIPPLE) { + long axis = LONG_MAX; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL && !panel_timeline->is_clip_selected(c, true)) { - for (int j=0;jtrim_in_point) ? axis->timeline_in : axis->timeline_out; - bool clip_is_pre = (c->timeline_in < comp_point); - QVector& clip_list = clip_is_pre ? pre_clips : post_clips; - bool found = false; - for (int k=0;ktrack == c->track) { - if (clip_is_pre == (c->timeline_in > cached->timeline_in)) { - clip_list[k] = c; - } - found = true; - break; - } - } - if (!found) { - clip_list.append(c); - } - } - } - } - } + for (int i=0;ighosts.size();i++) { + Clip* c = sequence->clips.at(panel_timeline->ghosts.at(i).clip); + if (panel_timeline->trim_in_point) { + axis = qMin(axis, c->timeline_in); + } else { + axis = qMin(axis, c->timeline_out); + } + } - // store selections - selection_command = new SetSelectionsCommand(sequence); - selection_command->old_data = sequence->selections; + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL && !panel_timeline->is_clip_selected(c, true)) { + bool clip_is_post = (c->timeline_in >= axis); - panel_timeline->moving_proc = true; - } - update_ui(false); - } else if (panel_timeline->splitting) { - int track_start = qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start); - int track_end = qMax(panel_timeline->cursor_track, panel_timeline->drag_track_start); - int track_size = 1 + track_end - track_start; - panel_timeline->split_tracks.resize(track_size); - for (int i=0;isplit_tracks[i] = track_start + i; - } + // see if this a clip on this track is already in the list, and if it's closer + bool found = false; + QVector& clip_list = clip_is_post ? post_clips : pre_clips; + for (int j=0;jtrack == c->track) { + if ((!clip_is_post && compare->timeline_out < c->timeline_out) + || (clip_is_post && compare->timeline_in > c->timeline_in)) { + clip_list[j] = c; + } + found = true; + break; + } + } + if (!found) { + clip_list.append(c); + } + } + } + } - if (!alt) { - for (int i=0;idrag_frame_start, panel_timeline->split_tracks[i]); - if (clip_index > -1) { - QVector tracks = panel_timeline->get_tracks_of_linked_clips(clip_index); - for (int j=0;j track_end) { - panel_timeline->split_tracks.append(tracks.at(j)); - } - } - } - } - } - update_ui(false); - } else if (panel_timeline->rect_select_init) { - if (panel_timeline->rect_select_proc) { - panel_timeline->rect_select_w = event->pos().x() - panel_timeline->rect_select_x; - panel_timeline->rect_select_h = event->pos().y() - panel_timeline->rect_select_y; - if (bottom_align) panel_timeline->rect_select_h -= height(); + // store selections + selection_command = new SetSelectionsCommand(sequence); + selection_command->old_data = sequence->selections; + + panel_timeline->moving_proc = true; + } + update_ui(false); + } else if (panel_timeline->splitting) { + int track_start = qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start); + int track_end = qMax(panel_timeline->cursor_track, panel_timeline->drag_track_start); + int track_size = 1 + track_end - track_start; + panel_timeline->split_tracks.resize(track_size); + for (int i=0;isplit_tracks[i] = track_start + i; + } + + if (!alt) { + for (int i=0;idrag_frame_start, panel_timeline->split_tracks[i]); + if (clip_index > -1) { + QVector tracks = panel_timeline->get_tracks_of_linked_clips(clip_index); + for (int j=0;j track_end) { + panel_timeline->split_tracks.append(tracks.at(j)); + } + } + } + } + } + update_ui(false); + } else if (panel_timeline->rect_select_init) { + if (panel_timeline->rect_select_proc) { + panel_timeline->rect_select_w = event->pos().x() - panel_timeline->rect_select_x; + panel_timeline->rect_select_h = event->pos().y() - panel_timeline->rect_select_y; + if (bottom_align) panel_timeline->rect_select_h -= height(); long frame_start = panel_timeline->getTimelineFrameFromScreenPoint(panel_timeline->rect_select_x); long frame_end = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x()); - long frame_min = qMin(frame_start, frame_end); - long frame_max = qMax(frame_start, frame_end); + long frame_min = qMin(frame_start, frame_end); + long frame_max = qMax(frame_start, frame_end); - int rsy = panel_timeline->rect_select_y; - if (bottom_align) rsy += height(); - int track_start = getTrackFromScreenPoint(rsy); - int track_end = getTrackFromScreenPoint(event->pos().y()); - int track_min = qMin(track_start, track_end); - int track_max = qMax(track_start, track_end); + int rsy = panel_timeline->rect_select_y; + if (bottom_align) rsy += height(); + int track_start = getTrackFromScreenPoint(rsy); + int track_end = getTrackFromScreenPoint(event->pos().y()); + int track_min = qMin(track_start, track_end); + int track_max = qMax(track_start, track_end); - QVector selected_clips; - for (int i=0;iclips.size();i++) { - Clip* clip = sequence->clips.at(i); - if (clip != NULL && - clip->track >= track_min && - clip->track <= track_max && - !(clip->timeline_in < frame_min && clip->timeline_out < frame_min) && - !(clip->timeline_in > frame_max && clip->timeline_out > frame_max)) { - QVector session_clips; - session_clips.append(clip); + QVector selected_clips; + for (int i=0;iclips.size();i++) { + Clip* clip = sequence->clips.at(i); + if (clip != NULL && + clip->track >= track_min && + clip->track <= track_max && + !(clip->timeline_in < frame_min && clip->timeline_out < frame_min) && + !(clip->timeline_in > frame_max && clip->timeline_out > frame_max)) { + QVector session_clips; + session_clips.append(clip); - if (!alt) { - for (int j=0;jlinked.size();j++) { - session_clips.append(sequence->clips.at(clip->linked.at(j))); - } - } + if (!alt) { + for (int j=0;jlinked.size();j++) { + session_clips.append(sequence->clips.at(clip->linked.at(j))); + } + } - for (int j=0;jselections.resize(selected_clips.size() + panel_timeline->selection_offset); - for (int i=0;iselections[i+panel_timeline->selection_offset]; - Clip* clip = selected_clips.at(i); - s.old_in = s.in = clip->timeline_in; - s.old_out = s.out = clip->timeline_out; - s.old_track = s.track = clip->track; - } + Clip* clip = selected_clips.at(i); + s.old_in = s.in = clip->timeline_in; + s.old_out = s.out = clip->timeline_out; + s.old_track = s.track = clip->track; + } panel_timeline->repaint_timeline(); - } else { - panel_timeline->rect_select_x = event->pos().x(); - panel_timeline->rect_select_y = event->pos().y(); - if (bottom_align) panel_timeline->rect_select_y -= height(); - panel_timeline->rect_select_w = 0; - panel_timeline->rect_select_h = 0; - panel_timeline->rect_select_proc = true; - } + } else { + panel_timeline->rect_select_x = event->pos().x(); + panel_timeline->rect_select_y = event->pos().y(); + if (bottom_align) panel_timeline->rect_select_y -= height(); + panel_timeline->rect_select_w = 0; + panel_timeline->rect_select_h = 0; + panel_timeline->rect_select_proc = true; + } } else if (isLiveEditing()) { // redraw because we have a cursor panel_timeline->repaint_timeline(); - } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER || - panel_timeline->tool == TIMELINE_TOOL_RIPPLE || - panel_timeline->tool == TIMELINE_TOOL_ROLLING) { + } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER || + panel_timeline->tool == TIMELINE_TOOL_RIPPLE || + panel_timeline->tool == TIMELINE_TOOL_ROLLING) { QToolTip::hideText(); - QPoint pos = event->pos(); + QPoint pos = event->pos(); - int lim = 5; - int mouse_track = getTrackFromScreenPoint(pos.y()); + int lim = 5; + int mouse_track = getTrackFromScreenPoint(pos.y()); long mouse_frame_lower = panel_timeline->getTimelineFrameFromScreenPoint(pos.x()-lim)-1; long mouse_frame_upper = panel_timeline->getTimelineFrameFromScreenPoint(pos.x()+lim)+1; - bool found = false; - bool cursor_contains_clip = false; - int closeness = INT_MAX; + bool found = false; + bool cursor_contains_clip = false; + int closeness = INT_MAX; int min_track = INT_MAX; int max_track = INT_MIN; panel_timeline->transition_select = TA_NO_TRANSITION; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); if (c != NULL) { min_track = qMin(min_track, c->track); max_track = qMax(max_track, c->track); @@ -1980,9 +1986,9 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { tooltip_timer.start(); tooltip_clip = i; - if (c->get_opening_transition() != NULL && panel_timeline->cursor_frame <= c->timeline_in + c->get_opening_transition()->get_true_length()) { + if (c->get_opening_transition() != NULL && panel_timeline->cursor_frame <= c->timeline_in + c->get_opening_transition()->get_true_length()) { panel_timeline->transition_select = TA_OPENING_TRANSITION; - } else if (c->get_closing_transition() != NULL && panel_timeline->cursor_frame >= c->timeline_out - c->get_closing_transition()->get_true_length()) { + } else if (c->get_closing_transition() != NULL && panel_timeline->cursor_frame >= c->timeline_out - c->get_closing_transition()->get_true_length()) { panel_timeline->transition_select = TA_CLOSING_TRANSITION; } } @@ -2005,8 +2011,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } } if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { - if (c->get_opening_transition() != NULL) { - long transition_point = c->timeline_in + c->get_opening_transition()->get_true_length(); + if (c->get_opening_transition() != NULL) { + long transition_point = c->timeline_in + c->get_opening_transition()->get_true_length(); if (transition_point > mouse_frame_lower && transition_point < mouse_frame_upper) { int nc = qAbs(transition_point - 1 - panel_timeline->cursor_frame); @@ -2019,8 +2025,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } } } - if (c->get_closing_transition() != NULL) { - long transition_point = c->timeline_out - c->get_closing_transition()->get_true_length(); + if (c->get_closing_transition() != NULL) { + long transition_point = c->timeline_out - c->get_closing_transition()->get_true_length(); if (transition_point > mouse_frame_lower && transition_point < mouse_frame_upper) { int nc = qAbs(transition_point + 1 - panel_timeline->cursor_frame); if (nc < closeness) { @@ -2035,19 +2041,19 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } } } - } - /*if (cursor_contains_clip) { + } + /*if (cursor_contains_clip) { QToolTip::showText(mapToGlobal(event->pos()), "HOVER OVER CLIP"); - }*/ - if (found) { - setCursor(Qt::SizeHorCursor); - } else { - panel_timeline->trim_target = -1; + }*/ + if (found) { + setCursor(Qt::SizeHorCursor); + } else { + panel_timeline->trim_target = -1; - // look for track heights - int track_y = 0; - for (int i=0;iget_track_height_size(bottom_align);i++) { - int track = (bottom_align) ? -1-i : i; + // look for track heights + int track_y = 0; + for (int i=0;iget_track_height_size(bottom_align);i++) { + int track = (bottom_align) ? -1-i : i; if (track >= min_track && track <= max_track) { int track_height = panel_timeline->calculate_track_height(track, -1); track_y += track_height; @@ -2065,74 +2071,74 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { break; } } - } + } - if (found) { - setCursor(Qt::SizeVerCursor); - } else { - unsetCursor(); - } + if (found) { + setCursor(Qt::SizeVerCursor); + } else { + unsetCursor(); + } } - } else if (panel_timeline->tool == TIMELINE_TOOL_SLIP) { - if (getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track) > -1) { - setCursor(Qt::SizeHorCursor); - } else { - unsetCursor(); - } - } else if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION) { - if (panel_timeline->transition_tool_init) { - if (panel_timeline->transition_tool_proc) { - update_ghosts(event->pos(), event->modifiers() & Qt::ShiftModifier); - } else { - Clip* c = sequence->clips.at(panel_timeline->transition_tool_pre_clip); + } else if (panel_timeline->tool == TIMELINE_TOOL_SLIP) { + if (getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track) > -1) { + setCursor(Qt::SizeHorCursor); + } else { + unsetCursor(); + } + } else if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION) { + if (panel_timeline->transition_tool_init) { + if (panel_timeline->transition_tool_proc) { + update_ghosts(event->pos(), event->modifiers() & Qt::ShiftModifier); + } else { + Clip* c = sequence->clips.at(panel_timeline->transition_tool_pre_clip); - Ghost g; + Ghost g; - g.in = g.old_in = g.out = g.old_out = (panel_timeline->transition_tool_type == TA_OPENING_TRANSITION) ? c->timeline_in : c->timeline_out; - g.track = c->track; - g.clip = panel_timeline->transition_tool_pre_clip; - g.media_stream = panel_timeline->transition_tool_type; - g.trimming = false; + g.in = g.old_in = g.out = g.old_out = (panel_timeline->transition_tool_type == TA_OPENING_TRANSITION) ? c->timeline_in : c->timeline_out; + g.track = c->track; + g.clip = panel_timeline->transition_tool_pre_clip; + g.media_stream = panel_timeline->transition_tool_type; + g.trimming = false; - panel_timeline->ghosts.append(g); + panel_timeline->ghosts.append(g); - panel_timeline->transition_tool_proc = true; - } - } else { + panel_timeline->transition_tool_proc = true; + } + } else { int mouse_clip = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); if (mouse_clip > -1) { Clip* c = sequence->clips.at(mouse_clip); if (same_sign(c->track, panel_timeline->transition_tool_side)) { - panel_timeline->transition_tool_pre_clip = mouse_clip; + panel_timeline->transition_tool_pre_clip = mouse_clip; long halfway = c->timeline_in + (c->getLength()/2); - long between_range = getFrameFromScreenPoint(panel_timeline->zoom, TRANSITION_BETWEEN_RANGE) + 1; + long between_range = getFrameFromScreenPoint(panel_timeline->zoom, TRANSITION_BETWEEN_RANGE) + 1; - if (panel_timeline->cursor_frame > halfway) { - panel_timeline->transition_tool_type = TA_CLOSING_TRANSITION; - } else { - panel_timeline->transition_tool_type = TA_OPENING_TRANSITION; - } + if (panel_timeline->cursor_frame > halfway) { + panel_timeline->transition_tool_type = TA_CLOSING_TRANSITION; + } else { + panel_timeline->transition_tool_type = TA_OPENING_TRANSITION; + } - panel_timeline->transition_tool_post_clip = -1; - if (panel_timeline->cursor_frame < c->timeline_in + between_range) { - panel_timeline->transition_tool_post_clip = getClipIndexFromCoords(c->timeline_in-1, c->track); - } else if (panel_timeline->cursor_frame > c->timeline_out - between_range) { - panel_timeline->transition_tool_post_clip = getClipIndexFromCoords(c->timeline_out+1, c->track); - } + panel_timeline->transition_tool_post_clip = -1; + if (panel_timeline->cursor_frame < c->timeline_in + between_range) { + panel_timeline->transition_tool_post_clip = getClipIndexFromCoords(c->timeline_in-1, c->track); + } else if (panel_timeline->cursor_frame > c->timeline_out - between_range) { + panel_timeline->transition_tool_post_clip = getClipIndexFromCoords(c->timeline_out+1, c->track); + } } - } else { - panel_timeline->transition_tool_pre_clip = -1; - panel_timeline->transition_tool_post_clip = -1; - } - } + } else { + panel_timeline->transition_tool_pre_clip = -1; + panel_timeline->transition_tool_post_clip = -1; + } + } - panel_timeline->repaint_timeline(); - } - } + panel_timeline->repaint_timeline(); + } + } } void TimelineWidget::leaveEvent(QEvent*) { - tooltip_timer.stop(); + tooltip_timer.stop(); } int color_brightness(int r, int g, int b) { @@ -2171,52 +2177,52 @@ void draw_waveform(Clip* clip, FootageStream* ms, long media_length, QPainter *p } void draw_transition(QPainter& p, Clip* c, const QRect& clip_rect, QRect& text_rect, int transition_type) { - Transition* t = (transition_type == TA_OPENING_TRANSITION) ? c->get_opening_transition() : c->get_closing_transition(); - if (t != NULL) { - QColor transition_color(255, 0, 0, 16); - int transition_width = getScreenPointFromFrame(panel_timeline->zoom, t->get_true_length()); - int transition_height = clip_rect.height(); - int tr_y = clip_rect.y(); - int tr_x = 0; - if (transition_type == TA_OPENING_TRANSITION) { - tr_x = clip_rect.x(); - text_rect.setX(text_rect.x()+transition_width); - } else { - tr_x = clip_rect.right()-transition_width; - text_rect.setWidth(text_rect.width()-transition_width); - } - QRect transition_rect = QRect(tr_x, tr_y, transition_width, transition_height); - p.fillRect(transition_rect, transition_color); - QRect transition_text_rect(transition_rect.x() + CLIP_TEXT_PADDING, transition_rect.y() + CLIP_TEXT_PADDING, transition_rect.width() - CLIP_TEXT_PADDING, transition_rect.height() - CLIP_TEXT_PADDING); - if (transition_text_rect.width() > MAX_TEXT_WIDTH) { - bool draw_text = true; + Transition* t = (transition_type == TA_OPENING_TRANSITION) ? c->get_opening_transition() : c->get_closing_transition(); + if (t != NULL) { + QColor transition_color(255, 0, 0, 16); + int transition_width = getScreenPointFromFrame(panel_timeline->zoom, t->get_true_length()); + int transition_height = clip_rect.height(); + int tr_y = clip_rect.y(); + int tr_x = 0; + if (transition_type == TA_OPENING_TRANSITION) { + tr_x = clip_rect.x(); + text_rect.setX(text_rect.x()+transition_width); + } else { + tr_x = clip_rect.right()-transition_width; + text_rect.setWidth(text_rect.width()-transition_width); + } + QRect transition_rect = QRect(tr_x, tr_y, transition_width, transition_height); + p.fillRect(transition_rect, transition_color); + QRect transition_text_rect(transition_rect.x() + CLIP_TEXT_PADDING, transition_rect.y() + CLIP_TEXT_PADDING, transition_rect.width() - CLIP_TEXT_PADDING, transition_rect.height() - CLIP_TEXT_PADDING); + if (transition_text_rect.width() > MAX_TEXT_WIDTH) { + bool draw_text = true; - p.setPen(QColor(0, 0, 0, 96)); - if (t->secondary_clip == NULL) { - if (transition_type == TA_OPENING_TRANSITION) { - p.drawLine(transition_rect.bottomLeft(), transition_rect.topRight()); - } else { - p.drawLine(transition_rect.topLeft(), transition_rect.bottomRight()); - } - } else { - if (transition_type == TA_OPENING_TRANSITION) { - p.drawLine(QPoint(transition_rect.left(), transition_rect.center().y()), transition_rect.topRight()); - p.drawLine(QPoint(transition_rect.left(), transition_rect.center().y()), transition_rect.bottomRight()); - draw_text = false; - } else { - p.drawLine(QPoint(transition_rect.right(), transition_rect.center().y()), transition_rect.topLeft()); - p.drawLine(QPoint(transition_rect.right(), transition_rect.center().y()), transition_rect.bottomLeft()); - } - } + p.setPen(QColor(0, 0, 0, 96)); + if (t->secondary_clip == NULL) { + if (transition_type == TA_OPENING_TRANSITION) { + p.drawLine(transition_rect.bottomLeft(), transition_rect.topRight()); + } else { + p.drawLine(transition_rect.topLeft(), transition_rect.bottomRight()); + } + } else { + if (transition_type == TA_OPENING_TRANSITION) { + p.drawLine(QPoint(transition_rect.left(), transition_rect.center().y()), transition_rect.topRight()); + p.drawLine(QPoint(transition_rect.left(), transition_rect.center().y()), transition_rect.bottomRight()); + draw_text = false; + } else { + p.drawLine(QPoint(transition_rect.right(), transition_rect.center().y()), transition_rect.topLeft()); + p.drawLine(QPoint(transition_rect.right(), transition_rect.center().y()), transition_rect.bottomLeft()); + } + } - if (draw_text) { - p.setPen(Qt::white); - p.drawText(transition_text_rect, 0, t->meta->name, &transition_text_rect); - } - } - p.setPen(Qt::black); - p.drawRect(transition_rect); - } + if (draw_text) { + p.setPen(Qt::white); + p.drawText(transition_text_rect, 0, t->meta->name, &transition_text_rect); + } + } + p.setPen(Qt::black); + p.drawRect(transition_rect); + } } @@ -2258,7 +2264,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { QRect clip_rect(panel_timeline->getTimelineScreenPointFromFrame(clip->timeline_in), getScreenPointFromTrack(clip->track), getScreenPointFromFrame(panel_timeline->zoom, clip->getLength()), panel_timeline->calculate_track_height(clip->track, -1)); QRect text_rect(clip_rect.left() + CLIP_TEXT_PADDING, clip_rect.top() + CLIP_TEXT_PADDING, clip_rect.width() - CLIP_TEXT_PADDING - 1, clip_rect.height() - CLIP_TEXT_PADDING - 1); if (clip_rect.left() < width() && clip_rect.right() >= 0 && clip_rect.top() < height() && clip_rect.bottom() >= 0) { - QRect actual_clip_rect = clip_rect; + QRect actual_clip_rect = clip_rect; if (actual_clip_rect.x() < 0) actual_clip_rect.setX(0); if (actual_clip_rect.right() > width()) actual_clip_rect.setRight(width()); if (actual_clip_rect.y() < 0) actual_clip_rect.setY(0); @@ -2267,46 +2273,46 @@ void TimelineWidget::paintEvent(QPaintEvent*) { int thumb_x = clip_rect.x() + 1; - if (clip->media != NULL && clip->media->get_type() == MEDIA_TYPE_FOOTAGE) { + if (clip->media != NULL && clip->media->get_type() == MEDIA_TYPE_FOOTAGE) { bool draw_checkerboard = false; QRect checkerboard_rect(clip_rect); - Footage* m = clip->media->to_footage(); + Footage* m = clip->media->to_footage(); FootageStream* ms = m->get_stream_from_file_index(clip->track < 0, clip->media_stream); if (ms == NULL) { draw_checkerboard = true; } else if (ms->preview_done) { // draw top and tail triangles - int triangle_size = TRACK_MIN_HEIGHT >> 2; - if (!ms->infinite_length && clip_rect.width() > triangle_size) { - p.setPen(Qt::NoPen); - p.setBrush(QColor(80, 80, 80)); - if (clip->clip_in == 0 - && clip_rect.x() + triangle_size > 0 - && clip_rect.y() + triangle_size > 0 - && clip_rect.x() < width() - && clip_rect.y() < height()) { - const QPoint points[3] = { - QPoint(clip_rect.x(), clip_rect.y()), - QPoint(clip_rect.x() + triangle_size, clip_rect.y()), - QPoint(clip_rect.x(), clip_rect.y() + triangle_size) - }; - p.drawPolygon(points, 3); - text_rect.setLeft(text_rect.left() + (triangle_size >> 2)); - } - if (clip->timeline_out - clip->timeline_in + clip->clip_in == clip->getMaximumLength() - && clip_rect.right() - triangle_size < width() - && clip_rect.y() + triangle_size > 0 - && clip_rect.right() > 0 - && clip_rect.y() < height()) { - const QPoint points[3] = { - QPoint(clip_rect.right(), clip_rect.y()), - QPoint(clip_rect.right() - triangle_size, clip_rect.y()), - QPoint(clip_rect.right(), clip_rect.y() + triangle_size) - }; - p.drawPolygon(points, 3); - text_rect.setRight(text_rect.right() - (triangle_size >> 2)); - } - } + int triangle_size = TRACK_MIN_HEIGHT >> 2; + if (!ms->infinite_length && clip_rect.width() > triangle_size) { + p.setPen(Qt::NoPen); + p.setBrush(QColor(80, 80, 80)); + if (clip->clip_in == 0 + && clip_rect.x() + triangle_size > 0 + && clip_rect.y() + triangle_size > 0 + && clip_rect.x() < width() + && clip_rect.y() < height()) { + const QPoint points[3] = { + QPoint(clip_rect.x(), clip_rect.y()), + QPoint(clip_rect.x() + triangle_size, clip_rect.y()), + QPoint(clip_rect.x(), clip_rect.y() + triangle_size) + }; + p.drawPolygon(points, 3); + text_rect.setLeft(text_rect.left() + (triangle_size >> 2)); + } + if (clip->timeline_out - clip->timeline_in + clip->clip_in == clip->getMaximumLength() + && clip_rect.right() - triangle_size < width() + && clip_rect.y() + triangle_size > 0 + && clip_rect.right() > 0 + && clip_rect.y() < height()) { + const QPoint points[3] = { + QPoint(clip_rect.right(), clip_rect.y()), + QPoint(clip_rect.right() - triangle_size, clip_rect.y()), + QPoint(clip_rect.right(), clip_rect.y() + triangle_size) + }; + p.drawPolygon(points, 3); + text_rect.setRight(text_rect.right() - (triangle_size >> 2)); + } + } p.setBrush(Qt::NoBrush); @@ -2317,23 +2323,23 @@ void TimelineWidget::paintEvent(QPaintEvent*) { // draw thumbnail int thumb_y = p.fontMetrics().height()+CLIP_TEXT_PADDING+CLIP_TEXT_PADDING; if (thumb_x < width() && thumb_y < height()) { - int space_for_thumb = clip_rect.width()-1; - if (clip->get_opening_transition() != NULL) { - int ot_width = getScreenPointFromFrame(panel_timeline->zoom, clip->get_opening_transition()->get_true_length()); + int space_for_thumb = clip_rect.width()-1; + if (clip->get_opening_transition() != NULL) { + int ot_width = getScreenPointFromFrame(panel_timeline->zoom, clip->get_opening_transition()->get_true_length()); thumb_x += ot_width; space_for_thumb -= ot_width; } - if (clip->get_closing_transition() != NULL) { - space_for_thumb -= getScreenPointFromFrame(panel_timeline->zoom, clip->get_closing_transition()->get_true_length()); - } + if (clip->get_closing_transition() != NULL) { + space_for_thumb -= getScreenPointFromFrame(panel_timeline->zoom, clip->get_closing_transition()->get_true_length()); + } int thumb_height = clip_rect.height()-thumb_y; int thumb_width = (thumb_height*((double)ms->video_preview.width()/(double)ms->video_preview.height())); if (thumb_x + thumb_width >= 0 && thumb_height > thumb_y - && thumb_y + thumb_height >= 0 - && space_for_thumb > MAX_TEXT_WIDTH) { - int thumb_clip_width = qMin(thumb_width, space_for_thumb); - p.drawImage(QRect(thumb_x, clip_rect.y()+thumb_y, thumb_clip_width, thumb_height), ms->video_preview, QRect(0, 0, thumb_clip_width*((double)ms->video_preview.width()/(double)thumb_width), ms->video_preview.height())); + && thumb_y + thumb_height >= 0 + && space_for_thumb > MAX_TEXT_WIDTH) { + int thumb_clip_width = qMin(thumb_width, space_for_thumb); + p.drawImage(QRect(thumb_x, clip_rect.y()+thumb_y, thumb_clip_width, thumb_height), ms->video_preview, QRect(0, 0, thumb_clip_width*((double)ms->video_preview.width()/(double)thumb_width), ms->video_preview.height())); } } } else if (clip_rect.height() > TRACK_MIN_HEIGHT) { @@ -2387,8 +2393,8 @@ void TimelineWidget::paintEvent(QPaintEvent*) { } // draw clip transitions - draw_transition(p, clip, clip_rect, text_rect, TA_OPENING_TRANSITION); - draw_transition(p, clip, clip_rect, text_rect, TA_CLOSING_TRANSITION); + draw_transition(p, clip, clip_rect, text_rect, TA_OPENING_TRANSITION); + draw_transition(p, clip, clip_rect, text_rect, TA_CLOSING_TRANSITION); // top left bevel p.setPen(Qt::white); @@ -2418,41 +2424,41 @@ void TimelineWidget::paintEvent(QPaintEvent*) { } // bottom right gray - p.setPen(QColor(0, 0, 0, 128)); - if (clip_rect.right() >= 0 && clip_rect.right() < width()) p.drawLine(clip_rect.bottomRight(), clip_rect.topRight()); + p.setPen(QColor(0, 0, 0, 128)); + if (clip_rect.right() >= 0 && clip_rect.right() < width()) p.drawLine(clip_rect.bottomRight(), clip_rect.topRight()); if (clip_rect.bottom() >= 0 && clip_rect.bottom() < height()) p.drawLine(QPoint(qMax(0, clip_rect.left()), clip_rect.bottom()), QPoint(qMin(width(), clip_rect.right()), clip_rect.bottom())); - // draw transition tool - if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION && (panel_timeline->transition_tool_pre_clip == i || panel_timeline->transition_tool_post_clip == i)) { - int type = panel_timeline->transition_tool_type; - if (panel_timeline->transition_tool_post_clip == i) { - // invert transition type - type = (type == TA_CLOSING_TRANSITION) ? TA_OPENING_TRANSITION : TA_CLOSING_TRANSITION; - } - QRect transition_tool_rect = clip_rect; - if (type == TA_CLOSING_TRANSITION) { - if (panel_timeline->transition_tool_post_clip > -1) { - transition_tool_rect.setLeft(transition_tool_rect.right() - TRANSITION_BETWEEN_RANGE); - } else { - transition_tool_rect.setLeft(transition_tool_rect.left() + (3*(transition_tool_rect.width()>>2))); - } - } else { - if (panel_timeline->transition_tool_post_clip > -1) { - transition_tool_rect.setWidth(TRANSITION_BETWEEN_RANGE); - } else { - transition_tool_rect.setWidth(transition_tool_rect.width()>>2); - } - } - if (transition_tool_rect.left() < width() && transition_tool_rect.right() > 0) { - if (transition_tool_rect.left() < 0) { - transition_tool_rect.setLeft(0); - } - if (transition_tool_rect.right() > width()) { - transition_tool_rect.setRight(width()); - } - p.fillRect(transition_tool_rect, QColor(0, 0, 0, 128)); - } - } + // draw transition tool + if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION && (panel_timeline->transition_tool_pre_clip == i || panel_timeline->transition_tool_post_clip == i)) { + int type = panel_timeline->transition_tool_type; + if (panel_timeline->transition_tool_post_clip == i) { + // invert transition type + type = (type == TA_CLOSING_TRANSITION) ? TA_OPENING_TRANSITION : TA_CLOSING_TRANSITION; + } + QRect transition_tool_rect = clip_rect; + if (type == TA_CLOSING_TRANSITION) { + if (panel_timeline->transition_tool_post_clip > -1) { + transition_tool_rect.setLeft(transition_tool_rect.right() - TRANSITION_BETWEEN_RANGE); + } else { + transition_tool_rect.setLeft(transition_tool_rect.left() + (3*(transition_tool_rect.width()>>2))); + } + } else { + if (panel_timeline->transition_tool_post_clip > -1) { + transition_tool_rect.setWidth(TRANSITION_BETWEEN_RANGE); + } else { + transition_tool_rect.setWidth(transition_tool_rect.width()>>2); + } + } + if (transition_tool_rect.left() < width() && transition_tool_rect.right() > 0) { + if (transition_tool_rect.left() < 0) { + transition_tool_rect.setLeft(0); + } + if (transition_tool_rect.right() > width()) { + transition_tool_rect.setRight(width()); + } + p.fillRect(transition_tool_rect, QColor(0, 0, 0, 128)); + } + } } } } @@ -2531,16 +2537,16 @@ void TimelineWidget::paintEvent(QPaintEvent*) { } } - // draw rectangle select - if (panel_timeline->rect_select_proc) { - int rsy = panel_timeline->rect_select_y; - int rsh = panel_timeline->rect_select_h; - if (bottom_align) { - rsy += height(); - } + // draw rectangle select + if (panel_timeline->rect_select_proc) { + int rsy = panel_timeline->rect_select_y; + int rsh = panel_timeline->rect_select_h; + if (bottom_align) { + rsy += height(); + } QRect rect_select(panel_timeline->rect_select_x, rsy, panel_timeline->rect_select_w, rsh); draw_selection_rectangle(p, rect_select); - } + } // Draw ghosts if (!panel_timeline->ghosts.isEmpty()) { @@ -2564,7 +2570,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { } } - // draw insert indicator + // draw insert indicator if (panel_timeline->move_insert && !insert_points.isEmpty()) { p.setBrush(Qt::white); p.setPen(Qt::NoPen); @@ -2583,35 +2589,35 @@ void TimelineWidget::paintEvent(QPaintEvent*) { } - // Draw splitting cursor - if (panel_timeline->splitting) { - for (int i=0;isplit_tracks.size();i++) { - if (is_track_visible(panel_timeline->split_tracks.at(i))) { + // Draw splitting cursor + if (panel_timeline->splitting) { + for (int i=0;isplit_tracks.size();i++) { + if (is_track_visible(panel_timeline->split_tracks.at(i))) { int cursor_x = panel_timeline->getTimelineScreenPointFromFrame(panel_timeline->drag_frame_start); - int cursor_y = getScreenPointFromTrack(panel_timeline->split_tracks.at(i)); + int cursor_y = getScreenPointFromTrack(panel_timeline->split_tracks.at(i)); p.setPen(QColor(64, 64, 64)); p.drawLine(cursor_x, cursor_y, cursor_x, cursor_y + panel_timeline->calculate_track_height(panel_timeline->split_tracks.at(i), -1)); - } - } - } + } + } + } - // Draw playhead - p.setPen(Qt::red); + // Draw playhead + p.setPen(Qt::red); int playhead_x = panel_timeline->getTimelineScreenPointFromFrame(sequence->playhead); - p.drawLine(playhead_x, rect().top(), playhead_x, rect().bottom()); + p.drawLine(playhead_x, rect().top(), playhead_x, rect().bottom()); - // draw border - p.setPen(QColor(0, 0, 0, 64)); - int edge_y = (bottom_align) ? rect().height()-1 : 0; - p.drawLine(0, edge_y, rect().width(), edge_y); + // draw border + p.setPen(QColor(0, 0, 0, 64)); + int edge_y = (bottom_align) ? rect().height()-1 : 0; + p.drawLine(0, edge_y, rect().width(), edge_y); - // draw snap point - if (panel_timeline->snapped) { - p.setPen(Qt::white); + // draw snap point + if (panel_timeline->snapped) { + p.setPen(Qt::white); int snap_x = panel_timeline->getTimelineScreenPointFromFrame(panel_timeline->snap_point); - p.drawLine(snap_x, 0, snap_x, height()); - } + p.drawLine(snap_x, 0, snap_x, height()); + } // Draw edit cursor if (isLiveEditing() && is_track_visible(panel_timeline->cursor_track)) { @@ -2621,15 +2627,15 @@ void TimelineWidget::paintEvent(QPaintEvent*) { p.setPen(Qt::gray); p.drawLine(cursor_x, cursor_y, cursor_x, cursor_y + panel_timeline->calculate_track_height(panel_timeline->cursor_track, -1)); } - } + } } void TimelineWidget::resizeEvent(QResizeEvent *event) { - scrollBar->setPageStep(height()); + scrollBar->setPageStep(height()); } bool TimelineWidget::is_track_visible(int track) { - return (bottom_align == (track < 0)); + return (bottom_align == (track < 0)); } // ************************************** @@ -2638,44 +2644,44 @@ bool TimelineWidget::is_track_visible(int track) { int TimelineWidget::getTrackFromScreenPoint(int y) { y += scroll; - if (bottom_align) { + if (bottom_align) { y = -(y - height()); - } - y--; - int height_measure = 0; - int counter = ((!bottom_align && y > 0) || (bottom_align && y < 0)) ? 0 : -1; - int track_height = panel_timeline->calculate_track_height(counter, -1); - while (qAbs(y) > height_measure+track_height) { - if (config.show_track_lines && counter != -1) y--; - height_measure += track_height; - if ((!bottom_align && y > 0) || (bottom_align && y < 0)) { - counter++; - } else { - counter--; - } - track_height = panel_timeline->calculate_track_height(counter, -1); - } - return counter; + } + y--; + int height_measure = 0; + int counter = ((!bottom_align && y > 0) || (bottom_align && y < 0)) ? 0 : -1; + int track_height = panel_timeline->calculate_track_height(counter, -1); + while (qAbs(y) > height_measure+track_height) { + if (config.show_track_lines && counter != -1) y--; + height_measure += track_height; + if ((!bottom_align && y > 0) || (bottom_align && y < 0)) { + counter++; + } else { + counter--; + } + track_height = panel_timeline->calculate_track_height(counter, -1); + } + return counter; } int TimelineWidget::getScreenPointFromTrack(int track) { int y = 0; - int counter = 0; - while (counter != track) { - if (bottom_align) counter--; - y += panel_timeline->calculate_track_height(counter, -1); - if (!bottom_align) counter++; - if (config.show_track_lines && counter != -1) y++; - } - y++; + int counter = 0; + while (counter != track) { + if (bottom_align) counter--; + y += panel_timeline->calculate_track_height(counter, -1); + if (!bottom_align) counter++; + if (config.show_track_lines && counter != -1) y++; + } + y++; return (bottom_align) ? height() - y - scroll : y - scroll; } int TimelineWidget::getClipIndexFromCoords(long frame, int track) { - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); - if (c != NULL && c->track == track && frame >= c->timeline_in && frame < c->timeline_out) { - return i; + for (int i=0;iclips.size();i++) { + Clip* c = sequence->clips.at(i); + if (c != NULL && c->track == track && frame >= c->timeline_in && frame < c->timeline_out) { + return i; } } return -1; @@ -2687,5 +2693,5 @@ void TimelineWidget::setScroll(int s) { } void TimelineWidget::reveal_media() { - panel_project->reveal_media(rc_reveal_media); + panel_project->reveal_media(rc_reveal_media); } diff --git a/ui/timelinewidget.h b/ui/timelinewidget.h index 63d7ee067..bf03b1595 100644 --- a/ui/timelinewidget.h +++ b/ui/timelinewidget.h @@ -33,13 +33,13 @@ public: protected: void paintEvent(QPaintEvent*); - void resizeEvent(QResizeEvent *event); + void resizeEvent(QResizeEvent *event); - void mouseDoubleClickEvent(QMouseEvent *event); - void mousePressEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); - void leaveEvent(QEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void leaveEvent(QEvent *event); void dragEnterEvent(QDragEnterEvent *event); void dragLeaveEvent(QDragLeaveEvent *event); @@ -49,18 +49,18 @@ protected: void wheelEvent(QWheelEvent *event); private: void init_ghosts(); - void update_ghosts(const QPoint& mouse_pos, bool lock_frame); - bool is_track_visible(int track); - int getTrackFromScreenPoint(int y); + void update_ghosts(const QPoint& mouse_pos, bool lock_frame); + bool is_track_visible(int track); + int getTrackFromScreenPoint(int y); int getScreenPointFromTrack(int track); int getClipIndexFromCoords(long frame, int track); - int track_resize_mouse_cache; - int track_resize_old_value; - bool track_resizing; - int track_target; + int track_resize_mouse_cache; + int track_resize_old_value; + bool track_resizing; + int track_target; - QVector pre_clips; + QVector pre_clips; QVector post_clips; Sequence* self_created_sequence; @@ -68,10 +68,10 @@ private: // used for "right click ripple" long rc_ripple_min; long rc_ripple_max; - Media* rc_reveal_media; + Media* rc_reveal_media; - QTimer tooltip_timer; - int tooltip_clip; + QTimer tooltip_timer; + int tooltip_clip; int scroll; @@ -84,11 +84,12 @@ public slots: private slots: void reveal_media(); void right_click_ripple(); - void show_context_menu(const QPoint& pos); - void toggle_autoscale(); - void tooltip_timer_timeout(); + void show_context_menu(const QPoint& pos); + void toggle_autoscale(); + void tooltip_timer_timeout(); void rename_clip(); - void show_stabilizer_diag(); + void show_stabilizer_diag(); + void open_sequence_properties(); }; #endif // TIMELINEWIDGET_H diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index f84c27b6f..a501fbfec 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -11,7 +11,6 @@ #include "playback/playback.h" #include "playback/audio.h" #include "project/footage.h" -#include "ui_timeline.h" #include "playback/cacher.h" #include "io/config.h" #include "debug.h" @@ -21,6 +20,7 @@ #include "project/media.h" #include "ui/viewercontainer.h" #include "io/avtogl.h" +#include "ui/timelinewidget.h" #include #include @@ -36,6 +36,7 @@ #include #include #include +#include extern "C" { #include @@ -47,40 +48,40 @@ ViewerWidget::ViewerWidget(QWidget *parent) : QOpenGLWidget(parent), default_fbo(NULL), waveform(false), - dragging(false), - selected_gizmo(NULL), - waveform_zoom(1.0), - waveform_scroll(0) + dragging(false), + selected_gizmo(NULL), + waveform_zoom(1.0), + waveform_scroll(0) { - setMouseTracking(true); + setMouseTracking(true); setFocusPolicy(Qt::ClickFocus); QSurfaceFormat format; format.setDepthBufferSize(24); setFormat(format); - // error handler - retries after 50ms if we couldn't get the entire image - retry_timer.setInterval(50); + // error handler - retries after 50ms if we couldn't get the entire image + retry_timer.setInterval(50); connect(&retry_timer, SIGNAL(timeout()), this, SLOT(retry())); setContextMenuPolicy(Qt::CustomContextMenu); - connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu())); + connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu())); } void ViewerWidget::delete_function() { - // destroy all textures as well + // destroy all textures as well if (viewer->seq != NULL) { - makeCurrent(); - closeActiveClips(viewer->seq, true); - doneCurrent(); - } + makeCurrent(); + closeActiveClips(viewer->seq, true); + doneCurrent(); + } } void ViewerWidget::set_waveform_scroll(int s) { - if (waveform) { - waveform_scroll = s; - update(); - } + if (waveform) { + waveform_scroll = s; + update(); + } } void ViewerWidget::show_context_menu() { @@ -89,47 +90,47 @@ void ViewerWidget::show_context_menu() { QAction* save_frame_as_image = menu.addAction("Save Frame as Image..."); connect(save_frame_as_image, SIGNAL(triggered(bool)), this, SLOT(save_frame())); - QAction* show_fullscreen_action = menu.addAction("Show Fullscreen"); - connect(show_fullscreen_action, SIGNAL(triggered()), this, SLOT(show_fullscreen())); + QAction* show_fullscreen_action = menu.addAction("Show Fullscreen"); + connect(show_fullscreen_action, SIGNAL(triggered()), this, SLOT(show_fullscreen())); - QMenu zoom_menu("Zoom"); - QAction* fit_zoom = zoom_menu.addAction("Fit"); - connect(fit_zoom, SIGNAL(triggered(bool)), this, SLOT(set_fit_zoom())); - zoom_menu.addAction("10%")->setData(0.1); - zoom_menu.addAction("25%")->setData(0.25); - zoom_menu.addAction("50%")->setData(0.5); - zoom_menu.addAction("75%")->setData(0.75); - zoom_menu.addAction("100%")->setData(1.0); - zoom_menu.addAction("150%")->setData(1.5); - zoom_menu.addAction("200%")->setData(2.0); - zoom_menu.addAction("400%")->setData(4.0); - QAction* custom_zoom = zoom_menu.addAction("Custom"); - connect(custom_zoom, SIGNAL(triggered(bool)), this, SLOT(set_custom_zoom())); - connect(&zoom_menu, SIGNAL(triggered(QAction*)), this, SLOT(set_menu_zoom(QAction*))); - menu.addMenu(&zoom_menu); + QMenu zoom_menu("Zoom"); + QAction* fit_zoom = zoom_menu.addAction("Fit"); + connect(fit_zoom, SIGNAL(triggered(bool)), this, SLOT(set_fit_zoom())); + zoom_menu.addAction("10%")->setData(0.1); + zoom_menu.addAction("25%")->setData(0.25); + zoom_menu.addAction("50%")->setData(0.5); + zoom_menu.addAction("75%")->setData(0.75); + zoom_menu.addAction("100%")->setData(1.0); + zoom_menu.addAction("150%")->setData(1.5); + zoom_menu.addAction("200%")->setData(2.0); + zoom_menu.addAction("400%")->setData(4.0); + QAction* custom_zoom = zoom_menu.addAction("Custom"); + connect(custom_zoom, SIGNAL(triggered(bool)), this, SLOT(set_custom_zoom())); + connect(&zoom_menu, SIGNAL(triggered(QAction*)), this, SLOT(set_menu_zoom(QAction*))); + menu.addMenu(&zoom_menu); menu.exec(QCursor::pos()); } void ViewerWidget::save_frame() { - QFileDialog fd(this); - fd.setAcceptMode(QFileDialog::AcceptSave); - fd.setFileMode(QFileDialog::AnyFile); - fd.setWindowTitle("Save Frame"); - fd.setNameFilter("Portable Network Graphic (*.png);;JPEG (*.jpg);;Windows Bitmap (*.bmp);;Portable Pixmap (*.ppm);;X11 Bitmap (*.xbm);;X11 Pixmap (*.xpm)"); + QFileDialog fd(this); + fd.setAcceptMode(QFileDialog::AcceptSave); + fd.setFileMode(QFileDialog::AnyFile); + fd.setWindowTitle("Save Frame"); + fd.setNameFilter("Portable Network Graphic (*.png);;JPEG (*.jpg);;Windows Bitmap (*.bmp);;Portable Pixmap (*.ppm);;X11 Bitmap (*.xbm);;X11 Pixmap (*.xpm)"); - if (fd.exec()) { - QString fn = fd.selectedFiles().at(0); - QString selected_ext = fd.selectedNameFilter().mid(fd.selectedNameFilter().indexOf(QRegExp("\\*.[a-z][a-z][a-z]")) + 1, 4); - if (!fn.endsWith(selected_ext, Qt::CaseInsensitive)) { - fn += selected_ext; - } + if (fd.exec()) { + QString fn = fd.selectedFiles().at(0); + QString selected_ext = fd.selectedNameFilter().mid(fd.selectedNameFilter().indexOf(QRegExp("\\*.[a-z][a-z][a-z]")) + 1, 4); + if (!fn.endsWith(selected_ext, Qt::CaseInsensitive)) { + fn += selected_ext; + } QOpenGLFramebufferObject fbo(viewer->seq->width, viewer->seq->height, QOpenGLFramebufferObject::CombinedDepthStencil, GL_TEXTURE_RECTANGLE); rendering = true; fbo.bind(); - default_fbo = &fbo; + default_fbo = &fbo; paintGL(); @@ -138,37 +139,37 @@ void ViewerWidget::save_frame() { img.save(fn); fbo.release(); - default_fbo = NULL; + default_fbo = NULL; rendering = false; - } + } } void ViewerWidget::show_fullscreen() { - showFullScreen(); + showFullScreen(); } void ViewerWidget::set_fit_zoom() { - container->fit = true; - container->adjust(); + container->fit = true; + container->adjust(); } void ViewerWidget::set_custom_zoom() { - bool ok; - double d = QInputDialog::getDouble(this, "Viewer Zoom", "Set Custom Zoom Value:", container->zoom*100, 0, 2147483647, 2, &ok); - if (ok) { - container->fit = false; - container->zoom = d*0.01; - container->adjust(); - } + bool ok; + double d = QInputDialog::getDouble(this, "Viewer Zoom", "Set Custom Zoom Value:", container->zoom*100, 0, 2147483647, 2, &ok); + if (ok) { + container->fit = false; + container->zoom = d*0.01; + container->adjust(); + } } void ViewerWidget::set_menu_zoom(QAction* action) { - const QVariant& data = action->data(); - if (!data.isNull()) { - container->fit = false; - container->zoom = data.toDouble(); - container->adjust(); - } + const QVariant& data = action->data(); + if (!data.isNull()) { + container->fit = false; + container->zoom = data.toDouble(); + container->adjust(); + } } void ViewerWidget::retry() { @@ -176,11 +177,11 @@ void ViewerWidget::retry() { } void ViewerWidget::initializeGL() { - initializeOpenGLFunctions(); + initializeOpenGLFunctions(); - connect(context(), SIGNAL(aboutToBeDestroyed()), this, SLOT(delete_function()), Qt::DirectConnection); + connect(context(), SIGNAL(aboutToBeDestroyed()), this, SLOT(delete_function()), Qt::DirectConnection); - retry_timer.start(); + retry_timer.start(); } //void ViewerWidget::resizeGL(int w, int h) @@ -195,210 +196,210 @@ void ViewerWidget::paintEvent(QPaintEvent *e) { } void ViewerWidget::seek_from_click(int x) { - viewer->seek(getFrameFromScreenPoint(waveform_zoom, x+waveform_scroll)); + viewer->seek(getFrameFromScreenPoint(waveform_zoom, x+waveform_scroll)); } EffectGizmo* ViewerWidget::get_gizmo_from_mouse(int x, int y) { - if (gizmos != NULL) { - double multiplier = (double) viewer->seq->width / (double) width(); - QPoint mouse_pos(qRound(x*multiplier), qRound(y*multiplier)); - int dot_size = 2 * qRound(GIZMO_DOT_SIZE * multiplier); - int target_size = 2 * qRound(GIZMO_TARGET_SIZE * multiplier); - for (int i=0;igizmo_count();i++) { - EffectGizmo* g = gizmos->gizmo(i); + if (gizmos != NULL) { + double multiplier = (double) viewer->seq->width / (double) width(); + QPoint mouse_pos(qRound(x*multiplier), qRound(y*multiplier)); + int dot_size = 2 * qRound(GIZMO_DOT_SIZE * multiplier); + int target_size = 2 * qRound(GIZMO_TARGET_SIZE * multiplier); + for (int i=0;igizmo_count();i++) { + EffectGizmo* g = gizmos->gizmo(i); - switch (g->get_type()) { - case GIZMO_TYPE_DOT: - if (mouse_pos.x() > g->screen_pos[0].x() - dot_size - && mouse_pos.y() > g->screen_pos[0].y() - dot_size - && mouse_pos.x() < g->screen_pos[0].x() + dot_size - && mouse_pos.y() < g->screen_pos[0].y() + dot_size) { - return g; - } - break; - case GIZMO_TYPE_POLY: - if (QPolygon(g->screen_pos).containsPoint(mouse_pos, Qt::OddEvenFill)) { - return g; - } - break; - case GIZMO_TYPE_TARGET: - if (mouse_pos.x() > g->screen_pos[0].x() - target_size - && mouse_pos.y() > g->screen_pos[0].y() - target_size - && mouse_pos.x() < g->screen_pos[0].x() + target_size - && mouse_pos.y() < g->screen_pos[0].y() + target_size) { - return g; - } - break; - } + switch (g->get_type()) { + case GIZMO_TYPE_DOT: + if (mouse_pos.x() > g->screen_pos[0].x() - dot_size + && mouse_pos.y() > g->screen_pos[0].y() - dot_size + && mouse_pos.x() < g->screen_pos[0].x() + dot_size + && mouse_pos.y() < g->screen_pos[0].y() + dot_size) { + return g; + } + break; + case GIZMO_TYPE_POLY: + if (QPolygon(g->screen_pos).containsPoint(mouse_pos, Qt::OddEvenFill)) { + return g; + } + break; + case GIZMO_TYPE_TARGET: + if (mouse_pos.x() > g->screen_pos[0].x() - target_size + && mouse_pos.y() > g->screen_pos[0].y() - target_size + && mouse_pos.x() < g->screen_pos[0].x() + target_size + && mouse_pos.y() < g->screen_pos[0].y() + target_size) { + return g; + } + break; + } - } - } - return NULL; + } + } + return NULL; } void ViewerWidget::move_gizmos(QMouseEvent *event, bool done) { - if (selected_gizmo != NULL) { - double multiplier = (double) viewer->seq->width / (double) width(); + if (selected_gizmo != NULL) { + double multiplier = (double) viewer->seq->width / (double) width(); - int x_movement = (event->pos().x() - drag_start_x)*multiplier; - int y_movement = (event->pos().y() - drag_start_y)*multiplier; + int x_movement = (event->pos().x() - drag_start_x)*multiplier; + int y_movement = (event->pos().y() - drag_start_y)*multiplier; - gizmos->gizmo_move(selected_gizmo, x_movement, y_movement, get_timecode(gizmos->parent_clip, gizmos->parent_clip->sequence->playhead), done); + gizmos->gizmo_move(selected_gizmo, x_movement, y_movement, get_timecode(gizmos->parent_clip, gizmos->parent_clip->sequence->playhead), done); - gizmo_x_mvmt += x_movement; - gizmo_y_mvmt += y_movement; + gizmo_x_mvmt += x_movement; + gizmo_y_mvmt += y_movement; - drag_start_x = event->pos().x(); - drag_start_y = event->pos().y(); + drag_start_x = event->pos().x(); + drag_start_y = event->pos().y(); - gizmos->field_changed(); - } + gizmos->field_changed(); + } } void ViewerWidget::mousePressEvent(QMouseEvent* event) { - if (waveform) { - seek_from_click(event->x()); - } else if (event->buttons() & Qt::MiddleButton || panel_timeline->tool == TIMELINE_TOOL_HAND) { - container->dragScrollPress(event->pos()); - } else { - drag_start_x = event->pos().x(); - drag_start_y = event->pos().y(); + if (waveform) { + seek_from_click(event->x()); + } else if (event->buttons() & Qt::MiddleButton || panel_timeline->tool == TIMELINE_TOOL_HAND) { + container->dragScrollPress(event->pos()); + } else { + drag_start_x = event->pos().x(); + drag_start_y = event->pos().y(); - gizmo_x_mvmt = 0; - gizmo_y_mvmt = 0; + gizmo_x_mvmt = 0; + gizmo_y_mvmt = 0; - selected_gizmo = get_gizmo_from_mouse(event->pos().x(), event->pos().y()); + selected_gizmo = get_gizmo_from_mouse(event->pos().x(), event->pos().y()); - if (selected_gizmo != NULL) { - selected_gizmo->set_previous_value(); - } - } - dragging = true; + if (selected_gizmo != NULL) { + selected_gizmo->set_previous_value(); + } + } + dragging = true; } void ViewerWidget::mouseMoveEvent(QMouseEvent* event) { - unsetCursor(); - if (panel_timeline->tool == TIMELINE_TOOL_HAND) { - setCursor(Qt::OpenHandCursor); - } - if (dragging) { + unsetCursor(); + if (panel_timeline->tool == TIMELINE_TOOL_HAND) { + setCursor(Qt::OpenHandCursor); + } + if (dragging) { if (waveform) { seek_from_click(event->x()); - } else if (event->buttons() & Qt::MiddleButton || panel_timeline->tool == TIMELINE_TOOL_HAND) { - container->dragScrollMove(event->pos()); - } else if (gizmos == NULL) { + } else if (event->buttons() & Qt::MiddleButton || panel_timeline->tool == TIMELINE_TOOL_HAND) { + container->dragScrollMove(event->pos()); + } else if (gizmos == NULL) { QDrag* drag = new QDrag(this); QMimeData* mimeData = new QMimeData; - mimeData->setText("h"); // QMimeData will fail without some kind of data + mimeData->setText("h"); // QMimeData will fail without some kind of data drag->setMimeData(mimeData); drag->exec(); - dragging = false; - } else { - move_gizmos(event, false); - } - } else { - EffectGizmo* g = get_gizmo_from_mouse(event->pos().x(), event->pos().y()); - if (g != NULL) { - if (g->get_cursor() > -1) { - setCursor(static_cast(g->get_cursor())); - } - } - } + dragging = false; + } else { + move_gizmos(event, false); + } + } else { + EffectGizmo* g = get_gizmo_from_mouse(event->pos().x(), event->pos().y()); + if (g != NULL) { + if (g->get_cursor() > -1) { + setCursor(static_cast(g->get_cursor())); + } + } + } } void ViewerWidget::mouseReleaseEvent(QMouseEvent *event) { - if (dragging) move_gizmos(event, true); - dragging = false; + if (dragging) move_gizmos(event, true); + dragging = false; } void ViewerWidget::drawTitleSafeArea() { - double halfWidth = 0.5; - double halfHeight = 0.5; - double viewportAr = (double) width() / (double) height(); - double halfAr = viewportAr*0.5; + double halfWidth = 0.5; + double halfHeight = 0.5; + double viewportAr = (double) width() / (double) height(); + double halfAr = viewportAr*0.5; - if (config.use_custom_title_safe_ratio && config.custom_title_safe_ratio > 0) { - if (config.custom_title_safe_ratio > viewportAr) { - halfHeight = (config.custom_title_safe_ratio/viewportAr)*0.5; - } else { - halfWidth = (viewportAr/config.custom_title_safe_ratio)*0.5; - } - } + if (config.use_custom_title_safe_ratio && config.custom_title_safe_ratio > 0) { + if (config.custom_title_safe_ratio > viewportAr) { + halfHeight = (config.custom_title_safe_ratio/viewportAr)*0.5; + } else { + halfWidth = (viewportAr/config.custom_title_safe_ratio)*0.5; + } + } - glLoadIdentity(); - glOrtho(-halfWidth, halfWidth, halfHeight, -halfHeight, 0, 1); + glLoadIdentity(); + glOrtho(-halfWidth, halfWidth, halfHeight, -halfHeight, 0, 1); glColor4f(0.66f, 0.66f, 0.66f, 1.0f); - glBegin(GL_LINES); + glBegin(GL_LINES); - // action safe rectangle - glVertex2d(-0.45, -0.45); - glVertex2d(0.45, -0.45); - glVertex2d(0.45, -0.45); - glVertex2d(0.45, 0.45); - glVertex2d(0.45, 0.45); - glVertex2d(-0.45, 0.45); - glVertex2d(-0.45, 0.45); - glVertex2d(-0.45, -0.45); + // action safe rectangle + glVertex2d(-0.45, -0.45); + glVertex2d(0.45, -0.45); + glVertex2d(0.45, -0.45); + glVertex2d(0.45, 0.45); + glVertex2d(0.45, 0.45); + glVertex2d(-0.45, 0.45); + glVertex2d(-0.45, 0.45); + glVertex2d(-0.45, -0.45); - // title safe rectangle - glVertex2d(-0.4, -0.4); - glVertex2d(0.4, -0.4); - glVertex2d(0.4, -0.4); - glVertex2d(0.4, 0.4); - glVertex2d(0.4, 0.4); - glVertex2d(-0.4, 0.4); - glVertex2d(-0.4, 0.4); - glVertex2d(-0.4, -0.4); + // title safe rectangle + glVertex2d(-0.4, -0.4); + glVertex2d(0.4, -0.4); + glVertex2d(0.4, -0.4); + glVertex2d(0.4, 0.4); + glVertex2d(0.4, 0.4); + glVertex2d(-0.4, 0.4); + glVertex2d(-0.4, 0.4); + glVertex2d(-0.4, -0.4); - // horizontal centers - glVertex2d(-0.45, 0); - glVertex2d(-0.375, 0); - glVertex2d(0.45, 0); - glVertex2d(0.375, 0); + // horizontal centers + glVertex2d(-0.45, 0); + glVertex2d(-0.375, 0); + glVertex2d(0.45, 0); + glVertex2d(0.375, 0); - // vertical centers - glVertex2d(0, -0.45); - glVertex2d(0, -0.375); - glVertex2d(0, 0.45); - glVertex2d(0, 0.375); + // vertical centers + glVertex2d(0, -0.45); + glVertex2d(0, -0.375); + glVertex2d(0, 0.45); + glVertex2d(0, 0.375); - glEnd(); + glEnd(); - // center cross - glLoadIdentity(); - glOrtho(-halfAr, halfAr, 0.5, -0.5, -1, 1); + // center cross + glLoadIdentity(); + glOrtho(-halfAr, halfAr, 0.5, -0.5, -1, 1); - glBegin(GL_LINES); + glBegin(GL_LINES); - glVertex2d(-0.05, 0); - glVertex2d(0.05, 0); - glVertex2d(0, -0.05); - glVertex2d(0, 0.05); + glVertex2d(-0.05, 0); + glVertex2d(0.05, 0); + glVertex2d(0, -0.05); + glVertex2d(0, 0.05); - glEnd(); + glEnd(); } GLuint ViewerWidget::draw_clip(QOpenGLFramebufferObject* fbo, GLuint texture, bool clear) { - glPushMatrix(); - glLoadIdentity(); - glOrtho(0, 1, 0, 1, -1, 1); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, 1, 0, 1, -1, 1); - fbo->bind(); + fbo->bind(); - if (clear) glClear(GL_COLOR_BUFFER_BIT); + if (clear) glClear(GL_COLOR_BUFFER_BIT); - // get current blend mode - GLint src_rgb, src_alpha, dst_rgb, dst_alpha; - glGetIntegerv(GL_BLEND_SRC_RGB, &src_rgb); - glGetIntegerv(GL_BLEND_SRC_ALPHA, &src_alpha); - glGetIntegerv(GL_BLEND_DST_RGB, &dst_rgb); - glGetIntegerv(GL_BLEND_DST_ALPHA, &dst_alpha); + // get current blend mode + GLint src_rgb, src_alpha, dst_rgb, dst_alpha; + glGetIntegerv(GL_BLEND_SRC_RGB, &src_rgb); + glGetIntegerv(GL_BLEND_SRC_ALPHA, &src_alpha); + glGetIntegerv(GL_BLEND_DST_RGB, &dst_rgb); + glGetIntegerv(GL_BLEND_DST_ALPHA, &dst_alpha); - GL_DEFAULT_BLEND + GL_DEFAULT_BLEND - glBindTexture(GL_TEXTURE_2D, texture); - glBegin(GL_QUADS); + glBindTexture(GL_TEXTURE_2D, texture); + glBegin(GL_QUADS); glTexCoord2f(0, 0); // top left glVertex2f(0, 0); // top left glTexCoord2f(1, 0); // top right @@ -408,14 +409,14 @@ GLuint ViewerWidget::draw_clip(QOpenGLFramebufferObject* fbo, GLuint texture, bo glTexCoord2f(0, 1); // bottom left glVertex2f(0, 1); // bottom left glEnd(); - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_2D, 0); fbo->release(); - // restore previous blendFunc - glBlendFuncSeparate(src_rgb, dst_rgb, src_alpha, dst_alpha); + // restore previous blendFunc + glBlendFuncSeparate(src_rgb, dst_rgb, src_alpha, dst_alpha); - if (default_fbo != NULL) default_fbo->bind(); + if (default_fbo != NULL) default_fbo->bind(); glPopMatrix(); return fbo->texture(); @@ -424,27 +425,27 @@ GLuint ViewerWidget::draw_clip(QOpenGLFramebufferObject* fbo, GLuint texture, bo void ViewerWidget::process_effect(Clip* c, Effect* e, double timecode, GLTextureCoords& coords, GLuint& composite_texture, bool& fbo_switcher, int data) { if (e->is_enabled()) { if (e->enable_coords) { - e->process_coords(timecode, coords, data); + e->process_coords(timecode, coords, data); } if (e->enable_shader || e->enable_superimpose) { - e->startEffect(); - if (e->enable_shader) { - e->process_shader(timecode, coords); - composite_texture = draw_clip(c->fbo[fbo_switcher], composite_texture, true); - fbo_switcher = !fbo_switcher; - } - if (e->enable_superimpose) { - GLuint superimpose_texture = e->process_superimpose(timecode); - if (superimpose_texture == 0) { - dout << "[WARNING] Superimpose texture was NULL, retrying..."; - texture_failed = true; - } else { - composite_texture = draw_clip(c->fbo[!fbo_switcher], superimpose_texture, false); - } - } - e->endEffect(); + e->startEffect(); + if (e->enable_shader) { + e->process_shader(timecode, coords); + composite_texture = draw_clip(c->fbo[fbo_switcher], composite_texture, true); + fbo_switcher = !fbo_switcher; + } + if (e->enable_superimpose) { + GLuint superimpose_texture = e->process_superimpose(timecode); + if (superimpose_texture == 0) { + dout << "[WARNING] Superimpose texture was NULL, retrying..."; + texture_failed = true; + } else { + composite_texture = draw_clip(c->fbo[!fbo_switcher], superimpose_texture, false); + } + } + e->endEffect(); } - } + } } int motion_blur_prog = 0; @@ -456,8 +457,8 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) if (!nests.isEmpty()) { for (int i=0;imedia->to_sequence(); - playhead += nests.at(i)->clip_in - nests.at(i)->get_timeline_in_with_transition(); + s = nests.at(i)->media->to_sequence(); + playhead += nests.at(i)->clip_in - nests.at(i)->get_timeline_in_with_transition(); playhead = refactor_frame_number(playhead, nests.at(i)->sequence->frame_rate, s->frame_rate); } @@ -470,45 +471,45 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) int audio_track_count = 0; - QVector current_clips; + QVector current_clips; - for (int i=0;iclips.size();i++) { + for (int i=0;iclips.size();i++) { Clip* c = s->clips.at(i); - // if clip starts within one second and/or hasn't finished yet + // if clip starts within one second and/or hasn't finished yet if (c != NULL) { if (!(!nests.isEmpty() && !same_sign(c->track, nests.last()->track))) { bool clip_is_active = false; - if (c->media != NULL && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { - Footage* m = c->media->to_footage(); - if (!m->invalid && !(c->track >= 0 && !is_audio_device_set())) { - if (m->ready) { - FootageStream* ms = m->get_stream_from_file_index(c->track < 0, c->media_stream); - if (ms != NULL && is_clip_active(c, playhead)) { - // if thread is already working, we don't want to touch this, - // but we also don't want to hang the UI thread - if (!c->open) { - open_clip(c, !rendering); - } - clip_is_active = true; - if (c->track >= 0) audio_track_count++; - } else if (c->open) { - close_clip(c); - } - } else { - //dout << "[WARNING] Media '" + m->name + "' was not ready, retrying..."; - texture_failed = true; - } - } - } else { - if (is_clip_active(c, playhead)) { - if (!c->open) open_clip(c, !rendering); - clip_is_active = true; - } else if (c->open) { - close_clip(c); - } - } + if (c->media != NULL && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { + Footage* m = c->media->to_footage(); + if (!m->invalid && !(c->track >= 0 && !is_audio_device_set())) { + if (m->ready) { + FootageStream* ms = m->get_stream_from_file_index(c->track < 0, c->media_stream); + if (ms != NULL && is_clip_active(c, playhead)) { + // if thread is already working, we don't want to touch this, + // but we also don't want to hang the UI thread + if (!c->open) { + open_clip(c, !rendering); + } + clip_is_active = true; + if (c->track >= 0) audio_track_count++; + } else if (c->open) { + close_clip(c); + } + } else { + //dout << "[WARNING] Media '" + m->name + "' was not ready, retrying..."; + texture_failed = true; + } + } + } else { + if (is_clip_active(c, playhead)) { + if (!c->open) open_clip(c, !rendering); + clip_is_active = true; + } else if (c->open) { + close_clip(c); + } + } if (clip_is_active) { bool added = false; for (int j=0;j& nests, bool render_audio) int half_height = s->height/2; if (rendering || !nests.isEmpty()) half_height = -half_height; // invert vertical - glPushMatrix(); - glLoadIdentity(); - glOrtho(-half_width, half_width, half_height, -half_height, -1, 10); + glPushMatrix(); + glLoadIdentity(); + glOrtho(-half_width, half_width, half_height, -half_height, -1, 10); - for (int i=0;imedia != NULL && c->media->get_type() == MEDIA_TYPE_FOOTAGE && !c->finished_opening) { + if (c->media != NULL && c->media->get_type() == MEDIA_TYPE_FOOTAGE && !c->finished_opening) { dout << "[WARNING] Tried to display clip" << i << "but it's closed"; - texture_failed = true; - } else { + texture_failed = true; + } else { if (c->track < 0) { GLuint textureID = 0; int video_width = c->getWidth(); int video_height = c->getHeight(); - if (c->media != NULL) { - switch (c->media->get_type()) { - case MEDIA_TYPE_FOOTAGE: - // set up opengl texture - if (c->texture == NULL) { - c->texture = new QOpenGLTexture(QOpenGLTexture::Target2D); - c->texture->setSize(c->stream->codecpar->width, c->stream->codecpar->height); + if (c->media != NULL) { + switch (c->media->get_type()) { + case MEDIA_TYPE_FOOTAGE: + // set up opengl texture + if (c->texture == NULL) { + c->texture = new QOpenGLTexture(QOpenGLTexture::Target2D); + c->texture->setSize(c->stream->codecpar->width, c->stream->codecpar->height); c->texture->setFormat(get_gl_tex_fmt_from_av(c->pix_fmt)); - c->texture->setMipLevels(c->texture->maximumMipLevels()); - c->texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear); + c->texture->setMipLevels(c->texture->maximumMipLevels()); + c->texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear); c->texture->allocateStorage(get_gl_pix_fmt_from_av(c->pix_fmt), QOpenGLTexture::UInt8); - } - get_clip_frame(c, playhead); - textureID = c->texture->textureId(); - break; - case MEDIA_TYPE_SEQUENCE: - textureID = -1; - break; - } - } + } + get_clip_frame(c, playhead); + textureID = c->texture->textureId(); + break; + case MEDIA_TYPE_SEQUENCE: + textureID = -1; + break; + } + } - if (textureID == 0 && c->media != NULL) { + if (textureID == 0 && c->media != NULL) { dout << "[WARNING] Texture hasn't been created yet"; texture_failed = true; - } else if (playhead >= c->get_timeline_in_with_transition()) { + } else if (playhead >= c->get_timeline_in_with_transition()) { glPushMatrix(); // start preparing cache @@ -595,84 +596,84 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) glViewport(0, 0, video_width, video_height); - GLuint composite_texture; + GLuint composite_texture; - if (c->media == NULL) { - c->fbo[fbo_switcher]->bind(); - glClear(GL_COLOR_BUFFER_BIT); - c->fbo[fbo_switcher]->release(); + if (c->media == NULL) { + c->fbo[fbo_switcher]->bind(); + glClear(GL_COLOR_BUFFER_BIT); + c->fbo[fbo_switcher]->release(); composite_texture = c->fbo[fbo_switcher]->texture(); } else { - // for nested sequences - if (c->media->get_type()== MEDIA_TYPE_SEQUENCE) { - nests.append(c); - textureID = compose_sequence(nests, render_audio); - nests.removeLast(); - fbo_switcher = true; - } + // for nested sequences + if (c->media->get_type()== MEDIA_TYPE_SEQUENCE) { + nests.append(c); + textureID = compose_sequence(nests, render_audio); + nests.removeLast(); + fbo_switcher = true; + } - composite_texture = draw_clip(c->fbo[fbo_switcher], textureID, true); + composite_texture = draw_clip(c->fbo[fbo_switcher], textureID, true); } - fbo_switcher = !fbo_switcher; + fbo_switcher = !fbo_switcher; - // set up default coords - GLTextureCoords coords; - coords.grid_size = 1; + // set up default coords + GLTextureCoords coords; + coords.grid_size = 1; coords.vertexTopLeftX = coords.vertexBottomLeftX = -video_width/2; coords.vertexTopLeftY = coords.vertexTopRightY = -video_height/2; coords.vertexTopRightX = coords.vertexBottomRightX = video_width/2; - coords.vertexBottomLeftY = coords.vertexBottomRightY = video_height/2; - coords.vertexBottomLeftZ = coords.vertexBottomRightZ = coords.vertexTopLeftZ = coords.vertexTopRightZ = 1; - coords.textureTopLeftY = coords.textureTopRightY = coords.textureTopLeftX = coords.textureBottomLeftX = 0.0; + coords.vertexBottomLeftY = coords.vertexBottomRightY = video_height/2; + coords.vertexBottomLeftZ = coords.vertexBottomRightZ = coords.vertexTopLeftZ = coords.vertexTopRightZ = 1; + coords.textureTopLeftY = coords.textureTopRightY = coords.textureTopLeftX = coords.textureBottomLeftX = 0.0; coords.textureBottomLeftY = coords.textureBottomRightY = coords.textureTopRightX = coords.textureBottomRightX = 1.0; - coords.textureTopLeftQ = coords.textureTopRightQ = coords.textureTopLeftQ = coords.textureBottomLeftQ = 1; + coords.textureTopLeftQ = coords.textureTopRightQ = coords.textureTopLeftQ = coords.textureBottomLeftQ = 1; - // set up autoscale - if (c->autoscale && (video_width != s->width && video_height != s->height)) { - float width_multiplier = (float) s->width / (float) video_width; - float height_multiplier = (float) s->height / (float) video_height; - float scale_multiplier = qMin(width_multiplier, height_multiplier); + // set up autoscale + if (c->autoscale && (video_width != s->width && video_height != s->height)) { + float width_multiplier = (float) s->width / (float) video_width; + float height_multiplier = (float) s->height / (float) video_height; + float scale_multiplier = qMin(width_multiplier, height_multiplier); glScalef(scale_multiplier, scale_multiplier, 1); } // EFFECT CODE START - double timecode = get_timecode(c, playhead); + double timecode = get_timecode(c, playhead); - Effect* first_gizmo_effect = NULL; - Effect* selected_effect = NULL; + Effect* first_gizmo_effect = NULL; + Effect* selected_effect = NULL; for (int j=0;jeffects.size();j++) { - Effect* e = c->effects.at(j); - process_effect(c, e, timecode, coords, composite_texture, fbo_switcher, TA_NO_TRANSITION); + Effect* e = c->effects.at(j); + process_effect(c, e, timecode, coords, composite_texture, fbo_switcher, TA_NO_TRANSITION); - if (e->are_gizmos_enabled()) { - if (first_gizmo_effect == NULL) first_gizmo_effect = e; - if (e->container->selected) selected_effect = e; - } + if (e->are_gizmos_enabled()) { + if (first_gizmo_effect == NULL) first_gizmo_effect = e; + if (e->container->selected) selected_effect = e; + } } - if (!rendering) { - if (selected_effect != NULL) { - gizmos = selected_effect; - } else if (panel_timeline->is_clip_selected(c, true)) { - gizmos = first_gizmo_effect; - } - } - - if (c->get_opening_transition() != NULL) { - int transition_progress = playhead - c->get_timeline_in_with_transition(); - if (transition_progress < c->get_opening_transition()->get_length()) { - process_effect(c, c->get_opening_transition(), (double)transition_progress/(double)c->get_opening_transition()->get_length(), coords, composite_texture, fbo_switcher, TA_OPENING_TRANSITION); + if (!rendering) { + if (selected_effect != NULL) { + gizmos = selected_effect; + } else if (panel_timeline->is_clip_selected(c, true)) { + gizmos = first_gizmo_effect; } - } + } - if (c->get_closing_transition() != NULL) { - int transition_progress = playhead - (c->get_timeline_out_with_transition() - c->get_closing_transition()->get_length()); - if (transition_progress >= 0 && transition_progress < c->get_closing_transition()->get_length()) { - process_effect(c, c->get_closing_transition(), (double)transition_progress/(double)c->get_closing_transition()->get_length(), coords, composite_texture, fbo_switcher, TA_CLOSING_TRANSITION); + if (c->get_opening_transition() != NULL) { + int transition_progress = playhead - c->get_timeline_in_with_transition(); + if (transition_progress < c->get_opening_transition()->get_length()) { + process_effect(c, c->get_opening_transition(), (double)transition_progress/(double)c->get_opening_transition()->get_length(), coords, composite_texture, fbo_switcher, TA_OPENING_TRANSITION); } - } + } + + if (c->get_closing_transition() != NULL) { + int transition_progress = playhead - (c->get_timeline_out_with_transition() - c->get_closing_transition()->get_length()); + if (transition_progress >= 0 && transition_progress < c->get_closing_transition()->get_length()) { + process_effect(c, c->get_closing_transition(), (double)transition_progress/(double)c->get_closing_transition()->get_length(), coords, composite_texture, fbo_switcher, TA_CLOSING_TRANSITION); + } + } // EFFECT CODE END if (!nests.isEmpty()) { @@ -681,13 +682,13 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) } else if (rendering) { glViewport(0, 0, s->width, s->height); } else { - int widget_width = width(); - int widget_height = height(); + int widget_width = width(); + int widget_height = height(); - widget_width *= QApplication::desktop()->devicePixelRatio(); - widget_height *= QApplication::desktop()->devicePixelRatio(); + widget_width *= QApplication::desktop()->devicePixelRatio(); + widget_height *= QApplication::desktop()->devicePixelRatio(); - glViewport(0, 0, widget_width, widget_height); + glViewport(0, 0, widget_width, widget_height); } glBindTexture(GL_TEXTURE_2D, composite_texture); @@ -695,62 +696,62 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glBegin(GL_QUADS); + glBegin(GL_QUADS); if (coords.grid_size <= 1) { - float z = 0.0f; + float z = 0.0f; - glTexCoord2f(coords.textureTopLeftX, coords.textureTopLeftY); // top left - glVertex3f(coords.vertexTopLeftX, coords.vertexTopLeftY, z); // top left - glTexCoord2f(coords.textureTopRightX, coords.textureTopRightY); // top right - glVertex3f(coords.vertexTopRightX, coords.vertexTopRightY, z); // top right - glTexCoord2f(coords.textureBottomRightX, coords.textureBottomRightY); // bottom right - glVertex3f(coords.vertexBottomRightX, coords.vertexBottomRightY, z); // bottom right - glTexCoord2f(coords.textureBottomLeftX, coords.textureBottomLeftY); // bottom left - glVertex3f(coords.vertexBottomLeftX, coords.vertexBottomLeftY, z); // bottom left + glTexCoord2f(coords.textureTopLeftX, coords.textureTopLeftY); // top left + glVertex3f(coords.vertexTopLeftX, coords.vertexTopLeftY, z); // top left + glTexCoord2f(coords.textureTopRightX, coords.textureTopRightY); // top right + glVertex3f(coords.vertexTopRightX, coords.vertexTopRightY, z); // top right + glTexCoord2f(coords.textureBottomRightX, coords.textureBottomRightY); // bottom right + glVertex3f(coords.vertexBottomRightX, coords.vertexBottomRightY, z); // bottom right + glTexCoord2f(coords.textureBottomLeftX, coords.textureBottomLeftY); // bottom left + glVertex3f(coords.vertexBottomLeftX, coords.vertexBottomLeftY, z); // bottom left } else { - float rows = coords.grid_size; - float cols = coords.grid_size; + float rows = coords.grid_size; + float cols = coords.grid_size; - for (float k=0;kgizmo_draw(timecode, coords); // set correct gizmo coords - gizmos->gizmo_world_to_screen(); + if (gizmos != NULL && !drawn_gizmos) { + gizmos->gizmo_draw(timecode, coords); // set correct gizmo coords + gizmos->gizmo_world_to_screen(); - drawn_gizmos = true; - } + drawn_gizmos = true; + } if (!nests.isEmpty()) { nests.last()->fbo[0]->release(); @@ -759,32 +760,32 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) glPopMatrix(); - /*GLfloat motion_blur_frac = (GLfloat) motion_blur_prog / (GLfloat) motion_blur_lim; - if (motion_blur_prog == 0) { - glAccum(GL_LOAD, motion_blur_frac); - } else { - glAccum(GL_ACCUM, motion_blur_frac); - } - motion_blur_prog++;*/ + /*GLfloat motion_blur_frac = (GLfloat) motion_blur_prog / (GLfloat) motion_blur_lim; + if (motion_blur_prog == 0) { + glAccum(GL_LOAD, motion_blur_frac); + } else { + glAccum(GL_ACCUM, motion_blur_frac); + } + motion_blur_prog++;*/ } - } else { - if (render_audio || (config.enable_audio_scrubbing && audio_scrub)) { - if (c->media != NULL && c->media->get_type() == MEDIA_TYPE_SEQUENCE) { - nests.append(c); - compose_sequence(nests, render_audio); - nests.removeLast(); - } else { - if (c->lock.tryLock()) { - // clip is not caching, start caching audio - cache_clip(c, playhead, c->audio_reset, !render_audio, nests); - c->lock.unlock(); - } - } + } else { + if (render_audio || (config.enable_audio_scrubbing && audio_scrub)) { + if (c->media != NULL && c->media->get_type() == MEDIA_TYPE_SEQUENCE) { + nests.append(c); + compose_sequence(nests, render_audio); + nests.removeLast(); + } else { + if (c->lock.tryLock()) { + // clip is not caching, start caching audio + cache_clip(c, playhead, c->audio_reset, !render_audio, nests); + c->lock.unlock(); + } + } } // visually update all the keyframe values if (c->sequence == viewer->seq) { // only if you can currently see them - double ts = (playhead - c->get_timeline_in_with_transition() + c->get_clip_in_with_transition())/s->frame_rate; + double ts = (playhead - c->get_timeline_in_with_transition() + c->get_clip_in_with_transition())/s->frame_rate; for (int i=0;ieffects.size();i++) { Effect* e = c->effects.at(i); for (int j=0;jrow_count();j++) { @@ -796,7 +797,7 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) } } } - } + } } if (audio_track_count == 0) { @@ -814,136 +815,136 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) } void ViewerWidget::paintGL() { - drawn_gizmos = false; - force_quit = false; - if (viewer->seq != NULL) { - gizmos = NULL; + drawn_gizmos = false; + force_quit = false; + if (viewer->seq != NULL) { + gizmos = NULL; - bool render_audio = (viewer->playing || rendering); - bool loop = false; - do { - loop = false; + bool render_audio = (viewer->playing || rendering); + bool loop = false; + do { + loop = false; - glClearColor(0, 0, 0, 1); - glMatrixMode(GL_MODELVIEW); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glEnable(GL_DEPTH); + glClearColor(0, 0, 0, 1); + glMatrixMode(GL_MODELVIEW); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glEnable(GL_DEPTH); - texture_failed = false; + texture_failed = false; - if (!rendering) retry_timer.stop(); + if (!rendering) retry_timer.stop(); - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT); - // compose video preview - glClearColor(0, 0, 0, 0); + // compose video preview + glClearColor(0, 0, 0, 0); - QVector nests; + QVector nests; - compose_sequence(nests, render_audio); + compose_sequence(nests, render_audio); - if (waveform) { - QPainter p(this); - if (viewer->seq->using_workarea) { - int in_x = getScreenPointFromFrame(waveform_zoom, viewer->seq->workarea_in) - waveform_scroll; - int out_x = getScreenPointFromFrame(waveform_zoom, viewer->seq->workarea_out) - waveform_scroll; + if (waveform) { + QPainter p(this); + if (viewer->seq->using_workarea) { + int in_x = getScreenPointFromFrame(waveform_zoom, viewer->seq->workarea_in) - waveform_scroll; + int out_x = getScreenPointFromFrame(waveform_zoom, viewer->seq->workarea_out) - waveform_scroll; - p.fillRect(QRect(in_x, 0, out_x - in_x, height()), QColor(255, 255, 255, 64)); - p.setPen(Qt::white); - p.drawLine(in_x, 0, in_x, height()); - p.drawLine(out_x, 0, out_x, height()); - } - QRect wr = rect(); - wr.setX(wr.x() - waveform_scroll); + p.fillRect(QRect(in_x, 0, out_x - in_x, height()), QColor(255, 255, 255, 64)); + p.setPen(Qt::white); + p.drawLine(in_x, 0, in_x, height()); + p.drawLine(out_x, 0, out_x, height()); + } + QRect wr = rect(); + wr.setX(wr.x() - waveform_scroll); - p.setPen(Qt::green); - draw_waveform(waveform_clip, waveform_ms, waveform_clip->timeline_out, &p, wr, waveform_scroll, width()+waveform_scroll, waveform_zoom); - p.setPen(Qt::red); - int playhead_x = getScreenPointFromFrame(waveform_zoom, viewer->seq->playhead) - waveform_scroll; - p.drawLine(playhead_x, 0, playhead_x, height()); - } + p.setPen(Qt::green); + draw_waveform(waveform_clip, waveform_ms, waveform_clip->timeline_out, &p, wr, waveform_scroll, width()+waveform_scroll, waveform_zoom); + p.setPen(Qt::red); + int playhead_x = getScreenPointFromFrame(waveform_zoom, viewer->seq->playhead) - waveform_scroll; + p.drawLine(playhead_x, 0, playhead_x, height()); + } - if (force_quit) break; - if (texture_failed) { - if (rendering) { - dout << "[INFO] Texture failed - looping"; - loop = true; - } else { - retry_timer.start(); - } - } + if (force_quit) break; + if (texture_failed) { + if (rendering) { + dout << "[INFO] Texture failed - looping"; + loop = true; + } else { + retry_timer.start(); + } + } - if (config.show_title_safe_area && !rendering) { - drawTitleSafeArea(); - } + if (config.show_title_safe_area && !rendering) { + drawTitleSafeArea(); + } - if (gizmos != NULL && drawn_gizmos) { - float color[4]; - glGetFloatv(GL_CURRENT_COLOR, color); + if (gizmos != NULL && drawn_gizmos) { + float color[4]; + glGetFloatv(GL_CURRENT_COLOR, color); - float dot_size = GIZMO_DOT_SIZE / width() * viewer->seq->width; - float target_size = GIZMO_TARGET_SIZE / width() * viewer->seq->width; + float dot_size = GIZMO_DOT_SIZE / width() * viewer->seq->width; + float target_size = GIZMO_TARGET_SIZE / width() * viewer->seq->width; - glPushMatrix(); - glLoadIdentity(); - glOrtho(0, viewer->seq->width, viewer->seq->height, 0, -1, 10); - float gizmo_z = 0.0f; - for (int j=0;jgizmo_count();j++) { - EffectGizmo* g = gizmos->gizmo(j); - glColor4f(g->color.redF(), g->color.greenF(), g->color.blueF(), 1.0); - switch (g->get_type()) { - case GIZMO_TYPE_DOT: // draw dot - glBegin(GL_QUADS); - glVertex3f(g->screen_pos[0].x()-dot_size, g->screen_pos[0].y()-dot_size, gizmo_z); - glVertex3f(g->screen_pos[0].x()+dot_size, g->screen_pos[0].y()-dot_size, gizmo_z); - glVertex3f(g->screen_pos[0].x()+dot_size, g->screen_pos[0].y()+dot_size, gizmo_z); - glVertex3f(g->screen_pos[0].x()-dot_size, g->screen_pos[0].y()+dot_size, gizmo_z); - glEnd(); - break; - case GIZMO_TYPE_POLY: // draw lines - glBegin(GL_LINES); - for (int k=1;kget_point_count();k++) { - glVertex3f(g->screen_pos[k-1].x(), g->screen_pos[k-1].y(), gizmo_z); - glVertex3f(g->screen_pos[k].x(), g->screen_pos[k].y(), gizmo_z); - } - glVertex3f(g->screen_pos[g->get_point_count()-1].x(), g->screen_pos[g->get_point_count()-1].y(), gizmo_z); - glVertex3f(g->screen_pos[0].x(), g->screen_pos[0].y(), gizmo_z); - glEnd(); - break; - case GIZMO_TYPE_TARGET: // draw target - glBegin(GL_LINES); - glVertex3f(g->screen_pos[0].x()-target_size, g->screen_pos[0].y()-target_size, gizmo_z); - glVertex3f(g->screen_pos[0].x()+target_size, g->screen_pos[0].y()-target_size, gizmo_z); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, viewer->seq->width, viewer->seq->height, 0, -1, 10); + float gizmo_z = 0.0f; + for (int j=0;jgizmo_count();j++) { + EffectGizmo* g = gizmos->gizmo(j); + glColor4f(g->color.redF(), g->color.greenF(), g->color.blueF(), 1.0); + switch (g->get_type()) { + case GIZMO_TYPE_DOT: // draw dot + glBegin(GL_QUADS); + glVertex3f(g->screen_pos[0].x()-dot_size, g->screen_pos[0].y()-dot_size, gizmo_z); + glVertex3f(g->screen_pos[0].x()+dot_size, g->screen_pos[0].y()-dot_size, gizmo_z); + glVertex3f(g->screen_pos[0].x()+dot_size, g->screen_pos[0].y()+dot_size, gizmo_z); + glVertex3f(g->screen_pos[0].x()-dot_size, g->screen_pos[0].y()+dot_size, gizmo_z); + glEnd(); + break; + case GIZMO_TYPE_POLY: // draw lines + glBegin(GL_LINES); + for (int k=1;kget_point_count();k++) { + glVertex3f(g->screen_pos[k-1].x(), g->screen_pos[k-1].y(), gizmo_z); + glVertex3f(g->screen_pos[k].x(), g->screen_pos[k].y(), gizmo_z); + } + glVertex3f(g->screen_pos[g->get_point_count()-1].x(), g->screen_pos[g->get_point_count()-1].y(), gizmo_z); + glVertex3f(g->screen_pos[0].x(), g->screen_pos[0].y(), gizmo_z); + glEnd(); + break; + case GIZMO_TYPE_TARGET: // draw target + glBegin(GL_LINES); + glVertex3f(g->screen_pos[0].x()-target_size, g->screen_pos[0].y()-target_size, gizmo_z); + glVertex3f(g->screen_pos[0].x()+target_size, g->screen_pos[0].y()-target_size, gizmo_z); - glVertex3f(g->screen_pos[0].x()+target_size, g->screen_pos[0].y()-target_size, gizmo_z); - glVertex3f(g->screen_pos[0].x()+target_size, g->screen_pos[0].y()+target_size, gizmo_z); + glVertex3f(g->screen_pos[0].x()+target_size, g->screen_pos[0].y()-target_size, gizmo_z); + glVertex3f(g->screen_pos[0].x()+target_size, g->screen_pos[0].y()+target_size, gizmo_z); - glVertex3f(g->screen_pos[0].x()+target_size, g->screen_pos[0].y()+target_size, gizmo_z); - glVertex3f(g->screen_pos[0].x()-target_size, g->screen_pos[0].y()+target_size, gizmo_z); + glVertex3f(g->screen_pos[0].x()+target_size, g->screen_pos[0].y()+target_size, gizmo_z); + glVertex3f(g->screen_pos[0].x()-target_size, g->screen_pos[0].y()+target_size, gizmo_z); - glVertex3f(g->screen_pos[0].x()-target_size, g->screen_pos[0].y()+target_size, gizmo_z); - glVertex3f(g->screen_pos[0].x()-target_size, g->screen_pos[0].y()-target_size, gizmo_z); + glVertex3f(g->screen_pos[0].x()-target_size, g->screen_pos[0].y()+target_size, gizmo_z); + glVertex3f(g->screen_pos[0].x()-target_size, g->screen_pos[0].y()-target_size, gizmo_z); - glVertex3f(g->screen_pos[0].x()-target_size, g->screen_pos[0].y(), gizmo_z); - glVertex3f(g->screen_pos[0].x()+target_size, g->screen_pos[0].y(), gizmo_z); + glVertex3f(g->screen_pos[0].x()-target_size, g->screen_pos[0].y(), gizmo_z); + glVertex3f(g->screen_pos[0].x()+target_size, g->screen_pos[0].y(), gizmo_z); - glVertex3f(g->screen_pos[0].x(), g->screen_pos[0].y()-target_size, gizmo_z); - glVertex3f(g->screen_pos[0].x(), g->screen_pos[0].y()+target_size, gizmo_z); - glEnd(); - break; - } - } - glPopMatrix(); + glVertex3f(g->screen_pos[0].x(), g->screen_pos[0].y()-target_size, gizmo_z); + glVertex3f(g->screen_pos[0].x(), g->screen_pos[0].y()+target_size, gizmo_z); + glEnd(); + break; + } + } + glPopMatrix(); - glColor4f(color[0], color[1], color[2], color[3]); + glColor4f(color[0], color[1], color[2], color[3]); - drawn_gizmos = true; - } + drawn_gizmos = true; + } - glDisable(GL_DEPTH); - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - } while (loop); - } + glDisable(GL_DEPTH); + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + } while (loop); + } }