rewrite nearly complete

This commit is contained in:
itsmattkc
2019-04-03 01:38:01 +11:00
parent 8989333e99
commit 2d4714547b
102 changed files with 3213 additions and 2892 deletions
+7 -7
View File
@@ -31,7 +31,7 @@
#include "panels/panels.h"
#include "panels/timeline.h"
AutoCutSilenceDialog::AutoCutSilenceDialog(QWidget *parent, QVector<int> clips) :
AutoCutSilenceDialog::AutoCutSilenceDialog(QWidget *parent, QVector<Clip*> clips) :
QDialog(parent),
clips_(clips)
{
@@ -124,16 +124,16 @@ void AutoCutSilenceDialog::cut_silence() {
// Loop over clips provided to this dialog
for (int j=0;j<clips_.size();j++) {
Clip* clip = olive::ActiveSequence->clips.at(clips_.at(j)).get();
Clip* clip = clips_.at(j);
// Check if this clip is an audio footage clip
if (clip->track() >= 0
if (clip->type() == Track::kTypeAudio
&& clip->media() != nullptr
&& clip->media_stream()->preview_done) { // TODO provide warning for preview not being done
QVector<long> split_positions;
int clip_start = clip->timeline_in();
long clip_start = clip->timeline_in();
const FootageStream* ms = clip->media_stream();
long media_length = clip->media_length();
@@ -156,7 +156,7 @@ void AutoCutSilenceDialog::cut_silence() {
// read the current sample into the circular array
qint8 tmp = 0;
for (int k=start; k<start+chunk_size; k++){
for (long k=start; k<start+chunk_size; k++){
tmp = qMax(tmp, qint8(qRound(double(ms->audio_preview.at(k)))));
}
vols[circular_index] = tmp;
@@ -202,13 +202,13 @@ void AutoCutSilenceDialog::cut_silence() {
}
}
panel_timeline->split_clip_at_positions(ca, clips_.at(j), split_positions);
clip->track()->sequence()->SplitClipAtPositions(ca, clips_.at(j), split_positions);
}
}
if (ca->hasActions()) {
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
} else {
delete ca;
}
+2 -2
View File
@@ -31,7 +31,7 @@ class AutoCutSilenceDialog : public QDialog
{
Q_OBJECT
public:
AutoCutSilenceDialog(QWidget* parent, QVector<int> clips);
AutoCutSilenceDialog(QWidget* parent, QVector<Clip*> clips);
public slots:
virtual int exec() override;
private slots:
@@ -39,7 +39,7 @@ private slots:
private:
void cut_silence();
QVector<int> clips_;
QVector<Clip*> clips_;
LabelSlider* attack_threshold;
LabelSlider* release_threshold;
+3 -3
View File
@@ -92,7 +92,7 @@ ClipPropertiesDialog::ClipPropertiesDialog(QWidget *parent, QVector<Clip *> clip
}
// it's assumed all the clips come from the same sequence
duration_field_->SetFrameRate(first_clip->sequence->frame_rate);
duration_field_->SetFrameRate(first_clip->track()->sequence()->frame_rate);
if (all_clips_have_same_duration) {
duration_field_->SetDefault(first_clip->length());
@@ -124,7 +124,7 @@ void ClipPropertiesDialog::accept()
long clip_duration_rounded = qRound(clip_duration);
if (clip->length() != clip_duration_rounded) {
clip->move(ca,
clip->Move(ca,
clip->timeline_in(),
clip->timeline_in() + clip_duration_rounded,
clip->clip_in(),
@@ -135,7 +135,7 @@ void ClipPropertiesDialog::accept()
}
if (ca->hasActions()) {
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
update_ui(false);
} else {
delete ca;
+15 -13
View File
@@ -68,14 +68,15 @@ enum ExportFormats {
FORMAT_SIZE
};
ExportDialog::ExportDialog(QWidget *parent) :
QDialog(parent)
ExportDialog::ExportDialog(QWidget *parent, Sequence* sequence) :
QDialog(parent),
sequence_(sequence)
{
setWindowTitle(tr("Export \"%1\"").arg(olive::ActiveSequence->name));
setWindowTitle(tr("Export \"%1\"").arg(sequence->name));
setup_ui();
rangeCombobox->setCurrentIndex(0);
if (olive::ActiveSequence->using_workarea) {
if (sequence->using_workarea) {
rangeCombobox->setEnabled(true);
rangeCombobox->setCurrentIndex(1);
}
@@ -109,10 +110,10 @@ ExportDialog::ExportDialog(QWidget *parent) :
formatCombobox->setCurrentIndex(FORMAT_MPEG4);
// default to sequence's native dimensions
widthSpinbox->setValue(olive::ActiveSequence->width);
heightSpinbox->setValue(olive::ActiveSequence->height);
samplingRateSpinbox->setValue(olive::ActiveSequence->audio_frequency);
framerateSpinbox->setValue(olive::ActiveSequence->frame_rate);
widthSpinbox->setValue(sequence->width);
heightSpinbox->setValue(sequence->height);
samplingRateSpinbox->setValue(sequence->audio_frequency);
framerateSpinbox->setValue(sequence->frame_rate);
// set some advanced defaults
vcodec_params.threads = 0;
@@ -537,6 +538,7 @@ void ExportDialog::StartExport() {
// Set up export parameters to send to the ExportThread
ExportParams params;
params.sequence = sequence_;
params.filename = filename;
params.video_enabled = videoGroupbox->isChecked();
if (params.video_enabled) {
@@ -555,10 +557,10 @@ void ExportDialog::StartExport() {
}
params.start_frame = 0;
params.end_frame = olive::ActiveSequence->getEndFrame(); // entire sequence
params.end_frame = sequence_->GetEndFrame(); // entire sequence
if (rangeCombobox->currentIndex() == 1) {
params.start_frame = qMax(olive::ActiveSequence->workarea_in, params.start_frame);
params.end_frame = qMin(olive::ActiveSequence->workarea_out, params.end_frame);
params.start_frame = qMax(sequence_->workarea_in, params.start_frame);
params.end_frame = qMin(sequence_->workarea_out, params.end_frame);
}
// Create export thread
@@ -573,7 +575,7 @@ void ExportDialog::StartExport() {
panel_effect_controls->Clear();
// Close all currently open clips
olive::ActiveSequence->Close();
sequence_->Close();
olive::Global->set_export_state(true);
@@ -654,7 +656,7 @@ void ExportDialog::comp_type_changed(int) {
case COMPRESSION_TYPE_CBR:
case COMPRESSION_TYPE_TARGETBR:
videoBitrateLabel->setText(tr("Bitrate (Mbps):"));
videobitrateSpinbox->setValue(qMax(0.5, (double) qRound((0.01528 * olive::ActiveSequence->height) - 4.5)));
videobitrateSpinbox->setValue(qMax(0.5, (double) qRound((0.01528 * sequence_->height) - 4.5)));
break;
case COMPRESSION_TYPE_CFR:
videoBitrateLabel->setText(tr("Quality (CRF):"));
+3 -1
View File
@@ -50,7 +50,7 @@ public:
*
* QWidget parent. Usually MainWindow.
*/
explicit ExportDialog(QWidget *parent);
explicit ExportDialog(QWidget *parent, Sequence *sequence);
private slots:
/**
@@ -270,6 +270,8 @@ private:
* @brief Time value set when exporting begins to determine the total duration of the export
*/
qint64 total_export_time_start;
Sequence* sequence_;
};
#endif // EXPORTDIALOG_H
+5 -5
View File
@@ -114,12 +114,12 @@ MediaPropertiesDialog::MediaPropertiesDialog(QWidget *parent, Media *i) :
interlacing_box = new QComboBox(this);
interlacing_box->addItem(
tr("Auto (%1)").arg(
get_interlacing_name(f->video_tracks.at(0).video_auto_interlacing)
Footage::get_interlacing_name(f->video_tracks.at(0).video_auto_interlacing)
)
);
interlacing_box->addItem(get_interlacing_name(VIDEO_PROGRESSIVE));
interlacing_box->addItem(get_interlacing_name(VIDEO_TOP_FIELD_FIRST));
interlacing_box->addItem(get_interlacing_name(VIDEO_BOTTOM_FIELD_FIRST));
interlacing_box->addItem(Footage::get_interlacing_name(VIDEO_PROGRESSIVE));
interlacing_box->addItem(Footage::get_interlacing_name(VIDEO_TOP_FIELD_FIRST));
interlacing_box->addItem(Footage::get_interlacing_name(VIDEO_BOTTOM_FIELD_FIRST));
interlacing_box->setCurrentIndex(
(f->video_tracks.at(0).video_auto_interlacing == f->video_tracks.at(0).video_interlacing)
@@ -232,7 +232,7 @@ void MediaPropertiesDialog::accept() {
}
ca->appendPost(new UpdateViewer());
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
QDialog::accept();
}
+10 -12
View File
@@ -108,8 +108,8 @@ void NewSequenceDialog::accept() {
s->audio_layout = AV_CH_LAYOUT_STEREO;
ComboAction* ca = new ComboAction();
panel_project->create_sequence_internal(ca, s, true, nullptr);
olive::UndoStack.push(ca);
olive::project_model.CreateSequence(ca, s, true, nullptr);
olive::undo_stack.push(ca);
} else if (existing_item != nullptr) {
@@ -128,14 +128,12 @@ void NewSequenceDialog::accept() {
esc->audio_layout = AV_CH_LAYOUT_STEREO;
ca->append(esc);
for (int i=0;i<existing_sequence->clips.size();i++) {
ClipPtr c = existing_sequence->clips.at(i);
if (c != nullptr) {
c->refactor_frame_rate(ca, multiplier, true);
}
QVector<Clip*> existing_sequence_clips = existing_sequence->GetAllClips();
for (int i=0;i<existing_sequence_clips.size();i++) {
existing_sequence_clips.at(i)->refactor_frame_rate(ca, multiplier, true);
}
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
} else if (existing_sequence != nullptr) {
@@ -235,13 +233,13 @@ void NewSequenceDialog::setup_ui() {
videoLayout->addWidget(new QLabel(tr("Width:"), this), 0, 0, 1, 1);
width_numeric = new QSpinBox(videoGroupBox);
width_numeric->setMaximum(9999);
width_numeric->setValue(olive::CurrentConfig.default_sequence_width);
width_numeric->setValue(olive::config.default_sequence_width);
videoLayout->addWidget(width_numeric, 0, 2, 1, 2);
videoLayout->addWidget(new QLabel(tr("Height:"), this), 1, 0, 1, 2);
height_numeric = new QSpinBox(videoGroupBox);
height_numeric->setMaximum(9999);
height_numeric->setValue(olive::CurrentConfig.default_sequence_height);
height_numeric->setValue(olive::config.default_sequence_height);
videoLayout->addWidget(height_numeric, 1, 2, 1, 2);
videoLayout->addWidget(new QLabel(tr("Frame Rate:"), this), 2, 0, 1, 1);
@@ -258,7 +256,7 @@ void NewSequenceDialog::setup_ui() {
frame_rate_combobox->addItem("59.94 FPS", 59.94);
frame_rate_combobox->addItem("60 FPS", 60.0);
for (int i=0;i<frame_rate_combobox->count();i++) {
if (qFuzzyCompare(frame_rate_combobox->itemData(i).toDouble(), olive::CurrentConfig.default_sequence_framerate)) {
if (qFuzzyCompare(frame_rate_combobox->itemData(i).toDouble(), olive::config.default_sequence_framerate)) {
frame_rate_combobox->setCurrentIndex(i);
}
}
@@ -288,7 +286,7 @@ void NewSequenceDialog::setup_ui() {
audio_frequency_combobox = new QComboBox(audioGroupBox);
combobox_audio_sample_rates(audio_frequency_combobox);
for (int i=0;i<audio_frequency_combobox->count();i++) {
if (audio_frequency_combobox->itemData(i) == olive::CurrentConfig.default_sequence_audio_frequency) {
if (audio_frequency_combobox->itemData(i) == olive::config.default_sequence_audio_frequency) {
audio_frequency_combobox->setCurrentIndex(i);
}
}
+94 -94
View File
@@ -90,11 +90,11 @@ PreferencesDialog::PreferencesDialog(QWidget *parent) :
// set up default sequence
default_sequence.name = tr("Default Sequence");
default_sequence.width = olive::CurrentConfig.default_sequence_width;
default_sequence.height = olive::CurrentConfig.default_sequence_height;
default_sequence.frame_rate = olive::CurrentConfig.default_sequence_framerate;
default_sequence.audio_frequency = olive::CurrentConfig.default_sequence_audio_frequency;
default_sequence.audio_layout = olive::CurrentConfig.default_sequence_audio_channel_layout;
default_sequence.width = olive::config.default_sequence_width;
default_sequence.height = olive::config.default_sequence_height;
default_sequence.frame_rate = olive::config.default_sequence_framerate;
default_sequence.audio_frequency = olive::config.default_sequence_audio_frequency;
default_sequence.audio_layout = olive::config.default_sequence_audio_channel_layout;
}
void PreferencesDialog::setup_kbd_shortcut_worker(QMenu* menu, QTreeWidgetItem* parent) {
@@ -187,13 +187,13 @@ void PreferencesDialog::populate_ocio_menus(OCIO::ConstConfigRcPtr config)
ocio_default_input->addItem(colorspace);
if (colorspace == olive::CurrentConfig.ocio_default_input_colorspace) {
if (colorspace == olive::config.ocio_default_input_colorspace) {
ocio_default_input->setCurrentIndex(i);
}
}
// Get current display name (if the config is empty, get the current default display)
QString current_display = olive::CurrentConfig.ocio_display;
QString current_display = olive::config.ocio_display;
if (current_display.isEmpty()) {
current_display = config->getDefaultDisplay();
}
@@ -219,7 +219,7 @@ void PreferencesDialog::populate_ocio_menus(OCIO::ConstConfigRcPtr config)
ocio_look->addItem(look, look);
if (look == olive::CurrentConfig.ocio_look) {
if (look == olive::config.ocio_look) {
ocio_look->setCurrentIndex(i);
}
}
@@ -249,7 +249,7 @@ void PreferencesDialog::update_ocio_view_menu(OCIO::ConstConfigRcPtr config)
QString display = ocio_display->currentText();
// Get current view
QString current_view = olive::CurrentConfig.ocio_view;
QString current_view = olive::config.ocio_view;
if (current_view.isEmpty()) {
current_view = config->getDefaultView(display.toUtf8());
}
@@ -351,7 +351,7 @@ void PreferencesDialog::accept() {
);
return;
} else if (olive::CurrentConfig.ocio_config_path != ocio_config_file->text()) {
} else if (olive::config.ocio_config_path != ocio_config_file->text()) {
// Check whether OCIO can load it
OCIO::ConstConfigRcPtr file_config = TestOCIOConfig(ocio_config_file->text().toUtf8());
@@ -375,10 +375,10 @@ void PreferencesDialog::accept() {
// Check if any settings will require a restart of Olive (including the bool options determined above)
if (bool_requires_restart
|| olive::CurrentConfig.thumbnail_resolution != thumbnail_res_spinbox->value()
|| olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()
|| olive::CurrentConfig.css_path != custom_css_fn->text()
|| olive::CurrentConfig.style != static_cast<olive::styling::Style>(ui_style->currentData().toInt())) {
|| olive::config.thumbnail_resolution != thumbnail_res_spinbox->value()
|| olive::config.waveform_resolution != waveform_res_spinbox->value()
|| olive::config.css_path != custom_css_fn->text()
|| olive::config.style != static_cast<olive::styling::Style>(ui_style->currentData().toInt())) {
// any changes to these settings will require a restart - ask the user if we should do one now or later
@@ -406,65 +406,65 @@ void PreferencesDialog::accept() {
// Everything checks out, start saving settings from the UI to the backend
olive::CurrentConfig.css_path = custom_css_fn->text();
olive::CurrentConfig.recording_mode = recordingComboBox->currentIndex() + 1;
olive::CurrentConfig.img_seq_formats = imgSeqFormatEdit->text();
olive::CurrentConfig.upcoming_queue_size = upcoming_queue_spinbox->value();
olive::CurrentConfig.upcoming_queue_type = upcoming_queue_type->currentIndex();
olive::CurrentConfig.previous_queue_size = previous_queue_spinbox->value();
olive::CurrentConfig.previous_queue_type = previous_queue_type->currentIndex();
olive::config.css_path = custom_css_fn->text();
olive::config.recording_mode = recordingComboBox->currentIndex() + 1;
olive::config.img_seq_formats = imgSeqFormatEdit->text();
olive::config.upcoming_queue_size = upcoming_queue_spinbox->value();
olive::config.upcoming_queue_type = upcoming_queue_type->currentIndex();
olive::config.previous_queue_size = previous_queue_spinbox->value();
olive::config.previous_queue_type = previous_queue_type->currentIndex();
// Audio settings may require the audio device to be re-initiated.
if (olive::CurrentConfig.preferred_audio_output != audio_output_devices->currentData().toString()
|| olive::CurrentConfig.preferred_audio_input != audio_input_devices->currentData().toString()
|| olive::CurrentConfig.audio_rate != audio_sample_rate->currentData().toInt()) {
if (olive::config.preferred_audio_output != audio_output_devices->currentData().toString()
|| olive::config.preferred_audio_input != audio_input_devices->currentData().toString()
|| olive::config.audio_rate != audio_sample_rate->currentData().toInt()) {
reinit_audio = true;
}
olive::CurrentConfig.preferred_audio_output = audio_output_devices->currentData().toString();
olive::CurrentConfig.preferred_audio_input = audio_input_devices->currentData().toString();
olive::CurrentConfig.audio_rate = audio_sample_rate->currentData().toInt();
olive::config.preferred_audio_output = audio_output_devices->currentData().toString();
olive::config.preferred_audio_input = audio_input_devices->currentData().toString();
olive::config.audio_rate = audio_sample_rate->currentData().toInt();
olive::CurrentConfig.effect_textbox_lines = effect_textbox_lines_field->value();
olive::config.effect_textbox_lines = effect_textbox_lines_field->value();
// see if the language file should be reloaded (not necessary if the app is restarting anyway)
if (!restart_after_saving
&& olive::CurrentConfig.language_file != language_combobox->currentData().toString()) {
&& olive::config.language_file != language_combobox->currentData().toString()) {
reload_language = true;
}
olive::CurrentConfig.language_file = language_combobox->currentData().toString();
olive::config.language_file = language_combobox->currentData().toString();
// Check whether OCIO settings will require a reset of the render threads
if (olive::CurrentConfig.playback_bit_depth != playback_bit_depth->currentIndex()
|| olive::CurrentConfig.export_bit_depth != export_bit_depth->currentIndex()) {
if (olive::config.playback_bit_depth != playback_bit_depth->currentIndex()
|| olive::config.export_bit_depth != export_bit_depth->currentIndex()) {
reset_render_threads = true;
}
if (olive::CurrentConfig.ocio_config_path != ocio_config_file->text()
|| olive::CurrentConfig.ocio_display != ocio_display->currentText()
|| olive::CurrentConfig.ocio_view != ocio_view->currentText()
|| olive::CurrentConfig.ocio_look != ocio_look->currentData().toString()) {
if (olive::config.ocio_config_path != ocio_config_file->text()
|| olive::config.ocio_display != ocio_display->currentText()
|| olive::config.ocio_view != ocio_view->currentText()
|| olive::config.ocio_look != ocio_look->currentData().toString()) {
reset_ocio_shaders = true;
}
if (olive::CurrentConfig.ocio_config_path != ocio_config_file->text()) {
if (olive::config.ocio_config_path != ocio_config_file->text()) {
OCIO::SetCurrentConfig(OCIO::Config::CreateFromFile(ocio_config_file->text().toUtf8()));
olive::CurrentConfig.ocio_config_path = ocio_config_file->text();
olive::config.ocio_config_path = ocio_config_file->text();
}
olive::CurrentConfig.enable_color_management = enable_color_management->isChecked();
olive::CurrentConfig.playback_bit_depth = playback_bit_depth->currentIndex();
olive::CurrentConfig.export_bit_depth = export_bit_depth->currentIndex();
olive::CurrentConfig.ocio_display = ocio_display->currentText();
olive::CurrentConfig.ocio_default_input_colorspace = ocio_default_input->currentText();
olive::CurrentConfig.ocio_view = ocio_view->currentText();
olive::config.enable_color_management = enable_color_management->isChecked();
olive::config.playback_bit_depth = playback_bit_depth->currentIndex();
olive::config.export_bit_depth = export_bit_depth->currentIndex();
olive::config.ocio_display = ocio_display->currentText();
olive::config.ocio_default_input_colorspace = ocio_default_input->currentText();
olive::config.ocio_view = ocio_view->currentText();
// We use data here instead of text because there's a "(None)" option with an empty string
olive::CurrentConfig.ocio_look = ocio_look->currentData().toString();
olive::config.ocio_look = ocio_look->currentData().toString();
// Set default sequence options
olive::CurrentConfig.default_sequence_width = default_sequence.width;
olive::CurrentConfig.default_sequence_height = default_sequence.height;
olive::CurrentConfig.default_sequence_framerate = default_sequence.frame_rate;
olive::CurrentConfig.default_sequence_audio_frequency = default_sequence.audio_frequency;
olive::CurrentConfig.default_sequence_audio_channel_layout = default_sequence.audio_layout;
olive::config.default_sequence_width = default_sequence.width;
olive::config.default_sequence_height = default_sequence.height;
olive::config.default_sequence_framerate = default_sequence.frame_rate;
olive::config.default_sequence_audio_frequency = default_sequence.audio_frequency;
olive::config.default_sequence_audio_channel_layout = default_sequence.audio_layout;
// Set all bool options
for (int i=0;i<bool_ui.size();i++) {
@@ -472,27 +472,27 @@ void PreferencesDialog::accept() {
}
// Set new style
olive::CurrentConfig.style = static_cast<olive::styling::Style>(ui_style->currentData().toInt());
olive::config.style = static_cast<olive::styling::Style>(ui_style->currentData().toInt());
// Check if the thumbnail or waveform icon fields have changed, we may need to recreate the previews if so
if (olive::CurrentConfig.thumbnail_resolution != thumbnail_res_spinbox->value()
|| olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()) {
if (olive::config.thumbnail_resolution != thumbnail_res_spinbox->value()
|| olive::config.waveform_resolution != waveform_res_spinbox->value()) {
// we're changing the size of thumbnails and waveforms, so let's delete them and regenerate them next start
// delete nothing
PreviewDeleteTypes delete_type = DELETE_NONE;
if (olive::CurrentConfig.thumbnail_resolution != thumbnail_res_spinbox->value()) {
if (olive::config.thumbnail_resolution != thumbnail_res_spinbox->value()) {
// delete existing thumbnails
olive::CurrentConfig.thumbnail_resolution = thumbnail_res_spinbox->value();
olive::config.thumbnail_resolution = thumbnail_res_spinbox->value();
// delete only thumbnails
delete_type = DELETE_THUMBNAILS;
}
if (olive::CurrentConfig.waveform_resolution != waveform_res_spinbox->value()) {
if (olive::config.waveform_resolution != waveform_res_spinbox->value()) {
// delete existing waveforms
olive::CurrentConfig.waveform_resolution = waveform_res_spinbox->value();
olive::config.waveform_resolution = waveform_res_spinbox->value();
// if we're already deleting thumbnails
if (delete_type == DELETE_THUMBNAILS) {
@@ -749,7 +749,7 @@ void PreferencesDialog::setup_ui() {
QString locale_str = locale_file_basename.mid(locale_file_basename.lastIndexOf('_')+1);
language_combobox->addItem(QLocale(locale_str).nativeLanguageName(), locale_relative_path);
if (olive::CurrentConfig.language_file == locale_relative_path) {
if (olive::config.language_file == locale_relative_path) {
language_combobox->setCurrentIndex(language_combobox->count() - 1);
}
}
@@ -764,7 +764,7 @@ void PreferencesDialog::setup_ui() {
general_layout->addWidget(new QLabel(tr("Image sequence formats:"), this), row, 0);
imgSeqFormatEdit = new QLineEdit(general_tab);
imgSeqFormatEdit->setText(olive::CurrentConfig.img_seq_formats);
imgSeqFormatEdit->setText(olive::config.img_seq_formats);
general_layout->addWidget(imgSeqFormatEdit, row, 1, 1, 4);
row++;
@@ -775,7 +775,7 @@ void PreferencesDialog::setup_ui() {
thumbnail_res_spinbox = new QSpinBox(this);
thumbnail_res_spinbox->setMinimum(0);
thumbnail_res_spinbox->setMaximum(INT_MAX);
thumbnail_res_spinbox->setValue(olive::CurrentConfig.thumbnail_resolution);
thumbnail_res_spinbox->setValue(olive::config.thumbnail_resolution);
general_layout->addWidget(thumbnail_res_spinbox, row, 1);
general_layout->addWidget(new QLabel(tr("Waveform Resolution:"), this), row, 2);
@@ -783,7 +783,7 @@ void PreferencesDialog::setup_ui() {
waveform_res_spinbox = new QSpinBox(this);
waveform_res_spinbox->setMinimum(0);
waveform_res_spinbox->setMaximum(INT_MAX);
waveform_res_spinbox->setValue(olive::CurrentConfig.waveform_resolution);
waveform_res_spinbox->setValue(olive::config.waveform_resolution);
general_layout->addWidget(waveform_res_spinbox, row, 3);
QPushButton* delete_preview_btn = new QPushButton(tr("Delete Previews"));
@@ -796,13 +796,13 @@ void PreferencesDialog::setup_ui() {
// General -> Use Software Fallbacks When Possible
QCheckBox* use_software_fallbacks_checkbox = new QCheckBox(tr("Use Software Fallbacks When Possible"));
AddBoolPair(use_software_fallbacks_checkbox, &olive::CurrentConfig.use_software_fallback, true);
AddBoolPair(use_software_fallbacks_checkbox, &olive::config.use_software_fallback, true);
misc_general->addWidget(use_software_fallbacks_checkbox);
// General -> Don't Use Proxies When Exporting
QCheckBox* dont_use_proxies_when_exporting = new QCheckBox(tr("Don't Use Proxies When Exporting"));
dont_use_proxies_when_exporting->setToolTip(tr("Use originals instead of proxies when exporting"));
AddBoolPair(dont_use_proxies_when_exporting, &olive::CurrentConfig.dont_use_proxies_on_export);
AddBoolPair(dont_use_proxies_when_exporting, &olive::config.dont_use_proxies_on_export);
misc_general->addWidget(dont_use_proxies_when_exporting);
// General -> Default Sequence Settings
@@ -823,68 +823,68 @@ void PreferencesDialog::setup_ui() {
ColumnedGridLayout* behavior_tab_layout = new ColumnedGridLayout(behavior_tab, 2);
QCheckBox* add_default_effects_to_clips = new QCheckBox(tr("Add Default Effects to New Clips"));
AddBoolPair(add_default_effects_to_clips, &olive::CurrentConfig.add_default_effects_to_clips);
AddBoolPair(add_default_effects_to_clips, &olive::config.add_default_effects_to_clips);
behavior_tab_layout->Add(add_default_effects_to_clips);
QCheckBox* auto_seek_to_beginning = new QCheckBox(tr("Automatically Seek to the Beginning When Playing at the End of a Sequence"));
AddBoolPair(auto_seek_to_beginning, &olive::CurrentConfig.auto_seek_to_beginning);
AddBoolPair(auto_seek_to_beginning, &olive::config.auto_seek_to_beginning);
behavior_tab_layout->Add(auto_seek_to_beginning);
QCheckBox* selecting_also_seeks = new QCheckBox(tr("Selecting Also Seeks"));
AddBoolPair(selecting_also_seeks, &olive::CurrentConfig.select_also_seeks);
AddBoolPair(selecting_also_seeks, &olive::config.select_also_seeks);
behavior_tab_layout->Add(selecting_also_seeks);
QCheckBox* edit_tool_also_seeks = new QCheckBox(tr("Edit Tool Also Seeks"));
AddBoolPair(edit_tool_also_seeks, &olive::CurrentConfig.edit_tool_also_seeks);
AddBoolPair(edit_tool_also_seeks, &olive::config.edit_tool_also_seeks);
behavior_tab_layout->Add(edit_tool_also_seeks);
QCheckBox* edit_tool_selects_links = new QCheckBox(tr("Edit Tool Selects Links"));
AddBoolPair(edit_tool_selects_links, &olive::CurrentConfig.edit_tool_selects_links);
AddBoolPair(edit_tool_selects_links, &olive::config.edit_tool_selects_links);
behavior_tab_layout->Add(edit_tool_selects_links);
QCheckBox* seek_also_selects = new QCheckBox(tr("Seek Also Selects"));
AddBoolPair(seek_also_selects, &olive::CurrentConfig.seek_also_selects);
AddBoolPair(seek_also_selects, &olive::config.seek_also_selects);
behavior_tab_layout->Add(seek_also_selects);
QCheckBox* seek_to_end_of_pastes = new QCheckBox(tr("Seek to the End of Pastes"));
AddBoolPair(seek_to_end_of_pastes, &olive::CurrentConfig.paste_seeks);
AddBoolPair(seek_to_end_of_pastes, &olive::config.paste_seeks);
behavior_tab_layout->Add(seek_to_end_of_pastes);
QCheckBox* scroll_wheel_zooms = new QCheckBox(tr("Scroll Wheel Zooms"));
scroll_wheel_zooms->setToolTip(tr("Hold CTRL to toggle this setting"));
AddBoolPair(scroll_wheel_zooms, &olive::CurrentConfig.scroll_zooms);
AddBoolPair(scroll_wheel_zooms, &olive::config.scroll_zooms);
behavior_tab_layout->Add(scroll_wheel_zooms);
QCheckBox* invert_timeline_scroll_axes = new QCheckBox(tr("Invert Timeline Scroll Axes"));
AddBoolPair(invert_timeline_scroll_axes, &olive::CurrentConfig.invert_timeline_scroll_axes);
AddBoolPair(invert_timeline_scroll_axes, &olive::config.invert_timeline_scroll_axes);
behavior_tab_layout->Add(invert_timeline_scroll_axes);
QCheckBox* enable_drag_files_to_timeline = new QCheckBox(tr("Enable Drag Files to Timeline"));
AddBoolPair(enable_drag_files_to_timeline, &olive::CurrentConfig.enable_drag_files_to_timeline);
AddBoolPair(enable_drag_files_to_timeline, &olive::config.enable_drag_files_to_timeline);
behavior_tab_layout->Add(enable_drag_files_to_timeline);
QCheckBox* autoscale_by_default = new QCheckBox(tr("Auto-Scale By Default"));
AddBoolPair(autoscale_by_default, &olive::CurrentConfig.autoscale_by_default);
AddBoolPair(autoscale_by_default, &olive::config.autoscale_by_default);
behavior_tab_layout->Add(autoscale_by_default);
QCheckBox* enable_seek_to_import = new QCheckBox(tr("Auto-Seek to Imported Clips"));
AddBoolPair(enable_seek_to_import, &olive::CurrentConfig.enable_seek_to_import);
AddBoolPair(enable_seek_to_import, &olive::config.enable_seek_to_import);
behavior_tab_layout->Add(enable_seek_to_import);
QCheckBox* enable_audio_scrubbing = new QCheckBox(tr("Audio Scrubbing"));
AddBoolPair(enable_audio_scrubbing, &olive::CurrentConfig.enable_audio_scrubbing);
AddBoolPair(enable_audio_scrubbing, &olive::config.enable_audio_scrubbing);
behavior_tab_layout->Add(enable_audio_scrubbing);
QCheckBox* enable_drop_on_media_to_replace = new QCheckBox(tr("Drop Files on Media to Replace"));
AddBoolPair(enable_drop_on_media_to_replace, &olive::CurrentConfig.drop_on_media_to_replace);
AddBoolPair(enable_drop_on_media_to_replace, &olive::config.drop_on_media_to_replace);
behavior_tab_layout->Add(enable_drop_on_media_to_replace);
QCheckBox* enable_hover_focus = new QCheckBox(tr("Enable Hover Focus"));
AddBoolPair(enable_hover_focus, &olive::CurrentConfig.hover_focus);
AddBoolPair(enable_hover_focus, &olive::config.hover_focus);
behavior_tab_layout->Add(enable_hover_focus);
QCheckBox* set_name_and_marker = new QCheckBox(tr("Ask For Name When Setting Marker"));
AddBoolPair(set_name_and_marker, &olive::CurrentConfig.set_name_with_marker);
AddBoolPair(set_name_and_marker, &olive::config.set_name_with_marker);
behavior_tab_layout->Add(set_name_and_marker);
// Appearance
@@ -903,7 +903,7 @@ void PreferencesDialog::setup_ui() {
ui_style->addItem(tr("Olive Light"), olive::styling::kOliveDefaultLight);
ui_style->addItem(tr("Native"), olive::styling::kNativeDarkIcons);
ui_style->addItem(tr("Native (Light Icons)"), olive::styling::kNativeLightIcons);
ui_style->setCurrentIndex(olive::CurrentConfig.style);
ui_style->setCurrentIndex(olive::config.style);
appearance_layout->addWidget(ui_style, row, 1, 1, 2);
row++;
@@ -922,7 +922,7 @@ void PreferencesDialog::setup_ui() {
appearance_layout->addWidget(new QLabel(tr("Custom CSS:"), this), row, 0);
custom_css_fn = new QLineEdit(general_tab);
custom_css_fn->setText(olive::CurrentConfig.css_path);
custom_css_fn->setText(olive::config.css_path);
appearance_layout->addWidget(custom_css_fn, row, 1);
QPushButton* custom_css_browse = new QPushButton(tr("Browse"), general_tab);
@@ -936,7 +936,7 @@ void PreferencesDialog::setup_ui() {
effect_textbox_lines_field = new QSpinBox(general_tab);
effect_textbox_lines_field->setMinimum(1);
effect_textbox_lines_field->setValue(olive::CurrentConfig.effect_textbox_lines);
effect_textbox_lines_field->setValue(olive::config.effect_textbox_lines);
appearance_layout->addWidget(effect_textbox_lines_field, row, 1, 1, 2);
row++;
@@ -951,21 +951,21 @@ void PreferencesDialog::setup_ui() {
QGridLayout* memory_usage_layout = new QGridLayout(memory_usage_group);
memory_usage_layout->addWidget(new QLabel(tr("Upcoming Frame Queue:"), playback_tab), 0, 0);
upcoming_queue_spinbox = new QDoubleSpinBox(playback_tab);
upcoming_queue_spinbox->setValue(olive::CurrentConfig.upcoming_queue_size);
upcoming_queue_spinbox->setValue(olive::config.upcoming_queue_size);
memory_usage_layout->addWidget(upcoming_queue_spinbox, 0, 1);
upcoming_queue_type = new QComboBox(playback_tab);
upcoming_queue_type->addItem(tr("frames"));
upcoming_queue_type->addItem(tr("seconds"));
upcoming_queue_type->setCurrentIndex(olive::CurrentConfig.upcoming_queue_type);
upcoming_queue_type->setCurrentIndex(olive::config.upcoming_queue_type);
memory_usage_layout->addWidget(upcoming_queue_type, 0, 2);
memory_usage_layout->addWidget(new QLabel(tr("Previous Frame Queue:"), playback_tab), 1, 0);
previous_queue_spinbox = new QDoubleSpinBox(playback_tab);
previous_queue_spinbox->setValue(olive::CurrentConfig.previous_queue_size);
previous_queue_spinbox->setValue(olive::config.previous_queue_size);
memory_usage_layout->addWidget(previous_queue_spinbox, 1, 1);
previous_queue_type = new QComboBox(playback_tab);
previous_queue_type->addItem(tr("frames"));
previous_queue_type->addItem(tr("seconds"));
previous_queue_type->setCurrentIndex(olive::CurrentConfig.previous_queue_type);
previous_queue_type->setCurrentIndex(olive::config.previous_queue_type);
memory_usage_layout->addWidget(previous_queue_type, 1, 2);
playback_tab_layout->addWidget(memory_usage_group);
@@ -991,7 +991,7 @@ void PreferencesDialog::setup_ui() {
for (int i=0;i<devs.size();i++) {
audio_output_devices->addItem(devs.at(i).deviceName(), devs.at(i).deviceName());
if (!found_preferred_device
&& devs.at(i).deviceName() == olive::CurrentConfig.preferred_audio_output) {
&& devs.at(i).deviceName() == olive::config.preferred_audio_output) {
audio_output_devices->setCurrentIndex(audio_output_devices->count()-1);
found_preferred_device = true;
}
@@ -1014,7 +1014,7 @@ void PreferencesDialog::setup_ui() {
for (int i=0;i<devs.size();i++) {
audio_input_devices->addItem(devs.at(i).deviceName(), devs.at(i).deviceName());
if (!found_preferred_device
&& devs.at(i).deviceName() == olive::CurrentConfig.preferred_audio_input) {
&& devs.at(i).deviceName() == olive::config.preferred_audio_input) {
audio_input_devices->setCurrentIndex(audio_input_devices->count()-1);
found_preferred_device = true;
}
@@ -1031,7 +1031,7 @@ void PreferencesDialog::setup_ui() {
audio_sample_rate = new QComboBox();
combobox_audio_sample_rates(audio_sample_rate);
for (int i=0;i<audio_sample_rate->count();i++) {
if (audio_sample_rate->itemData(i).toInt() == olive::CurrentConfig.audio_rate) {
if (audio_sample_rate->itemData(i).toInt() == olive::config.audio_rate) {
audio_sample_rate->setCurrentIndex(i);
break;
}
@@ -1047,7 +1047,7 @@ void PreferencesDialog::setup_ui() {
recordingComboBox = new QComboBox(general_tab);
recordingComboBox->addItem(tr("Mono"));
recordingComboBox->addItem(tr("Stereo"));
recordingComboBox->setCurrentIndex(olive::CurrentConfig.recording_mode - 1);
recordingComboBox->setCurrentIndex(olive::config.recording_mode - 1);
audio_tab_layout->addWidget(recordingComboBox, row, 1);
row++;
@@ -1066,7 +1066,7 @@ void PreferencesDialog::setup_ui() {
// COLOR MANAGEMENT -> Enable Color Management
enable_color_management = new QCheckBox(tr("Enable Color Management"));
enable_color_management->setChecked(olive::CurrentConfig.enable_color_management);
enable_color_management->setChecked(olive::config.enable_color_management);
color_management_layout->addWidget(enable_color_management, row, 0);
row++;
@@ -1078,7 +1078,7 @@ void PreferencesDialog::setup_ui() {
opencolorio_groupbox_layout->addWidget(new QLabel(tr("OpenColorIO Config File:")), 0, 0);
ocio_config_file = new QLineEdit();
ocio_config_file->setText(olive::CurrentConfig.ocio_config_path);
ocio_config_file->setText(olive::config.ocio_config_path);
connect(ocio_config_file, SIGNAL(textChanged(const QString &)), this, SLOT(update_ocio_config(const QString&)));
opencolorio_groupbox_layout->addWidget(ocio_config_file, 0, 1, 1, 4);
@@ -1120,7 +1120,7 @@ void PreferencesDialog::setup_ui() {
for (int i=0;i<olive::pixel_formats.size();i++) {
playback_bit_depth->addItem(olive::pixel_formats.at(i).name, i);
}
playback_bit_depth->setCurrentIndex(olive::CurrentConfig.playback_bit_depth);
playback_bit_depth->setCurrentIndex(olive::config.playback_bit_depth);
bit_depth_groupbox_layout->addWidget(new QLabel(tr("Playback (Offline):")), 0, 0);
bit_depth_groupbox_layout->addWidget(playback_bit_depth, 0, 1);
@@ -1129,7 +1129,7 @@ void PreferencesDialog::setup_ui() {
for (int i=0;i<olive::pixel_formats.size();i++) {
export_bit_depth->addItem(olive::pixel_formats.at(i).name, i);
}
export_bit_depth->setCurrentIndex(olive::CurrentConfig.export_bit_depth);
export_bit_depth->setCurrentIndex(olive::config.export_bit_depth);
bit_depth_groupbox_layout->addWidget(new QLabel(tr("Export (Online):")), 0, 2);
bit_depth_groupbox_layout->addWidget(export_bit_depth, 0, 3);
+9 -5
View File
@@ -95,7 +95,10 @@ void ReplaceClipMediaDialog::accept() {
QMessageBox::Ok
);
} else {
if (new_item->get_type() == MEDIA_TYPE_SEQUENCE && olive::ActiveSequence == new_item->to_sequence()) {
SequencePtr top_sequence = Timeline::GetTopSequence();
if (new_item->get_type() == MEDIA_TYPE_SEQUENCE && top_sequence == new_item->to_sequence()) {
QMessageBox::critical(
this,
tr("Active sequence selected"),
@@ -109,14 +112,15 @@ void ReplaceClipMediaDialog::accept() {
use_same_media_in_points->isChecked()
);
for (int i=0;i<olive::ActiveSequence->clips.size();i++) {
ClipPtr c = olive::ActiveSequence->clips.at(i);
if (c != nullptr && c->media() == media) {
QVector<Clip*> all_clips = top_sequence->GetAllClips();
for (int i=0;i<all_clips.size();i++) {
Clip* c = all_clips.at(i);
if (c->media() == media) {
rcmc->clips.append(c);
}
}
olive::UndoStack.push(rcmc);
olive::undo_stack.push(rcmc);
QDialog::accept();
}
+32 -25
View File
@@ -61,7 +61,7 @@ SpeedDialog::SpeedDialog(QWidget *parent, QVector<Clip*> clips) : QDialog(parent
grid->addWidget(new QLabel(tr("Duration:"), this), 2, 0);
duration = new LabelSlider(this);
duration->SetDisplayType(LabelSlider::FrameNumber);
duration->SetFrameRate(olive::ActiveSequence->frame_rate);
duration->SetFrameRate(clips_.first()->track()->sequence()->frame_rate);
grid->addWidget(duration, 2, 1);
main_layout->addLayout(grid);
@@ -103,7 +103,7 @@ int SpeedDialog::exec() {
// get default frame rate/percentage
clip_percent = c->speed().value;
if (c->track() < 0) {
if (c->type() == Track::kTypeVideo) {
bool process_video = true;
if (c->media() != nullptr && c->media()->get_type() == MEDIA_TYPE_FOOTAGE) {
FootageStream* ms = c->media_stream();
@@ -131,7 +131,7 @@ int SpeedDialog::exec() {
enable_frame_rate = true;
}
} else {
} else if (c->type() == Track::kTypeAudio) {
maintain_pitch->setEnabled(true);
if (!multiple_audio) {
@@ -192,7 +192,7 @@ void SpeedDialog::percent_update() {
Clip* c = clips_.at(i);
// get frame rate
if (frame_rate->isEnabled() && c->track() < 0) {
if (frame_rate->isEnabled() && c->type() == Track::kTypeVideo) {
double clip_fr = c->media_frame_rate() * percent->value();
if (got_fr) {
if (!qIsNaN(fr_val) && !qFuzzyCompare(fr_val, clip_fr)) {
@@ -236,7 +236,7 @@ void SpeedDialog::duration_update() {
}
// get frame rate
if (frame_rate->isEnabled() && c->track() < 0) {
if (frame_rate->isEnabled() && c->type() == Track::kTypeVideo) {
double clip_fr = c->media_frame_rate() * clip_pc;
if (got_fr) {
if (!qIsNaN(fr_val) && !qFuzzyCompare(fr_val, clip_fr)) {
@@ -276,7 +276,7 @@ void SpeedDialog::frame_rate_update() {
old_pc_val = qSNaN();
}
if (c->track() < 0) {
if (c->type() == Track::kTypeVideo) {
// what would the new speed be based on this frame rate
double new_clip_speed = frame_rate->value() / c->media_frame_rate();
if (!got_pc_val) {
@@ -301,7 +301,7 @@ void SpeedDialog::frame_rate_update() {
for (int i=0;i<clips_.size();i++) {
Clip* c = clips_.at(i);
if (c->track() >= 0) {
if (c->type() == Track::kTypeAudio) {
long new_clip_len = (qIsNaN(old_pc_val) || qIsNaN(pc_val)) ?
c->length() : qRound((c->length() * c->speed().value) / pc_val);
@@ -318,15 +318,17 @@ void SpeedDialog::frame_rate_update() {
}
void set_speed(ComboAction* ca, Clip* c, double speed, bool ripple, long& ep, long& lr) {
panel_timeline->deselect_area(c->timeline_in(), c->timeline_out(), c->track());
c->track()->DeselectArea(c->timeline_in(), c->timeline_out());
long proposed_out = c->timeline_out();
double multiplier = (c->speed().value / speed);
proposed_out = qRound(c->timeline_in() + (c->length() * multiplier));
ca->append(new SetSpeedAction(c, speed));
if (!ripple && proposed_out > c->timeline_out()) {
for (int i=0;i<c->sequence->clips.size();i++) {
ClipPtr compare = c->sequence->clips.at(i);
QVector<Clip*> all_clips = c->track()->sequence()->GetAllClips();
for (int i=0;i<all_clips.size();i++) {
Clip* compare = all_clips.at(i);
if (compare != nullptr
&& compare->track() == c->track()
&& compare->timeline_in() >= c->timeline_out() && compare->timeline_in() < proposed_out) {
@@ -336,15 +338,16 @@ 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());
c->move(ca, c->timeline_in(), proposed_out, qRound(c->clip_in() * multiplier), c->track());
c->track()->sequence()->MoveClip(c,
ca,
c->timeline_in(),
proposed_out,
qRound(c->clip_in() * multiplier),
c->track());
c->refactor_frame_rate(ca, multiplier, false);
Selection sel;
sel.in = c->timeline_in();
sel.out = proposed_out;
sel.track = c->track();
olive::ActiveSequence->selections.append(sel);
c->track()->SelectArea(c->timeline_in(), proposed_out);
}
void SpeedDialog::accept() {
@@ -357,8 +360,8 @@ void SpeedDialog::accept() {
SetClipProperty* reversed_action = new SetClipProperty(kSetClipPropertyReversed);
// undoable action for restoring clip selections
SetSelectionsCommand* sel_command = new SetSelectionsCommand(olive::ActiveSequence.get());
sel_command->old_data = olive::ActiveSequence->selections;
Sequence* sequence = clips_.first()->track()->sequence();
QVector<Selection> old_selections = sequence->Selections();
// variables used to calculate ripples
long earliest_point = LONG_MAX;
@@ -373,7 +376,7 @@ void SpeedDialog::accept() {
}
// set maintain audio pitch if the user made a selection
if (c->track() >= 0
if (c->type() == Track::kTypeAudio
&& maintain_pitch->checkState() != Qt::PartiallyChecked
&& c->speed().maintain_audio_pitch != maintain_pitch->isChecked()) {
audio_pitch_action->AddSetting(c, maintain_pitch->isChecked());
@@ -382,7 +385,12 @@ void SpeedDialog::accept() {
// set reverse setting if the user made a selection
if (reverse->checkState() != Qt::PartiallyChecked && c->reversed() != reverse->isChecked()) {
long new_clip_in = (c->media_length() - (c->length() + c->clip_in()));
c->move(ca, c->timeline_in(), c->timeline_out(), new_clip_in, c->track());
c->track()->sequence()->MoveClip(c,
ca,
c->timeline_in(),
c->timeline_out(),
new_clip_in,
c->track());
c->set_clip_in(new_clip_in);
reversed_action->AddSetting(c, reverse->isChecked());
}
@@ -423,7 +431,7 @@ void SpeedDialog::accept() {
// make changes
for (int i=0;i<clips_.size();i++) {
Clip* c = clips_.at(i);
if (c->track() < 0) {
if (c->type() == Track::kTypeVideo) {
set_speed(ca, c, frame_rate->value() / c->media_frame_rate(), ripple->isChecked(), earliest_point, longest_ripple);
} else if (can_change_all) {
set_speed(ca, c, frame_rate->value() / cached_fr, ripple->isChecked(), earliest_point, longest_ripple);
@@ -438,16 +446,15 @@ void SpeedDialog::accept() {
}
if (ripple->isChecked()) {
ripple_clips(ca, clips_.at(0)->sequence, earliest_point, longest_ripple);
sequence->Ripple(ca, earliest_point, longest_ripple);
}
sel_command->new_data = olive::ActiveSequence->selections;
ca->append(sel_command);
ca->append(new SetSelectionsCommand(sequence, old_selections, sequence->Selections()));
ca->append(reversed_action);
ca->append(audio_pitch_action);
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
update_ui(true);
QDialog::accept();
+10 -10
View File
@@ -48,7 +48,7 @@
#include "global/path.h"
#include "ui/mainwindow.h"
#include "global/math.h"
#include "project/clipboard.h"
#include "global/clipboard.h"
#include "global/config.h"
#include "transition.h"
#include "undo/undostack.h"
@@ -412,7 +412,7 @@ void Effect::FieldChanged() {
}
void Effect::delete_self() {
olive::UndoStack.push(new EffectDeleteCommand(this));
olive::undo_stack.push(new EffectDeleteCommand(this));
update_ui(true);
}
@@ -426,7 +426,7 @@ void Effect::move_up() {
command->clip = parent_clip;
command->from = index_of_effect;
command->to = command->from - 1;
olive::UndoStack.push(command);
olive::undo_stack.push(command);
panel_effect_controls->Reload();
panel_sequence_viewer->viewer_widget()->frame_update();
}
@@ -441,7 +441,7 @@ void Effect::move_down() {
command->clip = parent_clip;
command->from = index_of_effect;
command->to = command->from + 1;
olive::UndoStack.push(command);
olive::undo_stack.push(command);
panel_effect_controls->Reload();
panel_sequence_viewer->viewer_widget()->frame_update();
}
@@ -488,7 +488,7 @@ void Effect::load_from_file() {
QFile file_handle(file);
if (file_handle.open(QFile::ReadOnly)) {
olive::UndoStack.push(new SetEffectData(this, file_handle.readAll()));
olive::undo_stack.push(new SetEffectData(this, file_handle.readAll()));
file_handle.close();
@@ -743,7 +743,7 @@ void Effect::open() {
qWarning() << "Tried to open an effect that was already open";
close();
}
if (olive::CurrentRuntimeConfig.shaders_are_enabled && (Flags() & ShaderFlag)) {
if (olive::runtime_config.shaders_are_enabled && (Flags() & ShaderFlag)) {
if (QOpenGLContext::currentContext() == nullptr) {
qWarning() << "No current context to create a shader program for - will retry next repaint";
} else {
@@ -1023,7 +1023,7 @@ void Effect::gizmo_move(EffectGizmo* gizmo, int x_movement, int y_movement, doub
ca->append(gizmo_dragging_actions_.at(j));
}
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
gizmo_dragging_actions_.clear();
}
@@ -1044,10 +1044,10 @@ void Effect::gizmo_world_to_screen(const QMatrix4x4& matrix, const QMatrix4x4& p
projection,
QRect(0,
0,
parent_clip->sequence->width,
parent_clip->sequence->height));
parent_clip->track()->sequence()->width,
parent_clip->track()->sequence()->height));
g->screen_pos[j] = QPoint(screen_pos.x(), parent_clip->sequence->height-screen_pos.y());
g->screen_pos[j] = QPoint(screen_pos.x(), parent_clip->track()->sequence()->height-screen_pos.y());
}
}
+4 -4
View File
@@ -235,13 +235,13 @@ void EffectField::SetValueAt(double time, const QVariant &value)
double EffectField::Now()
{
Clip* c = GetParentRow()->GetParentEffect()->parent_clip;
return playhead_to_clip_seconds(c, c->sequence->playhead);
return playhead_to_clip_seconds(c, c->track()->sequence()->playhead);
}
long EffectField::NowInFrames()
{
Clip* c = GetParentRow()->GetParentEffect()->parent_clip;
return playhead_to_clip_frame(c, c->sequence->playhead);
return playhead_to_clip_frame(c, c->track()->sequence()->playhead);
}
void EffectField::PrepareDataForKeyframing(bool enabled, ComboAction *ca)
@@ -331,11 +331,11 @@ double EffectField::GetValidKeyframeHandlePosition(int key, bool post) {
}
double EffectField::FrameToSeconds(long frame) {
return (double(frame) / GetParentRow()->GetParentEffect()->parent_clip->sequence->frame_rate);
return (double(frame) / GetParentRow()->GetParentEffect()->parent_clip->track()->sequence()->frame_rate);
}
long EffectField::SecondsToFrame(double seconds) {
return qRound(seconds * GetParentRow()->GetParentEffect()->parent_clip->sequence->frame_rate);
return qRound(seconds * GetParentRow()->GetParentEffect()->parent_clip->track()->sequence()->frame_rate);
}
void EffectField::GetKeyframeData(double timecode, int &before, int &after, double &progress) {
+5 -5
View File
@@ -34,7 +34,7 @@
QMutex olive::effects_loaded;
void load_internal_effects() {
if (!olive::CurrentRuntimeConfig.shaders_are_enabled) {
if (!olive::runtime_config.shaders_are_enabled) {
qWarning() << "Shaders are disabled, some effects may be nonfunctional";
}
@@ -44,7 +44,7 @@ void load_internal_effects() {
em.path = ":/internalshaders";
em.type = EFFECT_TYPE_EFFECT;
em.subtype = EFFECT_TYPE_AUDIO;
em.subtype = Track::kTypeAudio;
em.name = "Volume";
em.internal = EFFECT_INTERNAL_VOLUME;
@@ -70,7 +70,7 @@ void load_internal_effects() {
em.internal = EFFECT_INTERNAL_FILLLEFTRIGHT;
olive::effects.append(em);
em.subtype = EFFECT_TYPE_VIDEO;
em.subtype = Track::kTypeVideo;
em.name = "Transform";
em.category = "Distort";
@@ -115,7 +115,7 @@ void load_internal_effects() {
em.internal = TRANSITION_INTERNAL_CROSSDISSOLVE;
olive::effects.append(em);
em.subtype = EFFECT_TYPE_AUDIO;
em.subtype = Track::kTypeAudio;
em.name = "Linear Fade";
em.internal = TRANSITION_INTERNAL_LINEARFADE;
@@ -181,7 +181,7 @@ void load_shader_effects_worker(const QString& effects_path) {
if (!effect_name.isEmpty()) {
EffectMeta em;
em.type = EFFECT_TYPE_EFFECT;
em.subtype = EFFECT_TYPE_VIDEO;
em.subtype = Track::kTypeVideo;
em.name = effect_name;
em.category = effect_cat;
em.filename = file.fileName();
+6 -6
View File
@@ -93,7 +93,7 @@ void EffectRow::SetKeyframingEnabled(bool enabled) {
Field(i)->PrepareDataForKeyframing(true, ca);
}
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
update_ui(false);
@@ -116,7 +116,7 @@ void EffectRow::SetKeyframingEnabled(bool enabled) {
// Disable keyframing setting on this row
ca->append(new SetIsKeyframing(this, false));
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
update_ui(false);
@@ -131,7 +131,7 @@ void EffectRow::SetKeyframingEnabled(bool enabled) {
void EffectRow::GoToPreviousKeyframe() {
long key = LONG_MIN;
Clip* c = GetParentEffect()->parent_clip;
long sequence_playhead = c->sequence->playhead;
long sequence_playhead = c->track()->sequence()->playhead;
// Used to convert clip frame number to sequence frame number
long time_adjustment = c->timeline_in() - c->clip_in();
@@ -158,7 +158,7 @@ void EffectRow::GoToPreviousKeyframe() {
void EffectRow::ToggleKeyframe() {
Clip* c = GetParentEffect()->parent_clip;
long sequence_playhead = c->sequence->playhead;
long sequence_playhead = c->track()->sequence()->playhead;
// Used to convert clip frame number to sequence frame number
long time_adjustment = c->timeline_in() - c->clip_in();
@@ -222,7 +222,7 @@ void EffectRow::ToggleKeyframe() {
}
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
update_ui(false);
}
@@ -233,7 +233,7 @@ void EffectRow::GoToNextKeyframe() {
EffectField* f = Field(i);
for (int j=0;j<f->keyframes.size();j++) {
long comp = f->keyframes.at(j).time - c->clip_in() + c->timeline_in();
if (comp > olive::ActiveSequence->playhead) {
if (comp > c->track()->sequence()->playhead) {
key = qMin(comp, key);
}
}
+1 -1
View File
@@ -92,5 +92,5 @@ void BoolField::UpdateFromWidget(bool b)
SetValueAt(Now(), b);
kdc->SetNewKeyframes();
olive::UndoStack.push(kdc);
olive::undo_stack.push(kdc);
}
+1 -1
View File
@@ -67,5 +67,5 @@ void ColorField::UpdateFromWidget(const QColor& c)
SetValueAt(Now(), c);
kdc->SetNewKeyframes();
olive::UndoStack.push(kdc);
olive::undo_stack.push(kdc);
}
+1 -1
View File
@@ -87,5 +87,5 @@ void ComboField::UpdateFromWidget(int index)
SetValueAt(Now(), items_.at(index).data);
kdc->SetNewKeyframes();
olive::UndoStack.push(kdc);
olive::undo_stack.push(kdc);
}
+1 -1
View File
@@ -143,7 +143,7 @@ void DoubleField::UpdateFromWidget(double d)
if (!ls->IsDragging() && kdc_ != nullptr) {
kdc_->SetNewKeyframes();
olive::UndoStack.push(kdc_);
olive::undo_stack.push(kdc_);
kdc_ = nullptr;
}
+1 -1
View File
@@ -62,5 +62,5 @@ void FileField::UpdateFromWidget(const QString &s)
SetValueAt(Now(), s);
kdc->SetNewKeyframes();
olive::UndoStack.push(kdc);
olive::undo_stack.push(kdc);
}
+1 -1
View File
@@ -89,5 +89,5 @@ void FontField::UpdateFromWidget(const QString& s)
SetValueAt(Now(), s);
kdc->SetNewKeyframes();
olive::UndoStack.push(kdc);
olive::undo_stack.push(kdc);
}
+2 -2
View File
@@ -51,7 +51,7 @@ QWidget *StringField::CreateWidget(QWidget *existing)
text_edit->setUndoRedoEnabled(true);
// the "2" is because the height needs one extra pixel of padding on the top and the bottom
text_edit->setTextHeight(qCeil(text_edit->fontMetrics().lineSpacing()*olive::CurrentConfig.effect_textbox_lines
text_edit->setTextHeight(qCeil(text_edit->fontMetrics().lineSpacing()*olive::config.effect_textbox_lines
+ text_edit->document()->documentMargin()
+ text_edit->document()->documentMargin() + 2));
@@ -95,5 +95,5 @@ void StringField::UpdateFromWidget(const QString &s)
SetValueAt(Now(), s);
kdc->SetNewKeyframes();
olive::UndoStack.push(kdc);
olive::undo_stack.push(kdc);
}
+6 -4
View File
@@ -88,14 +88,16 @@ TimecodeEffect::TimecodeEffect(Clip* c, const EffectMeta* em) :
void TimecodeEffect::redraw(double timecode) {
Sequence* sequence = parent_clip->track()->sequence();
if (tc_select->GetValueAt(timecode).toBool()) {
display_timecode = prepend_text->GetStringAt(timecode) + frame_to_timecode(olive::ActiveSequence->playhead,
olive::CurrentConfig.timecode_view,
olive::ActiveSequence->frame_rate);
display_timecode = prepend_text->GetStringAt(timecode) + frame_to_timecode(sequence->playhead,
olive::config.timecode_view,
sequence->frame_rate);
} else {
double media_rate = parent_clip->media_frame_rate();
display_timecode = prepend_text->GetStringAt(timecode) + frame_to_timecode(qRound(timecode * media_rate),
olive::CurrentConfig.timecode_view,
olive::config.timecode_view,
media_rate);
}
img.fill(Qt::transparent);
+1 -1
View File
@@ -55,7 +55,7 @@ void ToneEffect::process_audio(double timecode_start, double timecode_end, quint
double timecode = timecode_start+(interval*i);
qint16 left_tone_sample = qint16(qRound(qSin((2*M_PI*sinX*freq_val->GetDoubleAt(timecode))
/parent_clip->sequence->audio_frequency)
/parent_clip->track()->sequence()->audio_frequency)
*log_volume(amount_val->GetDoubleAt(timecode)*0.01)*INT16_MAX));
qint16 right_tone_sample = left_tone_sample;
+7 -7
View File
@@ -152,13 +152,13 @@ TransformEffect::TransformEffect(Clip* c, const EffectMeta* em) : Effect(c, em)
}
void TransformEffect::refresh() {
if (parent_clip != nullptr && parent_clip->sequence != nullptr) {
if (parent_clip != nullptr && parent_clip->track()->sequence() != nullptr) {
position_x->SetDefault(parent_clip->sequence->width/2);
position_y->SetDefault(parent_clip->sequence->height/2);
position_x->SetDefault(parent_clip->track()->sequence()->width/2);
position_y->SetDefault(parent_clip->track()->sequence()->height/2);
double x_percent_multipler = 200.0 / parent_clip->sequence->width;
double y_percent_multipler = 200.0 / parent_clip->sequence->height;
double x_percent_multipler = 200.0 / parent_clip->track()->sequence()->width;
double y_percent_multipler = 200.0 / parent_clip->track()->sequence()->height;
top_left_gizmo->x_field_multi1 = -x_percent_multipler;
top_left_gizmo->y_field_multi1 = -y_percent_multipler;
@@ -190,8 +190,8 @@ void TransformEffect::toggle_uniform_scale(bool enabled) {
void TransformEffect::process_coords(double timecode, GLTextureCoords& coords, int) {
// position
coords.matrix.translate(position_x->GetDoubleAt(timecode)-(parent_clip->sequence->width/2),
position_y->GetDoubleAt(timecode)-(parent_clip->sequence->height/2),
coords.matrix.translate(position_x->GetDoubleAt(timecode)-(parent_clip->track()->sequence()->width/2),
position_y->GetDoubleAt(timecode)-(parent_clip->track()->sequence()->height/2),
0);
// anchor point
+1 -1
View File
@@ -60,7 +60,7 @@ void delete_keyframes(QVector<EffectField *>& selected_key_fields, QVector<int>
for (int i=0;i<key_indices.size();i++) {
ca->append(new KeyframeDelete(fields.at(i), key_indices.at(i)));
}
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
selected_keys.clear();
selected_key_fields.clear();
update_ui(false);
+3 -4
View File
@@ -24,8 +24,7 @@
#include "timeline/clip.h"
#include "timeline/sequence.h"
#include "global/debug.h"
#include "project/clipboard.h"
#include "global/clipboard.h"
#include "effects/internal/crossdissolvetransition.h"
#include "effects/internal/linearfadetransition.h"
@@ -50,8 +49,8 @@ Transition::Transition(Clip *c, Clip *s, const EffectMeta* em) :
length_field->SetDefault(30);
length_field->SetMinimum(1);
length_field->SetDisplayType(LabelSlider::FrameNumber);
length_field->SetFrameRate(parent_clip->sequence == nullptr ?
parent_clip->cached_frame_rate() : parent_clip->sequence->frame_rate);
length_field->SetFrameRate(parent_clip->track()->sequence() == nullptr ?
parent_clip->cached_frame_rate() : parent_clip->track()->sequence()->frame_rate);
connect(length_field, SIGNAL(Changed()), this, SLOT(UpdateMaximumLength()));
}
@@ -34,6 +34,16 @@ void Clipboard::Append(VoidPtr obj)
clipboard_.append(obj);
}
void Clipboard::Insert(int pos, VoidPtr obj)
{
clipboard_.insert(pos, obj);
}
void Clipboard::RemoveAt(int pos)
{
clipboard_.removeAt(pos);
}
void Clipboard::Clear()
{
clipboard_.clear();
@@ -50,6 +60,16 @@ VoidPtr Clipboard::Get(int i)
return clipboard_.at(i);
}
void Clipboard::SetType(Clipboard::Type type)
{
if (type == type_) {
return;
}
Clear();
type_ = type;
}
bool Clipboard::IsEmpty()
{
return clipboard_.isEmpty();
@@ -36,6 +36,8 @@ public:
Clipboard();
void Append(VoidPtr obj);
void Insert(int pos, VoidPtr obj);
void RemoveAt(int pos);
void Clear();
int Count();
VoidPtr Get(int i);
+5 -10
View File
@@ -29,12 +29,11 @@
#include "debug.h"
Config olive::CurrentConfig;
RuntimeConfig olive::CurrentRuntimeConfig;
Config olive::config;
RuntimeConfig olive::runtime_config;
Config::Config()
: show_track_lines(true),
scroll_zooms(false),
: scroll_zooms(false),
edit_tool_selects_links(false),
edit_tool_also_seeks(false),
select_also_seeks(false),
@@ -94,10 +93,7 @@ void Config::load(QString path) {
while (!stream.atEnd()) {
stream.readNext();
if (stream.isStartElement()) {
if (stream.name() == "ShowTrackLines") {
stream.readNext();
show_track_lines = (stream.text() == "1");
} else if (stream.name() == "ScrollZooms") {
if (stream.name() == "ScrollZooms") {
stream.readNext();
scroll_zooms = (stream.text() == "1");
} else if (stream.name() == "InvertTimelineScrollAxes") {
@@ -295,7 +291,6 @@ void Config::save(QString path) {
stream.writeStartElement("Configuration"); // configuration
stream.writeTextElement("Version", QString::number(olive::kSaveVersion));
stream.writeTextElement("ShowTrackLines", QString::number(show_track_lines));
stream.writeTextElement("ScrollZooms", QString::number(scroll_zooms));
stream.writeTextElement("InvertTimelineScrollAxes", QString::number(invert_timeline_scroll_axes));
stream.writeTextElement("EditToolSelectsLinks", QString::number(edit_tool_selects_links));
@@ -320,7 +315,7 @@ void Config::save(QString path) {
stream.writeTextElement("HoverFocus", QString::number(hover_focus));
stream.writeTextElement("ProjectViewType", QString::number(project_view_type));
stream.writeTextElement("SetNameWithMarker", QString::number(set_name_with_marker));
stream.writeTextElement("ShowProjectToolbar", QString::number(panel_project->IsToolbarVisible()));
stream.writeTextElement("ShowProjectToolbar", QString::number(panel_project.first()->IsToolbarVisible()));
stream.writeTextElement("PreviousFrameQueueSize", QString::number(previous_queue_size));
stream.writeTextElement("PreviousFrameQueueType", QString::number(previous_queue_type));
stream.writeTextElement("UpcomingFrameQueueSize", QString::number(upcoming_queue_size));
+3 -9
View File
@@ -24,6 +24,7 @@
#include <QString>
#include "ui/styling.h"
#include "timeline/timelinetools.h"
namespace olive {
/**
@@ -159,13 +160,6 @@ struct Config {
*/
Config();
/**
* @brief Show track lines
*
* **TRUE** if the Timeline should show lines between tracks.
*/
bool show_track_lines;
/**
* @brief The scroll wheel zooms rather than scrolls
*
@@ -674,8 +668,8 @@ struct RuntimeConfig {
};
namespace olive {
extern Config CurrentConfig;
extern RuntimeConfig CurrentRuntimeConfig;
extern Config config;
extern RuntimeConfig runtime_config;
}
#endif // CONFIG_H
+58 -67
View File
@@ -30,7 +30,8 @@
#include "panels/panels.h"
#include "global/path.h"
#include "global/config.h"
#include "project/clipboard.h"
#include "global/timing.h"
#include "global/clipboard.h"
#include "rendering/audio.h"
#include "dialogs/demonotice.h"
#include "dialogs/preferencesdialog.h"
@@ -147,12 +148,12 @@ QString OliveGlobal::get_recent_project_list_file() {
}
void OliveGlobal::load_translation_from_config() {
QString language_file = olive::CurrentRuntimeConfig.external_translation_file.isEmpty() ?
olive::CurrentConfig.language_file :
olive::CurrentRuntimeConfig.external_translation_file;
QString language_file = olive::runtime_config.external_translation_file.isEmpty() ?
olive::config.language_file :
olive::runtime_config.external_translation_file;
// clear runtime language file so if the user sets a different language, we won't load it next time
olive::CurrentRuntimeConfig.external_translation_file.clear();
olive::runtime_config.external_translation_file.clear();
// remove current translation if there is one
QApplication::removeTranslator(translator.get());
@@ -195,7 +196,7 @@ void OliveGlobal::add_recent_project(const QString &url)
}
if (!found) {
recent_projects.prepend(url);
if (recent_projects.size() > olive::CurrentConfig.maximum_recent_projects) {
if (recent_projects.size() > olive::config.maximum_recent_projects) {
recent_projects.removeLast();
}
}
@@ -229,6 +230,11 @@ const QString &OliveGlobal::recent_project(int index)
return recent_projects.at(index);
}
const QString &OliveGlobal::get_autorecovery_filename()
{
return autorecovery_filename;
}
void OliveGlobal::LoadProject(const QString &fn, bool autorecovery)
{
// QSortFilterProxyModels are not thread-safe, and as we'll be loading in another thread, leaving it connected
@@ -265,7 +271,7 @@ void OliveGlobal::ClearProject()
panel_effect_controls->Clear(true);
// clear existing project
set_sequence(nullptr);
Timeline::CloseAll();
panel_footage_viewer->set_media(nullptr);
// delete sequences first because it's important to close all the clips before deleting the media
@@ -278,7 +284,7 @@ void OliveGlobal::ClearProject()
olive::project_model.clear();
// clear undo stack
olive::UndoStack.clear();
olive::undo_stack.clear();
// empty current project filename
update_project_filename("");
@@ -308,36 +314,42 @@ void OliveGlobal::save_recent_projects()
}
}
void OliveGlobal::PasteInternal(Sequence *s)
void OliveGlobal::PasteInternal(Sequence *s, bool insert)
{
if (s == nullptr) {
return;
}
if (!olive::clipboard.IsEmpty()) {
if (olive::clipboard.type() == Clipboard::CLIPBOARD_TYPE_CLIP) {
ComboAction* ca = new ComboAction();
// create copies and delete areas that we'll be pasting to
QVector<Selection> delete_areas;
QVector<Clip*> original_clips;
QVector<ClipPtr> pasted_clips;
long paste_start = LONG_MAX;
long paste_end = LONG_MIN;
for (int i=0;i<olive::clipboard.size();i++) {
ClipPtr c = std::static_pointer_cast<Clip>(olive::clipboard.at(i));
for (int i=0;i<olive::clipboard.Count();i++) {
ClipPtr c = std::static_pointer_cast<Clip>(olive::clipboard.Get(i));
// create copy of clip and offset by playhead
ClipPtr cc = c->copy(olive::ActiveSequence.get());
ClipPtr cc = c->copy(s->GetTrackList(c->track()->type())->TrackAt(c->track()->Index()));
// convert frame rates
cc->set_timeline_in(rescale_frame_number(cc->timeline_in(), c->cached_frame_rate(), olive::ActiveSequence->frame_rate));
cc->set_timeline_out(rescale_frame_number(cc->timeline_out(), c->cached_frame_rate(), olive::ActiveSequence->frame_rate));
cc->set_clip_in(rescale_frame_number(cc->clip_in(), c->cached_frame_rate(), olive::ActiveSequence->frame_rate));
cc->set_timeline_in(rescale_frame_number(cc->timeline_in(), c->cached_frame_rate(), s->frame_rate));
cc->set_timeline_out(rescale_frame_number(cc->timeline_out(), c->cached_frame_rate(), s->frame_rate));
cc->set_clip_in(rescale_frame_number(cc->clip_in(), c->cached_frame_rate(), s->frame_rate));
cc->set_timeline_in(cc->timeline_in() + olive::ActiveSequence->playhead);
cc->set_timeline_out(cc->timeline_out() + olive::ActiveSequence->playhead);
cc->set_timeline_in(cc->timeline_in() + s->playhead);
cc->set_timeline_out(cc->timeline_out() + s->playhead);
cc->set_track(c->track());
paste_start = qMin(paste_start, cc->timeline_in());
paste_end = qMax(paste_end, cc->timeline_out());
original_clips.append(c.get());
pasted_clips.append(cc);
if (!insert) {
@@ -345,52 +357,40 @@ void OliveGlobal::PasteInternal(Sequence *s)
}
}
if (insert) {
split_all_clips_at_point(ca, olive::ActiveSequence->playhead);
ripple_clips(ca, olive::ActiveSequence.get(), paste_start, paste_end - paste_start);
s->SplitAllClipsAtPoint(ca, s->playhead);
s->Ripple(ca, paste_start, paste_end - paste_start);
} else {
delete_areas_and_relink(ca, delete_areas, false);
s->DeleteAreas(ca, delete_areas, false);
}
// correct linked clips
for (int i=0;i<clipboard.size();i++) {
// these indices should correspond
ClipPtr oc = std::static_pointer_cast<Clip>(clipboard.at(i));
olive::timeline::RelinkClips(original_clips, pasted_clips);
for (int j=0;j<oc->linked.size();j++) {
for (int k=0;k<clipboard.size();k++) { // find clip with that ID
ClipPtr comp = std::static_pointer_cast<Clip>(clipboard.at(k));
if (comp->load_id == oc->linked.at(j)) {
pasted_clips.at(i)->linked.append(k);
}
}
}
}
ca->append(new AddClipCommand(pasted_clips));
ca->append(new AddClipCommand(olive::ActiveSequence.get(), pasted_clips));
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
update_ui(true);
if (olive::CurrentConfig.paste_seeks) {
if (olive::config.paste_seeks) {
panel_sequence_viewer->seek(paste_end);
}
} else if (clipboard_type == CLIPBOARD_TYPE_EFFECT) {
} else if (olive::clipboard.type() == Clipboard::CLIPBOARD_TYPE_EFFECT) {
ComboAction* ca = new ComboAction();
bool replace = false;
bool skip = false;
bool ask_conflict = true;
QVector<Clip*> selected_clips = olive::ActiveSequence->SelectedClips();
QVector<Clip*> selected_clips = s->SelectedClips();
for (int i=0;i<selected_clips.size();i++) {
Clip* c = selected_clips.at(i);
for (int j=0;j<clipboard.size();j++) {
EffectPtr e = std::static_pointer_cast<Effect>(clipboard.at(j));
if ((c->track() < 0) == (e->meta->subtype == EFFECT_TYPE_VIDEO)) {
for (int j=0;j<olive::clipboard.Count();j++) {
EffectPtr e = std::static_pointer_cast<Effect>(olive::clipboard.Get(j));
if (c->type() == e->meta->subtype) {
int found = -1;
if (ask_conflict) {
replace = false;
@@ -403,7 +403,7 @@ void OliveGlobal::PasteInternal(Sequence *s)
}
}
if (found >= 0 && ask_conflict) {
QMessageBox box(this);
QMessageBox box(olive::MainWindow);
box.setWindowTitle(tr("Effect already exists"));
box.setText(tr("Clip '%1' already contains a '%2' effect. "
"Would you like to replace it with the pasted one or add it as a separate effect?")
@@ -441,7 +441,7 @@ void OliveGlobal::PasteInternal(Sequence *s)
}
if (ca->hasActions()) {
ca->appendPost(new ReloadEffectsCommand());
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
} else {
delete ca;
}
@@ -528,7 +528,7 @@ bool OliveGlobal::can_close_project() {
return true;
}
void OliveGlobal::new_sequence()
void OliveGlobal::open_new_sequence_dialog()
{
NewSequenceDialog nsd(olive::MainWindow);
nsd.set_sequence_name(olive::project_model.GetNextSequenceName());
@@ -557,7 +557,7 @@ void OliveGlobal::open_import_dialog()
void OliveGlobal::open_export_dialog() {
if (CheckForActiveSequence()) {
ExportDialog e(olive::MainWindow);
ExportDialog e(olive::MainWindow, Timeline::GetTopSequence().get());
e.exec();
}
}
@@ -609,15 +609,10 @@ void OliveGlobal::open_preferences() {
pd.exec();
}
void OliveGlobal::set_sequence(SequencePtr s)
void OliveGlobal::PrimarySequenceChanged()
{
panel_graph_editor->set_row(nullptr);
panel_effect_controls->Clear(true);
olive::ActiveSequence = s;
panel_sequence_viewer->set_main_sequence();
panel_timeline->update_sequence();
panel_timeline->setFocus();
}
void OliveGlobal::clear_recent_projects()
@@ -630,12 +625,12 @@ void OliveGlobal::OpenProjectWorker(QString fn, bool autorecovery) {
ClearProject();
update_project_filename(fn);
LoadProject(fn, autorecovery);
olive::UndoStack.clear();
olive::undo_stack.clear();
}
bool OliveGlobal::CheckForActiveSequence(bool show_msg)
{
if (olive::ActiveSequence == nullptr) {
if (Timeline::GetTopSequence() == nullptr) {
if (show_msg) {
QMessageBox::information(olive::MainWindow,
@@ -651,30 +646,26 @@ bool OliveGlobal::CheckForActiveSequence(bool show_msg)
void OliveGlobal::undo() {
// workaround to prevent crash (and also users should never need to do this)
if (!panel_timeline->importing) {
olive::UndoStack.undo();
if (!Timeline::IsImporting()) {
olive::undo_stack.undo();
update_ui(true);
}
}
void OliveGlobal::redo() {
// workaround to prevent crash (and also users should never need to do this)
if (!panel_timeline->importing) {
olive::UndoStack.redo();
if (!Timeline::IsImporting()) {
olive::undo_stack.redo();
update_ui(true);
}
}
void OliveGlobal::paste() {
if (olive::ActiveSequence != nullptr) {
panel_timeline->paste(false);
}
PasteInternal(Timeline::GetTopSequence().get(), false);
}
void OliveGlobal::paste_insert() {
if (olive::ActiveSequence != nullptr) {
panel_timeline->paste(true);
}
PasteInternal(Timeline::GetTopSequence().get(), true);
}
void OliveGlobal::open_about_dialog() {
@@ -687,9 +678,9 @@ void OliveGlobal::open_debug_log() {
}
void OliveGlobal::open_speed_dialog() {
if (olive::ActiveSequence != nullptr) {
if (Timeline::GetTopSequence() != nullptr) {
QVector<Clip*> selected_clips = olive::ActiveSequence->SelectedClips();
QVector<Clip*> selected_clips = Timeline::GetTopSequence()->SelectedClips();
if (!selected_clips.isEmpty()) {
SpeedDialog s(olive::MainWindow, selected_clips);
@@ -701,7 +692,7 @@ void OliveGlobal::open_speed_dialog() {
void OliveGlobal::open_autocut_silence_dialog() {
if (CheckForActiveSequence()) {
QVector<int> selected_clips = olive::ActiveSequence->SelectedClipIndexes();
QVector<Clip*> selected_clips = Timeline::GetTopSequence()->SelectedClips();
if (selected_clips.isEmpty()) {
QMessageBox::critical(olive::MainWindow,
@@ -717,7 +708,7 @@ void OliveGlobal::open_autocut_silence_dialog() {
}
void OliveGlobal::clear_undo_stack() {
olive::UndoStack.clear();
olive::undo_stack.clear();
}
void OliveGlobal::open_action_search() {
+22 -27
View File
@@ -204,6 +204,18 @@ public:
*/
const QString& get_autorecovery_filename();
/**
* @brief Returns whether a Sequence is currently active or not, and optionally displays a messagebox if not
*
* Checks whether a Sequence is active and can display a messagebox if not to inform users to make one active in
* order to perform said action.
*
* @return
*
* TRUE if there is an active Sequence, FALSE if not.
*/
bool CheckForActiveSequence(bool show_msg = true);
public slots:
/**
* @brief Undo user's last action
@@ -313,7 +325,7 @@ public slots:
/**
* @brief Opens the NewSequenceDialog to create a new Sequence
*/
void new_sequence();
void open_new_sequence_dialog();
/**
* @brief Open a file dialog for importing files into the project
@@ -378,19 +390,6 @@ public slots:
*/
void open_preferences();
/**
* @brief Set the current active Sequence
*
* Call this to change the active Sequence (e.g. when the user double clicks a Sequence in the Project panel).
* This will affect panel_timeline, panel_sequence_viewer, and panel_effect_controls and can then be retrieved
* using olive::ActiveSequence.
*
* @param s
*
* The Sequence to set as the active Sequence.
*/
void set_sequence(SequencePtr s);
/**
* @brief Clear the recent projects list
*
@@ -398,6 +397,14 @@ public slots:
*/
void clear_recent_projects();
/**
* @brief Slot for when the primary sequence has changed.
*
* Usually by opening a sequence or bringing a corresponding
* Timeline widget on top.
*/
void PrimarySequenceChanged();
private:
/**
* @brief Internal function to handle loading a project from file
@@ -417,18 +424,6 @@ private:
*/
void OpenProjectWorker(QString fn, bool autorecovery);
/**
* @brief Returns whether a Sequence is currently active or not, and optionally displays a messagebox if not
*
* Checks whether a Sequence is active and can display a messagebox if not to inform users to make one active in
* order to perform said action.
*
* @return
*
* TRUE if there is an active Sequence, FALSE if not.
*/
bool CheckForActiveSequence(bool show_msg = true);
/**
* @brief Create a LoadDialog and start a LoadThread to load data from a project
*
@@ -475,7 +470,7 @@ private:
/**
* @brief Internal pasting function
*/
void PasteInternal(Sequence* s);
void PasteInternal(Sequence* s, bool insert);
/**
* @brief File filter used for any file dialogs relating to Olive project files.
+4
View File
@@ -41,4 +41,8 @@ QRect fit_size_into_rect(const QRect& r, int width, int height);
double amplitude_to_db(double amplitude);
double db_to_amplitude(double db);
// frame <-> pixel conversion functions
int getScreenPointFromFrame(double zoom, long frame);
long getFrameFromScreenPoint(double zoom, int x);
#endif // MATH_H
+2 -2
View File
@@ -5,7 +5,7 @@
#include "global/config.h"
double get_timecode(Clip* c, long playhead) {
return double(playhead_to_clip_frame(c, playhead))/c->sequence->frame_rate;
return double(playhead_to_clip_frame(c, playhead))/c->track()->sequence()->frame_rate;
}
long rescale_frame_number(long framenumber, double source_frame_rate, double target_frame_rate) {
@@ -24,7 +24,7 @@ double playhead_to_clip_seconds(Clip* c, long playhead) {
clip_frame = c->media_length() - clip_frame - 1;
}
double secs = (double(clip_frame)/c->sequence->frame_rate)*c->speed().value;
double secs = (double(clip_frame)/c->track()->sequence()->frame_rate)*c->speed().value;
if (c->media() != nullptr && c->media()->get_type() == MEDIA_TYPE_FOOTAGE) {
secs *= c->media()->to_footage()->speed;
}
+2 -2
View File
@@ -70,13 +70,13 @@ int main(int argc, char *argv[]) {
} else if (!strcmp(argv[i], "--fullscreen") || !strcmp(argv[i], "-f")) {
launch_fullscreen = true;
} else if (!strcmp(argv[i], "--disable-shaders")) {
olive::CurrentRuntimeConfig.shaders_are_enabled = false;
olive::runtime_config.shaders_are_enabled = false;
} else if (!strcmp(argv[i], "--no-debug")) {
use_internal_logger = false;
} else if (!strcmp(argv[i], "--translation")) {
if (i + 1 < argc && argv[i + 1][0] != '-') {
// load translation file
olive::CurrentRuntimeConfig.external_translation_file = argv[i + 1];
olive::runtime_config.external_translation_file = argv[i + 1];
i++;
} else {
+7 -7
View File
@@ -75,7 +75,6 @@ SOURCES += \
dialogs/preferencesdialog.cpp \
ui/audiomonitor.cpp \
undo/undo.cpp \
ui/scrollarea.cpp \
ui/comboboxex.cpp \
ui/colorbutton.cpp \
dialogs/replaceclipmediadialog.cpp \
@@ -108,7 +107,6 @@ SOURCES += \
effects/effect.cpp \
effects/effectrow.cpp \
effects/effectgizmo.cpp \
project/clipboard.cpp \
ui/resizablescrollbar.cpp \
ui/sourceiconview.cpp \
project/sourcescommon.cpp \
@@ -182,7 +180,10 @@ SOURCES += \
timeline/timelineshared.cpp \
ui/timelineview.cpp \
ui/timelinelabel.cpp \
timeline/selection.cpp
timeline/selection.cpp \
global/clipboard.cpp \
timeline/timelinetools.cpp \
timeline/ghost.cpp
HEADERS += \
ui/mainwindow.h \
@@ -204,14 +205,12 @@ HEADERS += \
ui/collapsiblewidget.h \
panels/panels.h \
rendering/exportthread.h \
ui/timelinetools.h \
ui/timelineheader.h \
project/previewgenerator.h \
ui/labelslider.h \
dialogs/preferencesdialog.h \
ui/audiomonitor.h \
undo/undo.h \
ui/scrollarea.h \
ui/comboboxex.h \
ui/colorbutton.h \
dialogs/replaceclipmediadialog.h \
@@ -246,7 +245,6 @@ HEADERS += \
effects/effectrow.h \
effects/internal/cubetransition.h \
effects/effectgizmo.h \
project/clipboard.h \
ui/resizablescrollbar.h \
ui/sourceiconview.h \
project/sourcescommon.h \
@@ -323,7 +321,9 @@ HEADERS += \
ui/timelinearea.h \
timeline/timelineshared.h \
ui/timelineview.h \
ui/timelinelabel.h
ui/timelinelabel.h \
global/clipboard.h \
timeline/timelinetools.h
FORMS +=
+14 -9
View File
@@ -47,7 +47,7 @@
#include "ui/viewerwidget.h"
#include "ui/menuhelper.h"
#include "ui/icons.h"
#include "project/clipboard.h"
#include "global/clipboard.h"
#include "global/config.h"
#include "ui/timelineheader.h"
#include "ui/keyframeview.h"
@@ -89,7 +89,10 @@ EffectControls::~EffectControls()
void EffectControls::set_zoom(bool in) {
zoom *= (in) ? 2 : 0.5;
update_keyframes();
scroll_to_frame(olive::ActiveSequence->playhead);
if (!selected_clips_.isEmpty()) {
scroll_to_frame(selected_clips_.first()->track()->sequence()->playhead);
}
}
void EffectControls::menu_select(QAction* q) {
@@ -104,21 +107,21 @@ void EffectControls::menu_select(QAction* q) {
nullptr,
nullptr,
meta,
olive::CurrentConfig.default_transition_length));
olive::config.default_transition_length));
}
if (c->closing_transition == nullptr) {
ca->append(new AddTransitionCommand(nullptr,
c,
nullptr,
meta,
olive::CurrentConfig.default_transition_length));
olive::config.default_transition_length));
}
} else {
ca->append(new AddEffectCommand(c, nullptr, meta));
}
}
}
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
if (effect_menu_type == EFFECT_TYPE_TRANSITION) {
update_ui(true);
} else {
@@ -175,7 +178,7 @@ void EffectControls::copy(bool del) {
if (del) {
if (ca->hasActions()) {
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
} else {
delete ca;
}
@@ -587,7 +590,7 @@ void EffectControls::DeleteSelectedEffects() {
}
if (ca->hasActions()) {
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
update_ui(true);
} else {
delete ca;
@@ -620,11 +623,13 @@ void EffectControls::SetClips()
{
Clear(true);
if (olive::ActiveSequence == nullptr) {
Sequence* top_sequence = Timeline::GetTopSequence().get();
if (top_sequence == nullptr) {
selected_clips_.clear();
} else {
// replace clip vector
selected_clips_ = olive::ActiveSequence->SelectedClips(false);
selected_clips_ = top_sequence->SelectedClips(false);
Load();
}
+1 -1
View File
@@ -27,7 +27,7 @@
#include "ui/keyframenavigator.h"
#include "ui/timelineheader.h"
#include "ui/timelinetools.h"
#include "timeline/timelinetools.h"
#include "ui/labelslider.h"
#include "ui/graphview.h"
#include "effects/effect.h"
+20 -9
View File
@@ -25,6 +25,7 @@
#include "effects/transition.h"
#include "global/config.h"
#include "global/debug.h"
#include "global/math.h"
#include <QScrollBar>
#include <QCoreApplication>
@@ -33,7 +34,7 @@ QVector<Project*> panel_project;
EffectControls* panel_effect_controls = nullptr;
Viewer* panel_sequence_viewer = nullptr;
Viewer* panel_footage_viewer = nullptr;
Timeline* panel_timeline = nullptr;
QVector<Timeline*> panel_timeline;
GraphEditor* panel_graph_editor = nullptr;
void update_ui(bool modified) {
@@ -41,14 +42,16 @@ void update_ui(bool modified) {
panel_effect_controls->SetClips();
}
panel_effect_controls->update_keyframes();
panel_timeline->repaint_timeline();
for (int i=0;i<panel_timeline.size();i++) {
panel_timeline.at(i)->repaint_timeline();
}
panel_sequence_viewer->update_viewer();
panel_graph_editor->update_panel();
}
QDockWidget *get_focused_panel(bool force_hover) {
QDockWidget* w = nullptr;
if (olive::CurrentConfig.hover_focus || force_hover) {
if (olive::config.hover_focus || force_hover) {
for (int i=0;i<olive::panels.size();i++) {
if (olive::panels.at(i)->underMouse()) {
w = olive::panels.at(i);
@@ -78,8 +81,9 @@ void alloc_panels(QWidget* parent) {
panel_project.append(first_project_panel);
panel_effect_controls = new EffectControls(parent);
panel_effect_controls->setObjectName("fx_controls");
panel_timeline = new Timeline(parent);
panel_timeline->setObjectName("timeline");
Timeline* first_timeline_panel = new Timeline(parent);
first_timeline_panel->setObjectName("timeline");
panel_timeline.append(first_timeline_panel);
panel_graph_editor = new GraphEditor(parent);
panel_graph_editor->setObjectName("graph_editor");
}
@@ -89,12 +93,19 @@ void free_panels() {
panel_sequence_viewer = nullptr;
delete panel_footage_viewer;
panel_footage_viewer = nullptr;
delete panel_project;
panel_project = nullptr;
for (int i=0;i<panel_project.size();i++) {
delete panel_project.at(i);
}
panel_project.clear();
delete panel_effect_controls;
panel_effect_controls = nullptr;
delete panel_timeline;
panel_timeline = nullptr;
for (int i=0;i<panel_timeline.size();i++) {
delete panel_timeline.at(i);
}
panel_timeline.clear();
}
void scroll_to_frame_internal(QScrollBar* bar, long frame, double zoom, int area_width) {
+1 -1
View File
@@ -31,7 +31,7 @@ extern QVector<Project*> panel_project;
extern EffectControls* panel_effect_controls;
extern Viewer* panel_sequence_viewer;
extern Viewer* panel_footage_viewer;
extern Timeline* panel_timeline;
extern QVector<Timeline*> panel_timeline;
extern GraphEditor* panel_graph_editor;
void update_ui(bool modified);
+39 -51
View File
@@ -54,7 +54,7 @@ extern "C" {
#include "dialogs/mediapropertiesdialog.h"
#include "dialogs/newsequencedialog.h"
#include "dialogs/loaddialog.h"
#include "project/clipboard.h"
#include "global/clipboard.h"
#include "ui/sourcetable.h"
#include "ui/sourceiconview.h"
#include "ui/icons.h"
@@ -83,7 +83,7 @@ Project::Project(QWidget *parent) :
// optional toolbar
toolbar_widget = new QWidget();
toolbar_widget->setVisible(olive::CurrentConfig.show_project_toolbar);
toolbar_widget->setVisible(olive::config.show_project_toolbar);
toolbar_widget->setObjectName("project_toolbar");
QHBoxLayout* toolbar = new QHBoxLayout(toolbar_widget);
@@ -233,7 +233,7 @@ void Project::duplicate_selected() {
}
}
if (duped) {
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
} else {
delete ca;
}
@@ -250,7 +250,9 @@ void Project::replace_selected_file() {
}
void Project::replace_clip_media() {
if (olive::ActiveSequence == nullptr) {
Sequence* top_sequence = Timeline::GetTopSequence().get();
if (top_sequence == nullptr) {
QMessageBox::critical(this,
tr("No active sequence"),
tr("No sequence is active, please open the sequence you want to replace clips from."),
@@ -259,7 +261,7 @@ void Project::replace_clip_media() {
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 && olive::ActiveSequence == item->to_sequence()) {
if (item->get_type() == MEDIA_TYPE_SEQUENCE && top_sequence == item->to_sequence().get()) {
QMessageBox::critical(this,
tr("Active sequence selected"),
tr("You cannot insert a sequence into itself, so no clips of this media would be in this sequence."),
@@ -299,7 +301,7 @@ void Project::open_properties() {
item->get_name());
if (!new_name.isEmpty()) {
MediaRename* mr = new MediaRename(item, new_name);
olive::UndoStack.push(mr);
olive::undo_stack.push(mr);
}
}
}
@@ -308,10 +310,10 @@ void Project::open_properties() {
void Project::new_folder() {
MediaPtr m = olive::project::CreateFolder(nullptr);
olive::UndoStack.push(new AddMediaCommand(m, get_selected_folder()));
olive::undo_stack.push(new AddMediaCommand(m, get_selected_folder()));
QModelIndex index = olive::project_model.create_index(m->row(), 0, m.get());
switch (olive::CurrentConfig.project_view_type) {
switch (olive::config.project_view_type) {
case olive::PROJECT_VIEW_TREE:
tree_view->edit(sorter.mapFromSource(index));
break;
@@ -451,8 +453,9 @@ void Project::delete_selected_media() {
panel_graph_editor->set_row(nullptr);
panel_effect_controls->Clear(true);
if (olive::ActiveSequence != nullptr) {
olive::ActiveSequence->ClearSelections();
Sequence* top_sequence = Timeline::GetTopSequence().get();
if (top_sequence != nullptr) {
top_sequence->ClearSelections();
}
// remove media and parents
@@ -474,9 +477,7 @@ void Project::delete_selected_media() {
Sequence* s = items.at(i)->to_sequence().get();
if (s == olive::ActiveSequence.get()) {
ca->append(new ChangeSequenceAction(nullptr));
}
Timeline::CloseSequence(s);
if (s == panel_footage_viewer->seq.get()) {
panel_footage_viewer->set_media(nullptr);
@@ -487,7 +488,7 @@ void Project::delete_selected_media() {
}
}
}
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
// redraw clips
if (redraw) {
@@ -527,7 +528,7 @@ bool Project::reveal_media(Media *media, QModelIndex parent) {
// retrieve its parent item
QModelIndex hierarchy = sorted_index.parent();
if (olive::CurrentConfig.project_view_type == olive::PROJECT_VIEW_TREE) {
if (olive::config.project_view_type == olive::PROJECT_VIEW_TREE) {
// if we're in tree view, expand every folder in the hierarchy containing the media
while (hierarchy.isValid()) {
@@ -542,7 +543,7 @@ bool Project::reveal_media(Media *media, QModelIndex parent) {
);
tree_view->selectionModel()->select(row_select, QItemSelectionModel::Select);
} else if (olive::CurrentConfig.project_view_type == olive::PROJECT_VIEW_ICON) {
} else if (olive::config.project_view_type == olive::PROJECT_VIEW_ICON) {
// if we're in icon view, we just "browse" to the parent folder
icon_view->setRootIndex(hierarchy);
@@ -563,55 +564,42 @@ bool Project::reveal_media(Media *media, QModelIndex parent) {
}
void Project::delete_clips_using_selected_media() {
if (olive::ActiveSequence == nullptr) {
Sequence* top_sequence = Timeline::GetTopSequence().get();
if (top_sequence == nullptr) {
QMessageBox::critical(this,
tr("No active sequence"),
tr("No sequence is active, please open the sequence you want to delete clips from."),
QMessageBox::Ok);
} else {
ComboAction* ca = new ComboAction();
bool deleted = false;
QModelIndexList items = get_current_selected();
QVector<Clip*> sequence_clips = olive::ActiveSequence->GetAllClips();
for (int i=0;i<sequence_clips.size();i++) {
Clip* c = sequence_clips.at(i);
for (int j=0;j<items.size();j++) {
Media* m = item_to_media(items.at(j));
if (c->media() == m) {
ca->append(new DeleteClipAction(c));
deleted = true;
}
}
}
for (int j=0;j<items.size();j++) {
Media* m = item_to_media(items.at(j));
if (olive::clipboard.DeleteClipsWithMedia(ca, m)) {
deleted = true;
}
}
if (deleted) {
olive::UndoStack.push(ca);
update_ui(true);
} else {
delete ca;
QModelIndexList items = get_current_selected();
QVector<Media*> media;
media.resize(items.size());
for (int i=0;i<items.size();i++) {
media[i] = item_to_media(items.at(i));
}
top_sequence->DeleteClipsUsingMedia(media);
}
}
void Project::update_view_type() {
tree_view->setVisible(olive::CurrentConfig.project_view_type == olive::PROJECT_VIEW_TREE);
icon_view_container->setVisible(olive::CurrentConfig.project_view_type == olive::PROJECT_VIEW_ICON
|| olive::CurrentConfig.project_view_type == olive::PROJECT_VIEW_LIST);
tree_view->setVisible(olive::config.project_view_type == olive::PROJECT_VIEW_TREE);
icon_view_container->setVisible(olive::config.project_view_type == olive::PROJECT_VIEW_ICON
|| olive::config.project_view_type == olive::PROJECT_VIEW_LIST);
switch (olive::CurrentConfig.project_view_type) {
switch (olive::config.project_view_type) {
case olive::PROJECT_VIEW_TREE:
sources_common.view = tree_view;
break;
case olive::PROJECT_VIEW_ICON:
case olive::PROJECT_VIEW_LIST:
icon_view->setViewMode(olive::CurrentConfig.project_view_type == olive::PROJECT_VIEW_ICON ?
icon_view->setViewMode(olive::config.project_view_type == olive::PROJECT_VIEW_ICON ?
QListView::IconMode : QListView::ListMode);
// update list/grid size since they use this value slightly differently
@@ -623,18 +611,18 @@ void Project::update_view_type() {
}
void Project::set_icon_view() {
olive::CurrentConfig.project_view_type = olive::PROJECT_VIEW_ICON;
olive::config.project_view_type = olive::PROJECT_VIEW_ICON;
update_view_type();
}
void Project::set_list_view()
{
olive::CurrentConfig.project_view_type = olive::PROJECT_VIEW_LIST;
olive::config.project_view_type = olive::PROJECT_VIEW_LIST;
update_view_type();
}
void Project::set_tree_view() {
olive::CurrentConfig.project_view_type = olive::PROJECT_VIEW_TREE;
olive::config.project_view_type = olive::PROJECT_VIEW_TREE;
update_view_type();
}
@@ -663,7 +651,7 @@ void Project::make_new_menu() {
}
QModelIndexList Project::get_current_selected() {
if (olive::CurrentConfig.project_view_type == olive::PROJECT_VIEW_TREE) {
if (olive::config.project_view_type == olive::PROJECT_VIEW_TREE) {
return tree_view->selectionModel()->selectedRows();
}
return icon_view->selectionModel()->selectedIndexes();
+248 -627
View File
File diff suppressed because it is too large Load Diff
+24 -41
View File
@@ -26,7 +26,8 @@
#include <QPushButton>
#include "ui/timelinearea.h"
#include "ui/timelinetools.h"
#include "timeline/timelinetools.h"
#include "timeline/timelinefunctions.h"
#include "timeline/selection.h"
#include "timeline/clip.h"
#include "timeline/mediaimportdata.h"
@@ -37,59 +38,44 @@
#include "ui/audiomonitor.h"
#include "ui/panel.h"
int getScreenPointFromFrame(double zoom, long frame);
long getFrameFromScreenPoint(double zoom, int x);
bool selection_contains_transition(const Selection& s, Clip *c, int type);
class Timeline : public Panel
{
Q_OBJECT
public:
explicit Timeline(QWidget *parent = nullptr);
static Timeline* GetTopTimeline();
static SequencePtr GetTopSequence();
static void OpenSequence(SequencePtr s);
static void CloseSequence(Sequence* s);
static void CloseAll();
static bool IsImporting();
void SetSequence(SequencePtr sequence);
virtual bool focused() override;
void multiply_zoom(double m);
void copy(bool del);
void clean_up_selections(QVector<Selection>& areas);
void deselect_area(long in, long out, int track);
void delete_areas_and_relink(ComboAction *ca, QVector<Selection>& areas, bool deselect_areas);
void update_sequence();
void edit_to_point_internal(bool in, bool ripple);
void delete_in_out_internal(bool ripple);
void create_ghosts_from_media(Sequence *seq, long entry_point, QVector<olive::timeline::MediaImportData> &media_list);
void add_clips_from_ghosts(ComboAction *ca, Sequence *s);
int getTimelineScreenPointFromFrame(long frame);
long getTimelineFrameFromScreenPoint(int x);
int getDisplayScreenPointFromFrame(long frame);
long getDisplayFrameFromScreenPoint(int x);
long get_snap_range();
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
int tool;
long cursor_frame;
int cursor_track;
Track* cursor_track;
double zoom;
bool zoom_just_changed;
long drag_frame_start;
int drag_track_start;
Track* drag_track_start;
void update_effect_controls();
bool showing_all;
double old_zoom;
// snapping
bool snapping;
bool snapped;
long snap_point;
// selecting functions
bool selecting;
int selection_offset;
@@ -102,18 +88,16 @@ public:
bool moving_init;
bool moving_proc;
QVector<Ghost> ghosts;
bool video_ghosts;
bool audio_ghosts;
bool move_insert;
// trimming
int trim_target;
Clip* trim_target;
olive::timeline::TrimType trim_type;
int transition_select;
// splitting
bool splitting;
QVector<int> split_tracks;
QVector<Track*> split_tracks;
// importing
bool importing;
@@ -121,15 +105,15 @@ public:
// creating variables
bool creating;
int creating_object;
olive::timeline::CreateObjects creating_object;
// transition variables
bool transition_tool_init;
bool transition_tool_proc;
int transition_tool_open_clip;
int transition_tool_close_clip;
Clip* transition_tool_open_clip;
Clip* transition_tool_close_clip;
const EffectMeta* transition_tool_meta;
int transition_tool_side;
Track::Type transition_tool_side;
// hand tool variables
bool hand_moving;
@@ -155,7 +139,6 @@ public:
QPushButton* snappingButton;
void scroll_to_frame(long frame);
void select_from_playhead();
bool can_ripple_empty_space(long frame, int track);
@@ -163,11 +146,9 @@ public:
protected:
virtual void resizeEvent(QResizeEvent *event) override;
public slots:
void paste(bool insert = false);
void repaint_timeline();
void toggle_show_all();
void deselect();
void toggle_links();
void split_at_playhead();
void ripple_delete();
void ripple_delete_empty_space();
@@ -184,9 +165,6 @@ public slots:
void IncreaseTrackHeight();
void DecreaseTrackHeight();
void previous_cut();
void next_cut();
void add_transition();
void nest();
@@ -194,6 +172,9 @@ public slots:
void zoom_in();
void zoom_out();
signals:
void SequenceChanged(SequencePtr s);
private slots:
void snapping_clicked(bool checked);
void add_btn_click();
@@ -206,6 +187,8 @@ private slots:
void set_tool();
private:
SequencePtr sequence_;
void ChangeTrackHeightUniformly(int diff);
void set_zoom_value(double v);
void set_tool(int tool);
+47 -47
View File
@@ -70,7 +70,8 @@ Viewer::Viewer(QWidget *parent) :
created_sequence(false),
minimum_zoom(1.0),
cue_recording_internal(false),
playback_speed(0)
playback_speed(0),
mode_(kTimelineMode)
{
setup_ui();
@@ -101,6 +102,16 @@ Viewer::Viewer(QWidget *parent) :
update_end_timecode();
}
void Viewer::SetMode(Viewer::Mode mode)
{
mode_ = mode;
}
Viewer::Mode Viewer::mode()
{
return mode_;
}
void Viewer::Retranslate() {
/// Viewer panels are retranslated through the MainWindow to differentiate Media and Sequence Viewers
// update_window_title();
@@ -116,14 +127,6 @@ bool Viewer::focused() {
|| go_to_end_frame->hasFocus();
}
bool Viewer::is_main_sequence() {
return main_sequence;
}
void Viewer::set_main_sequence() {
set_sequence(true, olive::ActiveSequence);
}
void Viewer::reset_all_audio() {
// reset all clip audio
if (seq != nullptr) {
@@ -150,20 +153,24 @@ void Viewer::reset_all_audio() {
void Viewer::seek(long p) {
pause();
if (main_sequence) {
if (mode_ == kTimelineMode) {
seq->playhead = p;
} else {
seq->playhead = qMin(seq->GetEndFrame(), qMax(0L, p));
}
bool update_fx = false;
if (main_sequence) {
panel_timeline->scroll_to_frame(p);
if (mode_ == kTimelineMode) {
panel_timeline.first()->scroll_to_frame(p);
panel_effect_controls->scroll_to_frame(p);
if (olive::CurrentConfig.seek_also_selects) {
panel_timeline->select_from_playhead();
if (olive::config.seek_also_selects) {
seq->SelectAtPlayhead();
update_fx = true;
}
}
reset_all_audio();
audio_scrub = true;
last_playhead = seq->playhead;
@@ -274,11 +281,11 @@ void Viewer::play(bool in_to_out) {
uncue_recording();
}
bool seek_to_in = (seq->using_workarea && (olive::CurrentConfig.loop || playing_in_to_out));
bool seek_to_in = (seq->using_workarea && (olive::config.loop || playing_in_to_out));
if (!is_recording_cued()
&& playback_speed >= 0
&& (playing_in_to_out
|| (olive::CurrentConfig.auto_seek_to_beginning && seq->playhead >= sequence_end_frame)
|| (olive::config.auto_seek_to_beginning && seq->playhead >= sequence_end_frame)
|| (seek_to_in && seq->playhead >= seq->workarea_out))) {
seek(seek_to_in ? seq->workarea_in : 0);
}
@@ -359,7 +366,7 @@ void Viewer::pause() {
QVector<ClipPtr> add_clips;
add_clips.append(c);
olive::UndoStack.push(new AddClipCommand(seq.get(), add_clips)); // add clip
olive::undo_stack.push(new AddClipCommand(add_clips)); // add clip
}
@@ -374,7 +381,7 @@ void Viewer::update_playhead_timecode(long p) {
}
void Viewer::update_end_timecode() {
end_timecode->setText((seq == nullptr) ? frame_to_timecode(0, olive::CurrentConfig.timecode_view, 30) : frame_to_timecode(seq->GetEndFrame(), olive::CurrentConfig.timecode_view, seq->frame_rate));
end_timecode->setText((seq == nullptr) ? frame_to_timecode(0, olive::config.timecode_view, 30) : frame_to_timecode(seq->GetEndFrame(), olive::config.timecode_view, seq->frame_rate));
}
void Viewer::update_header_zoom() {
@@ -392,11 +399,10 @@ void Viewer::update_header_zoom() {
}
void Viewer::update_parents(bool reload_fx) {
if (main_sequence) {
if (mode_ == kTimelineMode) {
update_ui(reload_fx);
} else {
update_viewer();
panel_timeline->repaint_timeline();
}
}
@@ -410,7 +416,7 @@ ViewerWidget *Viewer::viewer_widget()
}
void Viewer::set_marker() {
set_marker_internal(seq.get());
Marker::SetOnSequence(seq.get());
}
void Viewer::resizeEvent(QResizeEvent *e) {
@@ -435,7 +441,7 @@ void Viewer::prev_cut()
if (seq != nullptr
&& seq->playhead > 0) {
QVector<Clip*> sequence_clips = olive::ActiveSequence->GetAllClips();
QVector<Clip*> sequence_clips = seq->GetAllClips();
long p_cut = 0;
for (int i=0;i<sequence_clips.size();i++) {
@@ -489,7 +495,7 @@ void Viewer::initiate_drag(olive::timeline::MediaImportType drag_type)
void Viewer::clear_in() {
if (seq != nullptr
&& seq->using_workarea) {
olive::UndoStack.push(new SetTimelineInOutCommand(seq.get(), true, 0, seq->workarea_out));
olive::undo_stack.push(new SetTimelineInOutCommand(seq.get(), true, 0, seq->workarea_out));
update_parents();
}
}
@@ -497,7 +503,7 @@ void Viewer::clear_in() {
void Viewer::clear_out() {
if (seq != nullptr
&& seq->using_workarea) {
olive::UndoStack.push(new SetTimelineInOutCommand(seq.get(), true, seq->workarea_in, seq->GetEndFrame()));
olive::undo_stack.push(new SetTimelineInOutCommand(seq.get(), true, seq->workarea_in, seq->GetEndFrame()));
update_parents();
}
}
@@ -505,7 +511,7 @@ void Viewer::clear_out() {
void Viewer::clear_inout_point() {
if (seq != nullptr
&& seq->using_workarea) {
olive::UndoStack.push(new SetTimelineInOutCommand(seq.get(), false, 0, 0));
olive::undo_stack.push(new SetTimelineInOutCommand(seq.get(), false, 0, 0));
update_parents();
}
}
@@ -575,13 +581,13 @@ void Viewer::set_playback_speed(int s) {
}
long Viewer::get_seq_in() {
return ((olive::CurrentConfig.loop || playing_in_to_out) && seq->using_workarea)
return ((olive::config.loop || playing_in_to_out) && seq->using_workarea)
? seq->workarea_in
: 0;
}
long Viewer::get_seq_out() {
return ((olive::CurrentConfig.loop || playing_in_to_out) && seq->using_workarea && previous_playhead < seq->workarea_out)
return ((olive::config.loop || playing_in_to_out) && seq->using_workarea && previous_playhead < seq->workarea_out)
? seq->workarea_out
: seq->GetEndFrame();
}
@@ -713,7 +719,6 @@ void Viewer::setup_ui() {
}
void Viewer::set_media(Media* m) {
main_sequence = false;
media = m;
SequencePtr new_sequence = nullptr;
@@ -737,7 +742,7 @@ void Viewer::set_media(Media* m) {
new_sequence->workarea_out = footage->out;
}
new_sequence->frame_rate = olive::CurrentConfig.default_sequence_framerate;
new_sequence->frame_rate = olive::config.default_sequence_framerate;
if (footage->video_tracks.size() > 0) {
const FootageStream& video_stream = footage->video_tracks.at(0);
@@ -761,20 +766,19 @@ void Viewer::set_media(Media* m) {
c->refresh();
track->AddClip(c);
} else {
new_sequence->width = olive::CurrentConfig.default_sequence_width;
new_sequence->height = olive::CurrentConfig.default_sequence_height;
new_sequence->width = olive::config.default_sequence_width;
new_sequence->height = olive::config.default_sequence_height;
}
if (footage->audio_tracks.size() > 0) {
const FootageStream& audio_stream = footage->audio_tracks.at(0);
new_sequence->audio_frequency = audio_stream.audio_frequency;
ClipPtr c = std::make_shared<Clip>(new_sequence.get());
Track* track = new_sequence->GetTrackList(Track::kTypeAudio)->First();
ClipPtr c = std::make_shared<Clip>(track);
c->set_media(media, audio_stream.file_index);
c->set_timeline_in(0);
c->set_timeline_out(footage->get_length_in_frames(new_sequence->frame_rate));
Track* track = new_sequence->GetTrackList(Track::kTypeAudio)->First();
c->set_track(track);
c->set_clip_in(0);
c->refresh();
track->AddClip(c);
@@ -786,7 +790,7 @@ void Viewer::set_media(Media* m) {
viewer_widget_->frame_update();
}
} else {
new_sequence->audio_frequency = olive::CurrentConfig.default_sequence_audio_frequency;
new_sequence->audio_frequency = olive::config.default_sequence_audio_frequency;
}
new_sequence->audio_layout = AV_CH_LAYOUT_STEREO;
@@ -798,7 +802,7 @@ void Viewer::set_media(Media* m) {
}
}
set_sequence(false, new_sequence);
set_sequence(new_sequence);
}
void Viewer::update_playhead() {
@@ -810,11 +814,11 @@ void Viewer::timer_update() {
seq->playhead = qMax(0, qRound(playhead_start + ((QDateTime::currentMSecsSinceEpoch()-start_msecs) * 0.001 * seq->frame_rate * playback_speed)));
if (olive::CurrentConfig.seek_also_selects) {
panel_timeline->select_from_playhead();
if (olive::config.seek_also_selects) {
seq->SelectAtPlayhead();
}
update_parents(olive::CurrentConfig.seek_also_selects);
update_parents(olive::config.seek_also_selects);
if (playing) {
if (playback_speed < 0 && seq->playhead == 0) {
@@ -825,11 +829,11 @@ void Viewer::timer_update() {
}
} else if (playback_speed > 0) {
long end_frame = seq->GetEndFrame();
if ((olive::CurrentConfig.auto_seek_to_beginning || previous_playhead < end_frame) && seq->playhead >= end_frame) {
if ((olive::config.auto_seek_to_beginning || previous_playhead < end_frame) && seq->playhead >= end_frame) {
pause();
}
if (seq->using_workarea && seq->playhead >= seq->workarea_out) {
if (olive::CurrentConfig.loop) {
if (olive::config.loop) {
// loop
play();
} else if (playing_in_to_out) {
@@ -882,7 +886,7 @@ void Viewer::clean_created_seq() {
}
}
void Viewer::set_sequence(bool main, SequencePtr s) {
void Viewer::set_sequence(SequencePtr s) {
pause();
reset_all_audio();
@@ -896,11 +900,7 @@ void Viewer::set_sequence(bool main, SequencePtr s) {
clean_created_seq();
main_sequence = main;
seq = (main) ? olive::ActiveSequence : s;
seq = s;
bool null_sequence = (seq == nullptr);
+11 -3
View File
@@ -44,9 +44,16 @@ class Viewer : public Panel
public:
explicit Viewer(QWidget *parent = nullptr);
enum Mode {
kFootageMode,
kTimelineMode
};
void SetMode(Mode mode);
Mode mode();
virtual bool focused() override;
bool is_main_sequence();
void set_main_sequence();
void set_media(Media *m);
void compose();
void set_playpause_icon(bool play);
@@ -131,8 +138,7 @@ private slots:
private:
void update_window_title();
void clean_created_seq();
void set_sequence(bool main, SequencePtr s);
bool main_sequence;
void set_sequence(SequencePtr s);
bool created_sequence;
long cached_end_frame;
QString panel_name;
@@ -169,6 +175,8 @@ private:
long previous_playhead;
int playback_speed;
Mode mode_;
};
#endif // VIEWER_H
+24 -1
View File
@@ -23,6 +23,7 @@
#include <QDebug>
#include <QtMath>
#include <QPainter>
#include <QCoreApplication>
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE::v1;
@@ -114,7 +115,7 @@ QString Footage::Colorspace()
return guess_colorspace;
}
return olive::CurrentConfig.ocio_default_input_colorspace;
return olive::config.ocio_default_input_colorspace;
}
void Footage::SetColorspace(const QString &cs)
@@ -154,3 +155,25 @@ FootageStream* Footage::get_stream_from_file_index(bool video, int index) {
}
return nullptr;
}
QString Footage::get_interlacing_name(int interlacing) {
switch (interlacing) {
case VIDEO_PROGRESSIVE: return QCoreApplication::translate("InterlacingName", "None (Progressive)");
case VIDEO_TOP_FIELD_FIRST: return QCoreApplication::translate("InterlacingName", "Top Field First");
case VIDEO_BOTTOM_FIELD_FIRST: return QCoreApplication::translate("InterlacingName", "Bottom Field First");
default: return QCoreApplication::translate("InterlacingName", "Invalid");
}
}
QString Footage::get_channel_layout_name(int channels, uint64_t layout) {
switch (channels) {
case 0: return QCoreApplication::translate("ChannelLayoutName", "Invalid");
case 1: return QCoreApplication::translate("ChannelLayoutName", "Mono");
case 2: return QCoreApplication::translate("ChannelLayoutName", "Stereo");
default: {
char buf[50];
av_get_channel_layout_string(buf, sizeof(buf), channels, layout);
return QString(buf);
}
}
}
+16 -10
View File
@@ -27,6 +27,7 @@
#include "global/config.h"
#include "rendering/renderfunctions.h"
#include "project/previewgenerator.h"
#include "project/projectfunctions.h"
#include "effects/internal/voideffect.h"
#include "global/debug.h"
#include "effects/effectloaders.h"
@@ -82,8 +83,10 @@ void LoadThread::load_effect(QXmlStreamReader& stream, Clip* c) {
// Find the clip with the ID referenced in the transition
int clip_id = attr.value().toInt();
for (int i=0;i<c->sequence->clips.size();i++) {
Clip* test_clip = c->sequence->clips.at(i).get();
QVector<Clip*> sequence_clips = c->track()->sequence()->GetAllClips();
for (int i=0;i<sequence_clips.size();i++) {
Clip* test_clip = sequence_clips.at(i);
if (test_clip->load_id == clip_id) {
sharing_clip = test_clip;
break;
@@ -262,7 +265,7 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
switch (type) {
case MEDIA_TYPE_FOLDER:
{
MediaPtr folder = panel_project->create_folder_internal(nullptr);
MediaPtr folder = olive::project::CreateFolder(nullptr);
folder->temp_id2 = 0;
for (int j=0;j<stream.attributes().size();j++) {
const QXmlStreamAttribute& attr = stream.attributes().at(j);
@@ -440,7 +443,9 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
int media_id = -1;
int stream_id = -1;
ClipPtr c = std::make_shared<Clip>(s.get());
Track* t;
ClipPtr c = std::make_shared<Clip>(t);
//ClipPtr c = std::make_shared<Clip>(s.get());
QColor clip_color;
ClipSpeed speed_info = c->speed();
@@ -459,8 +464,6 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
c->set_timeline_in(attr.value().toLong());
} else if (attr.name() == "out") {
c->set_timeline_out(attr.value().toLong());
} else if (attr.name() == "track") {
c->set_track(attr.value().toInt());
} else if (attr.name() == "r") {
clip_color.setRed(attr.value().toInt());
} else if (attr.name() == "g") {
@@ -518,7 +521,8 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
for (int k=0;k<stream.attributes().size();k++) {
const QXmlStreamAttribute& link_attr = stream.attributes().at(k);
if (link_attr.name() == "id") {
c->linked.append(link_attr.value().toInt());
// FIXME reimplement this
//c->linked.append(link_attr.value().toInt());
break;
}
}
@@ -546,11 +550,12 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
}
if (cancelled_) return false;
s->clips.append(c);
//s->clips.append(c);
}
}
if (cancelled_) return false;
/*
// correct links, clip IDs, transitions
for (int i=0;i<s->clips.size();i++) {
// correct links
@@ -585,6 +590,7 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
MediaPtr m = panel_project->create_sequence_internal(nullptr, s, false, parent);
loaded_sequences.append(m.get());
*/
}
break;
}
@@ -780,11 +786,11 @@ void LoadThread::success_func() {
olive::Global->update_project_filename(orig_filename);
} else {
panel_project->add_recent_project(filename_);
olive::Global->add_recent_project(filename_);
}
olive::Global->set_modified(autorecovery_);
if (open_seq != nullptr) {
olive::Global->set_sequence(open_seq);
Timeline::OpenSequence(open_seq);
}
}
+6 -28
View File
@@ -39,28 +39,6 @@ extern "C" {
#include "global/debug.h"
#include "global/timing.h"
QString get_interlacing_name(int interlacing) {
switch (interlacing) {
case VIDEO_PROGRESSIVE: return QCoreApplication::translate("InterlacingName", "None (Progressive)");
case VIDEO_TOP_FIELD_FIRST: return QCoreApplication::translate("InterlacingName", "Top Field First");
case VIDEO_BOTTOM_FIELD_FIRST: return QCoreApplication::translate("InterlacingName", "Bottom Field First");
default: return QCoreApplication::translate("InterlacingName", "Invalid");
}
}
QString get_channel_layout_name(int channels, uint64_t layout) {
switch (channels) {
case 0: return QCoreApplication::translate("ChannelLayoutName", "Invalid");
case 1: return QCoreApplication::translate("ChannelLayoutName", "Mono");
case 2: return QCoreApplication::translate("ChannelLayoutName", "Stereo");
default: {
char buf[50];
av_get_channel_layout_string(buf, sizeof(buf), channels, layout);
return QString(buf);
}
}
}
Media::Media() :
root(false),
type(-1),
@@ -172,7 +150,7 @@ void Media::update_tooltip(const QString& error) {
if (i > 0) {
tooltip += ", ";
}
tooltip += get_interlacing_name(f->video_tracks.at(i).video_interlacing);
tooltip += Footage::get_interlacing_name(f->video_tracks.at(i).video_interlacing);
}
}
@@ -193,7 +171,7 @@ void Media::update_tooltip(const QString& error) {
if (i > 0) {
tooltip += ", ";
}
tooltip += get_channel_layout_name(f->audio_tracks.at(i).audio_channels, f->audio_tracks.at(i).audio_layout);
tooltip += Footage::get_channel_layout_name(f->audio_tracks.at(i).audio_channels, f->audio_tracks.at(i).audio_layout);
}
// tooltip += "\n";
}
@@ -216,7 +194,7 @@ void Media::update_tooltip(const QString& error) {
QString::number(s->height),
QString::number(s->frame_rate),
QString::number(s->audio_frequency),
get_channel_layout_name(av_get_channel_layout_nb_channels(s->audio_layout), s->audio_layout)
Footage::get_channel_layout_name(av_get_channel_layout_nb_channels(s->audio_layout), s->audio_layout)
);
}
break;
@@ -288,7 +266,7 @@ bool Media::setData(int col, const QVariant &value) {
if (col == 0) {
QString n = value.toString();
if (!n.isEmpty() && get_name() != n) {
olive::UndoStack.push(new MediaRename(this, value.toString()));
olive::undo_stack.push(new MediaRename(this, value.toString()));
return true;
}
}
@@ -310,7 +288,7 @@ int Media::columnCount() const {
QString Media::GetStringDuration() {
if (get_type() == MEDIA_TYPE_SEQUENCE) {
Sequence* s = to_sequence().get();
return frame_to_timecode(s->GetEndFrame(), olive::CurrentConfig.timecode_view, s->frame_rate);
return frame_to_timecode(s->GetEndFrame(), olive::config.timecode_view, s->frame_rate);
}
if (get_type() == MEDIA_TYPE_FOOTAGE) {
Footage* f = to_footage();
@@ -320,7 +298,7 @@ QString Media::GetStringDuration() {
r = f->video_tracks.at(0).video_frame_rate * f->speed;
long len = f->get_length_in_frames(r);
if (len > 0) return frame_to_timecode(len, olive::CurrentConfig.timecode_view, r);
if (len > 0) return frame_to_timecode(len, olive::config.timecode_view, r);
}
return QString();
}
+7 -6
View File
@@ -218,8 +218,9 @@ void PreviewGenerator::finalize_media() {
media_->update_tooltip();
}
if (olive::ActiveSequence != nullptr) {
olive::ActiveSequence->RefreshClips(media_);
QVector<Media*> all_sequences = olive::project_model.GetAllSequences();
for (int i=0;i<all_sequences.size();i++) {
all_sequences.at(i)->to_sequence()->RefreshClipsUsingMedia(media_);
}
}
}
@@ -258,8 +259,8 @@ void PreviewGenerator::generate_waveform() {
// we only generate previews for video and audio
// and only if the thumbnail and waveform sizes are > 0
if ((fmt_ctx_->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && olive::CurrentConfig.thumbnail_resolution > 0)
|| (fmt_ctx_->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && olive::CurrentConfig.waveform_resolution > 0)) {
if ((fmt_ctx_->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && olive::config.thumbnail_resolution > 0)
|| (fmt_ctx_->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && olive::config.waveform_resolution > 0)) {
AVCodec* codec = avcodec_find_decoder(fmt_ctx_->streams[i]->codecpar->codec_id);
if (codec != nullptr) {
@@ -332,7 +333,7 @@ void PreviewGenerator::generate_waveform() {
if (s != nullptr) {
if (fmt_ctx_->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
if (!s->preview_done) {
int dstH = olive::CurrentConfig.thumbnail_resolution;
int dstH = olive::config.thumbnail_resolution;
int dstW = qRound(dstH * (float(temp_frame->width)/float(temp_frame->height)));
sws_ctx = sws_getContext(
@@ -401,7 +402,7 @@ void PreviewGenerator::generate_waveform() {
// `config.waveform_resolution` determines how many samples per second are stored in waveform.
// `sample_rate` is samples per second, so `interval` is how many samples are averaged in
// each "point" of the waveform
int interval = qFloor((temp_frame->sample_rate/olive::CurrentConfig.waveform_resolution)/4)*4;
int interval = qFloor((temp_frame->sample_rate/olive::config.waveform_resolution)/4)*4;
// get the amount of bytes in an audio sample
int sample_size = av_get_bytes_per_sample(static_cast<AVSampleFormat>(swr_frame->format));
+5 -5
View File
@@ -21,11 +21,11 @@ SequencePtr olive::project::CreateSequenceFromMedia(QVector<olive::timeline::Med
s->name = olive::project_model.GetNextSequenceName();
// Retrieve default Sequence settings from Config
s->width = olive::CurrentConfig.default_sequence_width;
s->height = olive::CurrentConfig.default_sequence_height;
s->frame_rate = olive::CurrentConfig.default_sequence_framerate;
s->audio_frequency = olive::CurrentConfig.default_sequence_audio_frequency;
s->audio_layout = olive::CurrentConfig.default_sequence_audio_channel_layout;
s->width = olive::config.default_sequence_width;
s->height = olive::config.default_sequence_height;
s->frame_rate = olive::config.default_sequence_framerate;
s->audio_frequency = olive::config.default_sequence_audio_frequency;
s->audio_layout = olive::config.default_sequence_audio_channel_layout;
bool got_video_values = false;
bool got_audio_values = false;
+21 -13
View File
@@ -20,11 +20,18 @@
#include "projectmodel.h"
#include <QMessageBox>
#include "panels/panels.h"
#include "panels/viewer.h"
#include "ui/viewerwidget.h"
#include "ui/mainwindow.h"
#include "project/media.h"
#include "global/debug.h"
#include "global/config.h"
#include "global/global.h"
#include "projectfunctions.h"
#include "previewgenerator.h"
ProjectModel olive::project_model;
@@ -297,18 +304,14 @@ MediaPtr ProjectModel::CreateSequence(ComboAction *ca, SequencePtr s, bool open,
ca->append(new AddMediaCommand(item, parent));
if (open) {
ca->append(new ChangeSequenceAction(s));
}
} else {
appendChild(parent, item);
if (open) {
olive::Global->set_sequence(s);
}
}
if (open) {
Timeline::OpenSequence(s);
}
return item;
@@ -404,7 +407,7 @@ void ProjectModel::process_file_list(QStringList& files, bool recursive, MediaPt
bool imported = false;
// retrieve the array of image formats from the user's configuration
QStringList image_sequence_formats = olive::CurrentConfig.img_seq_formats.split("|");
QStringList image_sequence_formats = olive::config.img_seq_formats.split("|");
// a cache of image sequence formatted URLS to assist the user in importing image sequences
QVector<QString> image_sequence_urls;
@@ -422,8 +425,8 @@ void ProjectModel::process_file_list(QStringList& files, bool recursive, MediaPt
// If this file is a directory, we'll recursively call this function again to process the directory's contents
if (QFileInfo(files.at(i)).isDir()) {
QString folder_name = get_file_name_from_path(files.at(i));
MediaPtr folder = CreateFolder(folder_name);
QString folder_name = QFileInfo(files.at(i)).fileName();
MediaPtr folder = olive::project::CreateFolder(folder_name);
QDir directory(files.at(i));
directory.setFilter(QDir::NoDotAndDotDot | QDir::AllEntries);
@@ -452,7 +455,7 @@ void ProjectModel::process_file_list(QStringList& files, bool recursive, MediaPt
if (file.endsWith(".ove", Qt::CaseInsensitive)) {
// This file is an Olive project file. Ask the user if they really want to import it.
if (QMessageBox::question(this,
if (QMessageBox::question(olive::MainWindow,
tr("Import a Project"),
tr("\"%1\" is an Olive project file. It will merge with this project. "
"Do you wish to continue?").arg(file),
@@ -556,7 +559,7 @@ void ProjectModel::process_file_list(QStringList& files, bool recursive, MediaPt
image_sequence_urls.append(new_filename);
// This does look like an image sequence, let's ask the user if it'll indeed be an image sequence
if (QMessageBox::question(this,
if (QMessageBox::question(olive::MainWindow,
tr("Image sequence detected"),
tr("The file '%1' appears to be part of an image sequence. "
"Would you like to import it as such?").arg(file),
@@ -640,7 +643,7 @@ void ProjectModel::process_file_list(QStringList& files, bool recursive, MediaPt
}
if (create_undo_action) {
if (imported) {
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
for (int i=0;i<last_imported_media.size();i++) {
// generate waveform/thumbnail in another thread
@@ -651,3 +654,8 @@ void ProjectModel::process_file_list(QStringList& files, bool recursive, MediaPt
}
}
}
QVector<Media *> ProjectModel::GetLastImportedMedia()
{
return last_imported_media;
}
+4 -2
View File
@@ -9,11 +9,12 @@
#include "global/config.h"
#include "projectmodel.h"
/*
void RecursiveSave() {
}
void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, const QModelIndex& parent) {
void save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, const QModelIndex& parent) {
for (int i=0;i<olive::project_model.rowCount(parent);i++) {
const QModelIndex& item = olive::project_model.index(i, 0, parent);
Media* m = olive::project_model.getItem(item);
@@ -57,6 +58,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only,
}
}
}
*/
void olive::Save(bool autorecovery)
{
@@ -91,7 +93,7 @@ void olive::Save(bool autorecovery)
file.close();
if (!autorecovery) {
add_recent_project(olive::ActiveProjectFilename);
olive::Global->add_recent_project(olive::ActiveProjectFilename);
olive::Global->set_modified(false);
}
}
+14 -14
View File
@@ -68,12 +68,11 @@ void SourcesCommon::create_seq_from_selected() {
ComboAction* ca = new ComboAction();
SequencePtr s = olive::project::CreateSequenceFromMedia(media_list);
// add clips to it
panel_timeline->create_ghosts_from_media(s.get(), 0, media_list);
panel_timeline->add_clips_from_ghosts(ca, s.get());
// add clips to it
s->AddClipsFromGhosts(ca, olive::timeline::CreateGhostsFromMedia(s.get(), 0, media_list));
olive::project_model.CreateSequence(ca, s, true, nullptr);
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
}
}
@@ -245,14 +244,14 @@ void SourcesCommon::replace_media(MediaPtr item, QString filename)
{
if (filename.isEmpty()) {
filename = QFileDialog::getOpenFileName(
this,
olive::MainWindow,
tr("Replace '%1'").arg(item->get_name()),
"",
tr("All Files") + " (*)");
}
if (!filename.isEmpty()) {
ReplaceMediaCommand* rmc = new ReplaceMediaCommand(item, filename);
olive::UndoStack.push(rmc);
olive::undo_stack.push(rmc);
}
}
@@ -276,7 +275,7 @@ void SourcesCommon::mouseDoubleClickEvent(const QModelIndexList& selected_items)
} else if (selected_items.size() == 1) {
Media* media = project_parent->item_to_media(selected_items.at(0));
if (media->get_type() == MEDIA_TYPE_SEQUENCE) {
olive::UndoStack.push(new ChangeSequenceAction(media->to_sequence()));
Timeline::OpenSequence(media->to_sequence());
} else {
OpenSelectedMediaInMediaViewer(project_parent->item_to_media(selected_items.at(0)));
}
@@ -302,7 +301,7 @@ void SourcesCommon::dropEvent(QWidget* parent,
&& drop_item.isValid()
&& m->get_type() == MEDIA_TYPE_FOOTAGE
&& !QFileInfo(paths.at(0)).isDir()
&& olive::CurrentConfig.drop_on_media_to_replace
&& olive::config.drop_on_media_to_replace
&& QMessageBox::question(
parent,
tr("Replace Media"),
@@ -320,7 +319,7 @@ void SourcesCommon::dropEvent(QWidget* parent,
parent = drop_item.parent();
}
}
olive::project_model.process_file_list(paths, false, nullptr, panel_project->item_to_media(parent));
olive::project_model.process_file_list(paths, false, nullptr, project_parent->item_to_media(parent));
}
}
event->acceptProposedAction();
@@ -359,7 +358,7 @@ void SourcesCommon::dropEvent(QWidget* parent,
MediaMove* mm = new MediaMove();
mm->to = m.get();
mm->items = move_items;
olive::UndoStack.push(mm);
olive::undo_stack.push(mm);
}
}
}
@@ -403,7 +402,7 @@ void SourcesCommon::rename_interval() {
void SourcesCommon::item_renamed(Media* item) {
if (editing_item == item) {
MediaRename* mr = new MediaRename(item, "idk");
olive::UndoStack.push(mr);
olive::undo_stack.push(mr);
editing_item = nullptr;
}
}
@@ -447,9 +446,10 @@ void SourcesCommon::clear_proxies_from_selected() {
f->proxy_path.clear();
}
if (olive::ActiveSequence != nullptr) {
QVector<Media*> all_sequences = olive::project_model.GetAllSequences();
for (int i=0;i<all_sequences.size();i++) {
// close all clips so we can delete any proxies requested to be deleted
olive::ActiveSequence->Close();
all_sequences.at(i)->to_sequence()->Close();
}
// delete proxies requested to be deleted
@@ -457,7 +457,7 @@ void SourcesCommon::clear_proxies_from_selected() {
QFile::remove(delete_list.at(i));
}
if (olive::ActiveSequence != nullptr) {
if (panel_sequence_viewer->seq != nullptr) {
// update viewer (will re-open active clips with original media)
panel_sequence_viewer->viewer_widget()->frame_update();
}
+6 -7
View File
@@ -69,7 +69,7 @@ QAudioDeviceInfo get_audio_device(QAudio::Mode mode) {
QList<QAudioDeviceInfo> devs = QAudioDeviceInfo::availableDevices(mode);
// try to retrieve preferred device from config
QString preferred_device = (mode == QAudio::AudioOutput) ? olive::CurrentConfig.preferred_audio_output : olive::CurrentConfig.preferred_audio_input;
QString preferred_device = (mode == QAudio::AudioOutput) ? olive::config.preferred_audio_output : olive::config.preferred_audio_input;
if (!preferred_device.isEmpty()) {
for (int i=0;i<devs.size();i++) {
// try to match available devices with preferred device
@@ -98,7 +98,7 @@ void init_audio() {
stop_audio();
QAudioFormat audio_format;
audio_format.setSampleRate(olive::CurrentConfig.audio_rate);
audio_format.setSampleRate(olive::config.audio_rate);
audio_format.setChannelCount(2);
audio_format.setSampleSize(16);
audio_format.setCodec("audio/pcm");
@@ -232,7 +232,7 @@ int AudioSenderThread::send_audio_to_output(qint64 offset, int max) {
averages[i] = log_volume(1.0-(averages[i]));
}
panel_timeline->audio_monitor->set_value(averages);
panel_timeline.first()->audio_monitor->set_value(averages);
}
memset(audio_ibuffer+offset, 0, actual_write);
@@ -324,8 +324,7 @@ void write_wave_trailer(QFile& f) {
}
bool start_recording() {
if (olive::ActiveSequence == nullptr) {
qCritical() << "No active sequence to record into";
if (!olive::Global->CheckForActiveSequence(true)) {
return false;
}
@@ -355,8 +354,8 @@ bool start_recording() {
}
QAudioFormat audio_format = audio_output->format();
if (olive::CurrentConfig.recording_mode != audio_format.channelCount()) {
audio_format.setChannelCount(olive::CurrentConfig.recording_mode);
if (olive::config.recording_mode != audio_format.channelCount()) {
audio_format.setChannelCount(olive::config.recording_mode);
}
QAudioDeviceInfo info = get_audio_device(QAudio::AudioInput);
+32 -31
View File
@@ -65,8 +65,8 @@ void apply_audio_effects(Clip* clip, double timecode_start, AVFrame* frame, int
}
if (clip->opening_transition != nullptr) {
if (clip->media() != nullptr && clip->media()->get_type() == MEDIA_TYPE_FOOTAGE) {
double transition_start = (clip->clip_in(true) / clip->sequence->frame_rate);
double transition_end = (clip->clip_in(true) + clip->opening_transition->get_length()) / clip->sequence->frame_rate;
double transition_start = (clip->clip_in(true) / clip->track()->sequence()->frame_rate);
double transition_end = (clip->clip_in(true) + clip->opening_transition->get_length()) / clip->track()->sequence()->frame_rate;
if (timecode_end < transition_end) {
double adjustment = transition_end - transition_start;
double adjusted_range_start = (timecode_start - transition_start) / adjustment;
@@ -78,8 +78,8 @@ void apply_audio_effects(Clip* clip, double timecode_start, AVFrame* frame, int
if (clip->closing_transition != nullptr) {
if (clip->media() != nullptr && clip->media()->get_type() == MEDIA_TYPE_FOOTAGE) {
long length_with_transitions = clip->timeline_out(true) - clip->timeline_in(true);
double transition_start = (clip->clip_in(true) + length_with_transitions - clip->closing_transition->get_length()) / clip->sequence->frame_rate;
double transition_end = (clip->clip_in(true) + length_with_transitions) / clip->sequence->frame_rate;
double transition_start = (clip->clip_in(true) + length_with_transitions - clip->closing_transition->get_length()) / clip->track()->sequence()->frame_rate;
double transition_end = (clip->clip_in(true) + length_with_transitions) / clip->track()->sequence()->frame_rate;
if (timecode_start > transition_start) {
double adjustment = transition_end - transition_start;
double adjusted_range_start = (timecode_start - transition_start) / adjustment;
@@ -93,7 +93,7 @@ void apply_audio_effects(Clip* clip, double timecode_start, AVFrame* frame, int
Clip* next_nest = nests.last();
nests.removeLast();
apply_audio_effects(next_nest,
timecode_start + (double(clip->timeline_in(true)-clip->clip_in(true))/clip->sequence->frame_rate),
timecode_start + (double(clip->timeline_in(true)-clip->clip_in(true))/clip->track()->sequence()->frame_rate),
frame,
nb_bytes,
nests);
@@ -122,16 +122,16 @@ void Cacher::CacheAudioWorker() {
bool reverse_audio = IsReversed();
long frame_skip = 0;
double last_fr = clip->sequence->frame_rate;
double last_fr = clip->track()->sequence()->frame_rate;
if (!nests_.isEmpty()) {
for (int i=nests_.size()-1;i>=0;i--) {
timeline_in = rescale_frame_number(timeline_in, last_fr, nests_.at(i)->sequence->frame_rate) + nests_.at(i)->timeline_in(true) - nests_.at(i)->clip_in(true);
timeline_out = rescale_frame_number(timeline_out, last_fr, nests_.at(i)->sequence->frame_rate) + nests_.at(i)->timeline_in(true) - nests_.at(i)->clip_in(true);
target_frame = rescale_frame_number(target_frame, last_fr, nests_.at(i)->sequence->frame_rate) + nests_.at(i)->timeline_in(true) - nests_.at(i)->clip_in(true);
timeline_in = rescale_frame_number(timeline_in, last_fr, nests_.at(i)->track()->sequence()->frame_rate) + nests_.at(i)->timeline_in(true) - nests_.at(i)->clip_in(true);
timeline_out = rescale_frame_number(timeline_out, last_fr, nests_.at(i)->track()->sequence()->frame_rate) + nests_.at(i)->timeline_in(true) - nests_.at(i)->clip_in(true);
target_frame = rescale_frame_number(target_frame, last_fr, nests_.at(i)->track()->sequence()->frame_rate) + nests_.at(i)->timeline_in(true) - nests_.at(i)->clip_in(true);
timeline_out = qMin(timeline_out, nests_.at(i)->timeline_out(true));
frame_skip = rescale_frame_number(frame_skip, last_fr, nests_.at(i)->sequence->frame_rate);
frame_skip = rescale_frame_number(frame_skip, last_fr, nests_.at(i)->track()->sequence()->frame_rate);
long validator = nests_.at(i)->timeline_in(true) - timeline_in;
if (validator > 0) {
@@ -139,12 +139,13 @@ void Cacher::CacheAudioWorker() {
//timeline_in = nests_.at(i)->timeline_in(true);
}
last_fr = nests_.at(i)->sequence->frame_rate;
last_fr = nests_.at(i)->track()->sequence()->frame_rate;
}
}
if (temp_reverse) {
long seq_end = olive::ActiveSequence->GetEndFrame();
// FIXME breakable?
long seq_end = Timeline::GetTopSequence()->GetEndFrame();
timeline_in = seq_end - timeline_in;
timeline_out = seq_end - timeline_out;
target_frame = seq_end - target_frame;
@@ -394,7 +395,7 @@ void Cacher::CacheAudioWorker() {
// apply any audio effects to the data
if (nb_bytes == INT_MAX) nb_bytes = frame->nb_samples * av_get_bytes_per_sample(static_cast<AVSampleFormat>(frame->format)) * frame->channels;
if (new_frame) {
apply_audio_effects(clip, bytes_to_seconds(audio_buffer_write, 2, current_audio_freq()) + audio_ibuffer_timecode + ((double)clip->clip_in(true)/clip->sequence->frame_rate) - ((double)timeline_in/last_fr), frame, nb_bytes, nests_);
apply_audio_effects(clip, bytes_to_seconds(audio_buffer_write, 2, current_audio_freq()) + audio_ibuffer_timecode + ((double)clip->clip_in(true)/clip->track()->sequence()->frame_rate) - ((double)timeline_in/last_fr), frame, nb_bytes, nests_);
}
}
@@ -402,7 +403,7 @@ void Cacher::CacheAudioWorker() {
if (frame->nb_samples == 0) {
break;
} else {
qint64 buffer_timeline_out = get_buffer_offset_from_frame(clip->sequence->frame_rate, timeline_out);
qint64 buffer_timeline_out = get_buffer_offset_from_frame(clip->track()->sequence()->frame_rate, timeline_out);
audio_write_lock.lock();
@@ -597,15 +598,15 @@ void Cacher::CacheVideoWorker() {
// For reversed playback, we flip the queue stats as "upcoming" frames are going to be played before the "previous"
// frames now
if (reversed) {
previous_queue_type = olive::CurrentConfig.upcoming_queue_type;
previous_queue_size = olive::CurrentConfig.upcoming_queue_size;
upcoming_queue_type = olive::CurrentConfig.previous_queue_type;
upcoming_queue_size = olive::CurrentConfig.previous_queue_size;
previous_queue_type = olive::config.upcoming_queue_type;
previous_queue_size = olive::config.upcoming_queue_size;
upcoming_queue_type = olive::config.previous_queue_type;
upcoming_queue_size = olive::config.previous_queue_size;
} else {
previous_queue_type = olive::CurrentConfig.previous_queue_type;
previous_queue_size = olive::CurrentConfig.previous_queue_size;
upcoming_queue_type = olive::CurrentConfig.upcoming_queue_type;
upcoming_queue_size = olive::CurrentConfig.upcoming_queue_size;
previous_queue_type = olive::config.previous_queue_type;
previous_queue_size = olive::config.previous_queue_size;
upcoming_queue_type = olive::config.upcoming_queue_type;
upcoming_queue_size = olive::config.upcoming_queue_size;
}
// Determine "previous" queue statistics
@@ -794,7 +795,7 @@ void Cacher::CacheVideoWorker() {
void Cacher::Reset() {
// if we seek to a whole other place in the timeline, we'll need to reset the cache with new values
if (clip->media() == nullptr) {
if (clip->track() >= 0) {
if (clip->type() == Track::kTypeAudio) {
// a null-media audio clip is usually an auto-generated sound clip such as Tone or Noise
reached_end = false;
audio_target_frame = playhead_;
@@ -860,7 +861,7 @@ Cacher::Cacher(Clip* c) :
void Cacher::OpenWorker() {
// set some defaults for the audio cacher
if (clip->track() >= 0) {
if (clip->type() == Track::kTypeAudio) {
audio_reset_ = false;
frame_sample_index_ = -1;
audio_buffer_write = 0;
@@ -868,10 +869,10 @@ void Cacher::OpenWorker() {
reached_end = false;
if (clip->media() == nullptr) {
if (clip->track() >= 0) {
if (clip->type() == Track::kTypeAudio) {
frame_ = av_frame_alloc();
frame_->format = kDestSampleFmt;
frame_->channel_layout = clip->sequence->audio_layout;
frame_->channel_layout = clip->track()->sequence()->audio_layout;
frame_->channels = av_get_channel_layout_nb_channels(frame_->channel_layout);
frame_->sample_rate = current_audio_freq();
frame_->nb_samples = 2048;
@@ -889,7 +890,7 @@ void Cacher::OpenWorker() {
QByteArray ba;
// do we have a proxy?
if ((!olive::Global->is_exporting() || !olive::CurrentConfig.dont_use_proxies_on_export)
if ((!olive::Global->is_exporting() || !olive::config.dont_use_proxies_on_export)
&& m->proxy
&& !m->proxy_path.isEmpty()
&& QFileInfo::exists(m->proxy_path)) {
@@ -1029,8 +1030,8 @@ void Cacher::OpenWorker() {
reverse_frame->format = kDestSampleFmt;
reverse_frame->nb_samples = current_audio_freq()*10;
reverse_frame->channel_layout = clip->sequence->audio_layout;
reverse_frame->channels = av_get_channel_layout_nb_channels(clip->sequence->audio_layout);
reverse_frame->channel_layout = clip->track()->sequence()->audio_layout;
reverse_frame->channels = av_get_channel_layout_nb_channels(clip->track()->sequence()->audio_layout);
av_frame_get_buffer(reverse_frame, 0);
queue_.append(reverse_frame);
@@ -1116,7 +1117,7 @@ void Cacher::OpenWorker() {
}
void Cacher::CacheWorker() {
if (clip->track() < 0) {
if (clip->type() == Track::kTypeVideo) {
// clip is a video track, start caching video
CacheVideoWorker();
} else {
@@ -1207,7 +1208,7 @@ void Cacher::Open()
caching_ = true;
queued_ = false;
start((clip->track() < 0) ? QThread::HighPriority : QThread::TimeCriticalPriority);
start((clip->type() == Track::kTypeVideo) ? QThread::HighPriority : QThread::TimeCriticalPriority);
}
void Cacher::Cache(long playhead, bool scrubbing, QVector<Clip*>& nests, int playback_speed)
+12 -13
View File
@@ -34,7 +34,6 @@ extern "C" {
#include <QtMath>
#include "global/global.h"
#include "timeline/sequence.h"
#include "panels/panels.h"
#include "ui/viewerwidget.h"
#include "rendering/renderthread.h"
@@ -192,16 +191,16 @@ bool ExportThread::SetupVideo() {
video_frame = av_frame_alloc();
av_frame_make_writable(video_frame);
video_frame->format = AV_PIX_FMT_RGBA;
video_frame->width = olive::ActiveSequence->width;
video_frame->height = olive::ActiveSequence->height;
video_frame->width = params_.sequence->width;
video_frame->height = params_.sequence->height;
av_frame_get_buffer(video_frame, 0);
av_init_packet(&video_pkt);
// Set up conversion context
sws_ctx = sws_getContext(
olive::ActiveSequence->width,
olive::ActiveSequence->height,
params_.sequence->width,
params_.sequence->height,
AV_PIX_FMT_RGBA,
params_.video_width,
params_.video_height,
@@ -288,7 +287,7 @@ bool ExportThread::SetupAudio() {
acodec_ctx->channel_layout,
acodec_ctx->sample_fmt,
acodec_ctx->sample_rate,
olive::ActiveSequence->audio_layout,
params_.sequence->audio_layout,
AV_SAMPLE_FMT_S16,
acodec_ctx->sample_rate,
0,
@@ -417,7 +416,7 @@ void ExportThread::Export()
mutex.lock();
// Loop from now (set to the beginning frame earlier) to the end of the frame
while (olive::ActiveSequence->playhead <= params_.end_frame && !interrupt_) {
while (params_.sequence->playhead <= params_.end_frame && !interrupt_) {
// Start timing how long this frame will take
frame_start_time = QDateTime::currentMSecsSinceEpoch();
@@ -426,14 +425,14 @@ void ExportThread::Export()
if (params_.audio_enabled) {
waiting_for_audio_ = true;
SetAudioWakeObject(this);
olive::rendering::compose_audio(nullptr, olive::ActiveSequence.get(), 1, true);
olive::rendering::compose_audio(nullptr, params_.sequence, 1, true);
}
// If we're exporting video, trigger a render on the RenderThread
if (params_.video_enabled) {
do {
// TODO optimize by rendering the next frame while encoding the last
renderer->start_render(nullptr, olive::ActiveSequence.get(), 1, nullptr, video_frame->data[0], video_frame->linesize[0]/4);
renderer->start_render(nullptr, params_.sequence, 1, nullptr, video_frame->data[0], video_frame->linesize[0]/4);
// Wait for RenderThread to return
waitCond.wait(&mutex);
@@ -452,7 +451,7 @@ void ExportThread::Export()
}
// Get the current sequence playhead in seconds (used for timestamp calculations later on)
double timecode_secs = double(olive::ActiveSequence->playhead - params_.start_frame) / olive::ActiveSequence->frame_rate;
double timecode_secs = double(params_.sequence->playhead - params_.start_frame) / params_.sequence->frame_rate;
// If we're exporting video, construct an AVFrame in the destination codec's pixel format to convert the raw RGBA
// OpenGL buffer to
@@ -538,15 +537,15 @@ void ExportThread::Export()
// Generating encoding statistics (e.g. the time it took to encode this frame/estimated remaining time)
frame_time = (QDateTime::currentMSecsSinceEpoch()-frame_start_time);
total_time += frame_time;
remaining_frames = (params_.end_frame - olive::ActiveSequence->playhead);
remaining_frames = (params_.end_frame - params_.sequence->playhead);
avg_time = (total_time/frame_count);
eta = (remaining_frames*avg_time);
// Emit a signal for the percent of the sequence that's been encoded so far
emit ProgressChanged(qRound((double(olive::ActiveSequence->playhead - params_.start_frame) / double(params_.end_frame - params_.start_frame)) * 100.0), eta);
emit ProgressChanged(qRound((double(params_.sequence->playhead - params_.start_frame) / double(params_.end_frame - params_.start_frame)) * 100.0), eta);
// Increment sequence playhead
olive::ActiveSequence->playhead++;
params_.sequence->playhead++;
// Increment frame count (used for generating encoding statistics above)
frame_count++;
+14 -8
View File
@@ -21,11 +21,17 @@
#ifndef EXPORTTHREAD_H
#define EXPORTTHREAD_H
extern "C" {
#include <libavcodec/avcodec.h>
}
#include <QThread>
#include <QOffscreenSurface>
#include <QMutex>
#include <QWaitCondition>
#include "timeline/sequence.h"
struct AVFormatContext;
struct AVCodecContext;
struct AVFrame;
@@ -35,19 +41,19 @@ struct AVCodec;
struct SwsContext;
struct SwrContext;
extern "C" {
#include <libavcodec/avcodec.h>
}
#define COMPRESSION_TYPE_CBR 0
#define COMPRESSION_TYPE_CFR 1
#define COMPRESSION_TYPE_TARGETSIZE 2
#define COMPRESSION_TYPE_TARGETBR 3
enum CompressionType {
COMPRESSION_TYPE_CBR,
COMPRESSION_TYPE_CFR,
COMPRESSION_TYPE_TARGETSIZE,
COMPRESSION_TYPE_TARGETBR
};
// structs that store parameters passed from the export dialogs to this thread
struct ExportParams {
// export parameters
Sequence* sequence;
QString filename;
bool video_enabled;
int video_codec;
+2 -2
View File
@@ -68,8 +68,8 @@ void FramebufferObject::Create(QOpenGLContext *ctx, int width, int height)
// allocate storage for texture
const olive::PixelFormatInfo& bit_depth = olive::pixel_formats.at(olive::Global->is_exporting() ?
olive::CurrentConfig.export_bit_depth :
olive::CurrentConfig.playback_bit_depth);
olive::config.export_bit_depth :
olive::config.playback_bit_depth);
ctx->functions()->glTexImage2D(
GL_TEXTURE_2D,
+14 -13
View File
@@ -187,7 +187,7 @@ void process_effect(QOpenGLContext* ctx,
if (e->Flags() & Effect::CoordsFlag) {
e->process_coords(timecode, coords, data);
}
bool can_process_shaders = ((e->Flags() & Effect::ShaderFlag) && olive::CurrentRuntimeConfig.shaders_are_enabled);
bool can_process_shaders = ((e->Flags() & Effect::ShaderFlag) && olive::runtime_config.shaders_are_enabled);
if (can_process_shaders || (e->Flags() & Effect::SuperimposeFlag)) {
if (!e->is_open()) {
@@ -227,7 +227,7 @@ void process_effect(QOpenGLContext* ctx,
}
GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
GLuint final_fbo = params.video ? params.main_buffer->buffer() : 0;
GLuint final_fbo = params.type == Track::kTypeVideo ? params.main_buffer->buffer() : 0;
Sequence* s = params.seq;
long playhead = s->playhead;
@@ -237,10 +237,10 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
for (int i=0;i<params.nests.size();i++) {
s = params.nests.at(i)->media()->to_sequence().get();
playhead += params.nests.at(i)->clip_in(true) - params.nests.at(i)->timeline_in(true);
playhead = rescale_frame_number(playhead, params.nests.at(i)->sequence->frame_rate, s->frame_rate);
playhead = rescale_frame_number(playhead, params.nests.at(i)->track()->sequence()->frame_rate, s->frame_rate);
}
if (params.video && !params.nests.last()->fbo.isEmpty()) {
if (params.type == Track::kTypeVideo && !params.nests.last()->fbo.isEmpty()) {
params.nests.last()->fbo.at(0).BindBuffer();
params.ctx->functions()->glClear(GL_COLOR_BUFFER_BIT);
final_fbo = params.nests.last()->fbo.at(0).buffer();
@@ -253,14 +253,15 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
QVector<Clip*> current_clips;
// loop through clips, find currently active, and sort by track
for (int i=0;i<s->clips.size();i++) {
QVector<Clip*> sequence_clips = s->GetAllClips();
for (int i=0;i<sequence_clips.size();i++) {
Clip* c = s->clips.at(i).get();
Clip* c = sequence_clips.at(i);
if (c != nullptr) {
// if clip is video and we're processing video
if ((c->track() < 0) == params.video) {
if (c->type() == params.type) {
bool clip_is_active = false;
@@ -269,7 +270,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
Footage* m = c->media()->to_footage();
// does the clip have a valid media source?
if (!m->invalid && !(c->track() >= 0 && !is_audio_device_set())) {
if (!m->invalid && !(c->type() == Track::kTypeAudio && !is_audio_device_set())) {
// is the media process and ready?
if (m->ready) {
@@ -286,7 +287,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
clip_is_active = true;
// increment audio track count
if (c->track() >= 0) audio_track_count++;
if (c->type() == Track::kTypeAudio) audio_track_count++;
} else if (c->IsOpen()) {
@@ -320,7 +321,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
// track sorting is only necessary for video clips
// audio clips are mixed equally, so we skip sorting for those
if (params.video) {
if (params.type == Track::kTypeVideo) {
// insertion sort by track
for (int j=0;j<current_clips.size();j++) {
@@ -343,7 +344,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
QMatrix4x4 projection;
if (params.video) {
if (params.type == Track::kTypeVideo) {
// set default coordinates based on the sequence, with 0 in the direct center
params.ctx->functions()->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
@@ -444,7 +445,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
} else if (c->media()->get_type() == MEDIA_TYPE_FOOTAGE) {
// Convert frame from source to linear colorspace
if (olive::CurrentConfig.enable_color_management)
if (olive::config.enable_color_management)
{
// Convert texture to sequence's internal format
@@ -794,7 +795,7 @@ void olive::rendering::compose_audio(Viewer* viewer, Sequence* seq, int playback
params.viewer = viewer;
params.ctx = nullptr;
params.seq = seq;
params.video = false;
params.type = Track::kTypeAudio;
params.gizmos = nullptr;
params.wait_for_mutexes = wait_for_mutexes;
params.playback_speed = playback_speed;
+2 -2
View File
@@ -80,9 +80,9 @@ struct ComposeSequenceParams {
/**
* @brief Set compose mode to video or audio
*
* **TRUE** if this function should render video, **FALSE** if this function should render audio.
* Accepts Track::kTypeVideo to render video, Track::kTypeAudio if this function should render audio.
*/
bool video;
Track::Type type;
/**
* @brief Set to the Effect whose gizmos were chosen to be drawn on screen
+7 -7
View File
@@ -116,7 +116,7 @@ void RenderThread::run() {
}
// If there's no OpenColorIO shader or the configuration has changed, (re-)create it now
if (olive::CurrentConfig.enable_color_management && ocio_shader == nullptr) {
if (olive::config.enable_color_management && ocio_shader == nullptr) {
destroy_ocio();
set_up_ocio();
@@ -155,12 +155,12 @@ void RenderThread::set_up_ocio()
OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
// Get current OCIO display from Config (or defaults if there is no setting)
QString display = olive::CurrentConfig.ocio_display;
QString display = olive::config.ocio_display;
if (display.isEmpty()) {
display = config->getDefaultDisplay();
}
QString view = olive::CurrentConfig.ocio_view;
QString view = olive::config.ocio_view;
if (view.isEmpty()) {
view = config->getDefaultView(display.toUtf8());
}
@@ -171,8 +171,8 @@ void RenderThread::set_up_ocio()
transform->setDisplay(display.toUtf8());
transform->setView(view.toUtf8());
if (!olive::CurrentConfig.ocio_look.isEmpty()) {
transform->setLooksOverride(olive::CurrentConfig.ocio_look.toUtf8());
if (!olive::config.ocio_look.isEmpty()) {
transform->setLooksOverride(olive::config.ocio_look.toUtf8());
transform->setLooksOverrideEnabled(true);
}
@@ -206,7 +206,7 @@ void RenderThread::paint() {
params.viewer = nullptr;
params.ctx = ctx;
params.seq = seq;
params.video = true;
params.type = Track::kTypeVideo;
params.texture_failed = false;
params.wait_for_mutexes = true;
params.playback_speed = playback_speed_;
@@ -244,7 +244,7 @@ void RenderThread::paint() {
// Blit the composite buffer to one of the front buffers
// If we're color managing, conver the linear composited frame to display color space
if (olive::CurrentConfig.enable_color_management && ocio_shader != nullptr) {
if (olive::config.enable_color_management && ocio_shader != nullptr) {
olive::rendering::OCIOBlit(ocio_shader.get(),
ocio_lut_texture,
+89 -103
View File
@@ -32,8 +32,8 @@
#include "timeline/sequence.h"
#include "panels/timeline.h"
#include "project/media.h"
#include "project/clipboard.h"
#include "undo/undo.h"
#include "global/clipboard.h"
#include "global/debug.h"
#include "global/timing.h"
@@ -46,7 +46,7 @@ Clip::Clip(Track *s) :
timeline_out_(0),
media_(nullptr),
reverse_(false),
autoscale_(olive::CurrentConfig.autoscale_by_default),
autoscale_(olive::config.autoscale_by_default),
opening_transition(nullptr),
closing_transition(nullptr),
undeletable(false),
@@ -110,6 +110,11 @@ bool Clip::IsTransitionSelected(TransitionType type)
}
}
Selection Clip::ToSelection()
{
return Selection(timeline_in(), timeline_out(), track());
}
Track::Type Clip::type()
{
return track()->type();
@@ -158,6 +163,11 @@ void Clip::set_media(Media *m, int s)
media_stream_ = s;
}
void Clip::Move(ComboAction *ca, long iin, long iout, long iclip_in, Track *itrack, bool verify_transitions, bool relative)
{
track()->sequence()->MoveClip(this, ca, iin, iout, iclip_in, itrack, verify_transitions, relative);
}
bool Clip::enabled()
{
return enabled_;
@@ -168,39 +178,6 @@ void Clip::set_enabled(bool e)
enabled_ = e;
}
void Clip::move(ComboAction* ca, long iin, long iout, long iclip_in, int itrack, bool verify_transitions, bool relative)
{
ca->append(new MoveClipAction(this, iin, iout, iclip_in, itrack, relative));
if (verify_transitions) {
// if this is a shared transition, and the corresponding clip will be moved away somehow
if (opening_transition != nullptr
&& opening_transition->secondary_clip != nullptr
&& opening_transition->secondary_clip->timeline_out() != iin) {
// separate transition
ca->append(new SetPointer(reinterpret_cast<void**>(&opening_transition->secondary_clip), nullptr));
ca->append(new AddTransitionCommand(nullptr,
opening_transition->secondary_clip,
opening_transition,
nullptr,
0));
}
if (closing_transition != nullptr
&& closing_transition->secondary_clip != nullptr
&& closing_transition->parent_clip->timeline_in() != iout) {
// separate transition
ca->append(new SetPointer(reinterpret_cast<void**>(&closing_transition->secondary_clip), nullptr));
ca->append(new AddTransitionCommand(nullptr,
this,
closing_transition,
nullptr,
0));
}
}
}
void Clip::reset_audio() {
if (UsesCacher()) {
cacher.ResetAudio();
@@ -260,6 +237,9 @@ Clip::~Clip() {
void Clip::Save(QXmlStreamWriter &stream)
{
stream.writeStartElement("clip");
stream.writeAttribute("id", QString::number(load_id));
stream.writeAttribute("enabled", QString::number(enabled()));
stream.writeAttribute("name", name());
stream.writeAttribute("clipin", QString::number(clip_in()));
@@ -312,21 +292,17 @@ void Clip::Save(QXmlStreamWriter &stream)
if (transition != nullptr) {
stream.writeStartElement((t == kTransitionOpening) ? "opening" : "closing");
// check if this is a shared transition and the transition has already been saved
int transition_cache_index = transition_save_cache.indexOf(transition);
if (transition_cache_index > -1) {
// check if this is a shared transition
if (this == transition->secondary_clip) {
// if so, just save a reference to the other clip
stream.writeAttribute("shared",
QString::number(transition_clip_save_cache.at(transition_cache_index)));
QString::number(transition->parent_clip->load_id));
} else {
// otherwise save the whole transition
transition->save(stream);
transition_save_cache.append(transition);
transition_clip_save_cache.append(j);
}
stream.writeEndElement(); // opening
stream.writeEndElement(); // opening/closing
}
}
@@ -336,7 +312,7 @@ void Clip::Save(QXmlStreamWriter &stream)
stream.writeEndElement(); // effect
}
stream.writeEndElement(); // clip
}
long Clip::clip_in(bool with_transition) {
@@ -441,6 +417,15 @@ Track *Clip::track()
void Clip::set_track(Track *t)
{
// Ensure this clip has already been added to this track
bool found = false;
for (int i=0;i<t->ClipCount();i++) {
if (t->GetClip(i).get() == this) {
found = true;
break;
}
}
track_ = t;
}
@@ -510,13 +495,13 @@ int Clip::media_width() {
}
int Clip::media_height() {
if (media_ == nullptr && sequence != nullptr) return sequence->height;
if (media_ == nullptr && track() != nullptr) return track()->sequence()->height;
switch (media_->get_type()) {
case MEDIA_TYPE_FOOTAGE:
{
const FootageStream* ms = media_stream();
if (ms != nullptr) return ms->video_height;
if (sequence != nullptr) return sequence->height;
if (track() != nullptr) return track()->sequence()->height;
}
break;
case MEDIA_TYPE_SEQUENCE:
@@ -530,11 +515,12 @@ int Clip::media_height() {
void Clip::refactor_frame_rate(ComboAction* ca, double multiplier, bool change_timeline_points) {
if (change_timeline_points) {
this->move(ca,
qRound(double(timeline_in_) * multiplier),
qRound(double(timeline_out_) * multiplier),
qRound(double(clip_in_) * multiplier),
track_);
track()->sequence()->MoveClip(this,
ca,
qRound(double(timeline_in_) * multiplier),
qRound(double(timeline_out_) * multiplier),
qRound(double(clip_in_) * multiplier),
track_);
}
// move keyframes
@@ -645,79 +631,79 @@ bool Clip::Retrieve()
//if (frame->pts != texture_timestamp) {
bool allocate_data = false;
bool allocate_data = false;
QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions();
QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions();
// check if the opengl texture exists yet, create it if not
if (texture == 0) {
// check if the opengl texture exists yet, create it if not
if (texture == 0) {
// create texture object
f->glGenTextures(1, &texture);
// create texture object
f->glGenTextures(1, &texture);
f->glBindTexture(GL_TEXTURE_2D, texture);
f->glBindTexture(GL_TEXTURE_2D, texture);
// set texture filtering to bilinear
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// set texture filtering to bilinear
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// set texture wrapping to clamp
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// set texture wrapping to clamp
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// queue an allocation ahead
allocate_data = true;
// queue an allocation ahead
allocate_data = true;
} else {
} else {
f->glBindTexture(GL_TEXTURE_2D, texture);
f->glBindTexture(GL_TEXTURE_2D, texture);
}
}
int video_width = cacher.media_width();
int video_height = cacher.media_height();
int video_width = cacher.media_width();
int video_height = cacher.media_height();
const olive::PixelFormatInfo& pix_fmt_info = olive::pixel_formats.at(cacher.media_pixel_format());
const olive::PixelFormatInfo& pix_fmt_info = olive::pixel_formats.at(cacher.media_pixel_format());
f->glPixelStorei(GL_UNPACK_ROW_LENGTH, frame->linesize[0]/pix_fmt_info.bytes_per_pixel);
f->glPixelStorei(GL_UNPACK_ROW_LENGTH, frame->linesize[0]/pix_fmt_info.bytes_per_pixel);
if (allocate_data) {
if (allocate_data) {
// the raw frame size may differ from the one we're using (e.g. a lower resolution proxy), so we make sure
// the texture is using the correct dimensions, but then treat it as if it's the original resolution in the
// composition
f->glTexImage2D(
GL_TEXTURE_2D,
0,
pix_fmt_info.internal_format,
video_width,
video_height,
0,
pix_fmt_info.pixel_format,
pix_fmt_info.pixel_type,
frame->data[0]
);
// the raw frame size may differ from the one we're using (e.g. a lower resolution proxy), so we make sure
// the texture is using the correct dimensions, but then treat it as if it's the original resolution in the
// composition
f->glTexImage2D(
GL_TEXTURE_2D,
0,
pix_fmt_info.internal_format,
video_width,
video_height,
0,
pix_fmt_info.pixel_format,
pix_fmt_info.pixel_type,
frame->data[0]
);
} else {
} else {
f->glTexSubImage2D(GL_TEXTURE_2D,
0,
0,
0,
video_width,
video_height,
pix_fmt_info.pixel_format,
pix_fmt_info.pixel_type,
frame->data[0]
);
f->glTexSubImage2D(GL_TEXTURE_2D,
0,
0,
0,
video_width,
video_height,
pix_fmt_info.pixel_format,
pix_fmt_info.pixel_type,
frame->data[0]
);
}
}
f->glBindTexture(GL_TEXTURE_2D, 0);
f->glBindTexture(GL_TEXTURE_2D, 0);
f->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
f->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
texture_timestamp = frame->pts;
texture_timestamp = frame->pts;
//}
+7 -5
View File
@@ -59,6 +59,8 @@ public:
bool IsSelected(bool containing = true);
bool IsTransitionSelected(TransitionType type);
Selection ToSelection();
Track::Type type();
const QColor& color();
@@ -74,17 +76,17 @@ public:
long media_length();
void set_media(Media* m, int s);
bool enabled();
void set_enabled(bool e);
void move(ComboAction* ca,
void Move(ComboAction* ca,
long iin,
long iout,
long iclip_in,
int itrack,
Track *itrack,
bool verify_transitions = true,
bool relative = false);
bool enabled();
void set_enabled(bool e);
long clip_in(bool with_transition = false);
void set_clip_in(long c);
+6
View File
@@ -0,0 +1,6 @@
#include "ghost.h"
Selection Ghost::ToSelection() const
{
return Selection(in, out, track);
}
+15 -2
View File
@@ -2,11 +2,22 @@
#define GHOST_H
#include "effects/transition.h"
#include "timelinefunctions.h"
#include "track.h"
namespace olive {
namespace timeline {
enum TrimType {
TRIM_NONE,
TRIM_IN,
TRIM_OUT
};
}
}
struct Ghost {
int clip;
Clip* clip;
long in;
long out;
Track* track;
@@ -28,6 +39,8 @@ struct Ghost {
// transition trimming
TransitionPtr transition;
Selection ToSelection() const;
};
#endif // GHOST_H
+73 -44
View File
@@ -49,22 +49,24 @@ void Marker::Draw(QPainter &p, int x, int y, int bottom, bool selected) {
p.drawPolygon(points, 5);
}
void set_marker_internal(Sequence* seq, const QVector<int>& clips) {
// if clips is empty, the marker is being added to the sequence
void Marker::SetOnClips(const QVector<Clip *> &clips)
{
// Don't bother if there are no clips
if (clips.isEmpty()) {
return;
}
// add_marker is used to determine whether we're adding a marker, depending on whether the user input a marker name
// however if (config.set_name_with_marker) is true, we don't need a marker name so we just add
bool add_marker = !olive::CurrentConfig.set_name_with_marker;
bool add_marker = !olive::config.set_name_with_marker;
QString marker_name;
// if (config.set_name_with_marker) is false (set above), ask for a marker name
// if Config::set_name_with_marker is true (set above), ask for a marker name
if (!add_marker) {
QInputDialog d(olive::MainWindow);
d.setWindowTitle(QCoreApplication::translate("Marker", "Set Marker"));
d.setLabelText(clips.size() > 0
? QCoreApplication::translate("Marker", "Set clip marker name:")
: QCoreApplication::translate("Marker", "Set sequence marker name:"));
d.setLabelText(QCoreApplication::translate("Marker", "Set clip marker name:"));
d.setInputMode(QInputDialog::TextInput);
add_marker = (d.exec() == QDialog::Accepted);
marker_name = d.textValue();
@@ -75,43 +77,16 @@ void set_marker_internal(Sequence* seq, const QVector<int>& clips) {
ComboAction* ca = new ComboAction();
if (clips.size() > 0) {
// add a marker action for each clip
foreach (int i, clips) {
ClipPtr c = seq->clips.at(i);
ca->append(new AddMarkerAction(&c->get_markers(),
seq->playhead - c->timeline_in() + c->clip_in(),
marker_name));
}
} else {
// if no clips are selected, we're adding a marker to the sequence
// kind of hacky, we get the correct marker structure from the viewer panel object that the sequence is attached to
if (seq == panel_footage_viewer->seq.get()) {
// get correct marker reference from footage viewer
ca->append(new AddMarkerAction(panel_footage_viewer->marker_ref, seq->playhead, marker_name));
} else if (seq == panel_sequence_viewer->seq.get()) {
// get correct marker reference from sequence viewer
ca->append(new AddMarkerAction(panel_sequence_viewer->marker_ref, seq->playhead, marker_name));
} else {
// fallback to using markers from sequence provided
ca->append(new AddMarkerAction(&seq->markers, seq->playhead, marker_name));
}
// add a marker action for each clip
foreach (Clip* c, clips) {
ca->append(new AddMarkerAction(&c->get_markers(),
c->track()->sequence()->playhead - c->timeline_in() + c->clip_in(),
marker_name));
}
// push action
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
// redraw UI for new markers
update_ui(false);
@@ -120,11 +95,65 @@ void set_marker_internal(Sequence* seq, const QVector<int>& clips) {
}
}
void set_marker_internal(Sequence *seq) {
// create empty clip array
QVector<int> clips;
void Marker::SetOnSequence(Sequence *seq) {
// Don't bother if there is no sequence
if (seq == nullptr) {
return;
}
// add_marker is used to determine whether we're adding a marker, depending on whether the user input a marker name
// however if (config.set_name_with_marker) is true, we don't need a marker name so we just add
bool add_marker = !olive::config.set_name_with_marker;
QString marker_name;
// if Config::set_name_with_marker is true (set above), ask for a marker name
if (!add_marker) {
QInputDialog d(olive::MainWindow);
d.setWindowTitle(QCoreApplication::translate("Marker", "Set Marker"));
d.setLabelText(QCoreApplication::translate("Marker", "Set sequence marker name:"));
d.setInputMode(QInputDialog::TextInput);
add_marker = (d.exec() == QDialog::Accepted);
marker_name = d.textValue();
}
// if we've decided to add a marker
if (add_marker) {
ComboAction* ca = new ComboAction();
// FIXME kind of hacky, we get the correct marker structure from the viewer panel object that the sequence is
// attached to, as the viewers will give us the footage marker set if its footage rather than the sequence marker
// set
if (seq == panel_footage_viewer->seq.get()) {
// get correct marker reference from footage viewer
ca->append(new AddMarkerAction(panel_footage_viewer->marker_ref, seq->playhead, marker_name));
} else if (seq == panel_sequence_viewer->seq.get()) {
// get correct marker reference from sequence viewer
ca->append(new AddMarkerAction(panel_sequence_viewer->marker_ref, seq->playhead, marker_name));
} else {
// fallback to using markers from sequence provided
ca->append(new AddMarkerAction(&seq->markers, seq->playhead, marker_name));
}
// push action
olive::undo_stack.push(ca);
// redraw UI for new markers
update_ui(false);
panel_footage_viewer->update_viewer();
}
set_marker_internal(seq, clips);
}
void Marker::Save(QXmlStreamWriter &stream) const
+5 -4
View File
@@ -28,8 +28,8 @@
#include <QXmlStreamWriter>
#include <memory>
class Clip;
class Sequence;
using SequencePtr = std::shared_ptr<Sequence>;
struct Marker {
long frame;
@@ -37,9 +37,10 @@ struct Marker {
void Save(QXmlStreamWriter& stream) const;
static void Draw(QPainter& p, int x, int y, int bottom, bool selected);
static void SetOnClips(const QVector<Clip*>& clips);
static void SetOnSequence(Sequence* seq);
};
void set_marker_internal(Sequence *seq, const QVector<int>& clips);
void set_marker_internal(Sequence* seq);
#endif // MARKER_H
+26 -7
View File
@@ -1,12 +1,16 @@
#include "selection.h"
#include "effects/transition.h"
#include "timeline/clip.h"
Selection::Selection()
{
}
Selection::Selection(long in, long out, Track *track) :
in_(in),
out_(out),
track_(track),
old_in_(in),
old_out_(out),
old_track_(track)
track_(track)
{
}
@@ -35,7 +39,22 @@ void Selection::set_out(long out)
out_ = out;
}
void Selection::Tidy(QVector<Selection &> selections)
bool Selection::ContainsTransition(Clip* c, int type) const
{
if (type == kTransitionOpening) {
return c->opening_transition != nullptr
&& out_ == c->timeline_in() + c->opening_transition->get_true_length()
&& ((c->opening_transition->secondary_clip == nullptr && in_ == c->timeline_in())
|| (c->opening_transition->secondary_clip != nullptr && in_ == c->timeline_in() - c->opening_transition->get_true_length()));
} else {
return c->closing_transition != nullptr
&& in_ == c->timeline_out() - c->closing_transition->get_true_length()
&& ((c->closing_transition->secondary_clip == nullptr && out_ == c->timeline_out())
|| (c->closing_transition->secondary_clip != nullptr && out_ == c->timeline_out() + c->closing_transition->get_true_length()));
}
}
void Selection::Tidy(QVector<Selection>& selections)
{
for (int i=0;i<selections.size();i++) {
Selection& s = selections[i];
@@ -49,10 +68,10 @@ void Selection::Tidy(QVector<Selection &> selections)
} 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();
ss.set_out(s.out());
remove = true;
} else if (s.out() >= ss.in() && s.in() < ss.in()) {
ss.in = s.in();
ss.set_in(s.in());
remove = true;
}
if (remove) {
+5 -1
View File
@@ -23,10 +23,12 @@
#include <QVector>
class Clip;
class Track;
class Selection {
public:
Selection();
Selection(long in, long out, Track* track);
long in() const;
@@ -36,7 +38,9 @@ public:
void set_in(long in);
void set_out(long out);
static void Tidy(QVector<Selection&> selections);
bool ContainsTransition(Clip* c, int type) const;
static void Tidy(QVector<Selection> &selections);
private:
long in_;
+568 -27
View File
@@ -22,8 +22,10 @@
#include <QCoreApplication>
#include "timelinefunctions.h"
#include "panels/panels.h"
#include "project/clipboard.h"
#include "global/clipboard.h"
#include "global/config.h"
#include "global/debug.h"
Sequence::Sequence() :
@@ -77,7 +79,7 @@ void Sequence::Save(QXmlStreamWriter &stream)
stream.writeAttribute("framerate", QString::number(frame_rate, 'f', 10));
stream.writeAttribute("afreq", QString::number(audio_frequency));
stream.writeAttribute("alayout", QString::number(audio_layout));
if (this == olive::ActiveSequence.get()) {
if (this == Timeline::GetTopSequence().get()) {
stream.writeAttribute("open", "1");
}
stream.writeAttribute("workarea", QString::number(using_workarea));
@@ -170,13 +172,303 @@ QVector<Clip *> Sequence::SelectedClips(bool containing)
for (int j=0;j<tl->TrackCount();j++) {
Track* t = tl->TrackAt(j);
selected_clips.append(t->GetAllClips());
selected_clips.append(t->GetSelectedClips(containing));
}
}
return selected_clips;
}
void Sequence::AddClipsFromGhosts(ComboAction* ca, const QVector<Ghost>& ghosts)
{
// add clips
long earliest_point = LONG_MAX;
QVector<ClipPtr> added_clips;
for (int i=0;i<ghosts.size();i++) {
const Ghost& g = ghosts.at(i);
earliest_point = qMin(earliest_point, g.in);
ClipPtr c = std::make_shared<Clip>(g.track);
c->set_media(g.media, g.media_stream);
c->set_timeline_in(g.in);
c->set_timeline_out(g.out);
c->set_clip_in(g.clip_in);
c->set_track(g.track);
if (c->media()->get_type() == MEDIA_TYPE_FOOTAGE) {
Footage* m = c->media()->to_footage();
if (m->video_tracks.size() == 0) {
// audio only (greenish)
c->set_color(128, 192, 128);
} else if (m->audio_tracks.size() == 0) {
// video only (orangeish)
c->set_color(192, 160, 128);
} else {
// video and audio (blueish)
c->set_color(128, 128, 192);
}
c->set_name(m->name);
} else if (c->media()->get_type() == MEDIA_TYPE_SEQUENCE) {
// sequence (red?ish?)
c->set_color(192, 128, 128);
c->set_name(c->media()->to_sequence()->name);
}
c->refresh();
added_clips.append(c);
}
ca->append(new AddClipCommand(added_clips));
// link clips from the same media
for (int i=0;i<added_clips.size();i++) {
ClipPtr c = added_clips.at(i);
for (int j=0;j<added_clips.size();j++) {
ClipPtr cc = added_clips.at(j);
if (c != cc && c->media() == cc->media()) {
c->linked.append(cc.get());
}
}
if (olive::config.add_default_effects_to_clips) {
if (c->type() == Track::kTypeVideo) {
// add default video effects
c->effects.append(Effect::Create(c.get(), Effect::GetInternalMeta(EFFECT_INTERNAL_TRANSFORM, EFFECT_TYPE_EFFECT)));
} else if (c->type() == Track::kTypeAudio) {
// add default audio effects
c->effects.append(Effect::Create(c.get(), Effect::GetInternalMeta(EFFECT_INTERNAL_VOLUME, EFFECT_TYPE_EFFECT)));
c->effects.append(Effect::Create(c.get(), Effect::GetInternalMeta(EFFECT_INTERNAL_PAN, EFFECT_TYPE_EFFECT)));
}
}
}
if (olive::config.enable_seek_to_import) {
panel_sequence_viewer->seek(earliest_point);
}
olive::timeline::snapped = false;
}
void Sequence::MoveClip(Clip *c, ComboAction *ca, long iin, long iout, long iclip_in, Track *itrack, bool verify_transitions, bool relative)
{
ClipPtr clip_ptr = c->track()->GetClipObjectFromRawPtr(c);
ca->append(new MoveClipAction(clip_ptr, iin, iout, iclip_in, itrack, relative));
if (verify_transitions) {
// if this is a shared transition, and the corresponding clip will be moved away somehow
if (c->opening_transition != nullptr
&& c->opening_transition->secondary_clip != nullptr
&& c->opening_transition->secondary_clip->timeline_out() != iin) {
// separate transition
ca->append(new SetPointer(reinterpret_cast<void**>(&c->opening_transition->secondary_clip), nullptr));
ca->append(new AddTransitionCommand(nullptr,
c->opening_transition->secondary_clip,
c->opening_transition,
nullptr,
0));
}
if (c->closing_transition != nullptr
&& c->closing_transition->secondary_clip != nullptr
&& c->closing_transition->parent_clip->timeline_in() != iout) {
// separate transition
ca->append(new SetPointer(reinterpret_cast<void**>(&c->closing_transition->secondary_clip), nullptr));
ca->append(new AddTransitionCommand(nullptr,
c,
c->closing_transition,
nullptr,
0));
}
}
}
void Sequence::EditToPoint(bool in, bool ripple)
{
QVector<Clip*> all_clips = GetAllClips();
if (all_clips.size() > 0) {
long sequence_end = 0;
bool playhead_falls_on_in = false;
bool playhead_falls_on_out = false;
long next_cut = LONG_MAX;
long prev_cut = 0;
// find closest in point to playhead
for (int i=0;i<all_clips.size();i++) {
Clip* c = all_clips.at(i);
sequence_end = qMax(c->timeline_out(), sequence_end);
if (c->timeline_in() == playhead)
playhead_falls_on_in = true;
if (c->timeline_out() == playhead)
playhead_falls_on_out = true;
if (c->timeline_in() > playhead)
next_cut = qMin(c->timeline_in(), next_cut);
if (c->timeline_out() > playhead)
next_cut = qMin(c->timeline_out(), next_cut);
if (c->timeline_in() < playhead)
prev_cut = qMax(c->timeline_in(), prev_cut);
if (c->timeline_out() < playhead)
prev_cut = qMax(c->timeline_out(), prev_cut);
}
next_cut = qMin(sequence_end, next_cut);
QVector<Selection> areas;
ComboAction* ca = new ComboAction();
bool push_undo = true;
long seek = playhead;
if ((in && (playhead_falls_on_out || (playhead_falls_on_in && playhead == 0)))
|| (!in && (playhead_falls_on_in || (playhead_falls_on_out && playhead == sequence_end)))) { // one frame mode
if (ripple) {
// set up deletion areas based on track count
long in_point = playhead;
if (!in) {
in_point--;
seek--;
}
if (in_point >= 0) {
for (int i=0;i<track_lists_.size();i++) {
TrackList* tl = track_lists_.at(i);
for (int j=0;j<tl->TrackCount();j++) {
areas.append(Selection(in_point, in_point+1, tl->TrackAt(j)));
}
}
// trim and move clips around the in point
DeleteAreas(ca, areas, true);
if (ripple) {
Ripple(ca, in_point, -1);
}
} else {
push_undo = false;
}
} else {
push_undo = false;
}
} else {
// set up deletion areas based on track count
long area_in, area_out;
if (in) {
seek = prev_cut;
area_in = prev_cut;
area_out = playhead;
} else {
area_in = playhead;
area_out = next_cut;
}
if (area_in == area_out) {
push_undo = false;
} else {
for (int i=0;i<track_lists_.size();i++) {
TrackList* tl = track_lists_.at(i);
for (int j=0;j<tl->TrackCount();j++) {
areas.append(Selection(area_in, area_out, tl->TrackAt(j)));
}
}
// trim and move clips around the in point
DeleteAreas(ca, areas, true);
if (ripple) {
Ripple(ca, area_in, area_in - area_out);
}
}
}
if (push_undo) {
olive::undo_stack.push(ca);
update_ui(true);
if (seek != playhead && ripple) {
panel_sequence_viewer->seek(seek);
}
} else {
delete ca;
}
} else {
panel_sequence_viewer->seek(0);
}
}
bool Sequence::SnapPoint(long *l, double zoom, bool use_playhead, bool use_markers, bool use_workarea)
{
olive::timeline::snapped = false;
if (olive::timeline::snapping) {
if (use_playhead && !panel_sequence_viewer->playing) {
// snap to playhead
if (olive::timeline::SnapToPoint(playhead, l, zoom)) return true;
}
// snap to marker
if (use_markers) {
for (int i=0;i<markers.size();i++) {
if (olive::timeline::SnapToPoint(markers.at(i).frame, l, zoom)) return true;
}
}
// snap to in/out
if (use_workarea && using_workarea) {
if (olive::timeline::SnapToPoint(workarea_in, l, zoom)) return true;
if (olive::timeline::SnapToPoint(workarea_out, l, zoom)) return true;
}
// snap to clip/transition
QVector<Clip*> all_clips = GetAllClips();
for (int i=0;i<all_clips.size();i++) {
Clip* c = all_clips.at(i);
if (olive::timeline::SnapToPoint(c->timeline_in(), l, zoom)) {
return true;
} else if (olive::timeline::SnapToPoint(c->timeline_out(), l, zoom)) {
return true;
} else if (c->opening_transition != nullptr
&& olive::timeline::SnapToPoint(c->timeline_in() + c->opening_transition->get_true_length(), l, zoom)) {
return true;
} else if (c->closing_transition != nullptr
&& olive::timeline::SnapToPoint(c->timeline_out() - c->closing_transition->get_true_length(), l, zoom)) {
return true;
} else {
// try to snap to clip markers
for (int j=0;j<c->get_markers().size();j++) {
if (olive::timeline::SnapToPoint(c->get_markers().at(j).frame + c->timeline_in() - c->clip_in(), l, zoom)) {
return true;
}
}
}
}
}
return false;
}
void Sequence::DeleteInToOut(bool ripple)
{
if (using_workarea) {
@@ -198,13 +490,45 @@ void Sequence::DeleteInToOut(bool ripple)
if (ripple) Ripple(ca,
workarea_in,
workarea_in - workarea_out);
ca->append(new SetTimelineInOutCommand(olive::ActiveSequence.get(), false, 0, 0));
olive::UndoStack.push(ca);
ca->append(new SetTimelineInOutCommand(this, false, 0, 0));
olive::undo_stack.push(ca);
update_ui(true);
}
}
void Sequence::Ripple(ComboAction *ca, long point, long length, const QVector<int> &ignore)
void Sequence::DeleteClipsUsingMedia(const QVector<Media *>& media)
{
QVector<Clip*> all_clips = GetAllClips();
ComboAction* ca = new ComboAction();
bool deleted = false;
for (int j=0;j<media.size();j++) {
Media* m = media.at(j);
if (olive::clipboard.DeleteClipsWithMedia(ca, m)) {
deleted = true;
}
for (int i=0;i<all_clips.size();i++) {
Clip* c = all_clips.at(i);
if (c->media() == media.at(j)) {
ca->append(new DeleteClipAction(c));
deleted = true;
}
}
}
if (deleted) {
olive::undo_stack.push(ca);
update_ui(true);
} else {
delete ca;
}
}
void Sequence::Ripple(ComboAction *ca, long point, long length, const QVector<Clip*> &ignore)
{
ca->append(new RippleAction(this, point, length, ignore));
}
@@ -222,14 +546,95 @@ void Sequence::ChangeTrackHeightsRelatively(int diff)
}
}
void Sequence::DeleteAreas(ComboAction* ca, QVector<Selection> areas, bool deselect_areas)
void Sequence::ToggleLinksOnSelected()
{
QVector<Clip*> selected_clips = SelectedClips();
bool link = true;
QVector<Clip*> link_clips;
for (int i=0;i<selected_clips.size();i++) {
Clip* c = selected_clips.at(i);
if (!link_clips.contains(c)) {
link_clips.append(c);
}
if (c->linked.size() > 0) {
link = false; // prioritize unlinking
for (int j=0;j<c->linked.size();j++) { // add links to the command
if (!link_clips.contains(c->linked.at(j))) {
link_clips.append(c->linked.at(j));
}
}
}
}
if (!link_clips.isEmpty()) {
olive::undo_stack.push(new LinkCommand(link_clips, link));
}
}
void Sequence::Split()
{
ComboAction* ca = new ComboAction();
bool split_selected = false;
QVector<Clip*> selected_clips = SelectedClips(true);
if (selected_clips.size() > 0) {
// see if whole clips are selected
QVector<Clip*> pre_clips;
QVector<ClipPtr> post_clips;
for (int i=0;i<selected_clips.size();i++) {
Clip* c = selected_clips.at(i);
ClipPtr s = SplitClip(ca, true, c, playhead);
if (s != nullptr) {
pre_clips.append(c);
post_clips.append(s);
split_selected = true;
}
}
if (split_selected) {
// relink clips if we split
olive::timeline::RelinkClips(pre_clips, post_clips);
ca->append(new AddClipCommand(post_clips));
} else {
// split a selection if not
// FIXME reimplement split selection
//split_selected = split_selection(ca);
}
}
// if nothing was selected or no selections fell within playhead, simply split at playhead
if (!split_selected) {
split_selected = SplitAllClipsAtPoint(ca, playhead);
}
if (split_selected) {
olive::undo_stack.push(ca);
update_ui(true);
} else {
delete ca;
}
}
void Sequence::DeleteAreas(ComboAction* ca, QVector<Selection> areas, bool deselect_areas, bool ripple)
{
Selection::Tidy(areas);
panel_graph_editor->set_row(nullptr);
panel_effect_controls->Clear(true);
QVector<int> pre_clips;
QVector<Clip*> pre_clips;
QVector<ClipPtr> post_clips;
QVector<Clip*> all_clips = GetAllClips();
@@ -239,10 +644,10 @@ void Sequence::DeleteAreas(ComboAction* ca, QVector<Selection> areas, bool desel
for (int j=0;j<all_clips.size();j++) {
Clip* c = all_clips.at(j);
if (c->track() == s.track() && !c->undeletable) {
if (selection_contains_transition(s, c, kTransitionOpening)) {
if (s.ContainsTransition(c, kTransitionOpening)) {
// delete opening transition
ca->append(new DeleteTransitionCommand(c->opening_transition));
} else if (selection_contains_transition(s, c, kTransitionClosing)) {
} else if (s.ContainsTransition(c, kTransitionClosing)) {
// delete closing transition
ca->append(new DeleteTransitionCommand(c->closing_transition));
} else if (c->timeline_in() >= s.in() && c->timeline_out() <= s.out()) {
@@ -254,28 +659,30 @@ void Sequence::DeleteAreas(ComboAction* ca, QVector<Selection> areas, bool desel
// duplicate clip
ClipPtr post = SplitClip(ca, true, c, s.in(), s.out());
pre_clips.append(j);
pre_clips.append(c);
post_clips.append(post);
} else if (c->timeline_in() < s.in() && c->timeline_out() > s.in()) {
// only out point is in deletion area
c->move(ca, c->timeline_in(), s.in(), c->clip_in(), c->track());
MoveClip(c, ca, c->timeline_in(), s.in(), c->clip_in(), c->track());
if (c->closing_transition != nullptr) {
if (s.in() < c->timeline_out() - c->closing_transition->get_true_length()) {
ca->append(new DeleteTransitionCommand(c->closing_transition));
} else {
ca->append(new ModifyTransitionCommand(c->closing_transition, c->closing_transition->get_true_length() - (c->timeline_out() - s.in)));
ca->append(new ModifyTransitionCommand(c->closing_transition,
c->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
c->move(ca, s.out(), c->timeline_out(), c->clip_in() + (s.out() - c->timeline_in()), c->track());
MoveClip(c, ca, s.out(), c->timeline_out(), c->clip_in() + (s.out() - c->timeline_in()), c->track());
if (c->opening_transition != nullptr) {
if (s.out() > c->timeline_in() + c->opening_transition->get_true_length()) {
ca->append(new DeleteTransitionCommand(c->opening_transition));
} else {
ca->append(new ModifyTransitionCommand(c->opening_transition, c->opening_transition->get_true_length() - (s.out - c->timeline_in())));
ca->append(new ModifyTransitionCommand(c->opening_transition,
c->opening_transition->get_true_length() - (s.out() - c->timeline_in())));
}
}
}
@@ -288,12 +695,16 @@ void Sequence::DeleteAreas(ComboAction* ca, QVector<Selection> areas, bool desel
QVector<Selection> area_copy = areas;
for (int i=0;i<area_copy.size();i++) {
const Selection& s = area_copy.at(i);
deselect_area(s.in, s.out, s.track);
s.track()->DeselectArea(s.in(), s.out());
}
}
relink_clips_using_ids(pre_clips, post_clips);
ca->append(new AddClipCommand(olive::ActiveSequence.get(), post_clips));
if (ripple) {
}
olive::timeline::RelinkClips(pre_clips, post_clips);
ca->append(new AddClipCommand(post_clips));
}
bool Sequence::SplitAllClipsAtPoint(ComboAction *ca, long point)
@@ -314,10 +725,12 @@ bool Sequence::SplitAllClipsAtPoint(ComboAction *ca, long point)
return split;
}
void Sequence::SplitClipAtPositions(ComboAction *ca, Clip* clip, QVector<long> positions, bool relink)
bool Sequence::SplitClipAtPositions(ComboAction *ca, Clip* clip, QVector<long> positions, bool relink)
{
// Add the clip and each of its links to the pre_splits array
bool split_occurred = false;
QVector<Clip*> pre_splits;
pre_splits.append(clip);
@@ -346,15 +759,102 @@ void Sequence::SplitClipAtPositions(ComboAction *ca, Clip* clip, QVector<long> p
for (int j=0;j<pre_splits.size();j++) {
post_splits[i][j] = SplitClip(ca, true, pre_splits.at(j), positions.at(i));
if (post_splits[i][j] != nullptr && i + 1 < positions.size()) {
post_splits[i][j]->set_timeline_out(positions.at(i+1));
if (post_splits[i][j] != nullptr) {
split_occurred = true;
if (i + 1 < positions.size()) {
post_splits[i][j]->set_timeline_out(positions.at(i+1));
}
}
}
}
for (int i=0;i<post_splits.size();i++) {
olive::timeline::RelinkClips(pre_splits, post_splits[i]);
ca->append(new AddClipCommand(olive::ActiveSequence.get(), post_splits[i]));
ca->append(new AddClipCommand(post_splits[i]));
}
return split_occurred;
}
void Sequence::RippleDeleteEmptySpace(Track* track, long point)
{
QVector<Clip*> track_clips = track->GetAllClips();
long ripple_start = LONG_MAX;
long ripple_end = LONG_MAX;
for (int i=0;i<track_clips.size();i++) {
Clip* c = track_clips.at(i);
if (c->timeline_in() <= point && c->timeline_out() >= point) {
// This point is not actually empty, so there's nothing to do here
return;
}
if (c->timeline_out() < point) {
ripple_start = qMin(c->timeline_out(), ripple_start);
} else if (c->timeline_in() > point) {
ripple_end = qMin(c->timeline_in(), ripple_end);
}
}
// We now know the maximum ripple we could do to clear this empty space, but we need to ensure it won't cause
// overlaps of clips in other tracks
for (int i=0;i<track_lists_.size();i++) {
TrackList* tl = track_lists_.at(i);
for (int j=0;j<tl->TrackCount();j++) {
Track* t = tl->TrackAt(j);
// We've already tested `track`, so we don't need to test it again
if (t != track) {
long first_in_point_after_point = LONG_MAX;
long out_point_just_before_first_in_point = LONG_MIN;
QVector<Clip*> track_clips = t->GetAllClips();
// Find the in point of the clip directly after the point
for (int k=0;k<track_clips.size();k++) {
Clip* c = track_clips.at(k);
if (c->timeline_in() > point) {
first_in_point_after_point = qMin(first_in_point_after_point, c->timeline_in());
}
}
// Ensure we found a valid in point before proceeding
if (first_in_point_after_point != LONG_MAX) {
// Find the out point of the clip directly before the clip found above
for (int k=0;k<track_clips.size();k++) {
Clip* c = track_clips.at(k);
if (c->timeline_out() < first_in_point_after_point) {
out_point_just_before_first_in_point = qMax(out_point_just_before_first_in_point, c->timeline_out());
}
}
long gap_between_clips = first_in_point_after_point - out_point_just_before_first_in_point;
if (gap_between_clips > (ripple_end - ripple_start)) {
ripple_end = ripple_start + gap_between_clips;
}
}
}
}
}
if (ripple_start != ripple_end) {
ComboAction* ca = new ComboAction();
Ripple(ca, ripple_start, ripple_start - ripple_end);
olive::undo_stack.push(ca);
}
}
@@ -383,7 +883,7 @@ Effect *Sequence::GetSelectedGizmo()
for (int i=0;i<clips.size();i++) {
Clip* c = clips.at(i);
if (c->IsActiveAt(playhead)
&& IsClipSelected(c, true)) {
&& c->IsSelected()) {
// This clip is selected and currently active - we'll use this for gizmos
if (!c->effects.isEmpty()) {
@@ -516,7 +1016,7 @@ void Sequence::AddSelectionsToClipboard(bool delete_originals)
if (delete_originals) {
ComboAction* ca = new ComboAction();
DeleteAreas(ca, selections, true);
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
}
}
@@ -537,6 +1037,24 @@ QVector<Selection> Sequence::Selections()
return selections;
}
void Sequence::SetSelections(const QVector<Selection> &selections)
{
ClearSelections();
for (int i=0;i<selections.size();i++) {
const Selection& s = selections.at(i);
s.track()->SelectArea(s.in(), s.out());
}
}
void Sequence::TidySelections()
{
QVector<Selection> selections = Selections();
Selection::Tidy(selections);
SetSelections(selections);
}
ClipPtr Sequence::SplitClip(ComboAction *ca, bool transitions, Clip* pre, long frame)
{
return SplitClip(ca, transitions, pre, frame, frame);
@@ -558,7 +1076,7 @@ ClipPtr Sequence::SplitClip(ComboAction *ca, bool transitions, Clip* pre, long f
post->set_timeline_in(post_in);
post->set_clip_in(pre->clip_in() + (post->timeline_in() - pre->timeline_in()));
pre->move(ca, pre->timeline_in(), frame, pre->clip_in(), pre->track(), false);
MoveClip(pre, ca, pre->timeline_in(), frame, pre->clip_in(), pre->track(), false);
if (transitions) {
@@ -616,5 +1134,28 @@ ClipPtr Sequence::SplitClip(ComboAction *ca, bool transitions, Clip* pre, long f
return nullptr;
}
// static variable for the currently active sequence
SequencePtr olive::ActiveSequence = nullptr;
bool Sequence::SplitSelection(ComboAction *ca, QVector<Selection> selections)
{
QVector<Clip*> all_clips = GetAllClips();
for (int i=0;i<all_clips.size();i++) {
Clip* c = all_clips.at(i);
QVector<long> points;
for (int j=0;j<selections.size();j++) {
const Selection& s = selections.at(j);
if (s.track() == c->track()) {
if (c->timeline_in() < s.in() && c->timeline_out() > s.in()) {
points.append(s.in());
}
if (c->timeline_in() < s.out() && c->timeline_out() > s.out()) {
points.append(s.out());
}
}
}
}
}
+28 -9
View File
@@ -28,6 +28,7 @@
#include "marker.h"
#include "selection.h"
#include "tracklist.h"
#include "ghost.h"
class Sequence : public QObject {
Q_OBJECT
@@ -63,17 +64,37 @@ public:
void RefreshClipsUsingMedia(Media* m = nullptr);
QVector<Clip*> SelectedClips(bool containing = true);
//QVector<int> SelectedClipIndexes();
void DeleteAreas(ComboAction* ca, QVector<Selection> areas, bool deselect_areas);
void AddClipsFromGhosts(ComboAction *ca, const QVector<Ghost> &ghosts);
void MoveClip(Clip* c,
ComboAction* ca,
long iin,
long iout,
long iclip_in,
Track *itrack,
bool verify_transitions = true,
bool relative = false);
void EditToPoint(bool in, bool ripple);
bool SnapPoint(long* l, double zoom, bool use_playhead, bool use_markers, bool use_workarea);
void DeleteAreas(ComboAction* ca, QVector<Selection> areas, bool deselect_areas = false, bool ripple = false);
void DeleteInToOut(bool ripple);
void DeleteClipsUsingMedia(const QVector<Media *> &media);
void Ripple(ComboAction *ca, long point, long length, const QVector<int>& ignore = QVector<int>());
void Ripple(ComboAction *ca, long point, long length, const QVector<Clip *> &ignore = QVector<Clip*>());
void ChangeTrackHeightsRelatively(int diff);
void ToggleLinksOnSelected();
void Split();
bool SplitAllClipsAtPoint(ComboAction *ca, long point);
void SplitClipAtPositions(ComboAction* ca, Clip *clip, QVector<long> positions, bool relink = true);
bool SplitClipAtPositions(ComboAction* ca, Clip *clip, QVector<long> positions, bool relink = true);
void RippleDeleteEmptySpace(Track *track, long point);
Effect* GetSelectedGizmo();
@@ -85,6 +106,8 @@ public:
void ClearSelections();
void AddSelectionsToClipboard(bool delete_originals);
QVector<Selection> Selections();
void SetSelections(const QVector<Selection>& selections);
void TidySelections();
long playhead;
@@ -102,13 +125,9 @@ private:
ClipPtr SplitClip(ComboAction* ca, bool transitions, Clip *clip, long frame);
ClipPtr SplitClip(ComboAction* ca, bool transitions, Clip *clip, long frame, long post_in);
bool SplitSelection(ComboAction* ca, QVector<Selection> selections);
};
using SequencePtr = std::shared_ptr<Sequence>;
// static variable for the currently active sequence
namespace olive {
extern SequencePtr ActiveSequence;
}
#endif // SEQUENCE_H
+142
View File
@@ -1,6 +1,14 @@
#include "timelinefunctions.h"
#include "global/math.h"
#include "global/config.h"
#include "global/timing.h"
#include "sequence.h"
// snapping
bool olive::timeline::snapping = true;
bool olive::timeline::snapped = false;
long olive::timeline::snap_point = 0;
void olive::timeline::RelinkClips(QVector<Clip *> &pre_clips, QVector<ClipPtr> &post_clips)
{
@@ -28,3 +36,137 @@ void olive::timeline::RelinkClips(QVector<Clip *> &pre_clips, QVector<ClipPtr> &
}
}
}
bool olive::timeline::SnapToPoint(long point, long* l, double zoom) {
long limit = getFrameFromScreenPoint(zoom, 10); // FIXME magic number 10 used for on screen pixel threshold to snap to
if (*l > point-limit-1 && *l < point+limit+1) {
olive::timeline::snap_point = point;
*l = point;
olive::timeline::snapped = true;
return true;
}
return false;
}
QVector<Ghost> olive::timeline::CreateGhostsFromMedia(Sequence *seq,
long entry_point,
QVector<olive::timeline::MediaImportData> &media_list)
{
QVector<Ghost> ghosts;
for (int i=0;i<media_list.size();i++) {
bool can_import = true;
const olive::timeline::MediaImportData import_data = media_list.at(i);
Media* medium = import_data.media();
Footage* m = nullptr;
Sequence* s = nullptr;
long sequence_length = 0;
long default_clip_in = 0;
long default_clip_out = 0;
switch (medium->get_type()) {
case MEDIA_TYPE_FOOTAGE:
m = medium->to_footage();
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 * m->speed;
}
default_clip_in = rescale_frame_number(m->in, source_fr, seq->frame_rate);
default_clip_out = rescale_frame_number(m->out, source_fr, seq->frame_rate);
}
break;
case MEDIA_TYPE_SEQUENCE:
s = medium->to_sequence().get();
sequence_length = s->GetEndFrame();
if (seq != nullptr) sequence_length = rescale_frame_number(sequence_length, s->frame_rate, seq->frame_rate);
can_import = (s != seq && sequence_length != 0);
if (s->using_workarea) {
default_clip_in = rescale_frame_number(s->workarea_in, s->frame_rate, seq->frame_rate);
default_clip_out = rescale_frame_number(s->workarea_out, s->frame_rate, seq->frame_rate);
}
break;
default:
can_import = false;
}
if (can_import) {
Ghost g;
g.clip = nullptr;
g.trim_type = olive::timeline::TRIM_NONE;
g.old_clip_in = g.clip_in = default_clip_in;
g.media = medium;
g.in = entry_point;
g.transition = nullptr;
switch (medium->get_type()) {
case MEDIA_TYPE_FOOTAGE:
// is video source a still image?
if (m->video_tracks.size() > 0 && m->video_tracks.at(0).infinite_length && m->audio_tracks.size() == 0) {
g.out = g.in + 100;
} else {
long length = m->get_length_in_frames(seq->frame_rate);
g.out = entry_point + length - default_clip_in;
if (m->using_inout) {
g.out -= (length - default_clip_out);
}
}
if (import_data.type() == olive::timeline::kImportAudioOnly
|| import_data.type() == olive::timeline::kImportBoth) {
for (int j=0;j<m->audio_tracks.size();j++) {
if (m->audio_tracks.at(j).enabled) {
g.track = seq->GetTrackList(Track::kTypeAudio)->First() + j;
g.media_stream = m->audio_tracks.at(j).file_index;
ghosts.append(g);
}
}
}
if (import_data.type() == olive::timeline::kImportVideoOnly
|| import_data.type() == olive::timeline::kImportBoth) {
for (int j=0;j<m->video_tracks.size();j++) {
if (m->video_tracks.at(j).enabled) {
g.track = seq->GetTrackList(Track::kTypeVideo)->First() + j;
g.media_stream = m->video_tracks.at(j).file_index;
ghosts.append(g);
}
}
}
break;
case MEDIA_TYPE_SEQUENCE:
g.out = entry_point + sequence_length - default_clip_in;
if (s->using_workarea) {
g.out -= (sequence_length - default_clip_out);
}
if (import_data.type() == olive::timeline::kImportVideoOnly
|| import_data.type() == olive::timeline::kImportBoth) {
g.track = seq->GetTrackList(Track::kTypeVideo)->First();
ghosts.append(g);
}
if (import_data.type() == olive::timeline::kImportAudioOnly
|| import_data.type() == olive::timeline::kImportBoth) {
g.track = seq->GetTrackList(Track::kTypeAudio)->First();
ghosts.append(g);
}
break;
}
entry_point = g.out;
}
}
for (int i=0;i<ghosts.size();i++) {
Ghost& g = ghosts[i];
g.old_in = g.in;
g.old_out = g.out;
g.old_track = g.track;
}
return ghosts;
}
+11 -6
View File
@@ -4,6 +4,8 @@
#include <QVector>
#include "timeline/clip.h"
#include "timeline/mediaimportdata.h"
#include "ghost.h"
namespace olive {
namespace timeline {
@@ -17,12 +19,6 @@ enum CreateObjects {
ADD_OBJ_AUDIO
};
enum TrimType {
TRIM_NONE,
TRIM_IN,
TRIM_OUT
};
enum Alignment {
kAlignmentTop,
kAlignmentBottom,
@@ -31,6 +27,15 @@ enum Alignment {
void RelinkClips(QVector<Clip*>& pre_clips, QVector<ClipPtr> &post_clips);
bool SnapToPoint(long point, long* l, double zoom);
QVector<Ghost> CreateGhostsFromMedia(Sequence *seq, long entry_point, QVector<olive::timeline::MediaImportData> &media_list);
// snapping
extern bool snapping;
extern bool snapped;
extern long snap_point;
}
}
+3
View File
@@ -0,0 +1,3 @@
#include "timelinetools.h"
olive::timeline::Tool olive::timeline::current_tool = olive::timeline::TIMELINE_TOOL_POINTER;
@@ -21,7 +21,10 @@
#ifndef TIMELINETOOLS_H
#define TIMELINETOOLS_H
enum TimelineTool {
namespace olive {
namespace timeline {
enum Tool {
TIMELINE_TOOL_POINTER,
TIMELINE_TOOL_EDIT,
TIMELINE_TOOL_RAZOR,
@@ -36,4 +39,9 @@ enum TimelineTool {
TIMELINE_TOOL_COUNT
};
extern Tool current_tool;
}
}
#endif // TIMELINETOOLS_H
+32 -4
View File
@@ -50,12 +50,8 @@ void Track::Save(QXmlStreamWriter &stream)
for (int j=0;j<clips_.size();j++) {
Clip* c = clips_.at(j).get();
stream.writeStartElement("clip");
stream.writeAttribute("id", QString::number(c->load_id));
c->Save(stream);
stream.writeEndElement(); // clip
}
stream.writeEndElement(); // track
@@ -78,6 +74,10 @@ void Track::set_height(int h)
void Track::AddClip(ClipPtr clip)
{
if (clips_.contains(clip)) {
return;
}
clips_.append(clip);
if (clip->track() != nullptr) {
clip->track()->RemoveClip(clip.get());
@@ -85,6 +85,16 @@ void Track::AddClip(ClipPtr clip)
clip->set_track(this);
}
int Track::ClipCount()
{
return clips_.size();
}
ClipPtr Track::GetClip(int i)
{
return clips_.at(i);
}
void Track::RemoveClip(int i)
{
clips_.removeAt(i);
@@ -145,6 +155,19 @@ ClipPtr Track::GetClipObjectFromRawPtr(Clip *c)
Q_ASSERT(false);
}
Clip *Track::GetClipFromPoint(long point)
{
for (int i=0;i<clips_.size();i++) {
Clip* c = clips_.at(i).get();
if (c->timeline_in() <= point && c->timeline_out() > point) {
return c;
}
}
return nullptr;
}
int Track::Index()
{
return parent_->IndexOfTrack(this);
@@ -209,6 +232,11 @@ bool Track::IsTransitionSelected(Transition *t)
return false;
}
void Track::SelectArea(long in, long out)
{
selections_.append(Selection(in, out, this));
}
void Track::SelectClip(Clip* c)
{
selections_.append(Selection(c->timeline_in(), c->timeline_out(), this));
+2
View File
@@ -61,6 +61,7 @@ public:
QVector<Clip*> GetAllClips();
QVector<Clip*> GetSelectedClips(bool containing);
ClipPtr GetClipObjectFromRawPtr(Clip* c);
Clip* GetClipFromPoint(long point);
int Index();
@@ -71,6 +72,7 @@ public:
void DeleteArea(ComboAction *ca, const Selection& s);
void DeleteArea(ComboAction *ca, long in, long out);
void SelectArea(long in, long out);
void SelectClip(Clip *c);
void SelectAll();
void SelectAtPoint(long point);
+10
View File
@@ -82,7 +82,17 @@ QVector<Track*> TrackList::tracks()
return tracks_;
}
Track::Type TrackList::type()
{
return type_;
}
Sequence *TrackList::GetParent()
{
return static_cast<Sequence*>(parent());
}
void TrackList::ResizeTrackArray(int i)
{
tracks_.resize(i);
}
+2
View File
@@ -20,6 +20,8 @@ public:
Track* TrackAt(int i);
QVector<Track*> tracks();
Track::Type type();
Sequence* GetParent();
private:
+1 -1
View File
@@ -68,7 +68,7 @@ void AudioMonitor::resizeEvent(QResizeEvent *e) {
}
void AudioMonitor::paintEvent(QPaintEvent *) {
if (olive::ActiveSequence != nullptr && values.size() > 0) {
if (values.size() > 0) {
QPainter p(this);
int channel_x = AUDIO_MONITOR_GAP;
int channel_count = values.size();
+22 -19
View File
@@ -100,7 +100,7 @@ void FocusFilter::set_viewer_fullscreen() {
}
void FocusFilter::set_marker() {
if (olive::ActiveSequence != nullptr) {
if (Timeline::GetTopSequence() != nullptr) {
QDockWidget* focused_panel = get_focused_panel();
if (focused_panel == panel_footage_viewer) {
@@ -108,7 +108,7 @@ void FocusFilter::set_marker() {
} else if (focused_panel == panel_sequence_viewer) {
panel_sequence_viewer->set_marker();
} else {
panel_timeline->set_marker();
panel_timeline.first()->set_marker();
}
}
}
@@ -190,28 +190,31 @@ void FocusFilter::clear_inout() {
}
void FocusFilter::delete_function() {
if (panel_timeline->headers->hasFocus()) {
panel_timeline->headers->delete_markers();
if (panel_timeline.first()->headers->hasFocus()) {
panel_timeline.first()->headers->delete_markers();
} else if (panel_footage_viewer->headers->hasFocus()) {
panel_footage_viewer->headers->delete_markers();
} else if (panel_sequence_viewer->headers->hasFocus()) {
panel_sequence_viewer->headers->delete_markers();
} else if (panel_effect_controls->is_focused()) {
} else if (panel_effect_controls->focused()) {
panel_effect_controls->DeleteSelectedEffects();
} else if (panel_project->is_focused()) {
panel_project->delete_selected_media();
} else if (panel_effect_controls->keyframe_focus()) {
} else if (panel_project.first()->focused()) {
panel_project.first()->delete_selected_media();
} else if (panel_effect_controls->focused()) {
panel_effect_controls->delete_selected_keyframes();
} else if (panel_graph_editor->view_is_focused()) {
} else if (panel_graph_editor->focused()) {
panel_graph_editor->delete_selected_keys();
} else {
panel_timeline->delete_selection(olive::ActiveSequence->selections, false);
Sequence* top_sequence = Timeline::GetTopSequence().get();
ComboAction* ca = new ComboAction();
top_sequence->DeleteAreas(ca, top_sequence->Selections(), true);
olive::undo_stack.push(ca);
}
}
void FocusFilter::duplicate() {
if (panel_project->is_focused()) {
panel_project->duplicate_selected();
if (panel_project.first()->focused()) {
panel_project.first()->duplicate_selected();
}
}
@@ -220,7 +223,7 @@ void FocusFilter::select_all() {
if (focused_panel == panel_graph_editor) {
panel_graph_editor->select_all();
} else {
panel_timeline->select_all();
panel_timeline.first()->select_all();
}
}
@@ -233,7 +236,7 @@ void FocusFilter::zoom_in() {
} else if (focused_panel == panel_sequence_viewer) {
panel_sequence_viewer->set_zoom(true);
} else {
panel_timeline->zoom_in();
panel_timeline.first()->zoom_in();
}
}
@@ -246,28 +249,28 @@ void FocusFilter::zoom_out() {
} else if (focused_panel == panel_sequence_viewer) {
panel_sequence_viewer->set_zoom(false);
} else {
panel_timeline->zoom_out();
panel_timeline.first()->zoom_out();
}
}
void FocusFilter::cut() {
if (olive::ActiveSequence != nullptr) {
if (Timeline::GetTopSequence() != nullptr) {
QDockWidget* focused_panel = get_focused_panel();
if (panel_effect_controls == focused_panel) {
panel_effect_controls->copy(true);
} else {
panel_timeline->copy(true);
panel_timeline.first()->copy(true);
}
}
}
void FocusFilter::copy() {
if (olive::ActiveSequence != nullptr) {
if (Timeline::GetTopSequence() != nullptr) {
QDockWidget* focused_panel = get_focused_panel();
if (panel_effect_controls == focused_panel) {
panel_effect_controls->copy(false);
} else {
panel_timeline->copy(false);
panel_timeline.first()->copy(false);
}
}
}
+5 -5
View File
@@ -470,7 +470,7 @@ void GraphView::mousePressEvent(QMouseEvent *event) {
void GraphView::mouseMoveEvent(QMouseEvent *event) {
if (!mousedown || !click_add) unsetCursor();
if (mousedown) {
if (event->buttons() & Qt::MiddleButton || panel_timeline->tool == TIMELINE_TOOL_HAND) {
if (event->buttons() & Qt::MiddleButton || olive::timeline::current_tool == olive::timeline::TIMELINE_TOOL_HAND) {
set_scroll_x(x_scroll + start_x - event->pos().x());
set_scroll_y(y_scroll + event->pos().y() - start_y);
start_x = event->pos().x();
@@ -701,7 +701,7 @@ void GraphView::mouseMoveEvent(QMouseEvent *event) {
void GraphView::mouseReleaseEvent(QMouseEvent *) {
if (click_add_proc) {
olive::UndoStack.push(new KeyframeAdd(click_add_field, click_add_key));
olive::undo_stack.push(new KeyframeAdd(click_add_field, click_add_key));
} else if (moved_keys && selected_keys.size() > 0) {
ComboAction* ca = new ComboAction();
switch (current_handle) {
@@ -723,7 +723,7 @@ void GraphView::mouseReleaseEvent(QMouseEvent *) {
}
break;
}
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
}
moved_keys = false;
mousedown = false;
@@ -757,7 +757,7 @@ void GraphView::wheelEvent(QWheelEvent *event) {
double new_x_zoom = x_zoom;
double new_y_zoom = y_zoom;
if (ctrl != olive::CurrentConfig.scroll_zooms) {
if (ctrl != olive::config.scroll_zooms) {
zooming = true;
}
@@ -849,7 +849,7 @@ void GraphView::set_selected_keyframe_type(int type) {
EffectKeyframe& key = row->Field(selected_keys_fields.at(i))->keyframes[selected_keys.at(i)];
ca->append(new SetInt(&key.type, type));
}
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
update_ui(false);
}
}
+14 -12
View File
@@ -42,6 +42,7 @@
#include "effects/keyframe.h"
#include "ui/graphview.h"
#include "ui/menu.h"
#include "global/math.h"
KeyframeView::KeyframeView(QWidget *parent) :
QWidget(parent),
@@ -95,7 +96,7 @@ void KeyframeView::menu_set_key_type(QAction* a) {
EffectField* f = selected_fields.at(i);
ca->append(new SetInt(&f->keyframes[selected_keyframes.at(i)].type, a->data().toInt()));
}
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
update_ui(false);
}
}
@@ -172,8 +173,9 @@ void KeyframeView::paintEvent(QPaintEvent*) {
panel_effect_controls->horizontalScrollBar->setMaximum(qMax(max_width - width(), 0));
header->set_visible_in(visible_in);
int playhead_x = getScreenPointFromFrame(panel_effect_controls->zoom, olive::ActiveSequence->playhead-visible_in) - x_scroll;
if (dragging && panel_timeline->snapped) {
int playhead_x = getScreenPointFromFrame(panel_effect_controls->zoom,
open_effects_.first()->GetEffect()->parent_clip->track()->sequence()->playhead-visible_in) - x_scroll;
if (dragging && olive::timeline::snapped) {
p.setPen(Qt::white);
} else {
p.setPen(Qt::red);
@@ -234,7 +236,7 @@ void KeyframeView::mousePressEvent(QMouseEvent *event) {
rect_select_w = 0;
rect_select_h = 0;
if (panel_timeline->tool == TIMELINE_TOOL_HAND || event->buttons() & Qt::MiddleButton) {
if (olive::timeline::current_tool == olive::timeline::TIMELINE_TOOL_HAND || event->buttons() & Qt::MiddleButton) {
scroll_drag = true;
return;
}
@@ -323,7 +325,7 @@ void KeyframeView::mousePressEvent(QMouseEvent *event) {
}
void KeyframeView::mouseMoveEvent(QMouseEvent* event) {
if (panel_timeline->tool == TIMELINE_TOOL_HAND) {
if (olive::timeline::current_tool == olive::timeline::TIMELINE_TOOL_HAND) {
setCursor(Qt::OpenHandCursor);
} else {
unsetCursor();
@@ -376,14 +378,14 @@ void KeyframeView::mouseMoveEvent(QMouseEvent* event) {
long frame_diff = current_frame - drag_frame_start;
// snapping to playhead
panel_timeline->snapped = false;
if (panel_timeline->snapping) {
olive::timeline::snapped = false;
if (olive::timeline::snapping) {
for (int i=0;i<selected_keyframes.size();i++) {
EffectField* field = selected_fields.at(i);
Clip* c = field->GetParentRow()->GetParentEffect()->parent_clip;
long key_time = old_key_vals.at(i) + frame_diff - c->clip_in() + c->timeline_in();
long key_eval = key_time;
if (panel_timeline->snap_to_point(olive::ActiveSequence->playhead, &key_eval)) {
if (olive::timeline::SnapToPoint(c->track()->sequence()->playhead, &key_eval, header->get_zoom())) {
frame_diff += (key_eval - key_time);
break;
}
@@ -398,10 +400,10 @@ void KeyframeView::mouseMoveEvent(QMouseEvent* event) {
while (!keyframeIsSelected(field, j) && field->keyframes.at(j).time == eval_key + frame_diff) {
if (last_frame_diff > frame_diff) {
frame_diff++;
panel_timeline->snapped = false;
olive::timeline::snapped = false;
} else {
frame_diff--;
panel_timeline->snapped = false;
olive::timeline::snapped = false;
}
}
}
@@ -432,13 +434,13 @@ void KeyframeView::mouseReleaseEvent(QMouseEvent*) {
selected_fields.at(i)->keyframes.at(selected_keyframes.at(i)).time
));
}
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
}
select_rect = false;
dragging = false;
mousedown = false;
scroll_drag = false;
panel_timeline->snapped = false;
olive::timeline::snapped = false;
update_ui(false);
}
+2 -2
View File
@@ -94,7 +94,7 @@ QString LabelSlider::ValueToString() {
} else {
switch (display_type) {
case FrameNumber:
return frame_to_timecode(long(v), olive::CurrentConfig.timecode_view, frame_rate);
return frame_to_timecode(long(v), olive::config.timecode_view, frame_rate);
case Percent:
return QString::number((v*100), 'f', decimal_places).append("%");
case Decibel:
@@ -311,7 +311,7 @@ void LabelSlider::ShowDialog()
if (s.isEmpty()) return;
// parse string timecode to a frame number
d = timecode_to_frame(s, olive::CurrentConfig.timecode_view, frame_rate);
d = timecode_to_frame(s, olive::config.timecode_view, frame_rate);
} else {
+58 -69
View File
@@ -152,27 +152,27 @@ void MainWindow::setup_layout(bool reset) {
tabifyDockWidget(panel_footage_viewer, panel_effect_controls);
panel_footage_viewer->raise();
addDockWidget(Qt::TopDockWidgetArea, panel_sequence_viewer);
addDockWidget(Qt::BottomDockWidgetArea, panel_timeline);
addDockWidget(Qt::BottomDockWidgetArea, panel_timeline.first());
panel_project.first()->show();
panel_effect_controls->show();
panel_footage_viewer->show();
panel_sequence_viewer->show();
panel_timeline->show();
panel_timeline.first()->show();
panel_graph_editor->hide();
panel_project.first()->setFloating(false);
panel_effect_controls->setFloating(false);
panel_footage_viewer->setFloating(false);
panel_sequence_viewer->setFloating(false);
panel_timeline->setFloating(false);
panel_timeline.first()->setFloating(false);
panel_graph_editor->setFloating(true);
resizeDocks({panel_project.first(), panel_footage_viewer, panel_sequence_viewer},
{width()/3, width()/3, width()/3},
Qt::Horizontal);
resizeDocks({panel_project.first(), panel_timeline},
resizeDocks({panel_project.first(), panel_timeline.first()},
{height()/2, height()/2},
Qt::Vertical);
}
@@ -251,7 +251,7 @@ MainWindow::MainWindow(QWidget *parent) :
config_dir.mkpath(".");
QString config_fn = config_dir.filePath("config.xml");
if (QFileInfo::exists(config_fn)) {
olive::CurrentConfig.load(config_fn);
olive::config.load(config_fn);
}
}
@@ -260,9 +260,9 @@ MainWindow::MainWindow(QWidget *parent) :
olive::icon::Initialize();
// Load OpenColorIO configuration if set
if (olive::CurrentConfig.enable_color_management && !olive::CurrentConfig.ocio_config_path.isEmpty()) {
if (olive::config.enable_color_management && !olive::config.ocio_config_path.isEmpty()) {
try {
OCIO::SetCurrentConfig(OCIO::Config::CreateFromFile(olive::CurrentConfig.ocio_config_path.toUtf8()));
OCIO::SetCurrentConfig(OCIO::Config::CreateFromFile(olive::config.ocio_config_path.toUtf8()));
} catch (OCIO::Exception& e) {
QMessageBox::critical(this,
tr("OpenColorIO Config Error"),
@@ -397,8 +397,8 @@ void MainWindow::Restyle()
qApp->setStyle(QStyleFactory::create("Fusion"));
// Set up whether to load custom CSS or default CSS+palette
if (!olive::CurrentConfig.css_path.isEmpty()
&& load_css_from_file(olive::CurrentConfig.css_path)) {
if (!olive::config.css_path.isEmpty()
&& load_css_from_file(olive::config.css_path)) {
qApp->setPalette(qApp->style()->standardPalette());
@@ -407,7 +407,7 @@ void MainWindow::Restyle()
// set default palette
QPalette palette;
if (olive::CurrentConfig.style == olive::styling::kOliveDefaultLight) {
if (olive::config.style == olive::styling::kOliveDefaultLight) {
palette.setColor(QPalette::Window, QColor(208, 208, 208));
palette.setColor(QPalette::WindowText, Qt::black);
@@ -480,14 +480,14 @@ void MainWindow::Restyle()
}
void MainWindow::editMenu_About_To_Be_Shown() {
undo_action->setEnabled(olive::UndoStack.canUndo());
redo_action->setEnabled(olive::UndoStack.canRedo());
undo_action->setEnabled(olive::undo_stack.canUndo());
redo_action->setEnabled(olive::undo_stack.canRedo());
}
void MainWindow::setup_menus() {
QMenuBar* menuBar = new QMenuBar(this);
if (olive::CurrentConfig.use_native_menu_styling) {
if (olive::config.use_native_menu_styling) {
OliveGlobal::SetNativeStyling(menuBar);
}
@@ -538,7 +538,7 @@ void MainWindow::setup_menus() {
edit_menu->addSeparator();
select_all_action = MenuHelper::create_menu_action(edit_menu, "selectall", &olive::FocusFilter, SLOT(select_all()), QKeySequence("Ctrl+A"));
deselect_all_action = MenuHelper::create_menu_action(edit_menu, "deselectall", panel_timeline, SLOT(deselect()), QKeySequence("Ctrl+Shift+A"));
deselect_all_action = MenuHelper::create_menu_action(edit_menu, "deselectall", panel_timeline.first(), SLOT(deselect()), QKeySequence("Ctrl+Shift+A"));
edit_menu->addSeparator();
@@ -546,16 +546,16 @@ void MainWindow::setup_menus() {
edit_menu->addSeparator();
ripple_to_in_point_ = MenuHelper::create_menu_action(edit_menu, "rippletoin", panel_timeline, SLOT(ripple_to_in_point()), QKeySequence("Q"));
ripple_to_out_point_ = MenuHelper::create_menu_action(edit_menu, "rippletoout", panel_timeline, SLOT(ripple_to_out_point()), QKeySequence("W"));
edit_to_in_point_ = MenuHelper::create_menu_action(edit_menu, "edittoin", panel_timeline, SLOT(edit_to_in_point()), QKeySequence("Ctrl+Alt+Q"));
edit_to_out_point_ = MenuHelper::create_menu_action(edit_menu, "edittoout", panel_timeline, SLOT(edit_to_out_point()), QKeySequence("Ctrl+Alt+W"));
ripple_to_in_point_ = MenuHelper::create_menu_action(edit_menu, "rippletoin", panel_timeline.first(), SLOT(ripple_to_in_point()), QKeySequence("Q"));
ripple_to_out_point_ = MenuHelper::create_menu_action(edit_menu, "rippletoout", panel_timeline.first(), SLOT(ripple_to_out_point()), QKeySequence("W"));
edit_to_in_point_ = MenuHelper::create_menu_action(edit_menu, "edittoin", panel_timeline.first(), SLOT(edit_to_in_point()), QKeySequence("Ctrl+Alt+Q"));
edit_to_out_point_ = MenuHelper::create_menu_action(edit_menu, "edittoout", panel_timeline.first(), SLOT(edit_to_out_point()), QKeySequence("Ctrl+Alt+W"));
edit_menu->addSeparator();
olive::MenuHelper.make_inout_menu(edit_menu);
delete_inout_point_ = MenuHelper::create_menu_action(edit_menu, "deleteinout", panel_timeline, SLOT(delete_inout()), QKeySequence(";"));
ripple_delete_inout_point_ = MenuHelper::create_menu_action(edit_menu, "rippledeleteinout", panel_timeline, SLOT(ripple_delete_inout()), QKeySequence("'"));
delete_inout_point_ = MenuHelper::create_menu_action(edit_menu, "deleteinout", panel_timeline.first(), SLOT(delete_inout()), QKeySequence(";"));
ripple_delete_inout_point_ = MenuHelper::create_menu_action(edit_menu, "rippledeleteinout", panel_timeline.first(), SLOT(ripple_delete_inout()), QKeySequence("'"));
edit_menu->addSeparator();
@@ -567,21 +567,17 @@ void MainWindow::setup_menus() {
zoom_in_ = MenuHelper::create_menu_action(view_menu, "zoomin", &olive::FocusFilter, SLOT(zoom_in()), QKeySequence("="));
zoom_out_ = MenuHelper::create_menu_action(view_menu, "zoomout", &olive::FocusFilter, SLOT(zoom_out()), QKeySequence("-"));
increase_track_height_ = MenuHelper::create_menu_action(view_menu, "vzoomin", panel_timeline, SLOT(IncreaseTrackHeight()), QKeySequence("Ctrl+="));
decrease_track_height_ = MenuHelper::create_menu_action(view_menu, "vzoomout", panel_timeline, SLOT(DecreaseTrackHeight()), QKeySequence("Ctrl+-"));
increase_track_height_ = MenuHelper::create_menu_action(view_menu, "vzoomin", panel_timeline.first(), SLOT(IncreaseTrackHeight()), QKeySequence("Ctrl+="));
decrease_track_height_ = MenuHelper::create_menu_action(view_menu, "vzoomout", panel_timeline.first(), SLOT(DecreaseTrackHeight()), QKeySequence("Ctrl+-"));
show_all = MenuHelper::create_menu_action(view_menu, "showall", panel_timeline, SLOT(toggle_show_all()), QKeySequence("\\"));
show_all = MenuHelper::create_menu_action(view_menu, "showall", panel_timeline.first(), SLOT(toggle_show_all()), QKeySequence("\\"));
show_all->setCheckable(true);
view_menu->addSeparator();
track_lines = MenuHelper::create_menu_action(view_menu, "tracklines", &olive::MenuHelper, SLOT(toggle_bool_action()));
track_lines->setCheckable(true);
track_lines->setData(reinterpret_cast<quintptr>(&olive::CurrentConfig.show_track_lines));
rectified_waveforms = MenuHelper::create_menu_action(view_menu, "rectifiedwaveforms", &olive::MenuHelper, SLOT(toggle_bool_action()));
rectified_waveforms->setCheckable(true);
rectified_waveforms->setData(reinterpret_cast<quintptr>(&olive::CurrentConfig.rectified_waveforms));
rectified_waveforms->setData(reinterpret_cast<quintptr>(&olive::config.rectified_waveforms));
view_menu->addSeparator();
@@ -658,8 +654,8 @@ void MainWindow::setup_menus() {
playback_menu->addSeparator();
go_to_prev_cut_ = MenuHelper::create_menu_action(playback_menu, "prevcut", panel_timeline, SLOT(previous_cut()), QKeySequence("Up"));
go_to_next_cut_ = MenuHelper::create_menu_action(playback_menu, "nextcut", panel_timeline, SLOT(next_cut()), QKeySequence("Down"));
go_to_prev_cut_ = MenuHelper::create_menu_action(playback_menu, "prevcut", panel_project.first(), SLOT(previous_cut()), QKeySequence("Up"));
go_to_next_cut_ = MenuHelper::create_menu_action(playback_menu, "nextcut", panel_project.first(), SLOT(next_cut()), QKeySequence("Down"));
playback_menu->addSeparator();
@@ -676,7 +672,7 @@ void MainWindow::setup_menus() {
loop_action_ = MenuHelper::create_menu_action(playback_menu, "loop", &olive::MenuHelper, SLOT(toggle_bool_action()));
loop_action_->setCheckable(true);
loop_action_->setData(reinterpret_cast<quintptr>(&olive::CurrentConfig.loop));
loop_action_->setData(reinterpret_cast<quintptr>(&olive::config.loop));
// INITIALIZE WINDOW MENU
@@ -692,7 +688,7 @@ void MainWindow::setup_menus() {
window_timeline_action = MenuHelper::create_menu_action(window_menu, "paneltimeline", this, SLOT(toggle_panel_visibility()));
window_timeline_action->setCheckable(true);
window_timeline_action->setData(reinterpret_cast<quintptr>(panel_timeline));
window_timeline_action->setData(reinterpret_cast<quintptr>(panel_timeline.first()));
window_graph_editor_action = MenuHelper::create_menu_action(window_menu, "panelgrapheditor", this, SLOT(toggle_panel_visibility()));
window_graph_editor_action->setCheckable(true);
@@ -726,49 +722,49 @@ void MainWindow::setup_menus() {
pointer_tool_action = MenuHelper::create_menu_action(tools_menu, "pointertool", &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("V"));
pointer_tool_action->setCheckable(true);
pointer_tool_action->setData(reinterpret_cast<quintptr>(panel_timeline->toolArrowButton));
pointer_tool_action->setData(reinterpret_cast<quintptr>(panel_timeline.first()->toolArrowButton));
tools_group->addAction(pointer_tool_action);
edit_tool_action = MenuHelper::create_menu_action(tools_menu, "edittool", &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("X"));
edit_tool_action->setCheckable(true);
edit_tool_action->setData(reinterpret_cast<quintptr>(panel_timeline->toolEditButton));
edit_tool_action->setData(reinterpret_cast<quintptr>(panel_timeline.first()->toolEditButton));
tools_group->addAction(edit_tool_action);
ripple_tool_action = MenuHelper::create_menu_action(tools_menu, "rippletool", &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("B"));
ripple_tool_action->setCheckable(true);
ripple_tool_action->setData(reinterpret_cast<quintptr>(panel_timeline->toolRippleButton));
ripple_tool_action->setData(reinterpret_cast<quintptr>(panel_timeline.first()->toolRippleButton));
tools_group->addAction(ripple_tool_action);
razor_tool_action = MenuHelper::create_menu_action(tools_menu, "razortool", &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("C"));
razor_tool_action->setCheckable(true);
razor_tool_action->setData(reinterpret_cast<quintptr>(panel_timeline->toolRazorButton));
razor_tool_action->setData(reinterpret_cast<quintptr>(panel_timeline.first()->toolRazorButton));
tools_group->addAction(razor_tool_action);
slip_tool_action = MenuHelper::create_menu_action(tools_menu, "sliptool", &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("Y"));
slip_tool_action->setCheckable(true);
slip_tool_action->setData(reinterpret_cast<quintptr>(panel_timeline->toolSlipButton));
slip_tool_action->setData(reinterpret_cast<quintptr>(panel_timeline.first()->toolSlipButton));
tools_group->addAction(slip_tool_action);
slide_tool_action = MenuHelper::create_menu_action(tools_menu, "slidetool", &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("U"));
slide_tool_action->setCheckable(true);
slide_tool_action->setData(reinterpret_cast<quintptr>(panel_timeline->toolSlideButton));
slide_tool_action->setData(reinterpret_cast<quintptr>(panel_timeline.first()->toolSlideButton));
tools_group->addAction(slide_tool_action);
hand_tool_action = MenuHelper::create_menu_action(tools_menu, "handtool", &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("H"));
hand_tool_action->setCheckable(true);
hand_tool_action->setData(reinterpret_cast<quintptr>(panel_timeline->toolHandButton));
hand_tool_action->setData(reinterpret_cast<quintptr>(panel_timeline.first()->toolHandButton));
tools_group->addAction(hand_tool_action);
transition_tool_action = MenuHelper::create_menu_action(tools_menu, "transitiontool", &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("T"));
transition_tool_action->setCheckable(true);
transition_tool_action->setData(reinterpret_cast<quintptr>(panel_timeline->toolTransitionButton));
transition_tool_action->setData(reinterpret_cast<quintptr>(panel_timeline.first()->toolTransitionButton));
tools_group->addAction(transition_tool_action);
tools_menu->addSeparator();
snap_toggle = MenuHelper::create_menu_action(tools_menu, "snapping", &olive::MenuHelper, SLOT(menu_click_button()), QKeySequence("S"));
snap_toggle->setCheckable(true);
snap_toggle->setData(reinterpret_cast<quintptr>(panel_timeline->snappingButton));
snap_toggle->setData(reinterpret_cast<quintptr>(panel_timeline.first()->snappingButton));
tools_menu->addSeparator();
@@ -850,7 +846,6 @@ void MainWindow::Retranslate()
increase_track_height_->setText(tr("Increase Track Height"));
decrease_track_height_->setText(tr("Decrease Track Height"));
show_all->setText(tr("Toggle Show All"));
track_lines->setText(tr("Track Lines"));
rectified_waveforms->setText(tr("Rectified Waveforms"));
frames_action->setText(tr("Frames"));
drop_frame_action->setText(tr("Drop Frame"));
@@ -955,14 +950,10 @@ void MainWindow::closeEvent(QCloseEvent *e) {
panel_graph_editor->set_row(nullptr);
panel_effect_controls->Clear(true);
olive::Global->set_sequence(nullptr);
panel_footage_viewer->viewer_widget()->close_window();
panel_sequence_viewer->viewer_widget()->close_window();
panel_footage_viewer->set_main_sequence();
olive::UndoStack.clear();
olive::undo_stack.clear();
QString data_dir = get_data_path();
QString config_path = get_config_path();
@@ -980,7 +971,7 @@ void MainWindow::closeEvent(QCloseEvent *e) {
QString config_fn = config_dir.filePath("config.xml");
// save settings
olive::CurrentConfig.save(config_fn);
olive::config.save(config_fn);
// save panel layout
QFile panel_config(get_config_dir().filePath("layout"));
@@ -1123,32 +1114,30 @@ void MainWindow::playbackMenu_About_To_Be_Shown() {
}
void MainWindow::viewMenu_About_To_Be_Shown() {
olive::MenuHelper.set_bool_action_checked(track_lines);
olive::MenuHelper.set_bool_action_checked(rectified_waveforms);
olive::MenuHelper.set_int_action_checked(frames_action, olive::CurrentConfig.timecode_view);
olive::MenuHelper.set_int_action_checked(drop_frame_action, olive::CurrentConfig.timecode_view);
olive::MenuHelper.set_int_action_checked(nondrop_frame_action, olive::CurrentConfig.timecode_view);
olive::MenuHelper.set_int_action_checked(milliseconds_action, olive::CurrentConfig.timecode_view);
olive::MenuHelper.set_int_action_checked(frames_action, olive::config.timecode_view);
olive::MenuHelper.set_int_action_checked(drop_frame_action, olive::config.timecode_view);
olive::MenuHelper.set_int_action_checked(nondrop_frame_action, olive::config.timecode_view);
olive::MenuHelper.set_int_action_checked(milliseconds_action, olive::config.timecode_view);
title_safe_off->setChecked(!olive::CurrentConfig.show_title_safe_area);
title_safe_default->setChecked(olive::CurrentConfig.show_title_safe_area
&& !olive::CurrentConfig.use_custom_title_safe_ratio);
title_safe_43->setChecked(olive::CurrentConfig.show_title_safe_area
&& olive::CurrentConfig.use_custom_title_safe_ratio
&& qFuzzyCompare(olive::CurrentConfig.custom_title_safe_ratio, title_safe_43->data().toDouble()));
title_safe_169->setChecked(olive::CurrentConfig.show_title_safe_area
&& olive::CurrentConfig.use_custom_title_safe_ratio
&& qFuzzyCompare(olive::CurrentConfig.custom_title_safe_ratio, title_safe_169->data().toDouble()));
title_safe_custom->setChecked(olive::CurrentConfig.show_title_safe_area
&& olive::CurrentConfig.use_custom_title_safe_ratio
title_safe_off->setChecked(!olive::config.show_title_safe_area);
title_safe_default->setChecked(olive::config.show_title_safe_area
&& !olive::config.use_custom_title_safe_ratio);
title_safe_43->setChecked(olive::config.show_title_safe_area
&& olive::config.use_custom_title_safe_ratio
&& qFuzzyCompare(olive::config.custom_title_safe_ratio, title_safe_43->data().toDouble()));
title_safe_169->setChecked(olive::config.show_title_safe_area
&& olive::config.use_custom_title_safe_ratio
&& qFuzzyCompare(olive::config.custom_title_safe_ratio, title_safe_169->data().toDouble()));
title_safe_custom->setChecked(olive::config.show_title_safe_area
&& olive::config.use_custom_title_safe_ratio
&& !title_safe_43->isChecked()
&& !title_safe_169->isChecked());
full_screen->setChecked(windowState() == Qt::WindowFullScreen);
show_all->setChecked(panel_timeline->showing_all);
show_all->setChecked(panel_timeline.first()->showing_all);
}
void MainWindow::toolMenu_About_To_Be_Shown() {
@@ -1162,9 +1151,9 @@ void MainWindow::toolMenu_About_To_Be_Shown() {
olive::MenuHelper.set_button_action_checked(transition_tool_action);
olive::MenuHelper.set_button_action_checked(snap_toggle);
olive::MenuHelper.set_int_action_checked(no_autoscroll, olive::CurrentConfig.autoscroll);
olive::MenuHelper.set_int_action_checked(page_autoscroll, olive::CurrentConfig.autoscroll);
olive::MenuHelper.set_int_action_checked(smooth_autoscroll, olive::CurrentConfig.autoscroll);
olive::MenuHelper.set_int_action_checked(no_autoscroll, olive::config.autoscroll);
olive::MenuHelper.set_int_action_checked(page_autoscroll, olive::config.autoscroll);
olive::MenuHelper.set_int_action_checked(smooth_autoscroll, olive::config.autoscroll);
}
void MainWindow::toggle_panel_visibility() {
-1
View File
@@ -263,7 +263,6 @@ private:
QAction* zoom_out_;
QAction* increase_track_height_;
QAction* decrease_track_height_;
QAction* track_lines;
QAction* frames_action;
QAction* drop_frame_action;
QAction* nondrop_frame_action;
+2 -2
View File
@@ -26,7 +26,7 @@
Menu::Menu(QWidget *parent) :
QMenu(parent)
{
if (olive::CurrentConfig.use_native_menu_styling) {
if (olive::config.use_native_menu_styling) {
OliveGlobal::SetNativeStyling(this);
}
}
@@ -34,7 +34,7 @@ Menu::Menu(QWidget *parent) :
Menu::Menu(const QString &title, QWidget *parent) :
QMenu(title, parent)
{
if (olive::CurrentConfig.use_native_menu_styling) {
if (olive::config.use_native_menu_styling) {
OliveGlobal::SetNativeStyling(this);
}
}
+19 -19
View File
@@ -26,7 +26,7 @@
#include <QStyleFactory>
#include "global/config.h"
#include "project/clipboard.h"
#include "global/clipboard.h"
#include "ui/mainwindow.h"
#include "global/global.h"
#include "panels/panels.h"
@@ -39,10 +39,10 @@ void MenuHelper::InitializeSharedMenus()
new_project_ = create_menu_action(nullptr, "newproj", olive::Global.get(), SLOT(new_project()), QKeySequence("Ctrl+N"));
new_project_->setParent(this);
new_sequence_ = create_menu_action(nullptr, "newseq", panel_project, SLOT(new_sequence()), QKeySequence("Ctrl+Shift+N"));
new_sequence_ = create_menu_action(nullptr, "newseq", olive::Global.get(), SLOT(open_new_sequence_dialog()), QKeySequence("Ctrl+Shift+N"));
new_sequence_->setParent(this);
new_folder_ = create_menu_action(nullptr, "newfolder", panel_project, SLOT(new_folder()));
new_folder_ = create_menu_action(nullptr, "newfolder", panel_project.first(), SLOT(new_folder()));
new_folder_->setParent(this);
set_in_point_ = create_menu_action(nullptr, "setinpoint", &olive::FocusFilter, SLOT(set_in_point()), QKeySequence("I"));
@@ -60,16 +60,16 @@ void MenuHelper::InitializeSharedMenus()
clear_inout_point = create_menu_action(nullptr, "clearinout", &olive::FocusFilter, SLOT(clear_inout()), QKeySequence("G"));
clear_inout_point->setParent(this);
add_default_transition_ = create_menu_action(nullptr, "deftransition", panel_timeline, SLOT(add_transition()), QKeySequence("Ctrl+Shift+D"));
add_default_transition_ = create_menu_action(nullptr, "deftransition", panel_timeline.first(), SLOT(add_transition()), QKeySequence("Ctrl+Shift+D"));
add_default_transition_->setParent(this);
link_unlink_ = create_menu_action(nullptr, "linkunlink", panel_timeline, SLOT(toggle_links()), QKeySequence("Ctrl+L"));
link_unlink_ = create_menu_action(nullptr, "linkunlink", panel_timeline.first(), SLOT(toggle_links()), QKeySequence("Ctrl+L"));
link_unlink_->setParent(this);
enable_disable_ = create_menu_action(nullptr, "enabledisable", panel_timeline, SLOT(toggle_enable_on_selected_clips()), QKeySequence("Shift+E"));
enable_disable_ = create_menu_action(nullptr, "enabledisable", panel_timeline.first(), SLOT(toggle_enable_on_selected_clips()), QKeySequence("Shift+E"));
enable_disable_->setParent(this);
nest_ = create_menu_action(nullptr, "nest", panel_timeline, SLOT(nest()));
nest_ = create_menu_action(nullptr, "nest", panel_timeline.first(), SLOT(nest()));
nest_->setParent(this);
cut_ = create_menu_action(nullptr, "cut", &olive::FocusFilter, SLOT(cut()), QKeySequence("Ctrl+X"));
@@ -90,10 +90,10 @@ void MenuHelper::InitializeSharedMenus()
delete_ = create_menu_action(nullptr, "delete", &olive::FocusFilter, SLOT(delete_function()), QKeySequence("Del"));
delete_->setParent(this);
ripple_delete_ = create_menu_action(nullptr, "rippledelete", panel_timeline, SLOT(ripple_delete()), QKeySequence("Shift+Del"));
ripple_delete_ = create_menu_action(nullptr, "rippledelete", panel_timeline.first(), SLOT(ripple_delete()), QKeySequence("Shift+Del"));
ripple_delete_->setParent(this);
split_ = create_menu_action(nullptr, "split", panel_timeline, SLOT(split_at_playhead()), QKeySequence("Ctrl+K"));
split_ = create_menu_action(nullptr, "split", panel_timeline.first(), SLOT(split_at_playhead()), QKeySequence("Ctrl+K"));
split_->setParent(this);
Retranslate();
@@ -193,23 +193,23 @@ void MenuHelper::set_titlesafe_from_menu() {
if (qIsNaN(tsa)) {
// disable title safe area
olive::CurrentConfig.show_title_safe_area = false;
olive::config.show_title_safe_area = false;
} else {
// using title safe area
olive::CurrentConfig.show_title_safe_area = true;
olive::config.show_title_safe_area = true;
// are we using the default area aspect ratio, or a specific one
if (qIsNull(tsa)) {
// default title safe area
olive::CurrentConfig.use_custom_title_safe_ratio = false;
olive::config.use_custom_title_safe_ratio = false;
} else {
// using a specific aspect ratio
olive::CurrentConfig.use_custom_title_safe_ratio = true;
olive::config.use_custom_title_safe_ratio = true;
if (tsa < 0.0) {
@@ -229,13 +229,13 @@ void MenuHelper::set_titlesafe_from_menu() {
if (!input.isEmpty()) {
QStringList inputList = input.split(':');
olive::CurrentConfig.custom_title_safe_ratio = inputList.at(0).toDouble()/inputList.at(1).toDouble();
olive::config.custom_title_safe_ratio = inputList.at(0).toDouble()/inputList.at(1).toDouble();
}
} else {
// specified tsa is a specific custom aspect ratio
olive::CurrentConfig.custom_title_safe_ratio = tsa;
olive::config.custom_title_safe_ratio = tsa;
}
}
@@ -247,7 +247,7 @@ void MenuHelper::set_titlesafe_from_menu() {
void MenuHelper::set_autoscroll() {
QAction* action = static_cast<QAction*>(sender());
olive::CurrentConfig.autoscroll = action->data().toInt();
olive::config.autoscroll = action->data().toInt();
}
void MenuHelper::menu_click_button() {
@@ -256,7 +256,7 @@ void MenuHelper::menu_click_button() {
void MenuHelper::set_timecode_view() {
QAction* action = static_cast<QAction*>(sender());
olive::CurrentConfig.timecode_view = action->data().toInt();
olive::config.timecode_view = action->data().toInt();
update_ui(false);
}
@@ -267,8 +267,8 @@ void MenuHelper::open_recent_from_menu() {
void MenuHelper::create_effect_paste_action(QMenu *menu)
{
QAction* paste_action = menu->addAction(tr("&Paste"), panel_timeline, SLOT(paste(bool)));
paste_action->setEnabled(clipboard.size() > 0 && clipboard_type == CLIPBOARD_TYPE_EFFECT);
QAction* paste_action = menu->addAction(tr("&Paste"), olive::Global.get(), SLOT(paste(bool)));
paste_action->setEnabled(olive::clipboard.Count() > 0 && olive::clipboard.type() == Clipboard::CLIPBOARD_TYPE_EFFECT);
}
Menu* MenuHelper::create_submenu(QMenuBar* parent,
-44
View File
@@ -1,44 +0,0 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2019 Olive Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#include "scrollarea.h"
#include <QWheelEvent>
#include <QDebug>
#include "global/config.h"
#include "panels/panels.h"
#include "panels/timeline.h"
ScrollArea::ScrollArea(QWidget* parent) : QScrollArea(parent) {}
void ScrollArea::wheelEvent(QWheelEvent *e) {
if (olive::CurrentConfig.scroll_zooms) {
e->ignore();
if (e->angleDelta().y() > 0) {
panel_timeline->zoom_in();
} else if (e->angleDelta().y() < 0) {
panel_timeline->zoom_out();
}
} else {
QScrollArea::wheelEvent(e);
}
}
-33
View File
@@ -1,33 +0,0 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2019 Olive Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef SCROLLAREA_H
#define SCROLLAREA_H
#include <QScrollArea>
class ScrollArea : public QScrollArea
{
public:
ScrollArea(QWidget* parent = 0);
void wheelEvent(QWheelEvent *);
};
#endif // SCROLLAREA_H
+2 -2
View File
@@ -24,7 +24,7 @@
bool olive::styling::UseDarkIcons()
{
return olive::CurrentConfig.style == kOliveDefaultLight || olive::CurrentConfig.style == kNativeDarkIcons;
return olive::config.style == kOliveDefaultLight || olive::config.style == kNativeDarkIcons;
}
QColor olive::styling::GetIconColor()
@@ -40,5 +40,5 @@ QColor olive::styling::GetIconColor()
bool olive::styling::UseNativeUI()
{
return olive::CurrentConfig.style == kNativeLightIcons || olive::CurrentConfig.style == kNativeDarkIcons;
return olive::config.style == kNativeLightIcons || olive::config.style == kNativeDarkIcons;
}
+9 -5
View File
@@ -1,6 +1,7 @@
#include "timelinearea.h"
TimelineArea::TimelineArea() :
TimelineArea::TimelineArea(Timeline* timeline) :
timeline_(timeline),
track_list_(nullptr),
alignment_(olive::timeline::kAlignmentTop)
{
@@ -8,21 +9,24 @@ TimelineArea::TimelineArea() :
// LABELS
QWidget* label_container = new QWidget();
QVBoxLayout* label_container_layout = new QVBoxLayout(label_container);
label_container_layout_ = new QVBoxLayout(label_container);
layout->addWidget(label_container);
// VIEW
view_ = new TimelineView();
view_ = new TimelineView(timeline_);
layout->addWidget(view_);
// SCROLLBAR
QScrollBar* scrollbar = new QScrollBar(Qt::Vertical);
layout->addWidget(scrollbar);
view_->scrollBar = scrollbar;
}
void TimelineArea::SetAlignment(olive::timeline::Alignment alignment)
{
alignment_ = alignment;
view_->SetAlignment(alignment);
}
void TimelineArea::SetTrackList(Sequence *sequence, Track::Type track_list)
@@ -37,7 +41,7 @@ void TimelineArea::SetTrackList(Sequence *sequence, Track::Type track_list)
}
view_->SetTrackList(track_list_);
}
void TimelineArea::RefreshLabels()
@@ -48,7 +52,7 @@ void TimelineArea::RefreshLabels()
labels_.resize(track_list_->TrackCount());
for (int i=0;i<labels_.size();i++) {
labels_[i].SetTrack(track_list_->TrackAt(i));
labels_[i]->SetTrack(track_list_->TrackAt(i));
}
}
+4 -2
View File
@@ -12,17 +12,19 @@ class TimelineArea : public QWidget
{
Q_OBJECT
public:
TimelineArea();
TimelineArea(Timeline *timeline);
void SetAlignment(olive::timeline::Alignment alignment);
void SetTrackList(Sequence* sequence, Track::Type track_list);
public slots:
void RefreshLabels();
private:
Timeline* timeline_;
TrackList* track_list_;
TimelineView* view_;
QVector<TimelineLabel> labels_;
QVector<TimelineLabelPtr> labels_;
olive::timeline::Alignment alignment_;
QVBoxLayout* label_container_layout_;
};
#endif // TIMELINEAREA_H
+18 -17
View File
@@ -28,6 +28,7 @@
#include "mainwindow.h"
#include "panels/panels.h"
#include "global/math.h"
#include "timeline/sequence.h"
#include "undo/undo.h"
#include "project/media.h"
@@ -93,7 +94,7 @@ int TimelineHeader::getHeaderScreenPointFromFrame(long frame) {
void TimelineHeader::set_playhead(int mouse_x) {
long frame = getHeaderFrameFromScreenPoint(mouse_x);
if (snapping) panel_timeline->snap_to_timeline(&frame, false, true, true);
if (snapping) viewer->seq->SnapPoint(&frame, zoom, false, true, true);
if (frame != viewer->seq->playhead) {
viewer->seek(frame);
}
@@ -113,10 +114,10 @@ void TimelineHeader::set_in_point(long new_in) {
if (new_out == new_in) {
new_in--;
} else if (new_out < new_in) {
new_out = viewer->seq->getEndFrame();
new_out = viewer->seq->GetEndFrame();
}
olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq.get(), true, new_in, new_out));
olive::undo_stack.push(new SetTimelineInOutCommand(viewer->seq.get(), true, new_in, new_out));
update_parents();
}
@@ -128,7 +129,7 @@ void TimelineHeader::set_out_point(long new_out) {
new_in = 0;
}
olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq.get(), true, new_in, new_out));
olive::undo_stack.push(new SetTimelineInOutCommand(viewer->seq.get(), true, new_in, new_out));
update_parents();
}
@@ -149,7 +150,7 @@ void TimelineHeader::show_text(bool enable) {
void TimelineHeader::mousePressEvent(QMouseEvent* event) {
if (viewer->seq != nullptr && event->buttons() & Qt::LeftButton) {
if (resizing_workarea) {
sequence_end = viewer->seq->getEndFrame();
sequence_end = viewer->seq->GetEndFrame();
} else {
/*int
QPoint start(in_x, height()+2);
@@ -215,7 +216,7 @@ void TimelineHeader::mouseMoveEvent(QMouseEvent* event) {
if (dragging) {
if (resizing_workarea) {
long frame = getHeaderFrameFromScreenPoint(event->pos().x());
if (snapping) panel_timeline->snap_to_timeline(&frame, true, true, false);
if (snapping) viewer->seq->SnapPoint(&frame, zoom, true, true, false);
if (resizing_workarea_in) {
temp_workarea_in = qMax(qMin(temp_workarea_out-1, frame), 0L);
@@ -230,7 +231,7 @@ void TimelineHeader::mouseMoveEvent(QMouseEvent* event) {
// snap markers
for (int i=0;i<selected_markers.size();i++) {
long fm = selected_marker_original_times.at(i) + frame_movement;
if (snapping && panel_timeline->snap_to_timeline(&fm, true, false, true)) {
if (snapping && viewer->seq->SnapPoint(&fm, zoom, true, false, true)) {
frame_movement = fm - selected_marker_original_times.at(i);
break;
}
@@ -281,7 +282,7 @@ void TimelineHeader::mouseReleaseEvent(QMouseEvent*) {
if (viewer->seq != nullptr) {
dragging = false;
if (resizing_workarea) {
olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq.get(), true, temp_workarea_in, temp_workarea_out));
olive::undo_stack.push(new SetTimelineInOutCommand(viewer->seq.get(), true, temp_workarea_in, temp_workarea_out));
} else if (dragging_markers && selected_markers.size() > 0) {
bool moved = false;
ComboAction* ca = new ComboAction();
@@ -293,7 +294,7 @@ void TimelineHeader::mouseReleaseEvent(QMouseEvent*) {
}
}
if (moved) {
olive::UndoStack.push(ca);
olive::undo_stack.push(ca);
} else {
delete ca;
}
@@ -302,7 +303,7 @@ void TimelineHeader::mouseReleaseEvent(QMouseEvent*) {
resizing_workarea = false;
dragging = false;
dragging_markers = false;
panel_timeline->snapped = false;
olive::timeline::snapped = false;
update_parents();
}
}
@@ -331,7 +332,7 @@ void TimelineHeader::delete_markers() {
// Send command to delete selected markers
DeleteMarkerAction* dma = new DeleteMarkerAction(viewer->marker_ref);
dma->markers.append(selected_markers);
olive::UndoStack.push(dma);
olive::undo_stack.push(dma);
// remove any indices for the selected markers that no longer exist
for (int i=0;i<selected_markers.size();i++) {
@@ -388,14 +389,14 @@ void TimelineHeader::paintEvent(QPaintEvent*) {
// draw text
bool draw_text = false;
if (text_enabled && lineX-textWidth > lastTextBoundary) {
timecode = frame_to_timecode(frame + in_visible, olive::CurrentConfig.timecode_view, viewer->seq->frame_rate);
timecode = frame_to_timecode(frame + in_visible, olive::config.timecode_view, viewer->seq->frame_rate);
fullTextWidth = fm.width(timecode);
textWidth = fullTextWidth>>1;
text_x = lineX;
// centers the text to that point on the timeline, LEFT aligns it if not
if (olive::CurrentConfig.center_timeline_timecodes) {
if (olive::config.center_timeline_timecodes) {
text_x -= textWidth;
} else {
text_x += TEXT_PADDING_FROM_LINE;
@@ -415,7 +416,7 @@ void TimelineHeader::paintEvent(QPaintEvent*) {
// draw line markers
p.setPen(Qt::gray);
p.drawLine(lineX, (!olive::CurrentConfig.center_timeline_timecodes && draw_text) ? 0 : yoff, lineX, height());
p.drawLine(lineX, (!olive::config.center_timeline_timecodes && draw_text) ? 0 : yoff, lineX, height());
// draw sub-line markers
for (int j=1;j<sublineCount;j++) {
@@ -454,7 +455,7 @@ void TimelineHeader::paintEvent(QPaintEvent*) {
}
}
draw_marker(p, marker_x, yoff, height()-1, selected);
Marker::Draw(p, marker_x, yoff, height()-1, selected);
}
// draw playhead triangle
@@ -484,8 +485,8 @@ void TimelineHeader::show_context_menu(const QPoint &pos) {
QAction* center_timecodes = menu.addAction(tr("Center Timecodes"), &olive::MenuHelper, SLOT(toggle_bool_action()));
center_timecodes->setCheckable(true);
center_timecodes->setChecked(olive::CurrentConfig.center_timeline_timecodes);
center_timecodes->setData(reinterpret_cast<quintptr>(&olive::CurrentConfig.center_timeline_timecodes));
center_timecodes->setChecked(olive::config.center_timeline_timecodes);
center_timecodes->setData(reinterpret_cast<quintptr>(&olive::config.center_timeline_timecodes));
menu.exec(mapToGlobal(pos));
}
+3
View File
@@ -2,6 +2,7 @@
#define TIMELINELABEL_H
#include <QWidget>
#include <memory>
#include "timeline/track.h"
@@ -20,4 +21,6 @@ private:
Track* track_;
};
using TimelineLabelPtr = std::shared_ptr<TimelineLabel>;
#endif // TIMELINELABEL_H
+898 -972
View File
File diff suppressed because it is too large Load Diff
+26 -14
View File
@@ -30,23 +30,25 @@
#include "timeline/sequence.h"
#include "timeline/clip.h"
#include "timeline/timelinetools.h"
#include "timeline/timelinefunctions.h"
#include "project/footage.h"
#include "project/media.h"
#include "undo/undo.h"
#include "timelinetools.h"
class Timeline;
bool same_sign(int a, int b);
void draw_waveform(ClipPtr clip, const FootageStream *ms, long media_length, QPainter* p, const QRect& clip_rect, int waveform_start, int waveform_limit, double zoom);
void draw_waveform(Clip* clip, const FootageStream *ms, long media_length, QPainter* p, const QRect& clip_rect, int waveform_start, int waveform_limit, double zoom);
class TimelineView : public QWidget {
Q_OBJECT
public:
explicit TimelineView(QWidget *parent = nullptr);
explicit TimelineView(Timeline *parent);
void SetAlignment(olive::timeline::Alignment alignment);
void SetTrackList(TrackList* tl);
QScrollBar* scrollBar;
bool bottom_align;
public slots:
@@ -70,18 +72,29 @@ protected:
private:
void init_ghosts();
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);
Track* getTrackFromScreenPoint(int y);
int getScreenPointFromTrack(Track* track);
Timeline* ParentTimeline();
Sequence* sequence();
void delete_area_under_ghosts(ComboAction* ca, Sequence *s);
void insert_clips(ComboAction* ca, Sequence *s);
bool current_tool_shows_cursor();
void draw_transition(QPainter& p, Clip *c, const QRect& clip_rect, QRect& text_rect, int transition_type);
Clip* GetClipAtCursor();
void VerifyTransitionsAfterCreating(ComboAction* ca, Clip* open, Clip* close, long transition_start, long transition_end);
void VerifyTransitionHelper();
bool track_resizing;
int track_target;
Timeline* timeline_;
QVector<ClipPtr> pre_clips;
QVector<ClipPtr> post_clips;
olive::timeline::Alignment alignment_;
TrackList* track_list_;
bool track_resizing;
Track* track_target;
QVector<Clip*> pre_clips;
QVector<Clip*> post_clips;
Media* rc_reveal_media;
@@ -92,7 +105,6 @@ private:
int scroll;
SetSelectionsCommand* selection_command;
signals:
public slots:
+20 -15
View File
@@ -146,7 +146,7 @@ void ViewerWidget::show_context_menu() {
connect(&zoom_menu, SIGNAL(triggered(QAction*)), this, SLOT(set_menu_zoom(QAction*)));
menu.addMenu(&zoom_menu);
if (!viewer->is_main_sequence()) {
if (viewer->mode() != Viewer::kTimelineMode) {
menu.addAction(tr("Close Media"), viewer, SLOT(close_media()));
}
@@ -338,7 +338,12 @@ void ViewerWidget::move_gizmos(QMouseEvent *event, bool done) {
int x_movement = qRound((event->pos().x() - drag_start_x)*multiplier);
int y_movement = qRound((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->track()->sequence()->playhead),
done);
gizmo_x_mvmt += x_movement;
gizmo_y_mvmt += y_movement;
@@ -351,7 +356,7 @@ void ViewerWidget::move_gizmos(QMouseEvent *event, bool done) {
void ViewerWidget::mousePressEvent(QMouseEvent* event) {
if (waveform) {
seek_from_click(event->x());
} else if (event->buttons() & Qt::MiddleButton || panel_timeline->tool == TIMELINE_TOOL_HAND) {
} else if (event->buttons() & Qt::MiddleButton || olive::timeline::current_tool == olive::timeline::TIMELINE_TOOL_HAND) {
container->dragScrollPress(event->pos()*container->zoom);
} else if (event->buttons() & Qt::LeftButton) {
drag_start_x = event->pos().x();
@@ -367,13 +372,13 @@ void ViewerWidget::mousePressEvent(QMouseEvent* event) {
void ViewerWidget::mouseMoveEvent(QMouseEvent* event) {
unsetCursor();
if (panel_timeline->tool == TIMELINE_TOOL_HAND) {
if (olive::timeline::current_tool == olive::timeline::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) {
} else if (event->buttons() & Qt::MiddleButton || olive::timeline::current_tool == olive::timeline::TIMELINE_TOOL_HAND) {
container->dragScrollMove(event->pos()*container->zoom);
} else if (event->buttons() & Qt::LeftButton) {
if (gizmos == nullptr) {
@@ -397,7 +402,7 @@ void ViewerWidget::mouseReleaseEvent(QMouseEvent *event) {
if (dragging
&& gizmos != nullptr
&& event->button() == Qt::LeftButton
&& panel_timeline->tool != TIMELINE_TOOL_HAND) {
&& olive::timeline::current_tool != olive::timeline::TIMELINE_TOOL_HAND) {
move_gizmos(event, true);
}
dragging = false;
@@ -431,7 +436,7 @@ void ViewerWidget::draw_waveform_func() {
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);
draw_waveform(waveform_clip.get(), 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());
@@ -452,16 +457,16 @@ void ViewerWidget::draw_title_safe_area() {
matrix.ortho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
// adjust the horizontal center cross by the aspect ratio to appear "square"
if (olive::CurrentConfig.use_custom_title_safe_ratio && olive::CurrentConfig.custom_title_safe_ratio > 0) {
if (ar > olive::CurrentConfig.custom_title_safe_ratio) {
matrix.translate(((ar - olive::CurrentConfig.custom_title_safe_ratio) / 2.0) / ar, 0.0f);
matrix.scale(olive::CurrentConfig.custom_title_safe_ratio / ar, 1.0f);
if (olive::config.use_custom_title_safe_ratio && olive::config.custom_title_safe_ratio > 0) {
if (ar > olive::config.custom_title_safe_ratio) {
matrix.translate(((ar - olive::config.custom_title_safe_ratio) / 2.0) / ar, 0.0f);
matrix.scale(olive::config.custom_title_safe_ratio / ar, 1.0f);
} else {
matrix.translate(0.0f, (((olive::CurrentConfig.custom_title_safe_ratio - ar) / 2.0) / olive::CurrentConfig.custom_title_safe_ratio));
matrix.scale(1.0f, ar / olive::CurrentConfig.custom_title_safe_ratio);
matrix.translate(0.0f, (((olive::config.custom_title_safe_ratio - ar) / 2.0) / olive::config.custom_title_safe_ratio));
matrix.scale(1.0f, ar / olive::config.custom_title_safe_ratio);
}
horizontal_cross_size *= ar/olive::CurrentConfig.custom_title_safe_ratio;
horizontal_cross_size *= ar/olive::config.custom_title_safe_ratio;
}
float adjusted_cross_x1 = 0.5f - horizontal_cross_size;
@@ -745,7 +750,7 @@ void ViewerWidget::paintGL() {
f->glBindTexture(GL_TEXTURE_2D, 0);
// draw title/action safe area
if (olive::CurrentConfig.show_title_safe_area) {
if (olive::config.show_title_safe_area) {
draw_title_safe_area();
}
+109 -119
View File
@@ -38,11 +38,11 @@
#include "ui/labelslider.h"
#include "ui/viewerwidget.h"
#include "project/media.h"
#include "project/clipboard.h"
#include "global/clipboard.h"
#include "project/previewgenerator.h"
#include "ui/mainwindow.h"
MoveClipAction::MoveClipAction(Clip *c, long iin, long iout, long iclip_in, int itrack, bool irelative) :
MoveClipAction::MoveClipAction(ClipPtr c, long iin, long iout, long iclip_in, Track* itrack, bool irelative) :
clip(c),
old_in(c->timeline_in()),
old_out(c->timeline_out()),
@@ -63,13 +63,12 @@ void MoveClipAction::doUndo() {
clip->set_timeline_in (clip->timeline_in() - new_in);
clip->set_timeline_out (clip->timeline_out() - new_out);
clip->set_clip_in (clip->clip_in() - new_clip_in);
clip->set_track (clip->track() - new_track);
} else {
clip->set_timeline_in(old_in);
clip->set_timeline_out(old_out);
clip->set_clip_in(old_clip_in);
clip->set_track(old_track);
}
clip->set_track(old_track);
done = false;
}
@@ -79,13 +78,12 @@ void MoveClipAction::doRedo() {
clip->set_timeline_in(clip->timeline_in() + new_in);
clip->set_timeline_out(clip->timeline_out() + new_out);
clip->set_clip_in(clip->clip_in() + new_clip_in);
clip->set_track(clip->track() + new_track);
} else {
clip->set_timeline_in(new_in);
clip->set_timeline_out(new_out);
clip->set_clip_in(new_clip_in);
clip->set_track(new_track);
}
new_track->AddClip(clip);
done = true;
}
}
@@ -98,15 +96,13 @@ DeleteClipAction::DeleteClipAction(Clip *clip)
}
void DeleteClipAction::doUndo() {
// restore ref to clip
seq->clips[index] = ref;
// restore clip to this track
clip_->track()->AddClip(clip_);
// 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);
for (int i=0;i<clips_linked_to_this_one_.size();i++) {
clips_linked_to_this_one_.append(clip_.get());
}
ref = nullptr;
}
void DeleteClipAction::doRedo() {
@@ -118,36 +114,20 @@ void DeleteClipAction::doRedo() {
clip_->track()->RemoveClip(clip_.get());
// delete link to this clip
QVector<Clip*> clips = clip_->track()->
linkClipIndex.clear();
linkLinkIndex.clear();
for (int i=0;i<seq->clips.size();i++) {
ClipPtr c = seq->clips.at(i);
if (c != nullptr) {
for (int j=0;j<c->linked.size();j++) {
if (c->linked.at(j) == index) {
linkClipIndex.append(i);
linkLinkIndex.append(j);
c->linked.removeAt(j);
}
QVector<Clip*> clips = clip_->track()->sequence()->GetAllClips();
for (int i=0;i<clips.size();i++) {
Clip* c = clips.at(i);
for (int j=0;j<c->linked.size();j++) {
if (c->linked.at(j) == clip_.get()) {
c->linked.removeAt(j);
clips_linked_to_this_one_.append(c);
break;
}
}
}
}
ChangeSequenceAction::ChangeSequenceAction(SequencePtr s) {
new_sequence = s;
}
void ChangeSequenceAction::doUndo() {
olive::Global->set_sequence(old_sequence);
}
void ChangeSequenceAction::doRedo() {
old_sequence = olive::ActiveSequence;
olive::Global->set_sequence(new_sequence);
}
SetTimelineInOutCommand::SetTimelineInOutCommand(Sequence* s, bool enabled, long in, long out) {
seq = s;
new_enabled = enabled;
@@ -162,7 +142,7 @@ void SetTimelineInOutCommand::doUndo() {
// footage viewer functions
if (seq->wrapper_sequence) {
Footage* m = seq->clips.at(0)->media()->to_footage();
Footage* m = seq->GetAllClips().first()->media()->to_footage();
m->using_inout = old_enabled;
m->in = old_in;
m->out = old_out;
@@ -180,7 +160,7 @@ void SetTimelineInOutCommand::doRedo() {
// footage viewer functions
if (seq->wrapper_sequence) {
Footage* m = seq->clips.at(0)->media()->to_footage();
Footage* m = seq->GetAllClips().first()->media()->to_footage();
m->using_inout = new_enabled;
m->in = new_in;
m->out = new_out;
@@ -351,10 +331,8 @@ void DeleteMediaCommand::doRedo() {
olive::project_model.removeChild(parent, item.get());
}
AddClipCommand::AddClipCommand(Sequence *s, QVector<ClipPtr>& add) :
link_offset_(0),
seq(s),
clips(add),
AddClipCommand::AddClipCommand(const QVector<ClipPtr> &add) :
clips_(add),
done_(false)
{
doRedo();
@@ -365,26 +343,21 @@ void AddClipCommand::doUndo() {
panel_graph_editor->set_row(nullptr);
panel_effect_controls->Clear(true);
for (int i=0;i<clips.size();i++) {
ClipPtr c = seq->clips.last();
for (int i=0;i<clips_.size();i++) {
ClipPtr c = clips_.at(i);
if (c != nullptr) {
// un-offset all the clips
for (int j=0;j<c->linked.size();j++) {
c->linked[j] -= link_offset_;
}
c->track()->RemoveClip(c.get());
// deselect the area occupied by this clip
panel_timeline->deselect_area(c->timeline_in(), c->timeline_out(), c->track());
c->track()->DeselectArea(c->timeline_in(), c->timeline_out());
// if the clip is open, close it
if (c->IsOpen()) {
c->Close(true);
}
}
// remove it from the sequence
seq->clips.removeLast();
}
done_ = false;
@@ -392,54 +365,52 @@ void AddClipCommand::doUndo() {
void AddClipCommand::doRedo() {
if (!done_) {
link_offset_ = seq->clips.size();
for (int i=0;i<clips.size();i++) {
ClipPtr original = clips.at(i);
for (int i=0;i<clips_.size();i++) {
ClipPtr original = clips_.at(i);
if (original != nullptr) {
// offset all links by the current clip size
for (int j=0;j<original->linked.size();j++) {
original->linked[j] += link_offset_;
}
}
seq->clips.append(original);
original->track()->AddClip(original);
}
}
done_ = true;
}
}
LinkCommand::LinkCommand() {
link = true;
LinkCommand::LinkCommand(const QVector<Clip*>& clips, bool link) :
clips_(clips),
link_(link)
{
}
void LinkCommand::doUndo() {
for (int i=0;i<clips.size();i++) {
ClipPtr c = s->clips.at(clips.at(i));
if (link) {
for (int i=0;i<clips_.size();i++) {
Clip* c = clips_.at(i);
if (link_) {
c->linked.clear();
} else {
c->linked = old_links.at(i);
c->linked = old_links_.at(i);
}
}
}
void LinkCommand::doRedo() {
old_links.clear();
for (int i=0;i<clips.size();i++) {
ClipPtr c = s->clips.at(clips.at(i));
if (link) {
for (int j=0;j<clips.size();j++) {
old_links_.clear();
for (int i=0;i<clips_.size();i++) {
Clip* c = clips_.at(i);
if (link_) {
for (int j=0;j<clips_.size();j++) {
if (i != j) {
c->linked.append(clips.at(j));
c->linked.append(clips_.at(j));
}
}
} else {
old_links.append(c->linked);
old_links_.append(c->linked);
c->linked.clear();
}
}
}
@@ -472,12 +443,14 @@ ReplaceMediaCommand::ReplaceMediaCommand(MediaPtr i, QString s) {
void ReplaceMediaCommand::replace(QString& filename) {
// close any clips currently using this media
QVector<Media*> all_sequences = panel_project->list_all_project_sequences();
QVector<Media*> all_sequences = olive::project_model.GetAllSequences();
for (int i=0;i<all_sequences.size();i++) {
Sequence* s = all_sequences.at(i)->to_sequence().get();
for (int j=0;j<s->clips.size();j++) {
ClipPtr c = s->clips.at(j);
if (c != nullptr && c->media() == item.get() && c->IsOpen()) {
QVector<Clip*> sequence_clips = all_sequences.at(i)->to_sequence()->GetAllClips();
for (int j=0;j<sequence_clips.size();j++) {
Clip* c = sequence_clips.at(j);
if (c->media() == item.get() && c->IsOpen()) {
c->Close(true);
c->replaced = true;
}
@@ -487,7 +460,7 @@ void ReplaceMediaCommand::replace(QString& filename) {
// replace media
QStringList files;
files.append(filename);
panel_project->process_file_list(files, false, item, nullptr);
olive::project_model.process_file_list(files, false, item, nullptr);
PreviewGenerator::AnalyzeMedia(item.get());
}
@@ -513,7 +486,7 @@ void ReplaceClipMediaCommand::replace(bool undo) {
}
for (int i=0;i<clips.size();i++) {
ClipPtr c = clips.at(i);
Clip* c = clips.at(i);
if (c->IsOpen()) {
c->Close(true);
}
@@ -806,20 +779,25 @@ void SetBool::doRedo() {
*boolean = new_setting;
}
SetSelectionsCommand::SetSelectionsCommand(Sequence *s) {
seq = s;
done = true;
SetSelectionsCommand::SetSelectionsCommand(Sequence *s,
const QVector<Selection> &old_data,
const QVector<Selection> &new_data) :
old_data_(old_data),
new_data_(new_data),
done_(true)
{
}
void SetSelectionsCommand::doUndo() {
seq->selections = old_data;
done = false;
seq_->SetSelections(old_data_);
done_ = false;
}
void SetSelectionsCommand::doRedo() {
if (!done) {
seq->selections = new_data;
done = true;
if (!done_) {
seq_->SetSelections(new_data_);
done_ = true;
}
}
@@ -858,15 +836,12 @@ void EditSequenceCommand::update() {
// Update sequence's tooltip
item->update_tooltip();
for (int i=0;i<seq->clips.size();i++) {
if (seq->clips.at(i) != nullptr) {
seq->clips.at(i)->refresh();
QVector<Clip*> all_clips = seq->GetAllClips();
for (int i=0;i<all_clips.size();i++) {
if (all_clips.at(i) != nullptr) {
all_clips.at(i)->refresh();
}
}
if (olive::ActiveSequence == seq) {
olive::Global->set_sequence(seq);
}
}
SetInt::SetInt(int* pointer, int new_value) {
@@ -904,7 +879,11 @@ void CloseAllClipsCommand::doUndo() {
}
void CloseAllClipsCommand::doRedo() {
olive::ActiveSequence->Close();
QVector<Media*> sequences = olive::project_model.GetAllSequences();
for (int i=0;i<sequences.size();i++) {
sequences.at(i)->to_sequence()->Close();
}
}
UpdateFootageTooltip::UpdateFootageTooltip(Media *i) {
@@ -938,13 +917,13 @@ RemoveClipsFromClipboard::RemoveClipsFromClipboard(int index) {
RemoveClipsFromClipboard::~RemoveClipsFromClipboard() {}
void RemoveClipsFromClipboard::doUndo() {
clipboard.insert(pos, clip);
olive::clipboard.Insert(pos, clip);
done = false;
}
void RemoveClipsFromClipboard::doRedo() {
clip = std::static_pointer_cast<Clip>(clipboard.at(pos));
clipboard.removeAt(pos);
clip = std::static_pointer_cast<Clip>(olive::clipboard.Get(pos));
olive::clipboard.RemoveAt(pos);
done = true;
}
@@ -985,7 +964,7 @@ void ReloadEffectsCommand::doRedo() {
panel_effect_controls->Reload();
}
RippleAction::RippleAction(Sequence *is, long ipoint, long ilength, const QVector<int> &iignore) :
RippleAction::RippleAction(Sequence *is, long ipoint, long ilength, const QVector<Clip*> &iignore) :
s(is),
point(ipoint),
length(ilength),
@@ -1000,13 +979,21 @@ void RippleAction::doUndo() {
void RippleAction::doRedo() {
ca = new ComboAction();
for (int i=0;i<s->clips.size();i++) {
if (!ignore.contains(i)) {
ClipPtr c = s->clips.at(i);
if (c != nullptr) {
if (c->timeline_in() >= point) {
c->move(ca, length, length, 0, 0, true, true);
}
QVector<Clip*> all_clips = s->GetAllClips();
for (int i=0;i<all_clips.size();i++) {
Clip* c = all_clips.at(i);
if (!ignore.contains(c)) {
if (c->timeline_in() >= point) {
s->MoveClip(c,
ca,
length,
length,
0,
c->track(),
true,
true);
}
}
}
@@ -1092,8 +1079,9 @@ void SetIsKeyframing::doRedo() {
row->SetKeyframingInternal(b);
}
RefreshClips::RefreshClips(Media *m) {
media = m;
RefreshClips::RefreshClips(Media *m) :
media(m)
{
}
void RefreshClips::doUndo() {
@@ -1102,12 +1090,14 @@ void RefreshClips::doUndo() {
void RefreshClips::doRedo() {
// close any clips currently using this media
QVector<Media*> all_sequences = panel_project->list_all_project_sequences();
QVector<Media*> all_sequences = olive::project_model.GetAllSequences();
for (int i=0;i<all_sequences.size();i++) {
Sequence* s = all_sequences.at(i)->to_sequence().get();
for (int j=0;j<s->clips.size();j++) {
Clip* c = s->clips.at(j).get();
if (c != nullptr && c->media() == media) {
QVector<Clip*> sequence_clips = all_sequences.at(i)->to_sequence().get()->GetAllClips();
for (int j=0;j<sequence_clips.size();j++) {
Clip* c = sequence_clips.at(j);
if (c->media() == media || media == nullptr) {
c->replaced = true;
c->refresh();
}
+19 -32
View File
@@ -77,21 +77,21 @@ private:
class MoveClipAction : public OliveAction {
public:
MoveClipAction(Clip* c, long iin, long iout, long iclip_in, int itrack, bool irelative);
MoveClipAction(ClipPtr c, long iin, long iout, long iclip_in, Track* itrack, bool irelative);
virtual void doUndo() override;
virtual void doRedo() override;
private:
Clip* clip;
ClipPtr clip;
long old_in;
long old_out;
long old_clip_in;
int old_track;
Track* old_track;
long new_in;
long new_out;
long new_clip_in;
int new_track;
Track* new_track;
bool relative;
@@ -100,14 +100,14 @@ private:
class RippleAction : public OliveAction {
public:
RippleAction(Sequence* is, long ipoint, long ilength, const QVector<int>& iignore);
RippleAction(Sequence* is, long ipoint, long ilength, const QVector<Clip *> &iignore);
virtual void doUndo() override;
virtual void doRedo() override;
private:
Sequence* s;
long point;
long length;
QVector<int> ignore;
QVector<Clip*> ignore;
ComboAction* ca;
};
@@ -118,20 +118,9 @@ public:
virtual void doRedo() override;
private:
ClipPtr clip_;
QVector<Clip*> clips_linked_to_this_one_;
};
class ChangeSequenceAction : public OliveAction {
public:
ChangeSequenceAction(SequencePtr s);
virtual void doUndo() override;
virtual void doRedo() override;
private:
SequencePtr old_sequence;
SequencePtr new_sequence;
};
class AddEffectCommand : public OliveAction {
public:
AddEffectCommand(Clip* c, EffectPtr e, const EffectMeta* m, int insert_pos = -1);
@@ -223,26 +212,24 @@ private:
class AddClipCommand : public OliveAction {
public:
AddClipCommand(Sequence* s, QVector<ClipPtr>& add);
AddClipCommand(const QVector<ClipPtr>& add);
virtual void doUndo() override;
virtual void doRedo() override;
private:
Sequence* seq;
QVector<ClipPtr> clips;
int link_offset_;
Track* track_;
QVector<ClipPtr> clips_;
bool done_;
};
class LinkCommand : public OliveAction {
public:
LinkCommand();
LinkCommand(const QVector<Clip *> &clips, bool link);
virtual void doUndo() override;
virtual void doRedo() override;
Sequence* s;
QVector<int> clips;
bool link;
private:
QVector< QVector<int> > old_links;
QVector<Clip*> clips_;
bool link_;
QVector< QVector<Clip*> > old_links_;
};
class CheckboxCommand : public OliveAction {
@@ -274,7 +261,7 @@ public:
ReplaceClipMediaCommand(Media *, Media *, bool);
virtual void doUndo() override;
virtual void doRedo() override;
QVector<ClipPtr> clips;
QVector<Clip*> clips;
private:
Media* old_media;
Media* new_media;
@@ -423,14 +410,14 @@ private:
class SetSelectionsCommand : public OliveAction {
public:
SetSelectionsCommand(Sequence* s);
SetSelectionsCommand(Sequence* s, const QVector<Selection>& old_data, const QVector<Selection>& new_data);
virtual void doUndo() override;
virtual void doRedo() override;
QVector<Selection> old_data;
QVector<Selection> new_data;
private:
Sequence* seq;
bool done;
QVector<Selection> old_data_;
QVector<Selection> new_data_;
Sequence* seq_;
bool done_;
};
class EditSequenceCommand : public OliveAction {

Some files were not shown because too many files have changed in this diff Show More