From e9fe837236ec15ea65e28865f4d237cbfd342e4f Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 14 Feb 2019 05:27:21 -0800 Subject: [PATCH] first commit of big refactor --- dialogs/actionsearch.cpp | 2 +- dialogs/exportdialog.cpp | 30 +- dialogs/loaddialog.cpp | 8 +- dialogs/preferencesdialog.cpp | 7 +- dialogs/proxydialog.cpp | 3 +- dialogs/replaceclipmediadialog.cpp | 14 +- dialogs/speeddialog.cpp | 10 +- effects/internal/texteffect.cpp | 2 +- effects/internal/timecodeeffect.cpp | 2 +- effects/internal/vsthost.cpp | 6 +- io/exportthread.cpp | 35 +- io/loadthread.cpp | 37 +- io/path.cpp | 52 ++- io/path.h | 5 +- io/proxygenerator.cpp | 2 +- main.cpp | 21 +- mainwindow.cpp | 300 ++++--------- mainwindow.h | 47 +- olive.pro | 645 ++++++++++++++-------------- oliveglobal.cpp | 192 +++++++++ oliveglobal.h | 91 ++++ panels/effectcontrols.cpp | 14 +- panels/panels.cpp | 30 +- panels/panels.h | 10 +- panels/project.cpp | 59 ++- panels/project.h | 2 +- panels/timeline.cpp | 278 ++++++------ panels/viewer.cpp | 4 +- playback/audio.cpp | 27 +- playback/cacher.cpp | 2 +- playback/playback.cpp | 2 +- project/clip.cpp | 2 + project/clip.h | 3 - project/effect.cpp | 14 +- project/effectfield.h | 16 +- project/effectgizmo.h | 8 +- project/effectrow.cpp | 8 +- project/marker.cpp | 2 +- project/media.h | 8 +- project/projectelements.h | 15 + project/sequence.cpp | 2 +- project/sequence.h | 4 +- project/sourcescommon.cpp | 15 +- project/transition.cpp | 2 +- project/undo.cpp | 226 +++++----- ui/audiomonitor.cpp | 2 +- ui/comboboxex.cpp | 6 +- ui/keyframeview.cpp | 8 +- ui/menuhelper.cpp | 23 + ui/menuhelper.h | 45 ++ ui/timelineheader.cpp | 5 +- ui/timelinewidget.cpp | 252 +++++------ 52 files changed, 1419 insertions(+), 1186 deletions(-) create mode 100644 oliveglobal.cpp create mode 100644 oliveglobal.h create mode 100644 project/projectelements.h create mode 100644 ui/menuhelper.cpp create mode 100644 ui/menuhelper.h diff --git a/dialogs/actionsearch.cpp b/dialogs/actionsearch.cpp index 13c7f3c3b..1fe19c5b3 100644 --- a/dialogs/actionsearch.cpp +++ b/dialogs/actionsearch.cpp @@ -43,7 +43,7 @@ ActionSearch::ActionSearch(QWidget *parent) : void ActionSearch::search_update(const QString &s, const QString &p, QMenu *parent) { if (parent == nullptr) { list_widget->clear(); - QList menus = mainWindow->menuBar()->actions(); + QList menus = Olive::MainWindow->menuBar()->actions(); for (int i=0;imenu(); search_update(s, p, menu); diff --git a/dialogs/exportdialog.cpp b/dialogs/exportdialog.cpp index 9dfd6f0bb..15ecdbe75 100644 --- a/dialogs/exportdialog.cpp +++ b/dialogs/exportdialog.cpp @@ -15,11 +15,9 @@ #include #include -#include "debug.h" +#include "oliveglobal.h" #include "dialogs/advancedvideodialog.h" #include "panels/panels.h" -#include "panels/viewer.h" -#include "panels/timeline.h" #include "ui/viewerwidget.h" #include "project/sequence.h" #include "io/exportthread.h" @@ -58,11 +56,11 @@ enum ExportFormats { ExportDialog::ExportDialog(QWidget *parent) : QDialog(parent) { - setWindowTitle(tr("Export \"%1\"").arg(sequence->name)); + setWindowTitle(tr("Export \"%1\"").arg(Olive::ActiveSequence->name)); setup_ui(); rangeCombobox->setCurrentIndex(0); - if (sequence->using_workarea) { + if (Olive::ActiveSequence->using_workarea) { rangeCombobox->setEnabled(true); rangeCombobox->setCurrentIndex(1); } @@ -95,10 +93,10 @@ ExportDialog::ExportDialog(QWidget *parent) : } formatCombobox->setCurrentIndex(FORMAT_MPEG4); - widthSpinbox->setValue(sequence->width); - heightSpinbox->setValue(sequence->height); - samplingRateSpinbox->setValue(sequence->audio_frequency); - framerateSpinbox->setValue(sequence->frame_rate); + widthSpinbox->setValue(Olive::ActiveSequence->width); + heightSpinbox->setValue(Olive::ActiveSequence->height); + samplingRateSpinbox->setValue(Olive::ActiveSequence->audio_frequency); + framerateSpinbox->setValue(Olive::ActiveSequence->frame_rate); } ExportDialog::~ExportDialog() @@ -511,10 +509,10 @@ void ExportDialog::export_action() { } params.start_frame = 0; - params.end_frame = sequence->getEndFrame(); // entire sequence + params.end_frame = Olive::ActiveSequence->getEndFrame(); // entire sequence if (rangeCombobox->currentIndex() == 1) { - params.start_frame = qMax(sequence->workarea_in, params.start_frame); - params.end_frame = qMin(sequence->workarea_out, params.end_frame); + params.start_frame = qMax(Olive::ActiveSequence->workarea_in, params.start_frame); + params.end_frame = qMin(Olive::ActiveSequence->workarea_out, params.end_frame); } et = new ExportThread(params, vcodec_params, this); @@ -523,11 +521,11 @@ void ExportDialog::export_action() { connect(et, SIGNAL(finished()), this, SLOT(render_thread_finished())); connect(et, SIGNAL(progress_changed(int, qint64)), this, SLOT(update_progress_bar(int, qint64))); - closeActiveClips(sequence); + closeActiveClips(Olive::ActiveSequence); - mainWindow->set_rendering_state(true); + Olive::Global.data()->set_rendering_state(true); - mainWindow->autorecover_interval(); + Olive::Global.data()->save_autorecovery_file(); prep_ui_for_render(true); @@ -594,7 +592,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 * sequence->height) - 4.5))); + videobitrateSpinbox->setValue(qMax(0.5, (double) qRound((0.01528 * Olive::ActiveSequence->height) - 4.5))); break; case COMPRESSION_TYPE_CFR: videoBitrateLabel->setText(tr("Quality (CRF):")); diff --git a/dialogs/loaddialog.cpp b/dialogs/loaddialog.cpp index e0b555df8..046ebcda1 100644 --- a/dialogs/loaddialog.cpp +++ b/dialogs/loaddialog.cpp @@ -6,8 +6,10 @@ #include #include +#include "oliveglobal.h" + #include "panels/panels.h" -#include "panels/project.h" + #include "io/loadthread.h" #include "playback/playback.h" #include "ui/sourcetable.h" @@ -19,7 +21,7 @@ LoadDialog::LoadDialog(QWidget *parent, bool autorecovery) : QDialog(parent) { QVBoxLayout* layout = new QVBoxLayout(this); - layout->addWidget(new QLabel(tr("Loading '%1'...").arg(project_url.mid(project_url.lastIndexOf('/')+1)), this)); + layout->addWidget(new QLabel(tr("Loading '%1'...").arg(Olive::ActiveProjectFilename.mid(Olive::ActiveProjectFilename.lastIndexOf('/')+1)), this)); bar = new QProgressBar(this); bar->setValue(0); @@ -51,7 +53,7 @@ void LoadDialog::cancel() { } void LoadDialog::die() { - mainWindow->new_project(); + Olive::Global.data()->new_project(); reject(); } diff --git a/dialogs/preferencesdialog.cpp b/dialogs/preferencesdialog.cpp index aa26047ba..221f66a34 100644 --- a/dialogs/preferencesdialog.cpp +++ b/dialogs/preferencesdialog.cpp @@ -26,8 +26,7 @@ #include #include #include - -#include "debug.h" +#include KeySequenceEditor::KeySequenceEditor(QWidget* parent, QAction* a) : QKeySequenceEdit(parent), action(a) { @@ -161,7 +160,7 @@ void PreferencesDialog::save() { // save settings from UI to backend config.css_path = custom_css_fn->text(); - mainWindow->load_css_from_file(config.css_path); + Olive::MainWindow->load_css_from_file(config.css_path); config.recording_mode = recordingComboBox->currentIndex() + 1; config.img_seq_formats = imgSeqFormatEdit->text(); config.fast_seeking = fastSeekButton->isChecked(); @@ -411,7 +410,7 @@ void PreferencesDialog::setup_ui() { for (int i=0;i #include #include - #include #include "io/proxygenerator.h" @@ -133,7 +132,7 @@ void ProxyDialog::accept() { proxy_generator.queue(info_list.at(i)); } - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); QDialog::accept(); } diff --git a/dialogs/replaceclipmediadialog.cpp b/dialogs/replaceclipmediadialog.cpp index 7b4171a42..49a2940b2 100644 --- a/dialogs/replaceclipmediadialog.cpp +++ b/dialogs/replaceclipmediadialog.cpp @@ -2,15 +2,11 @@ #include "ui/sourcetable.h" #include "panels/panels.h" -#include "panels/timeline.h" -#include "panels/project.h" -#include "project/sequence.h" -#include "project/clip.h" +#include "project/projectelements.h" + #include "playback/playback.h" #include "playback/cacher.h" -#include "project/footage.h" #include "project/undo.h" -#include "project/media.h" #include #include @@ -84,7 +80,7 @@ void ReplaceClipMediaDialog::replace() { QMessageBox::Ok ); } else { - if (new_item->get_type() == MEDIA_TYPE_SEQUENCE && sequence == new_item->to_sequence()) { + if (new_item->get_type() == MEDIA_TYPE_SEQUENCE && Olive::ActiveSequence == new_item->to_sequence()) { QMessageBox::critical( this, tr("Active sequence selected"), @@ -98,8 +94,8 @@ void ReplaceClipMediaDialog::replace() { use_same_media_in_points->isChecked() ); - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr && c->media == media) { rcmc->clips.append(c); } diff --git a/dialogs/speeddialog.cpp b/dialogs/speeddialog.cpp index d5f411059..f00e39bb4 100644 --- a/dialogs/speeddialog.cpp +++ b/dialogs/speeddialog.cpp @@ -41,7 +41,7 @@ SpeedDialog::SpeedDialog(QWidget *parent) : QDialog(parent) { grid->addWidget(new QLabel(tr("Duration:"), this), 2, 0); duration = new LabelSlider(this); duration->set_display_type(LABELSLIDER_FRAMENUMBER); - duration->set_frame_rate(sequence->frame_rate); + duration->set_frame_rate(Olive::ActiveSequence->frame_rate); grid->addWidget(duration, 2, 1); main_layout->addLayout(grid); @@ -322,14 +322,14 @@ void set_speed(ComboAction* ca, Clip* c, double speed, bool ripple, long& ep, lo sel.in = c->timeline_in; sel.out = proposed_out; sel.track = c->track; - sequence->selections.append(sel); + Olive::ActiveSequence->selections.append(sel); } void SpeedDialog::accept() { ComboAction* ca = new ComboAction(); - SetSelectionsCommand* sel_command = new SetSelectionsCommand(sequence); - sel_command->old_data = sequence->selections; + SetSelectionsCommand* sel_command = new SetSelectionsCommand(Olive::ActiveSequence); + sel_command->old_data = Olive::ActiveSequence->selections; long earliest_point = LONG_MAX; long longest_ripple = LONG_MIN; @@ -402,7 +402,7 @@ void SpeedDialog::accept() { ripple_clips(ca, clips.at(0)->sequence, earliest_point, longest_ripple); } - sel_command->new_data = sequence->selections; + sel_command->new_data = Olive::ActiveSequence->selections; ca->append(sel_command); undo_stack.push(ca); diff --git a/effects/internal/texteffect.cpp b/effects/internal/texteffect.cpp index 7f4c36940..4fd0abb02 100644 --- a/effects/internal/texteffect.cpp +++ b/effects/internal/texteffect.cpp @@ -310,7 +310,7 @@ void TextEffect::text_edit_menu() { } void TextEffect::open_text_edit() { - TextEditDialog ted(mainWindow, text_val->get_current_data().toString()); + TextEditDialog ted(Olive::MainWindow, text_val->get_current_data().toString()); ted.exec(); QString result = ted.get_string(); if (!result.isEmpty()) { diff --git a/effects/internal/timecodeeffect.cpp b/effects/internal/timecodeeffect.cpp index 52a1d65c7..0d0aae920 100644 --- a/effects/internal/timecodeeffect.cpp +++ b/effects/internal/timecodeeffect.cpp @@ -62,7 +62,7 @@ TimecodeEffect::TimecodeEffect(Clip *c, const EffectMeta* em) : void TimecodeEffect::redraw(double timecode) { if (tc_select->get_combo_data(timecode).toBool()){ - display_timecode = prepend_text->get_string_value(timecode) + frame_to_timecode(sequence->playhead, config.timecode_view, sequence->frame_rate);} + display_timecode = prepend_text->get_string_value(timecode) + frame_to_timecode(Olive::ActiveSequence->playhead, config.timecode_view, Olive::ActiveSequence->frame_rate);} else { double media_rate = parent_clip->getMediaFrameRate(); display_timecode = prepend_text->get_string_value(timecode) + frame_to_timecode(timecode * media_rate, config.timecode_view, media_rate);} diff --git a/effects/internal/vsthost.cpp b/effects/internal/vsthost.cpp index fd22d4b94..0709bd027 100644 --- a/effects/internal/vsthost.cpp +++ b/effects/internal/vsthost.cpp @@ -63,7 +63,7 @@ extern "C" { // but we are aware of it break; case audioMasterEndEdit: // change made - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); break; default: qInfo() << "Plugin requested unhandled opcode" << opcode; @@ -178,7 +178,7 @@ bool VSTHost::configurePluginCallbacks() { // real VST plugin, or is otherwise corrupt. if(plugin->magic != kEffectMagic) { qCritical() << "Plugin's magic number is bad"; - QMessageBox::critical(mainWindow, tr("VST Error"), tr("Plugin's magic number is invalid")); + QMessageBox::critical(Olive::MainWindow, tr("VST Error"), tr("Plugin's magic number is invalid")); return false; } @@ -250,7 +250,7 @@ VSTHost::VSTHost(Clip* c, const EffectMeta *em) : Effect(c, em) { connect(show_interface_btn, SIGNAL(toggled(bool)), this, SLOT(show_interface(bool))); interface_row->add_widget(show_interface_btn); - dialog = new QDialog(mainWindow); + dialog = new QDialog(Olive::MainWindow); dialog->setWindowTitle(tr("VST Plugin")); dialog->setAttribute(Qt::WA_NativeWindow, true); dialog->setWindowFlags(dialog->windowFlags() | Qt::MSWindowsFixedSizeDialogHint); diff --git a/io/exportthread.cpp b/io/exportthread.cpp index 074327d88..48708a143 100644 --- a/io/exportthread.cpp +++ b/io/exportthread.cpp @@ -1,10 +1,11 @@ #include "exportthread.h" +#include "oliveglobal.h" + #include "project/sequence.h" #include "panels/panels.h" -#include "panels/timeline.h" -#include "panels/viewer.h" + #include "ui/viewerwidget.h" #include "ui/renderthread.h" #include "ui/renderfunctions.h" @@ -162,15 +163,15 @@ bool ExportThread::setupVideo() { video_frame = av_frame_alloc(); av_frame_make_writable(video_frame); video_frame->format = AV_PIX_FMT_RGBA; - video_frame->width = sequence->width; - video_frame->height = sequence->height; + video_frame->width = Olive::ActiveSequence->width; + video_frame->height = Olive::ActiveSequence->height; av_frame_get_buffer(video_frame, 0); av_init_packet(&video_pkt); sws_ctx = sws_getContext( - sequence->width, - sequence->height, + Olive::ActiveSequence->width, + Olive::ActiveSequence->height, AV_PIX_FMT_RGBA, params.video_width, params.video_height, @@ -253,9 +254,9 @@ bool ExportThread::setupAudio() { acodec_ctx->channel_layout, acodec_ctx->sample_fmt, acodec_ctx->sample_rate, - sequence->audio_layout, + Olive::ActiveSequence->audio_layout, AV_SAMPLE_FMT_S16, - sequence->audio_frequency, + Olive::ActiveSequence->audio_frequency, 0, nullptr ); @@ -263,7 +264,7 @@ bool ExportThread::setupAudio() { // initialize raw audio frame audio_frame = av_frame_alloc(); - audio_frame->sample_rate = sequence->audio_frequency; + audio_frame->sample_rate = Olive::ActiveSequence->audio_frequency; audio_frame->nb_samples = acodec_ctx->frame_size; if (audio_frame->nb_samples == 0) audio_frame->nb_samples = 256; // should possibly be smaller? audio_frame->format = AV_SAMPLE_FMT_S16; @@ -345,16 +346,16 @@ void ExportThread::run() { mutex.lock(); - while (sequence->playhead <= params.end_frame && continueEncode) { + while (Olive::ActiveSequence->playhead <= params.end_frame && continueEncode) { start_time = QDateTime::currentMSecsSinceEpoch(); if (params.audio_enabled) { - compose_audio(nullptr, sequence, true, false); + compose_audio(nullptr, Olive::ActiveSequence, true, false); } if (params.video_enabled) { do { // TODO optimize by rendering the next frame while encoding the last - renderer->start_render(nullptr, sequence, nullptr, video_frame->data[0], video_frame->linesize[0]/4); + renderer->start_render(nullptr, Olive::ActiveSequence, nullptr, video_frame->data[0], video_frame->linesize[0]/4); waitCond.wait(&mutex); if (!continueEncode) break; } while (renderer->did_texture_fail()); @@ -362,7 +363,7 @@ void ExportThread::run() { } // encode last frame while rendering next frame - double timecode_secs = double(sequence->playhead - params.start_frame) / sequence->frame_rate; + double timecode_secs = double(Olive::ActiveSequence->playhead - params.start_frame) / Olive::ActiveSequence->frame_rate; if (params.video_enabled) { // create sws_frame for converting pixel format @@ -423,12 +424,12 @@ void ExportThread::run() { // generating encoding statistics (time it took to encode this frame/estimated remaining time) frame_time = (QDateTime::currentMSecsSinceEpoch()-start_time); total_time += frame_time; - remaining_frames = (params.end_frame - sequence->playhead); + remaining_frames = (params.end_frame - Olive::ActiveSequence->playhead); avg_time = (total_time/frame_count); eta = (remaining_frames*avg_time); - emit progress_changed(qRound((double(sequence->playhead - params.start_frame) / double(params.end_frame - params.start_frame)) * 100.0), eta); - sequence->playhead++; + emit progress_changed(qRound((double(Olive::ActiveSequence->playhead - params.start_frame) / double(params.end_frame - params.start_frame)) * 100.0), eta); + Olive::ActiveSequence->playhead++; frame_count++; } @@ -442,7 +443,7 @@ void ExportThread::run() { if (params.audio_enabled) apkt_alloc = true; } - mainWindow->set_rendering_state(false); + Olive::Global.data()->set_rendering_state(false); if (params.audio_enabled && continueEncode) { // flush swresample diff --git a/io/loadthread.cpp b/io/loadthread.cpp index 290a26197..7e83c81dd 100644 --- a/io/loadthread.cpp +++ b/io/loadthread.cpp @@ -1,19 +1,17 @@ #include "loadthread.h" +#include "oliveglobal.h" + #include "mainwindow.h" + #include "panels/panels.h" -#include "panels/effectcontrols.h" -#include "panels/project.h" -#include "project/footage.h" + +#include "project/projectelements.h" + #include "io/config.h" -#include "project/clip.h" -#include "project/sequence.h" -#include "project/transition.h" -#include "project/effect.h" #include "playback/playback.h" #include "io/previewgenerator.h" #include "dialogs/loaddialog.h" -#include "project/media.h" #include "effects/internal/voideffect.h" #include "debug.h" @@ -575,7 +573,7 @@ Media* LoadThread::find_loaded_folder_by_id(int id) { void LoadThread::run() { mutex.lock(); - QFile file(project_url); + QFile file(Olive::ActiveProjectFilename); if (!file.open(QIODevice::ReadOnly)) { qCritical() << "Could not open file"; return; @@ -586,9 +584,9 @@ void LoadThread::run() { * case the project file has moved without the footage, * we check both */ - proj_dir = QFileInfo(project_url).absoluteDir(); - internal_proj_dir = QFileInfo(project_url).absoluteDir(); - internal_proj_url = project_url; + proj_dir = QFileInfo(Olive::ActiveProjectFilename).absoluteDir(); + internal_proj_dir = QFileInfo(Olive::ActiveProjectFilename).absoluteDir(); + internal_proj_url = Olive::ActiveProjectFilename; QXmlStreamReader stream(&file); @@ -696,7 +694,7 @@ void LoadThread::cancel() { void LoadThread::question_func(const QString &title, const QString &text, int buttons) { question_btn = QMessageBox::warning( - mainWindow, + Olive::MainWindow, title, text, static_cast(buttons)); @@ -706,12 +704,12 @@ void LoadThread::question_func(const QString &title, const QString &text, int bu void LoadThread::error_func() { if (xml_error) { qCritical() << "Error parsing XML." << error_str; - QMessageBox::critical(mainWindow, + QMessageBox::critical(Olive::MainWindow, tr("XML Parsing Error"), - tr("Couldn't load '%1'. %2").arg(project_url, error_str), + tr("Couldn't load '%1'. %2").arg(Olive::ActiveProjectFilename, error_str), QMessageBox::Ok); } else { - QMessageBox::critical(mainWindow, + QMessageBox::critical(Olive::MainWindow, tr("Project Load Error"), tr("Error loading project: %1").arg(error_str), QMessageBox::Ok); @@ -733,12 +731,13 @@ void LoadThread::success_func() { orig_filename.insert(insert_index, " (" + recover_text + ")"); counter++; } - mainWindow->updateTitle(orig_filename); + + Olive::Global.data()->update_project_filename(orig_filename); } else { - panel_project->add_recent_project(project_url); + panel_project->add_recent_project(Olive::ActiveProjectFilename); } - mainWindow->setWindowModified(autorecovery); + Olive::MainWindow->setWindowModified(autorecovery); if (open_seq != nullptr) set_sequence(open_seq); update_ui(false); } diff --git a/io/path.cpp b/io/path.cpp index dafa5ae7f..5bca2b4f4 100644 --- a/io/path.cpp +++ b/io/path.cpp @@ -8,41 +8,56 @@ #include "debug.h" -QString get_app_dir() { +QString get_app_path() { return QCoreApplication::applicationDirPath(); } +QDir get_app_dir() { + return QDir(get_app_path()); +} + QString get_data_path() { - QString app_dir = get_app_dir(); - if (QFileInfo::exists(app_dir + "/portable")) { - return app_dir; + QDir app_dir = get_app_dir(); + if (QFileInfo::exists(app_dir.filePath("portable"))) { + return app_dir.absolutePath(); } else { return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); } } +QDir get_data_dir() { + return QDir(get_data_path()); +} + QString get_config_path() { - QString app_dir = get_app_dir(); - if (QFileInfo::exists(app_dir + "/portable")) { - return app_dir; + QDir app_dir = get_app_dir(); + if (QFileInfo::exists(app_dir.filePath("portable"))) { + return app_dir.absolutePath(); } else { return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); } } +QDir get_config_dir() { + return QDir(get_config_path()); +} + QList get_effects_paths() { // returns a list of the effects paths to search QList effects_paths; + // get current app working directory + QDir app_dir = get_app_dir(); + // "effects" subfolder in program folder - best for Windows - effects_paths.append(get_app_dir() + "/effects"); + effects_paths.append(app_dir.filePath("effects")); // "Effects" folder one level above the program's directory - best for Mac - effects_paths.append(get_app_dir() + "/../Effects"); + effects_paths.append(app_dir.filePath("../Effects")); // folder in share folder - best for Linux - effects_paths.append(get_app_dir() + "/../share/olive-editor/effects"); + effects_paths.append(app_dir.filePath("/../share/olive-editor/effects")); // Olive will also accept a manually provided folder with an environment variable QString env_path(qgetenv("OLIVE_EFFECTS_PATH")); @@ -52,22 +67,29 @@ QList get_effects_paths() { } QString get_file_hash(const QString& filename) { - QFileInfo file_info(filename); - QString cache_file = filename.mid(filename.lastIndexOf('/')+1) + QString::number(file_info.size()) + QString::number(file_info.lastModified().toMSecsSinceEpoch()); + QFileInfo file_info(filename); + + QString cache_file = filename.mid(filename.lastIndexOf('/')+1) + + QString::number(file_info.size()) + + QString::number(file_info.lastModified().toMSecsSinceEpoch()); + return QCryptographicHash::hash(cache_file.toUtf8(), QCryptographicHash::Md5).toHex(); } QList get_language_paths() { QList language_paths; + // get current app working directory + QDir app_dir = get_app_dir(); + // subfolder in program folder - best for Windows (or compiling+running from source dir) - language_paths.append(get_app_dir() + "/ts"); + language_paths.append(app_dir.filePath("ts")); // folder one level above the program's directory - best for Mac - language_paths.append(get_app_dir() + "/../Translations"); + language_paths.append(app_dir.filePath("../Translations")); // folder in share folder - best for Linux - language_paths.append(get_app_dir() + "/../share/olive-editor/ts"); + language_paths.append(app_dir.filePath("../share/olive-editor/ts")); // Olive will also accept a manually provided folder with an environment variable QString env_path(qgetenv("OLIVE_LANG_PATH")); diff --git a/io/path.h b/io/path.h index 67771b330..9cd3f3b2f 100644 --- a/io/path.h +++ b/io/path.h @@ -2,10 +2,13 @@ #define PATH_H #include +#include -QString get_app_dir(); +QString get_app_path(); QString get_data_path(); +QDir get_data_dir(); QString get_config_path(); +QDir get_config_dir(); QList get_effects_paths(); QList get_language_paths(); diff --git a/io/proxygenerator.cpp b/io/proxygenerator.cpp index d09e58e63..3fc7effde 100644 --- a/io/proxygenerator.cpp +++ b/io/proxygenerator.cpp @@ -297,7 +297,7 @@ void ProxyGenerator::transcode(const ProxyInfo& info) { info.footage->proxy_path = info.path; qInfo() << "Finished creating proxy for" << info.footage->url; - QMetaObject::invokeMethod(mainWindow->statusBar(), + QMetaObject::invokeMethod(Olive::MainWindow->statusBar(), "showMessage", Qt::QueuedConnection, Q_ARG(QString, tr("Finished generating proxy for \"%1\"").arg(info.footage->url))); diff --git a/main.cpp b/main.cpp index f313bff71..4f748ab18 100644 --- a/main.cpp +++ b/main.cpp @@ -3,6 +3,8 @@ #include "debug.h" +#include "oliveglobal.h" + #include "io/config.h" extern "C" { @@ -11,12 +13,7 @@ extern "C" { } int main(int argc, char *argv[]) { - QString appName = "Olive (February 2019 | Alpha"; -#ifdef GITHASH - appName += " | "; - appName += GITHASH; -#endif - appName += ")"; + Olive::Global = QSharedPointer(new OliveGlobal); bool launch_fullscreen = false; QString load_proj; @@ -30,7 +27,7 @@ int main(int argc, char *argv[]) { #ifndef GITHASH qWarning() << "No Git commit information found"; #endif - printf("%s\n", appName.toUtf8().constData()); + printf("%s\n", Olive::AppName.toUtf8().constData()); return 0; } else if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) { printf("Usage: %s [options] [filename]\n\n" @@ -96,11 +93,13 @@ int main(int argc, char *argv[]) { QCoreApplication::setApplicationName("Olive"); QGuiApplication::setDesktopFileName("org.olivevideoeditor.Olive"); - MainWindow w(nullptr, appName); - w.updateTitle(""); + MainWindow w(nullptr); - if (!load_proj.isEmpty()) { - w.launch_with_project(load_proj); + // connect main window's first paint to global's init finished function + QObject::connect(&w, SIGNAL(finished_first_paint()), Olive::Global.data(), SLOT(finished_initialize())); + + if (!load_proj.isEmpty()) { + Olive::Global.data()->load_project_on_launch(load_proj); } if (launch_fullscreen) { w.showFullScreen(); diff --git a/mainwindow.cpp b/mainwindow.cpp index 28f0991b1..9c796a229 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,14 +1,15 @@ #include "mainwindow.h" +#include "oliveglobal.h" + +#include "ui/menuhelper.h" + +#include "project/projectelements.h" + #include "io/config.h" #include "io/path.h" #include "io/proxygenerator.h" -#include "project/footage.h" -#include "project/sequence.h" -#include "project/clip.h" -#include "project/undo.h" -#include "project/media.h" #include "project/projectfilter.h" #include "ui/sourcetable.h" @@ -54,14 +55,9 @@ #include #include -MainWindow* mainWindow; +MainWindow* Olive::MainWindow; #define DEFAULT_CSS "QPushButton::checked { background: rgb(25, 25, 25); }" -#define OLIVE_FILE_FILTER "Olive Project (*.ove)" - -QTimer autorecovery_timer; -QString config_fn; -bool demoNoticeShown = false; void MainWindow::setup_layout(bool reset) { panel_project->show(); @@ -81,7 +77,7 @@ void MainWindow::setup_layout(bool reset) { // load panels from file if (!reset) { - QFile panel_config(get_config_path() + "/layout"); + QFile panel_config(get_config_path() + "/layout"); if (panel_config.exists() && panel_config.open(QFile::ReadOnly)) { restoreState(panel_config.readAll(), 0); panel_config.close(); @@ -91,10 +87,9 @@ void MainWindow::setup_layout(bool reset) { layout()->update(); } -MainWindow::MainWindow(QWidget *parent, const QString &an) : - QMainWindow(parent), - enable_launch_with_project(false), - appName(an) +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + first_show(true) { init_custom_cursors(); @@ -102,7 +97,7 @@ MainWindow::MainWindow(QWidget *parent, const QString &an) : debug_dialog = new DebugDialog(this); - mainWindow = this; + Olive::MainWindow = this; // set up style? @@ -160,12 +155,12 @@ MainWindow::MainWindow(QWidget *parent, const QString &an) : if (deleted_ars > 0) qInfo() << "Deleted" << deleted_ars << "autorecovery" << ((deleted_ars == 1) ? "file that was" : "files that were") << "older than 7 days"; // delete previews older than 30 days - QDir preview_dir = QDir(data_dir + "/previews"); + QDir preview_dir = QDir(dir.filePath("previews")); if (preview_dir.exists()) { deleted_ars = 0; QStringList old_prevs = preview_dir.entryList(QDir::Files); for (int i=0;ishowMessage(tr("Welcome to %1").arg(appName)); + statusBar->showMessage(tr("Welcome to %1").arg(Olive::AppName)); setStatusBar(statusBar); // populate menu bars setup_menus(); - if (!data_dir.isEmpty()) { - // detect auto-recovery file - autorecovery_filename = data_dir + "/autorecovery.ove"; - if (QFile::exists(autorecovery_filename)) { - if (QMessageBox::question(nullptr, tr("Auto-recovery"), tr("Olive didn't close properly and an autorecovery file was detected. Would you like to open it?"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { - enable_launch_with_project = false; - open_project_worker(autorecovery_filename, true); - } - } - autorecovery_timer.setInterval(60000); - QObject::connect(&autorecovery_timer, SIGNAL(timeout()), this, SLOT(autorecover_interval())); - autorecovery_timer.start(); - } + Olive::Global.data()->check_for_autorecovery_file(); // set up panel layout setup_layout(false); @@ -255,6 +238,9 @@ MainWindow::MainWindow(QWidget *parent, const QString &an) : // start omnipotent proxy generator process proxy_generator.start(); + + // set default window title + updateTitle(); } MainWindow::~MainWindow() { @@ -262,28 +248,6 @@ MainWindow::~MainWindow() { close_debug_file(); } -void MainWindow::launch_with_project(const QString& s) { - project_url = s; - enable_launch_with_project = true; - demoNoticeShown = true; -} - -void MainWindow::make_new_menu(QMenu *parent) { - parent->addAction(tr("&Project"), this, SLOT(new_project()), QKeySequence("Ctrl+N"))->setProperty("id", "newproj"); - parent->addSeparator(); - parent->addAction(tr("&Sequence"), this, SLOT(new_sequence()), QKeySequence("Ctrl+Shift+N"))->setProperty("id", "newseq"); - parent->addAction(tr("&Folder"), this, SLOT(new_folder()))->setProperty("id", "newfolder"); -} - -void MainWindow::make_inout_menu(QMenu *parent) { - parent->addAction(tr("Set In Point"), this, SLOT(set_in_point()), QKeySequence("I"))->setProperty("id", "setinpoint"); - parent->addAction(tr("Set Out Point"), this, SLOT(set_out_point()), QKeySequence("O"))->setProperty("id", "setoutpoint"); - parent->addSeparator(); - parent->addAction(tr("Reset In Point"), this, SLOT(clear_in()))->setProperty("id", "resetin"); - parent->addAction(tr("Reset Out Point"), this, SLOT(clear_out()))->setProperty("id", "resetout"); - parent->addAction(tr("Clear In/Out Point"), this, SLOT(clear_inout()), QKeySequence("G"))->setProperty("id", "clearinout"); -} - void kbd_shortcut_processor(QByteArray& file, QMenu* menu, bool save, bool first) { QList actions = menu->actions(); for (int i=0;iheaders->hasFocus()) { panel_sequence_viewer->headers->delete_markers(); } else if (panel_timeline->focused()) { - panel_timeline->delete_selection(sequence->selections, false); + panel_timeline->delete_selection(Olive::ActiveSequence->selections, false); } else if (panel_effect_controls->is_focused()) { panel_effect_controls->delete_effects(); } else if (panel_project->is_focused()) { @@ -456,7 +411,7 @@ void MainWindow::zoom_out() { } void MainWindow::export_dialog() { - if (sequence == nullptr) { + if (Olive::ActiveSequence == nullptr) { QMessageBox::information(this, tr("No active sequence"), tr("Please open the sequence you wish to export."), QMessageBox::Ok); } else { ExportDialog e(this); @@ -465,9 +420,9 @@ void MainWindow::export_dialog() { } void MainWindow::ripple_delete() { - if (sequence != nullptr) { - if (sequence->selections.size() > 0) { - panel_timeline->delete_selection(sequence->selections, true); + if (Olive::ActiveSequence != nullptr) { + if (Olive::ActiveSequence->selections.size() > 0) { + panel_timeline->delete_selection(Olive::ActiveSequence->selections, true); } else if (config.hover_focus && get_focused_panel() == panel_timeline) { if (panel_timeline->can_ripple_empty_space(panel_timeline->cursor_frame, panel_timeline->cursor_track)) { panel_timeline->ripple_delete_empty_space(); @@ -494,10 +449,10 @@ void MainWindow::redo() { } void MainWindow::open_speed_dialog() { - if (sequence != nullptr) { + if (Olive::ActiveSequence != nullptr) { SpeedDialog s(this); - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { s.clips.append(c); } @@ -507,7 +462,7 @@ void MainWindow::open_speed_dialog() { } void MainWindow::cut() { - if (sequence != nullptr) { + if (Olive::ActiveSequence != nullptr) { QDockWidget* focused_panel = get_focused_panel(); if (panel_timeline == focused_panel) { panel_timeline->copy(true); @@ -518,7 +473,7 @@ void MainWindow::cut() { } void MainWindow::copy() { - if (sequence != nullptr) { + if (Olive::ActiveSequence != nullptr) { QDockWidget* focused_panel = get_focused_panel(); if (panel_timeline == focused_panel) { panel_timeline->copy(false); @@ -530,73 +485,11 @@ void MainWindow::copy() { void MainWindow::paste() { QDockWidget* focused_panel = get_focused_panel(); - if ((panel_timeline == focused_panel || panel_effect_controls == focused_panel) && sequence != nullptr) { + if ((panel_timeline == focused_panel || panel_effect_controls == focused_panel) && Olive::ActiveSequence != nullptr) { panel_timeline->paste(false); } } -void MainWindow::new_project() { - if (can_close_project()) { - panel_effect_controls->clear_effects(true); - undo_stack.clear(); - project_url.clear(); - panel_project->new_project(); - updateTitle(""); - update_ui(false); - panel_project->tree_view->update(); - } -} - -void MainWindow::autorecover_interval() { - if (isWindowModified()) { - panel_project->save_project(true); - qInfo() << "Auto-recovery project saved"; - } -} - -bool MainWindow::save_project_as() { - QString fn = QFileDialog::getSaveFileName(this, tr("Save Project As..."), "", OLIVE_FILE_FILTER); - if (!fn.isEmpty()) { - if (!fn.endsWith(".ove", Qt::CaseInsensitive)) { - fn += ".ove"; - } - updateTitle(fn); - panel_project->save_project(false); - return true; - } - return false; -} - -bool MainWindow::save_project() { - if (project_url.isEmpty()) { - return save_project_as(); - } else { - panel_project->save_project(false); - return true; - } -} - -bool MainWindow::can_close_project() { - if (isWindowModified()) { - QMessageBox* m = new QMessageBox( - QMessageBox::Question, - tr("Unsaved Project"), - tr("This project has changed since it was last saved. Would you like to save it before closing?"), - QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel, - this - ); - m->setWindowModality(Qt::WindowModal); - int r = m->exec(); - delete m; - if (r == QMessageBox::Yes) { - return save_project(); - } else if (r == QMessageBox::Cancel) { - return false; - } - } - return true; -} - void MainWindow::setup_menus() { QMenuBar* menuBar = new QMenuBar(this); setMenuBar(menuBar); @@ -607,9 +500,9 @@ void MainWindow::setup_menus() { connect(file_menu, SIGNAL(aboutToShow()), this, SLOT(fileMenu_About_To_Be_Shown())); QMenu* new_menu = file_menu->addMenu(tr("&New")); - make_new_menu(new_menu); + Olive::MenuHelper.make_new_menu(new_menu); - file_menu->addAction(tr("&Open Project"), this, SLOT(open_project()), QKeySequence("Ctrl+O"))->setProperty("id", "openproj"); + file_menu->addAction(tr("&Open Project"), Olive::Global.data(), SLOT(open_project()), QKeySequence("Ctrl+O"))->setProperty("id", "openproj"); clear_open_recent_action = new QAction(tr("Clear Recent List"), menuBar); clear_open_recent_action->setProperty("id", "clearopenrecent"); @@ -619,8 +512,8 @@ void MainWindow::setup_menus() { open_recent->addAction(clear_open_recent_action); - file_menu->addAction(tr("&Save Project"), this, SLOT(save_project()), QKeySequence("Ctrl+S"))->setProperty("id", "saveproj"); - file_menu->addAction(tr("Save Project &As"), this, SLOT(save_project_as()), QKeySequence("Ctrl+Shift+S"))->setProperty("id", "saveprojas"); + file_menu->addAction(tr("&Save Project"), Olive::Global.data(), SLOT(save_project()), QKeySequence("Ctrl+S"))->setProperty("id", "saveproj"); + file_menu->addAction(tr("Save Project &As"), Olive::Global.data(), SLOT(save_project_as()), QKeySequence("Ctrl+Shift+S"))->setProperty("id", "saveprojas"); file_menu->addSeparator(); @@ -677,7 +570,7 @@ void MainWindow::setup_menus() { edit_menu->addSeparator(); - make_inout_menu(edit_menu); + Olive::MenuHelper.make_inout_menu(edit_menu); edit_menu->addAction(tr("Delete In/Out Point"), this, SLOT(delete_inout()), QKeySequence(";"))->setProperty("id", "deleteinout"); edit_menu->addAction(tr("Ripple Delete In/Out Point"), this, SLOT(ripple_delete_inout()), QKeySequence("'"))->setProperty("id", "rippledeleteinout"); @@ -1016,13 +909,15 @@ void MainWindow::set_button_action_checked(QAction *a) { a->setChecked(reinterpret_cast(a->data().value())->isChecked()); } -void MainWindow::updateTitle(const QString& url) { - project_url = url; - setWindowTitle(appName + " - " + ((project_url.isEmpty()) ? tr("") : project_url) + "[*]"); +void MainWindow::updateTitle() { + setWindowTitle(QString("%1 - %2[*]").arg(Olive::AppName, + (Olive::ActiveProjectFilename.isEmpty()) ? + tr("") : Olive::ActiveProjectFilename) + ); } void MainWindow::closeEvent(QCloseEvent *e) { - if (can_close_project()) { + if (Olive::Global.data()->can_close_project()) { // stop proxy generator thread proxy_generator.cancel(); @@ -1036,18 +931,22 @@ void MainWindow::closeEvent(QCloseEvent *e) { panel_footage_viewer->set_main_sequence(); QString data_dir = get_data_path(); - QString config_dir = get_config_path(); + QString config_path = get_config_path(); if (!data_dir.isEmpty() && !autorecovery_filename.isEmpty()) { if (QFile::exists(autorecovery_filename)) { QFile::rename(autorecovery_filename, autorecovery_filename + "." + QDateTime::currentDateTimeUtc().toString("yyyyMMddHHmmss")); } } - if (!config_dir.isEmpty() && !config_fn.isEmpty()) { + if (!config_path.isEmpty()) { + QDir config_dir = QDir(config_path); + + QString config_fn = config_dir.filePath("config.xml"); + // save settings config.save(config_fn); // save panel layout - QFile panel_config(config_dir + "/layout"); + QFile panel_config(config_path + "/layout"); if (panel_config.open(QFile::WriteOnly)) { panel_config.write(saveState(0)); panel_config.close(); @@ -1055,7 +954,7 @@ void MainWindow::closeEvent(QCloseEvent *e) { qCritical() << "Failed to save layout"; } - save_shortcuts(config_dir + "/shortcuts"); + save_shortcuts(config_path + "/shortcuts"); } stop_audio(); @@ -1068,42 +967,17 @@ void MainWindow::closeEvent(QCloseEvent *e) { void MainWindow::paintEvent(QPaintEvent *event) { QMainWindow::paintEvent(event); - if (enable_launch_with_project) { - QTimer::singleShot(10, this, SLOT(load_with_launch())); - enable_launch_with_project = false; - } - if (!demoNoticeShown) { -#ifndef QT_DEBUG - DemoNotice* d = new DemoNotice(this); - connect(d, SIGNAL(finished(int)), d, SLOT(deleteLater())); - d->open(); -#endif - demoNoticeShown = true; - } + if (first_show) { + emit finished_first_paint(); + first_show = false; + } } void MainWindow::clear_undo_stack() { undo_stack.clear(); } -void MainWindow::open_project() { - QString fn = QFileDialog::getOpenFileName(this, tr("Open Project..."), "", OLIVE_FILE_FILTER); - if (!fn.isEmpty() && can_close_project()) { - open_project_worker(fn, false); - } -} - -void MainWindow::open_project_worker(const QString& fn, bool autorecovery) { - updateTitle(fn); - panel_project->load_project(autorecovery); - undo_stack.clear(); -} - -void MainWindow::load_with_launch() { - open_project_worker(project_url, false); -} - void MainWindow::show_action_search() { ActionSearch as(this); as.exec(); @@ -1214,14 +1088,14 @@ void MainWindow::decrease_speed() { void MainWindow::prev_cut() { QDockWidget* focused_panel = get_focused_panel(); - if (sequence != nullptr && (panel_timeline == focused_panel || panel_sequence_viewer == focused_panel)) { + if (Olive::ActiveSequence != nullptr && (panel_timeline == focused_panel || panel_sequence_viewer == focused_panel)) { panel_timeline->previous_cut(); } } void MainWindow::next_cut() { QDockWidget* focused_panel = get_focused_panel(); - if (sequence != nullptr && (panel_timeline == focused_panel || panel_sequence_viewer == focused_panel)) { + if (Olive::ActiveSequence != nullptr && (panel_timeline == focused_panel || panel_sequence_viewer == focused_panel)) { panel_timeline->next_cut(); } } @@ -1376,7 +1250,7 @@ void MainWindow::fileMenu_About_To_Be_Shown() { QAction* action = open_recent->addAction(recent_projects.at(i)); action->setProperty("keyignore", true); action->setData(i); - connect(action, SIGNAL(triggered()), this, SLOT(load_recent_project())); + connect(action, SIGNAL(triggered()), Olive::Global.data(), SLOT(open_recent())); } open_recent->addSeparator(); @@ -1386,26 +1260,6 @@ void MainWindow::fileMenu_About_To_Be_Shown() { } } -void MainWindow::fileMenu_About_To_Hide() { -} - -void MainWindow::load_recent_project() { - int index = static_cast(sender())->data().toInt(); - QString recent_url = recent_projects.at(index); - if (!QFile::exists(recent_url)) { - if (QMessageBox::question( - this, - tr("Missing recent project"), - tr("The project '%1' no longer exists. Would you like to remove it from the recent projects list?").arg(recent_url), - QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { - recent_projects.removeAt(index); - panel_project->save_recent_projects(); - } - } else if (can_close_project()) { - open_project_worker(recent_url, false); - } -} - void MainWindow::ripple_to_in_point() { if (panel_timeline->focused()) panel_timeline->ripple_to_in_point(true, true); } @@ -1526,7 +1380,7 @@ void MainWindow::set_tsa_custom() { } void MainWindow::set_marker() { - if (sequence != nullptr) { + if (Olive::ActiveSequence != nullptr) { QDockWidget* focused_panel = get_focused_panel(); if (focused_panel == panel_timeline) { @@ -1540,11 +1394,11 @@ void MainWindow::set_marker() { } void MainWindow::toggle_enable_clips() { - if (sequence != nullptr) { + if (Olive::ActiveSequence != nullptr) { ComboAction* ca = new ComboAction(); bool push_undo = false; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { ca->append(new SetEnableCommand(c, !c->enabled)); push_undo = true; @@ -1570,13 +1424,13 @@ void MainWindow::edit_to_out_point() { } void MainWindow::nest() { - if (sequence != nullptr) { + if (Olive::ActiveSequence != nullptr) { QVector selected_clips; long earliest_point = LONG_MAX; // get selected clips - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { selected_clips.append(i); earliest_point = qMin(c->timeline_in, earliest_point); @@ -1591,19 +1445,19 @@ void MainWindow::nest() { // create "nest" sequence s->name = panel_project->get_next_sequence_name(tr("Nested Sequence")); - s->width = sequence->width; - s->height = sequence->height; - s->frame_rate = sequence->frame_rate; - s->audio_frequency = sequence->audio_frequency; - s->audio_layout = sequence->audio_layout; + s->width = Olive::ActiveSequence->width; + s->height = Olive::ActiveSequence->height; + s->frame_rate = Olive::ActiveSequence->frame_rate; + s->audio_frequency = Olive::ActiveSequence->audio_frequency; + s->audio_layout = Olive::ActiveSequence->audio_layout; // copy all selected clips to the nest for (int i=0;iappend(new DeleteClipAction(sequence, selected_clips.at(i))); + ca->append(new DeleteClipAction(Olive::ActiveSequence, selected_clips.at(i))); // copy to new - Clip* copy = sequence->clips.at(selected_clips.at(i))->copy(s); + Clip* copy = Olive::ActiveSequence->clips.at(selected_clips.at(i))->copy(s); copy->timeline_in -= earliest_point; copy->timeline_out -= earliest_point; s->clips.append(copy); @@ -1618,11 +1472,11 @@ void MainWindow::nest() { // add nested sequence to active sequence QVector media_list; media_list.append(m); - panel_timeline->create_ghosts_from_media(sequence, earliest_point, media_list); - panel_timeline->add_clips_from_ghosts(ca, sequence); + panel_timeline->create_ghosts_from_media(Olive::ActiveSequence, earliest_point, media_list); + panel_timeline->add_clips_from_ghosts(ca, Olive::ActiveSequence); panel_effect_controls->clear_effects(true); - sequence->selections.clear(); + Olive::ActiveSequence->selections.clear(); undo_stack.push(ca); @@ -1633,7 +1487,7 @@ void MainWindow::nest() { void MainWindow::paste_insert() { QDockWidget* focused_panel = get_focused_panel(); - if (focused_panel == panel_timeline && sequence != nullptr) { + if (focused_panel == panel_timeline && Olive::ActiveSequence != nullptr) { panel_timeline->paste(true); } } diff --git a/mainwindow.h b/mainwindow.h index 50f4c2798..96c84b08c 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -11,36 +11,33 @@ class Timeline; class MainWindow : public QMainWindow { Q_OBJECT public: - explicit MainWindow(QWidget *parent, const QString& an); - void updateTitle(const QString &url); - ~MainWindow(); + explicit MainWindow(QWidget *parent); + virtual ~MainWindow() override; + + void updateTitle(); void launch_with_project(const QString& s); - void make_new_menu(QMenu* parent); - void make_inout_menu(QMenu* parent); - void load_shortcuts(const QString &fn, bool first = false); void save_shortcuts(const QString &fn); void load_css_from_file(const QString& fn); - void set_rendering_state(bool rendering); - public slots: void undo(); void redo(); void open_speed_dialog(); void cut(); void copy(); - void paste(); - void new_project(); - void autorecover_interval(); + void paste(); void nest(); void toggle_full_screen(); void toggle_bool_action(); +signals: + void finished_first_paint(); + protected: virtual void closeEvent(QCloseEvent *) override; virtual void paintEvent(QPaintEvent *event) override; @@ -60,10 +57,6 @@ private slots: void export_dialog(); void ripple_delete(); - void open_project(); - bool save_project_as(); - bool save_project(); - void go_to_in(); void go_to_out(); void go_to_start(); @@ -88,8 +81,7 @@ private slots: void full_screen_viewer(); - void fileMenu_About_To_Be_Shown(); - void fileMenu_About_To_Hide(); + void fileMenu_About_To_Be_Shown(); void editMenu_About_To_Be_Shown(); void windowMenu_About_To_Be_Shown(); void playbackMenu_About_To_Be_Shown(); @@ -100,9 +92,7 @@ private slots: void add_default_transition(); - void new_folder(); - - void load_recent_project(); + void new_folder(); void ripple_to_in_point(); void ripple_to_out_point(); @@ -132,16 +122,12 @@ private slots: void set_autoscroll(); void menu_click_button(); void toggle_panel_visibility(); - void set_timecode_view(); - void open_project_worker(const QString &fn, bool autorecovery); - - void load_with_launch(); + void set_timecode_view(); void show_action_search(); private: void setup_layout(bool reset); - bool can_close_project(); void setup_menus(); void set_bool_action_checked(QAction* a); @@ -202,14 +188,15 @@ private: QAction* undo_action; QAction* redo_action; - bool enable_launch_with_project; - - QString appName; - // used to store the panel state when one panel is maximized QByteArray temp_panel_state; + + // used in paintEvent() to determine the first paintEvent() performed + bool first_show; }; -extern MainWindow* mainWindow; +namespace Olive { + extern MainWindow* MainWindow; +} #endif // MAINWINDOW_H diff --git a/olive.pro b/olive.pro index 97df2a284..76763b4b9 100644 --- a/olive.pro +++ b/olive.pro @@ -1,320 +1,325 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2018-05-11T10:31:59 -# -#------------------------------------------------- - -QT += core gui multimedia opengl - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -mac { - TARGET = Olive -} -!mac { - TARGET = olive-editor -} -TEMPLATE = app - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -# Tries to get the current Git short hash -system("which git") { - GITHASHVAR = $$system(git --git-dir $$PWD/.git --work-tree $$PWD log -1 --format=%h) - DEFINES += GITHASH=\\"\"$$GITHASHVAR\\"\" -} - -CONFIG += c++11 - -CONFIG(debug, debug|release) { - CONFIG += console -} - -SOURCES += \ - main.cpp \ - mainwindow.cpp \ - panels/project.cpp \ - panels/effectcontrols.cpp \ - panels/viewer.cpp \ - panels/timeline.cpp \ - ui/sourcetable.cpp \ - dialogs/aboutdialog.cpp \ - ui/timelinewidget.cpp \ - project/media.cpp \ - project/footage.cpp \ - project/sequence.cpp \ - project/clip.cpp \ - playback/playback.cpp \ - playback/audio.cpp \ - io/config.cpp \ - dialogs/newsequencedialog.cpp \ - ui/viewerwidget.cpp \ - ui/viewercontainer.cpp \ - dialogs/exportdialog.cpp \ - ui/collapsiblewidget.cpp \ - panels/panels.cpp \ - playback/cacher.cpp \ - io/exportthread.cpp \ - ui/timelineheader.cpp \ - io/previewgenerator.cpp \ - ui/labelslider.cpp \ - dialogs/preferencesdialog.cpp \ - ui/audiomonitor.cpp \ - project/undo.cpp \ - ui/scrollarea.cpp \ - ui/comboboxex.cpp \ - ui/colorbutton.cpp \ - dialogs/replaceclipmediadialog.cpp \ - ui/fontcombobox.cpp \ - ui/checkboxex.cpp \ - ui/keyframeview.cpp \ - ui/texteditex.cpp \ - dialogs/demonotice.cpp \ - project/marker.cpp \ - dialogs/speeddialog.cpp \ - dialogs/mediapropertiesdialog.cpp \ - io/crc32.cpp \ - project/projectmodel.cpp \ - io/loadthread.cpp \ - dialogs/loaddialog.cpp \ - debug.cpp \ - io/path.cpp \ - effects/internal/linearfadetransition.cpp \ - effects/internal/transformeffect.cpp \ - effects/internal/solideffect.cpp \ - effects/internal/texteffect.cpp \ - effects/internal/timecodeeffect.cpp \ - effects/internal/audionoiseeffect.cpp \ - effects/internal/paneffect.cpp \ - effects/internal/toneeffect.cpp \ - effects/internal/volumeeffect.cpp \ - effects/internal/crossdissolvetransition.cpp \ - effects/internal/shakeeffect.cpp \ - effects/internal/exponentialfadetransition.cpp \ - effects/internal/logarithmicfadetransition.cpp \ - effects/internal/cornerpineffect.cpp \ - io/math.cpp \ - io/qpainterwrapper.cpp \ - project/effect.cpp \ - project/transition.cpp \ - project/effectrow.cpp \ - project/effectfield.cpp \ - effects/internal/cubetransition.cpp \ - project/effectgizmo.cpp \ - io/clipboard.cpp \ - dialogs/stabilizerdialog.cpp \ - io/avtogl.cpp \ - ui/resizablescrollbar.cpp \ - ui/sourceiconview.cpp \ - project/sourcescommon.cpp \ - ui/keyframenavigator.cpp \ - panels/grapheditor.cpp \ - ui/graphview.cpp \ - ui/keyframedrawing.cpp \ - ui/clickablelabel.cpp \ - project/keyframe.cpp \ - ui/rectangleselect.cpp \ - dialogs/actionsearch.cpp \ - ui/embeddedfilechooser.cpp \ - effects/internal/fillleftrighteffect.cpp \ - effects/internal/voideffect.cpp \ - dialogs/texteditdialog.cpp \ - dialogs/debugdialog.cpp \ - ui/renderthread.cpp \ - ui/renderfunctions.cpp \ - ui/viewerwindow.cpp \ - project/projectfilter.cpp \ - effects/internal/frei0reffect.cpp \ - project/effectloaders.cpp \ - io/crossplatformlib.cpp \ - effects/internal/vsthost.cpp \ - ui/flowlayout.cpp \ - dialogs/proxydialog.cpp \ - io/proxygenerator.cpp \ - dialogs/advancedvideodialog.cpp \ - ui/cursors.cpp - -HEADERS += \ - mainwindow.h \ - panels/project.h \ - panels/effectcontrols.h \ - panels/viewer.h \ - panels/timeline.h \ - ui/sourcetable.h \ - dialogs/aboutdialog.h \ - ui/timelinewidget.h \ - project/media.h \ - project/footage.h \ - project/sequence.h \ - project/clip.h \ - playback/playback.h \ - playback/audio.h \ - io/config.h \ - dialogs/newsequencedialog.h \ - ui/viewerwidget.h \ - ui/viewercontainer.h \ - dialogs/exportdialog.h \ - ui/collapsiblewidget.h \ - panels/panels.h \ - playback/cacher.h \ - io/exportthread.h \ - ui/timelinetools.h \ - ui/timelineheader.h \ - io/previewgenerator.h \ - ui/labelslider.h \ - dialogs/preferencesdialog.h \ - ui/audiomonitor.h \ - project/undo.h \ - ui/scrollarea.h \ - ui/comboboxex.h \ - ui/colorbutton.h \ - dialogs/replaceclipmediadialog.h \ - ui/fontcombobox.h \ - ui/checkboxex.h \ - ui/keyframeview.h \ - ui/texteditex.h \ - dialogs/demonotice.h \ - project/marker.h \ - project/selection.h \ - dialogs/speeddialog.h \ - dialogs/mediapropertiesdialog.h \ - io/crc32.h \ - project/projectmodel.h \ - io/loadthread.h \ - dialogs/loaddialog.h \ - debug.h \ - io/path.h \ - effects/internal/transformeffect.h \ - effects/internal/solideffect.h \ - effects/internal/texteffect.h \ - effects/internal/timecodeeffect.h \ - effects/internal/audionoiseeffect.h \ - effects/internal/paneffect.h \ - effects/internal/toneeffect.h \ - effects/internal/volumeeffect.h \ - effects/internal/shakeeffect.h \ - effects/internal/linearfadetransition.h \ - effects/internal/crossdissolvetransition.h \ - effects/internal/exponentialfadetransition.h \ - effects/internal/logarithmicfadetransition.h \ - effects/internal/cornerpineffect.h \ - io/math.h \ - io/qpainterwrapper.h \ - project/effect.h \ - project/transition.h \ - project/effectrow.h \ - project/effectfield.h \ - effects/internal/cubetransition.h \ - project/effectgizmo.h \ - io/clipboard.h \ - dialogs/stabilizerdialog.h \ - io/avtogl.h \ - ui/resizablescrollbar.h \ - ui/sourceiconview.h \ - project/sourcescommon.h \ - ui/keyframenavigator.h \ - panels/grapheditor.h \ - ui/graphview.h \ - ui/keyframedrawing.h \ - ui/clickablelabel.h \ - project/keyframe.h \ - ui/rectangleselect.h \ - dialogs/actionsearch.h \ - ui/embeddedfilechooser.h \ - effects/internal/fillleftrighteffect.h \ - effects/internal/voideffect.h \ - dialogs/texteditdialog.h \ - dialogs/debugdialog.h \ - ui/renderthread.h \ - ui/renderfunctions.h \ - ui/viewerwindow.h \ - project/projectfilter.h \ - effects/internal/frei0reffect.h \ - project/effectloaders.h \ - io/crossplatformlib.h \ - effects/internal/vsthost.h \ - ui/flowlayout.h \ - dialogs/proxydialog.h \ - io/proxygenerator.h \ - dialogs/advancedvideodialog.h \ - ui/cursors.h - -FORMS += - -TRANSLATIONS += \ - ts/olive_de.ts \ - ts/olive_es.ts \ - ts/olive_fr.ts \ - ts/olive_it.ts \ - ts/olive_cs.ts \ - ts/olive_ar.ts \ - ts/olive_ru.ts \ - ts/olive_bs.ts \ - ts/olive_sr.ts - -win32 { - RC_FILE = packaging/windows/resources.rc - LIBS += -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample -lopengl32 -luser32 -} - -mac { - LIBS += -L/usr/local/lib -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample -framework CoreFoundation - ICON = packaging/macos/olive.icns - INCLUDEPATH = /usr/local/include -} - -unix:!mac { - CONFIG += link_pkgconfig - PKGCONFIG += libavutil libavformat libavcodec libavfilter libswscale libswresample - LIBS += -ldl -} - -RESOURCES += \ - icons/icons.qrc \ - effects/internal/internalshaders.qrc \ - cursors/cursors.qrc - -unix:!mac:isEmpty(PREFIX) { - PREFIX = /usr/local -} - -unix:!mac:target.path = $$PREFIX/bin - -effects.files = $$PWD/effects/*.frag $$PWD/effects/*.xml $$PWD/effects/*.vert -unix:!mac:effects.path = $$PREFIX/share/olive-editor/effects - -translations.files = $$PWD/ts/*.qm -unix:!mac:translations.path = $$PREFIX/share/olive-editor/ts - -unix:!mac { - metainfo.files = $$PWD/packaging/linux/org.olivevideoeditor.Olive.appdata.xml - metainfo.path = $$PREFIX/share/metainfo - desktop.files = $$PWD/packaging/linux/org.olivevideoeditor.Olive.desktop - desktop.path = $$PREFIX/share/applications - mime.files = $$PWD/packaging/linux/org.olivevideoeditor.Olive.xml - mime.path = $$PREFIX/share/mime/packages - icon16.files = $$PWD/packaging/linux/icons/16x16/org.olivevideoeditor.Olive.png - icon16.path = $$PREFIX/share/icons/hicolor/16x16/apps - icon32.files = $$PWD/packaging/linux/icons/32x32/org.olivevideoeditor.Olive.png - icon32.path = $$PREFIX/share/icons/hicolor/32x32/apps - icon48.files = $$PWD/packaging/linux/icons/48x48/org.olivevideoeditor.Olive.png - icon48.path = $$PREFIX/share/icons/hicolor/48x48/apps - icon64.files = $$PWD/packaging/linux/icons/64x64/org.olivevideoeditor.Olive.png - icon64.path = $$PREFIX/share/icons/hicolor/64x64/apps - icon128.files = $$PWD/packaging/linux/icons/128x128/org.olivevideoeditor.Olive.png - icon128.path = $$PREFIX/share/icons/hicolor/128x128/apps - icon256.files = $$PWD/packaging/linux/icons/256x256/org.olivevideoeditor.Olive.png - icon256.path = $$PREFIX/share/icons/hicolor/256x256/apps - icon512.files = $$PWD/packaging/linux/icons/512x512/org.olivevideoeditor.Olive.png - icon512.path = $$PREFIX/share/icons/hicolor/512x512/apps - INSTALLS += target effects translations metainfo desktop mime icon16 icon32 icon48 icon64 icon128 icon256 icon512 -} +#------------------------------------------------- +# +# Project created by QtCreator 2018-05-11T10:31:59 +# +#------------------------------------------------- + +QT += core gui multimedia opengl + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +mac { + TARGET = Olive +} +!mac { + TARGET = olive-editor +} +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +# Tries to get the current Git short hash +system("which git") { + GITHASHVAR = $$system(git --git-dir $$PWD/.git --work-tree $$PWD log -1 --format=%h) + DEFINES += GITHASH=\\"\"$$GITHASHVAR\\"\" +} + +CONFIG += c++11 + +CONFIG(debug, debug|release) { + CONFIG += console +} + +SOURCES += \ + main.cpp \ + mainwindow.cpp \ + panels/project.cpp \ + panels/effectcontrols.cpp \ + panels/viewer.cpp \ + panels/timeline.cpp \ + ui/sourcetable.cpp \ + dialogs/aboutdialog.cpp \ + ui/timelinewidget.cpp \ + project/media.cpp \ + project/footage.cpp \ + project/sequence.cpp \ + project/clip.cpp \ + playback/playback.cpp \ + playback/audio.cpp \ + io/config.cpp \ + dialogs/newsequencedialog.cpp \ + ui/viewerwidget.cpp \ + ui/viewercontainer.cpp \ + dialogs/exportdialog.cpp \ + ui/collapsiblewidget.cpp \ + panels/panels.cpp \ + playback/cacher.cpp \ + io/exportthread.cpp \ + ui/timelineheader.cpp \ + io/previewgenerator.cpp \ + ui/labelslider.cpp \ + dialogs/preferencesdialog.cpp \ + ui/audiomonitor.cpp \ + project/undo.cpp \ + ui/scrollarea.cpp \ + ui/comboboxex.cpp \ + ui/colorbutton.cpp \ + dialogs/replaceclipmediadialog.cpp \ + ui/fontcombobox.cpp \ + ui/checkboxex.cpp \ + ui/keyframeview.cpp \ + ui/texteditex.cpp \ + dialogs/demonotice.cpp \ + project/marker.cpp \ + dialogs/speeddialog.cpp \ + dialogs/mediapropertiesdialog.cpp \ + io/crc32.cpp \ + project/projectmodel.cpp \ + io/loadthread.cpp \ + dialogs/loaddialog.cpp \ + debug.cpp \ + io/path.cpp \ + effects/internal/linearfadetransition.cpp \ + effects/internal/transformeffect.cpp \ + effects/internal/solideffect.cpp \ + effects/internal/texteffect.cpp \ + effects/internal/timecodeeffect.cpp \ + effects/internal/audionoiseeffect.cpp \ + effects/internal/paneffect.cpp \ + effects/internal/toneeffect.cpp \ + effects/internal/volumeeffect.cpp \ + effects/internal/crossdissolvetransition.cpp \ + effects/internal/shakeeffect.cpp \ + effects/internal/exponentialfadetransition.cpp \ + effects/internal/logarithmicfadetransition.cpp \ + effects/internal/cornerpineffect.cpp \ + io/math.cpp \ + io/qpainterwrapper.cpp \ + project/effect.cpp \ + project/transition.cpp \ + project/effectrow.cpp \ + project/effectfield.cpp \ + effects/internal/cubetransition.cpp \ + project/effectgizmo.cpp \ + io/clipboard.cpp \ + dialogs/stabilizerdialog.cpp \ + io/avtogl.cpp \ + ui/resizablescrollbar.cpp \ + ui/sourceiconview.cpp \ + project/sourcescommon.cpp \ + ui/keyframenavigator.cpp \ + panels/grapheditor.cpp \ + ui/graphview.cpp \ + ui/keyframedrawing.cpp \ + ui/clickablelabel.cpp \ + project/keyframe.cpp \ + ui/rectangleselect.cpp \ + dialogs/actionsearch.cpp \ + ui/embeddedfilechooser.cpp \ + effects/internal/fillleftrighteffect.cpp \ + effects/internal/voideffect.cpp \ + dialogs/texteditdialog.cpp \ + dialogs/debugdialog.cpp \ + ui/renderthread.cpp \ + ui/renderfunctions.cpp \ + ui/viewerwindow.cpp \ + project/projectfilter.cpp \ + effects/internal/frei0reffect.cpp \ + project/effectloaders.cpp \ + io/crossplatformlib.cpp \ + effects/internal/vsthost.cpp \ + ui/flowlayout.cpp \ + dialogs/proxydialog.cpp \ + io/proxygenerator.cpp \ + dialogs/advancedvideodialog.cpp \ + ui/cursors.cpp \ + ui/menuhelper.cpp \ + oliveglobal.cpp + +HEADERS += \ + mainwindow.h \ + panels/project.h \ + panels/effectcontrols.h \ + panels/viewer.h \ + panels/timeline.h \ + ui/sourcetable.h \ + dialogs/aboutdialog.h \ + ui/timelinewidget.h \ + project/media.h \ + project/footage.h \ + project/sequence.h \ + project/clip.h \ + playback/playback.h \ + playback/audio.h \ + io/config.h \ + dialogs/newsequencedialog.h \ + ui/viewerwidget.h \ + ui/viewercontainer.h \ + dialogs/exportdialog.h \ + ui/collapsiblewidget.h \ + panels/panels.h \ + playback/cacher.h \ + io/exportthread.h \ + ui/timelinetools.h \ + ui/timelineheader.h \ + io/previewgenerator.h \ + ui/labelslider.h \ + dialogs/preferencesdialog.h \ + ui/audiomonitor.h \ + project/undo.h \ + ui/scrollarea.h \ + ui/comboboxex.h \ + ui/colorbutton.h \ + dialogs/replaceclipmediadialog.h \ + ui/fontcombobox.h \ + ui/checkboxex.h \ + ui/keyframeview.h \ + ui/texteditex.h \ + dialogs/demonotice.h \ + project/marker.h \ + project/selection.h \ + dialogs/speeddialog.h \ + dialogs/mediapropertiesdialog.h \ + io/crc32.h \ + project/projectmodel.h \ + io/loadthread.h \ + dialogs/loaddialog.h \ + debug.h \ + io/path.h \ + effects/internal/transformeffect.h \ + effects/internal/solideffect.h \ + effects/internal/texteffect.h \ + effects/internal/timecodeeffect.h \ + effects/internal/audionoiseeffect.h \ + effects/internal/paneffect.h \ + effects/internal/toneeffect.h \ + effects/internal/volumeeffect.h \ + effects/internal/shakeeffect.h \ + effects/internal/linearfadetransition.h \ + effects/internal/crossdissolvetransition.h \ + effects/internal/exponentialfadetransition.h \ + effects/internal/logarithmicfadetransition.h \ + effects/internal/cornerpineffect.h \ + io/math.h \ + io/qpainterwrapper.h \ + project/effect.h \ + project/transition.h \ + project/effectrow.h \ + project/effectfield.h \ + effects/internal/cubetransition.h \ + project/effectgizmo.h \ + io/clipboard.h \ + dialogs/stabilizerdialog.h \ + io/avtogl.h \ + ui/resizablescrollbar.h \ + ui/sourceiconview.h \ + project/sourcescommon.h \ + ui/keyframenavigator.h \ + panels/grapheditor.h \ + ui/graphview.h \ + ui/keyframedrawing.h \ + ui/clickablelabel.h \ + project/keyframe.h \ + ui/rectangleselect.h \ + dialogs/actionsearch.h \ + ui/embeddedfilechooser.h \ + effects/internal/fillleftrighteffect.h \ + effects/internal/voideffect.h \ + dialogs/texteditdialog.h \ + dialogs/debugdialog.h \ + ui/renderthread.h \ + ui/renderfunctions.h \ + ui/viewerwindow.h \ + project/projectfilter.h \ + effects/internal/frei0reffect.h \ + project/effectloaders.h \ + io/crossplatformlib.h \ + effects/internal/vsthost.h \ + ui/flowlayout.h \ + dialogs/proxydialog.h \ + io/proxygenerator.h \ + dialogs/advancedvideodialog.h \ + ui/cursors.h \ + ui/menuhelper.h \ + oliveglobal.h \ + project/projectelements.h + +FORMS += + +TRANSLATIONS += \ + ts/olive_de.ts \ + ts/olive_es.ts \ + ts/olive_fr.ts \ + ts/olive_it.ts \ + ts/olive_cs.ts \ + ts/olive_ar.ts \ + ts/olive_ru.ts \ + ts/olive_bs.ts \ + ts/olive_sr.ts + +win32 { + RC_FILE = packaging/windows/resources.rc + LIBS += -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample -lopengl32 -luser32 +} + +mac { + LIBS += -L/usr/local/lib -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample -framework CoreFoundation + ICON = packaging/macos/olive.icns + INCLUDEPATH = /usr/local/include +} + +unix:!mac { + CONFIG += link_pkgconfig + PKGCONFIG += libavutil libavformat libavcodec libavfilter libswscale libswresample + LIBS += -ldl +} + +RESOURCES += \ + icons/icons.qrc \ + effects/internal/internalshaders.qrc \ + cursors/cursors.qrc + +unix:!mac:isEmpty(PREFIX) { + PREFIX = /usr/local +} + +unix:!mac:target.path = $$PREFIX/bin + +effects.files = $$PWD/effects/*.frag $$PWD/effects/*.xml $$PWD/effects/*.vert +unix:!mac:effects.path = $$PREFIX/share/olive-editor/effects + +translations.files = $$PWD/ts/*.qm +unix:!mac:translations.path = $$PREFIX/share/olive-editor/ts + +unix:!mac { + metainfo.files = $$PWD/packaging/linux/org.olivevideoeditor.Olive.appdata.xml + metainfo.path = $$PREFIX/share/metainfo + desktop.files = $$PWD/packaging/linux/org.olivevideoeditor.Olive.desktop + desktop.path = $$PREFIX/share/applications + mime.files = $$PWD/packaging/linux/org.olivevideoeditor.Olive.xml + mime.path = $$PREFIX/share/mime/packages + icon16.files = $$PWD/packaging/linux/icons/16x16/org.olivevideoeditor.Olive.png + icon16.path = $$PREFIX/share/icons/hicolor/16x16/apps + icon32.files = $$PWD/packaging/linux/icons/32x32/org.olivevideoeditor.Olive.png + icon32.path = $$PREFIX/share/icons/hicolor/32x32/apps + icon48.files = $$PWD/packaging/linux/icons/48x48/org.olivevideoeditor.Olive.png + icon48.path = $$PREFIX/share/icons/hicolor/48x48/apps + icon64.files = $$PWD/packaging/linux/icons/64x64/org.olivevideoeditor.Olive.png + icon64.path = $$PREFIX/share/icons/hicolor/64x64/apps + icon128.files = $$PWD/packaging/linux/icons/128x128/org.olivevideoeditor.Olive.png + icon128.path = $$PREFIX/share/icons/hicolor/128x128/apps + icon256.files = $$PWD/packaging/linux/icons/256x256/org.olivevideoeditor.Olive.png + icon256.path = $$PREFIX/share/icons/hicolor/256x256/apps + icon512.files = $$PWD/packaging/linux/icons/512x512/org.olivevideoeditor.Olive.png + icon512.path = $$PREFIX/share/icons/hicolor/512x512/apps + INSTALLS += target effects translations metainfo desktop mime icon16 icon32 icon48 icon64 icon128 icon256 icon512 +} diff --git a/oliveglobal.cpp b/oliveglobal.cpp new file mode 100644 index 000000000..da97a9e58 --- /dev/null +++ b/oliveglobal.cpp @@ -0,0 +1,192 @@ +#include "oliveglobal.h" + +#include "mainwindow.h" + +#include "panels/panels.h" + +#include "io/path.h" + +#include "playback/audio.h" + +#include "dialogs/demonotice.h" + +#include +#include +#include +#include + +QSharedPointer Olive::Global; +QString Olive::ActiveProjectFilename; +QString Olive::AppName; + +OliveGlobal::OliveGlobal() { + // sets current app name + QString version_id; +#ifdef GITHASH + version_id = QString(" | %1").arg(GITHASH); +#endif + Olive::AppName = QString("Olive (February 2019 | Alpha%1)").arg(version_id); + + // set the file filter used in all file dialogs pertaining to Olive project files. + project_file_filter = tr("Olive Project %1").arg("(*.ove)"); + + // set default value + enable_load_project_on_init = false; +} + +const QString &OliveGlobal::get_project_file_filter() { + return project_file_filter; +} + +void OliveGlobal::update_project_filename(const QString &s) { + // set filename to s + Olive::ActiveProjectFilename = s; + + // update main window title to reflect new project filename + Olive::MainWindow->updateTitle(); +} + +void OliveGlobal::check_for_autorecovery_file() { + QString data_dir = get_data_path(); + if (!data_dir.isEmpty()) { + // detect auto-recovery file + autorecovery_filename = data_dir + "/autorecovery.ove"; + if (QFile::exists(autorecovery_filename)) { + if (QMessageBox::question(nullptr, tr("Auto-recovery"), tr("Olive didn't close properly and an autorecovery file was detected. Would you like to open it?"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { + enable_load_project_on_init = false; + open_project_worker(autorecovery_filename, true); + } + } + autorecovery_timer.setInterval(60000); + QObject::connect(&autorecovery_timer, SIGNAL(timeout()), this, SLOT(save_autorecovery_file())); + autorecovery_timer.start(); + } +} + +void OliveGlobal::set_rendering_state(bool rendering) { + audio_rendering = rendering; + if (rendering) { + autorecovery_timer.stop(); + } else { + autorecovery_timer.start(); + } +} + +void OliveGlobal::load_project_on_launch(const QString& s) { + Olive::ActiveProjectFilename = s; + enable_load_project_on_init = true; +} + +void OliveGlobal::new_project() { + if (can_close_project()) { + // clear effects panel + panel_effect_controls->clear_effects(true); + + // clear project contents (footage, sequences, etc.) + panel_project->new_project(); + + // clear undo stack + undo_stack.clear(); + + // empty current project filename + update_project_filename(""); + + // full update of all panels + update_ui(false); + } +} + +void OliveGlobal::open_project() { + QString fn = QFileDialog::getOpenFileName(Olive::MainWindow, tr("Open Project..."), "", project_file_filter); + if (!fn.isEmpty() && can_close_project()) { + open_project_worker(fn, false); + } +} + +void OliveGlobal::open_recent() { + int index = static_cast(sender())->data().toInt(); + QString recent_url = recent_projects.at(index); + if (!QFile::exists(recent_url)) { + if (QMessageBox::question( + Olive::MainWindow, + tr("Missing recent project"), + tr("The project '%1' no longer exists. Would you like to remove it from the recent projects list?").arg(recent_url), + QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { + recent_projects.removeAt(index); + panel_project->save_recent_projects(); + } + } else if (Olive::Global.data()->can_close_project()) { + open_project_worker(recent_url, false); + } +} + +bool OliveGlobal::save_project_as() { + QString fn = QFileDialog::getSaveFileName(Olive::MainWindow, tr("Save Project As..."), "", project_file_filter); + if (!fn.isEmpty()) { + if (!fn.endsWith(".ove", Qt::CaseInsensitive)) { + fn += ".ove"; + } + update_project_filename(fn); + panel_project->save_project(false); + return true; + } + return false; +} + +bool OliveGlobal::save_project() { + if (Olive::ActiveProjectFilename.isEmpty()) { + return save_project_as(); + } else { + panel_project->save_project(false); + return true; + } +} + +bool OliveGlobal::can_close_project() { + if (Olive::MainWindow->isWindowModified()) { + QMessageBox* m = new QMessageBox( + QMessageBox::Question, + tr("Unsaved Project"), + tr("This project has changed since it was last saved. Would you like to save it before closing?"), + QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel, + Olive::MainWindow + ); + m->setWindowModality(Qt::WindowModal); + int r = m->exec(); + delete m; + if (r == QMessageBox::Yes) { + return save_project(); + } else if (r == QMessageBox::Cancel) { + return false; + } + } + return true; +} + +void OliveGlobal::finished_initialize() { + // if a project was set as a command line argument, we load it here + if (enable_load_project_on_init) { + open_project_worker(Olive::ActiveProjectFilename, false); + enable_load_project_on_init = false; + } else { + // if we are not loading a project on launch and are running a release build, open the demo notice dialog +#ifndef QT_DEBUG + DemoNotice* d = new DemoNotice(Olive::MainWindow); + connect(d, SIGNAL(finished(int)), d, SLOT(deleteLater())); + d->open(); +#endif + } +} + +void OliveGlobal::save_autorecovery_file() { + if (Olive::MainWindow->isWindowModified()) { + panel_project->save_project(true); + qInfo() << "Auto-recovery project saved"; + } +} + +void OliveGlobal::open_project_worker(const QString& fn, bool autorecovery) { + update_project_filename(fn); + panel_project->load_project(autorecovery); + undo_stack.clear(); +} diff --git a/oliveglobal.h b/oliveglobal.h new file mode 100644 index 000000000..c22431df9 --- /dev/null +++ b/oliveglobal.h @@ -0,0 +1,91 @@ +#ifndef OLIVEGLOBAL_H +#define OLIVEGLOBAL_H + +#include "project/undo.h" + +#include + +class OliveGlobal : public QObject { + Q_OBJECT +public: + OliveGlobal(); + + const QString& get_project_file_filter(); + + void update_project_filename(const QString& s); + + void check_for_autorecovery_file(); + + void set_rendering_state(bool rendering); + + void load_project_on_launch(const QString& s); + +public slots: + void new_project(); + void open_project(); + void open_recent(); + bool save_project_as(); + bool save_project(); + + bool can_close_project(); + + /** + * @brief Function called when Olive has finished starting up + * + * Sets up some last things for Olive that must be run after Olive has completed initialization. If a project was + * loaded as a command line argument, it's loaded here. + */ + void finished_initialize(); + + /** + * @brief Save an auto-recovery file of the current project. + * + * Call this function to save the current state of the project as an auto-recovery project. Called regularly by + * `autorecovery_timer`. + */ + void save_autorecovery_file(); + +private: + void open_project_worker(const QString& fn, bool autorecovery); + + /** + * @brief File filter used for any file dialogs relating to Olive project files. + */ + QString project_file_filter; + + /** + * @brief Regular interval to save an auto-recovery project. + */ + QTimer autorecovery_timer; + + /** + * @brief Internal variable set to **TRUE** by main() if a project file was set as an argument + */ + bool enable_load_project_on_init; + + +private slots: + +}; + +namespace Olive { + /** + * @brief Object resource for various global functions used throughout Olive + */ + extern QSharedPointer Global; + + /** + * @brief Currently active project filename + * + * Filename for the currently active project. Empty means the file has not + * been saved yet. + */ + extern QString ActiveProjectFilename; + + /** + * @brief Current application name + */ + extern QString AppName; +} + +#endif // OLIVEGLOBAL_H diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp index fd9969241..0dec04212 100644 --- a/panels/effectcontrols.cpp +++ b/panels/effectcontrols.cpp @@ -80,7 +80,7 @@ void EffectControls::set_zoom(bool in) { void EffectControls::menu_select(QAction* q) { ComboAction* ca = new ComboAction(); for (int i=0;iclips.at(selected_clips.at(i)); + Clip* c = Olive::ActiveSequence->clips.at(selected_clips.at(i)); if ((c->track < 0) == (effect_menu_subtype == EFFECT_TYPE_VIDEO)) { const EffectMeta* meta = reinterpret_cast(q->data().value()); if (effect_menu_type == EFFECT_TYPE_TRANSITION) { @@ -120,7 +120,7 @@ void EffectControls::copy(bool del) { ComboAction* ca = new ComboAction(); EffectDeleteCommand* del_com = (del) ? new EffectDeleteCommand() : nullptr; for (int i=0;iclips.at(selected_clips.at(i)); + Clip* c = Olive::ActiveSequence->clips.at(selected_clips.at(i)); for (int j=0;jeffects.size();j++) { Effect* effect = c->effects.at(j); if (effect->container->selected) { @@ -262,7 +262,7 @@ void EffectControls::clear_effects(bool clear_cache) { void EffectControls::deselect_all_effects(QWidget* sender) { for (int i=0;iclips.at(selected_clips.at(i)); + Clip* c = Olive::ActiveSequence->clips.at(selected_clips.at(i)); for (int j=0;jeffects.size();j++) { if (c->effects.at(j)->container != sender) { c->effects.at(j)->container->header_click(false, false); @@ -485,7 +485,7 @@ void EffectControls::load_effects() { if (!multiple) { // load in new clips for (int i=0;iclips.at(selected_clips.at(i)); + Clip* c = Olive::ActiveSequence->clips.at(selected_clips.at(i)); QVBoxLayout* layout; if (c->track < 0) { vcontainer->setVisible(true); @@ -505,7 +505,7 @@ void EffectControls::load_effects() { } } if (selected_clips.size() > 0) { - setWindowTitle(panel_name + sequence->clips.at(selected_clips.at(0))->name); + setWindowTitle(panel_name + Olive::ActiveSequence->clips.at(selected_clips.at(0))->name); keyframeView->setEnabled(true); headers->setVisible(true); @@ -519,7 +519,7 @@ void EffectControls::delete_effects() { if (mode == TA_NO_TRANSITION) { EffectDeleteCommand* command = new EffectDeleteCommand(); for (int i=0;iclips.at(selected_clips.at(i)); + Clip* c = Olive::ActiveSequence->clips.at(selected_clips.at(i)); for (int j=0;jeffects.size();j++) { Effect* effect = c->effects.at(j); if (effect->container->selected) { @@ -575,7 +575,7 @@ void EffectControls::resizeEvent(QResizeEvent*) { bool EffectControls::is_focused() { if (this->hasFocus()) return true; for (int i=0;iclips.at(selected_clips.at(i)); + Clip* c = Olive::ActiveSequence->clips.at(selected_clips.at(i)); if (c != nullptr) { for (int j=0;jeffects.size();j++) { if (c->effects.at(j)->container->is_focused()) { diff --git a/panels/panels.cpp b/panels/panels.cpp index 195acee58..d06c5b0ad 100644 --- a/panels/panels.cpp +++ b/panels/panels.cpp @@ -1,26 +1,22 @@ #include "panels.h" -#include "timeline.h" -#include "effectcontrols.h" -#include "viewer.h" -#include "project.h" #include "project/sequence.h" #include "project/clip.h" #include "project/transition.h" #include "io/config.h" -#include "grapheditor.h" + #include "project/effectloaders.h" #include "debug.h" #include #include -Project* panel_project = 0; -EffectControls* panel_effect_controls = 0; -Viewer* panel_sequence_viewer = 0; -Viewer* panel_footage_viewer = 0; -Timeline* panel_timeline = 0; -GraphEditor* panel_graph_editor = 0; +Project* panel_project = nullptr; +EffectControls* panel_effect_controls = nullptr; +Viewer* panel_sequence_viewer = nullptr; +Viewer* panel_footage_viewer = nullptr; +Timeline* panel_timeline = nullptr; +GraphEditor* panel_graph_editor = nullptr; void update_effect_controls() { // SEND CLIPS TO EFFECT CONTROLS @@ -32,12 +28,12 @@ void update_effect_controls() { int aclip = -1; QVector selected_clips; int mode = TA_NO_TRANSITION; - if (sequence != nullptr) { - for (int i=0;iclips.size();i++) { - Clip* clip = sequence->clips.at(i); + if (Olive::ActiveSequence != nullptr) { + for (int i=0;iclips.size();i++) { + Clip* clip = Olive::ActiveSequence->clips.at(i); if (clip != nullptr) { - for (int j=0;jselections.size();j++) { - const Selection& s = sequence->selections.at(j); + for (int j=0;jselections.size();j++) { + const Selection& s = Olive::ActiveSequence->selections.at(j); bool add = true; if (clip->timeline_in >= s.in && clip->timeline_out <= s.out && clip->track == s.track) { mode = TA_NO_TRANSITION; @@ -72,7 +68,7 @@ void update_effect_controls() { if (aclip >= 0) selected_clips.append(aclip); if (vclip >= 0 && aclip >= 0) { bool found = false; - Clip* vclip_ref = sequence->clips.at(vclip); + Clip* vclip_ref = Olive::ActiveSequence->clips.at(vclip); for (int i=0;ilinked.size();i++) { if (vclip_ref->linked.at(i) == aclip) { found = true; diff --git a/panels/panels.h b/panels/panels.h index 0e934513e..4f90bd4d5 100644 --- a/panels/panels.h +++ b/panels/panels.h @@ -1,11 +1,11 @@ #ifndef PANELS_H #define PANELS_H -class Project; -class EffectControls; -class Viewer; -class Timeline; -class GraphEditor; +#include "timeline.h" +#include "effectcontrols.h" +#include "viewer.h" +#include "grapheditor.h" +#include "project.h" class QWidget; class QDockWidget; diff --git a/panels/project.cpp b/panels/project.cpp index c98e094d0..4126418f2 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -1,15 +1,12 @@ #include "project.h" -#include "project/footage.h" + +#include "oliveglobal.h" + +#include "project/projectelements.h" #include "panels/panels.h" -#include "panels/timeline.h" -#include "panels/viewer.h" + #include "playback/playback.h" -#include "project/effect.h" -#include "project/transition.h" -#include "panels/timeline.h" -#include "project/sequence.h" -#include "project/clip.h" #include "io/previewgenerator.h" #include "project/undo.h" #include "mainwindow.h" @@ -21,9 +18,9 @@ #include "dialogs/mediapropertiesdialog.h" #include "dialogs/loaddialog.h" #include "io/clipboard.h" -#include "project/media.h" #include "ui/sourcetable.h" #include "ui/sourceiconview.h" +#include "ui/menuhelper.h" #include "project/sourcescommon.h" #include "project/projectfilter.h" #include "debug.h" @@ -54,7 +51,6 @@ extern "C" { ProjectModel project_model; QString autorecovery_filename; -QString project_url = ""; QStringList recent_projects; QString recent_proj_file; @@ -100,7 +96,7 @@ Project::Project(QWidget *parent) : icon2.addFile(QStringLiteral(":/icons/open-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); toolbar_open->setIcon(icon2); toolbar_open->setToolTip("Open Project"); - connect(toolbar_open, SIGNAL(clicked(bool)), mainWindow, SLOT(open_project())); + connect(toolbar_open, SIGNAL(clicked(bool)), Olive::Global.data(), SLOT(open_project())); toolbar->addWidget(toolbar_open); QPushButton* toolbar_save = new QPushButton(); @@ -109,7 +105,7 @@ Project::Project(QWidget *parent) : icon3.addFile(QStringLiteral(":/icons/save-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); toolbar_save->setIcon(icon3); toolbar_save->setToolTip("Save Project"); - connect(toolbar_save, SIGNAL(clicked(bool)), mainWindow, SLOT(save_project())); + connect(toolbar_save, SIGNAL(clicked(bool)), Olive::Global.data(), SLOT(save_project())); toolbar->addWidget(toolbar_save); QPushButton* toolbar_undo = new QPushButton(); @@ -118,7 +114,7 @@ Project::Project(QWidget *parent) : icon4.addFile(QStringLiteral(":/icons/undo-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); toolbar_undo->setIcon(icon4); toolbar_undo->setToolTip("Undo"); - connect(toolbar_undo, SIGNAL(clicked(bool)), mainWindow, SLOT(undo())); + connect(toolbar_undo, SIGNAL(clicked(bool)), Olive::MainWindow, SLOT(undo())); toolbar->addWidget(toolbar_undo); QPushButton* toolbar_redo = new QPushButton(); @@ -127,7 +123,7 @@ Project::Project(QWidget *parent) : icon5.addFile(QStringLiteral(":/icons/redo-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); toolbar_redo->setIcon(icon5); toolbar_redo->setToolTip("Redo"); - connect(toolbar_redo, SIGNAL(clicked(bool)), mainWindow, SLOT(redo())); + connect(toolbar_redo, SIGNAL(clicked(bool)), Olive::MainWindow, SLOT(redo())); toolbar->addWidget(toolbar_redo); QLineEdit* toolbar_search = new QLineEdit(); @@ -349,7 +345,7 @@ void Project::replace_media(Media* item, QString filename) { } void Project::replace_clip_media() { - if (sequence == nullptr) { + if (Olive::ActiveSequence == nullptr) { QMessageBox::critical(this, tr("No active sequence"), tr("No sequence is active, please open the sequence you want to replace clips from."), @@ -358,7 +354,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 && sequence == item->to_sequence()) { + if (item->get_type() == MEDIA_TYPE_SEQUENCE && Olive::ActiveSequence == item->to_sequence()) { 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."), @@ -573,7 +569,7 @@ void Project::delete_selected_media() { // remove if (remove) { panel_effect_controls->clear_effects(true); - if (sequence != nullptr) sequence->selections.clear(); + if (Olive::ActiveSequence != nullptr) Olive::ActiveSequence->selections.clear(); // remove media and parents for (int m=0;mto_sequence(); - if (s == sequence) { + if (s == Olive::ActiveSequence) { ca->append(new ChangeSequenceAction(nullptr)); } @@ -876,7 +872,7 @@ void Project::import_dialog() { } void Project::delete_clips_using_selected_media() { - if (sequence == nullptr) { + if (Olive::ActiveSequence == nullptr) { QMessageBox::critical(this, tr("No active sequence"), tr("No sequence is active, please open the sequence you want to delete clips from."), @@ -885,13 +881,13 @@ void Project::delete_clips_using_selected_media() { ComboAction* ca = new ComboAction(); bool deleted = false; QModelIndexList items = get_current_selected(); - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr) { for (int j=0;jmedia == m) { - ca->append(new DeleteClipAction(sequence, i)); + ca->append(new DeleteClipAction(Olive::ActiveSequence, i)); deleted = true; } } @@ -923,6 +919,9 @@ void Project::clear() { // delete everything else project_model.clear(); + + // update tree view (sometimes this doesn't seem to update reliably) + panel_project->tree_view->update(); } void Project::new_project() { @@ -930,7 +929,7 @@ void Project::new_project() { set_sequence(nullptr); panel_footage_viewer->set_media(nullptr); clear(); - mainWindow->setWindowModified(false); + Olive::MainWindow->setWindowModified(false); } void Project::load_project(bool autorecovery) { @@ -1035,7 +1034,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, stream.writeAttribute("framerate", QString::number(s->frame_rate, 'f', 10)); stream.writeAttribute("afreq", QString::number(s->audio_frequency)); stream.writeAttribute("alayout", QString::number(s->audio_layout)); - if (s == sequence) { + if (s == Olive::ActiveSequence) { stream.writeAttribute("open", "1"); } stream.writeAttribute("workarea", QString::number(s->using_workarea)); @@ -1135,7 +1134,7 @@ void Project::save_project(bool autorecovery) { media_id = 1; sequence_id = 1; - QFile file(autorecovery ? autorecovery_filename : project_url); + QFile file(autorecovery ? autorecovery_filename : Olive::ActiveProjectFilename); if (!file.open(QIODevice::WriteOnly/* | QIODevice::Text*/)) { qCritical() << "Could not open file"; return; @@ -1149,8 +1148,8 @@ void Project::save_project(bool autorecovery) { stream.writeTextElement("version", QString::number(SAVE_VERSION)); - stream.writeTextElement("url", project_url); - proj_dir = QFileInfo(project_url).absoluteDir(); + stream.writeTextElement("url", Olive::ActiveProjectFilename); + proj_dir = QFileInfo(Olive::ActiveProjectFilename).absoluteDir(); save_folder(stream, MEDIA_TYPE_FOLDER, true); @@ -1175,8 +1174,8 @@ void Project::save_project(bool autorecovery) { file.close(); if (!autorecovery) { - add_recent_project(project_url); - mainWindow->setWindowModified(false); + add_recent_project(Olive::ActiveProjectFilename); + Olive::MainWindow->setWindowModified(false); } } @@ -1241,7 +1240,7 @@ void Project::go_up_dir() { void Project::make_new_menu() { QMenu new_menu(this); - mainWindow->make_new_menu(&new_menu); + Olive::MenuHelper.make_new_menu(&new_menu); new_menu.exec(QCursor::pos()); } diff --git a/panels/project.h b/panels/project.h index 4f2c37aef..23a95d611 100644 --- a/panels/project.h +++ b/panels/project.h @@ -7,6 +7,7 @@ #include #include "project/projectmodel.h" +#include "project/projectfilter.h" struct Footage; struct Sequence; @@ -28,7 +29,6 @@ class SourcesCommon; #define LOAD_TYPE_URL 70 extern QString autorecovery_filename; -extern QString project_url; extern QStringList recent_projects; extern QString recent_proj_file; diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 192cc5717..0e1e773f4 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -1,22 +1,16 @@ #include "timeline.h" +#include "oliveglobal.h" + #include "panels/panels.h" -#include "panels/project.h" -#include "panels/effectcontrols.h" +#include "project/projectelements.h" + #include "ui/timelinewidget.h" -#include "project/sequence.h" -#include "project/clip.h" #include "ui/viewerwidget.h" #include "playback/audio.h" -#include "panels/viewer.h" #include "playback/cacher.h" #include "playback/playback.h" -#include "project/undo.h" -#include "project/media.h" #include "io/config.h" -#include "project/effect.h" -#include "project/transition.h" -#include "project/footage.h" #include "io/clipboard.h" #include "ui/timelineheader.h" #include "ui/resizablescrollbar.h" @@ -104,14 +98,14 @@ Timeline::Timeline(QWidget *parent) : Timeline::~Timeline() {} void Timeline::previous_cut() { - if (sequence->playhead > 0) { + if (Olive::ActiveSequence->playhead > 0) { long p_cut = 0; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr) { - if (c->timeline_out > p_cut && c->timeline_out < sequence->playhead) { + if (c->timeline_out > p_cut && c->timeline_out < Olive::ActiveSequence->playhead) { p_cut = c->timeline_out; - } else if (c->timeline_in > p_cut && c->timeline_in < sequence->playhead) { + } else if (c->timeline_in > p_cut && c->timeline_in < Olive::ActiveSequence->playhead) { p_cut = c->timeline_in; } } @@ -123,13 +117,13 @@ void Timeline::previous_cut() { void Timeline::next_cut() { bool seek_enabled = false; long n_cut = LONG_MAX; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr) { - if (c->timeline_in < n_cut && c->timeline_in > sequence->playhead) { + if (c->timeline_in < n_cut && c->timeline_in > Olive::ActiveSequence->playhead) { n_cut = c->timeline_in; seek_enabled = true; - } else if (c->timeline_out < n_cut && c->timeline_out > sequence->playhead) { + } else if (c->timeline_out < n_cut && c->timeline_out > Olive::ActiveSequence->playhead) { n_cut = c->timeline_out; seek_enabled = true; } @@ -143,11 +137,11 @@ void ripple_clips(ComboAction* ca, Sequence *s, long point, long length, const Q } void Timeline::toggle_show_all() { - if (sequence != nullptr) { + if (Olive::ActiveSequence != nullptr) { showing_all = !showing_all; if (showing_all) { old_zoom = zoom; - set_zoom_value(double(timeline_area->width() - 200) / double(sequence->getEndFrame())); + set_zoom_value(double(timeline_area->width() - 200) / double(Olive::ActiveSequence->getEndFrame())); } else { set_zoom_value(old_zoom); } @@ -347,8 +341,8 @@ void Timeline::add_transition() { ComboAction* ca = new ComboAction(); bool adding = false; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { int transition_to_add = (c->track < 0) ? TRANSITION_INTERNAL_CROSSDISSOLVE : TRANSITION_INTERNAL_LINEARFADE; if (c->get_opening_transition() == nullptr) { @@ -384,7 +378,7 @@ int Timeline::calculate_track_height(int track, int value) { } void Timeline::update_sequence() { - bool null_sequence = (sequence == nullptr); + bool null_sequence = (Olive::ActiveSequence == nullptr); for (int i=0;isetEnabled(!null_sequence); @@ -400,7 +394,7 @@ void Timeline::update_sequence() { if (null_sequence) { setWindowTitle(title + tr("")); } else { - setWindowTitle(title + sequence->name); + setWindowTitle(title + Olive::ActiveSequence->name); update_ui(false); } } @@ -410,27 +404,27 @@ int Timeline::get_snap_range() { } bool Timeline::focused() { - return (sequence != nullptr && (headers->hasFocus() || video_area->hasFocus() || audio_area->hasFocus())); + return (Olive::ActiveSequence != nullptr && (headers->hasFocus() || video_area->hasFocus() || audio_area->hasFocus())); } void Timeline::repaint_timeline() { if (!block_repaints) { bool draw = true; - if (sequence != nullptr + if (Olive::ActiveSequence != nullptr && !horizontalScrollBar->isSliderDown() && !horizontalScrollBar->is_resizing() && panel_sequence_viewer->playing && !zoom_just_changed) { // auto scroll if (config.autoscroll == AUTOSCROLL_PAGE_SCROLL) { - int playhead_x = panel_timeline->getTimelineScreenPointFromFrame(sequence->playhead); + int playhead_x = panel_timeline->getTimelineScreenPointFromFrame(Olive::ActiveSequence->playhead); if (playhead_x < 0 || playhead_x > (editAreas->width() - videoScrollbar->width())) { - horizontalScrollBar->setValue(getScreenPointFromFrame(zoom, sequence->playhead)); + horizontalScrollBar->setValue(getScreenPointFromFrame(zoom, Olive::ActiveSequence->playhead)); draw = false; } } else if (config.autoscroll == AUTOSCROLL_SMOOTH_SCROLL) { - if (center_scroll_to_playhead(horizontalScrollBar, zoom, sequence->playhead)) { + if (center_scroll_to_playhead(horizontalScrollBar, zoom, Olive::ActiveSequence->playhead)) { draw = false; } } @@ -443,7 +437,7 @@ void Timeline::repaint_timeline() { video_area->update(); audio_area->update(); - if (sequence != nullptr) { + if (Olive::ActiveSequence != nullptr) { set_sb_max(); } } @@ -451,16 +445,16 @@ void Timeline::repaint_timeline() { } void Timeline::select_all() { - if (sequence != nullptr) { - sequence->selections.clear(); - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + if (Olive::ActiveSequence != nullptr) { + Olive::ActiveSequence->selections.clear(); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr) { Selection s; s.in = c->timeline_in; s.out = c->timeline_out; s.track = c->track; - sequence->selections.append(s); + Olive::ActiveSequence->selections.append(s); } } repaint_timeline(); @@ -472,17 +466,17 @@ void Timeline::scroll_to_frame(long frame) { } void Timeline::select_from_playhead() { - sequence->selections.clear(); - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + Olive::ActiveSequence->selections.clear(); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr - && c->timeline_in <= sequence->playhead - && c->timeline_out > sequence->playhead) { + && c->timeline_in <= Olive::ActiveSequence->playhead + && c->timeline_out > Olive::ActiveSequence->playhead) { Selection s; s.in = c->timeline_in; s.out = c->timeline_out; s.track = c->track; - sequence->selections.append(s); + Olive::ActiveSequence->selections.append(s); } } } @@ -493,8 +487,8 @@ bool Timeline::can_ripple_empty_space(long frame, int track) { rc_ripple_min = 0; rc_ripple_max = LONG_MAX; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr) { if (c->timeline_in > frame || c->timeline_out > frame) { at_end_of_sequence = false; @@ -530,7 +524,7 @@ void Timeline::ripple_delete_empty_space() { void Timeline::resizeEvent(QResizeEvent *) { // adjust maximum scrollbar - if (sequence != nullptr) set_sb_max(); + if (Olive::ActiveSequence != nullptr) set_sb_max(); // resize tool button widget to its contents @@ -560,21 +554,21 @@ void Timeline::resizeEvent(QResizeEvent *) { } void Timeline::delete_in_out(bool ripple) { - if (sequence != nullptr && sequence->using_workarea) { + if (Olive::ActiveSequence != nullptr && Olive::ActiveSequence->using_workarea) { QVector areas; int video_tracks = 0, audio_tracks = 0; - sequence->getTrackLimits(&video_tracks, &audio_tracks); + Olive::ActiveSequence->getTrackLimits(&video_tracks, &audio_tracks); for (int i=video_tracks;i<=audio_tracks;i++) { Selection s; - s.in = sequence->workarea_in; - s.out = sequence->workarea_out; + s.in = Olive::ActiveSequence->workarea_in; + s.out = Olive::ActiveSequence->workarea_out; s.track = i; areas.append(s); } ComboAction* ca = new ComboAction(); delete_areas_and_relink(ca, areas, true); - if (ripple) ripple_clips(ca, sequence, sequence->workarea_in, sequence->workarea_in - sequence->workarea_out); - ca->append(new SetTimelineInOutCommand(sequence, false, 0, 0)); + if (ripple) ripple_clips(ca, Olive::ActiveSequence, Olive::ActiveSequence->workarea_in, Olive::ActiveSequence->workarea_in - Olive::ActiveSequence->workarea_out); + ca->append(new SetTimelineInOutCommand(Olive::ActiveSequence, false, 0, 0)); undo_stack.push(ca); update_ui(true); } @@ -603,8 +597,8 @@ void Timeline::delete_selection(QVector& selections, bool ripple_dele ripple_point++; bool can_ripple = true; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr && c->timeline_in < ripple_point && c->timeline_out > ripple_point) { // conflict detected, but this clip may be getting deleted so let's check bool deleted = false; @@ -618,8 +612,8 @@ void Timeline::delete_selection(QVector& selections, bool ripple_dele } } if (!deleted) { - for (int j=0;jclips.size();j++) { - Clip* cc = sequence->clips.at(j); + for (int j=0;jclips.size();j++) { + Clip* cc = Olive::ActiveSequence->clips.at(j); if (cc != nullptr && cc->track == c->track && cc->timeline_in > c->timeline_out @@ -632,7 +626,7 @@ void Timeline::delete_selection(QVector& selections, bool ripple_dele } if (can_ripple) { - ripple_clips(ca, sequence, ripple_point, -ripple_length); + ripple_clips(ca, Olive::ActiveSequence, ripple_point, -ripple_length); panel_sequence_viewer->seek(ripple_point-1); } } @@ -652,7 +646,7 @@ void Timeline::set_zoom_value(double v) { // TODO find a way to gradually move towards target_scroll instead of just centering it? if (!horizontalScrollBar->is_resizing()) - center_scroll_to_playhead(horizontalScrollBar, zoom, sequence->playhead); + center_scroll_to_playhead(horizontalScrollBar, zoom, Olive::ActiveSequence->playhead); } void Timeline::set_zoom(bool in) { @@ -668,9 +662,9 @@ void Timeline::decheck_tool_buttons(QObject* sender) { QVector Timeline::get_tracks_of_linked_clips(int i) { QVector tracks; - Clip* clip = sequence->clips.at(i); + Clip* clip = Olive::ActiveSequence->clips.at(i); for (int j=0;jlinked.size();j++) { - tracks.append(sequence->clips.at(clip->linked.at(j))->track); + tracks.append(Olive::ActiveSequence->clips.at(clip->linked.at(j))->track); } return tracks; } @@ -703,7 +697,7 @@ Clip* Timeline::split_clip(ComboAction* ca, bool transitions, int p, long frame) } Clip* Timeline::split_clip(ComboAction* ca, bool transitions, int p, long frame, long post_in) { - Clip* pre = sequence->clips.at(p); + Clip* pre = Olive::ActiveSequence->clips.at(p); if (pre != nullptr && pre->timeline_in < frame && pre->timeline_out > frame) { // guard against attempts to split at in/out points bool splitting_closing_dual_transition = false; @@ -713,7 +707,7 @@ Clip* Timeline::split_clip(ComboAction* ca, bool transitions, int p, long frame, splitting_closing_dual_transition = true; } - Clip* post = pre->copy(sequence, transitions && !splitting_closing_dual_transition); + Clip* post = pre->copy(Olive::ActiveSequence, transitions && !splitting_closing_dual_transition); long new_clip_length = frame - pre->timeline_in; @@ -778,7 +772,7 @@ bool Timeline::split_clip_and_relink(ComboAction *ca, int clip, long frame, bool split_cache.append(clip); - Clip* c = sequence->clips.at(clip); + Clip* c = Olive::ActiveSequence->clips.at(clip); if (c != nullptr) { QVector pre_clips; QVector post_clips; @@ -799,7 +793,7 @@ bool Timeline::split_clip_and_relink(ComboAction *ca, int clip, long frame, bool for (int i=0;ilinked.size();i++) { int l = c->linked.at(i); if (!has_clip_been_split(l)) { - Clip* link = sequence->clips.at(l); + Clip* link = Olive::ActiveSequence->clips.at(l); if ((original_clip_is_selected && is_clip_selected(link, true)) || !original_clip_is_selected) { split_cache.append(l); Clip* s = split_clip(ca, true, l, frame); @@ -813,7 +807,7 @@ bool Timeline::split_clip_and_relink(ComboAction *ca, int clip, long frame, bool relink_clips_using_ids(pre_clips, post_clips); } - ca->append(new AddClipCommand(sequence, post_clips)); + ca->append(new AddClipCommand(Olive::ActiveSequence, post_clips)); return true; } } @@ -873,8 +867,8 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& area for (int i=0;iclips.size();j++) { - Clip* c = sequence->clips.at(j); + for (int j=0;jclips.size();j++) { + Clip* c = Olive::ActiveSequence->clips.at(j); if (c != nullptr && c->track == s.track && !c->undeletable) { if (selection_contains_transition(s, c, TA_OPENING_TRANSITION)) { // delete opening transition @@ -884,7 +878,7 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& area ca->append(new DeleteTransitionCommand(c->sequence, c->closing_transition)); } else if (c->timeline_in >= s.in && c->timeline_out <= s.out) { // clips falls entirely within deletion area - ca->append(new DeleteClipAction(sequence, j)); + ca->append(new DeleteClipAction(Olive::ActiveSequence, j)); } else if (c->timeline_in < s.in && c->timeline_out > s.out) { // middle of clip is within deletion area @@ -930,7 +924,7 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& area } relink_clips_using_ids(pre_clips, post_clips); - ca->append(new AddClipCommand(sequence, post_clips)); + ca->append(new AddClipCommand(Olive::ActiveSequence, post_clips)); } void Timeline::copy(bool del) { @@ -939,11 +933,11 @@ void Timeline::copy(bool del) { long min_in = 0; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr) { - for (int j=0;jselections.size();j++) { - const Selection& s = sequence->selections.at(j); + for (int j=0;jselections.size();j++) { + const Selection& s = Olive::ActiveSequence->selections.at(j); if (s.track == c->track && !((c->timeline_in <= s.in && c->timeline_out <= s.in) || (c->timeline_in >= s.out && c->timeline_out >= s.out))) { if (!cleared) { clear_clipboard(); @@ -987,7 +981,7 @@ void Timeline::copy(bool del) { } if (del && copied) { - delete_selection(sequence->selections, false); + delete_selection(Olive::ActiveSequence->selections, false); } } @@ -995,7 +989,7 @@ void Timeline::relink_clips_using_ids(QVector& old_clips, QVector& n // relink pasted clips for (int i=0;iclips.at(old_clips.at(i)); + Clip* oc = Olive::ActiveSequence->clips.at(old_clips.at(i)); for (int j=0;jlinked.size();j++) { for (int k=0;klinked.at(j) == old_clips.at(k)) { @@ -1022,15 +1016,15 @@ void Timeline::paste(bool insert) { Clip* c = static_cast(clipboard.at(i)); // create copy of clip and offset by playhead - Clip* cc = c->copy(sequence); + Clip* cc = c->copy(Olive::ActiveSequence); // convert frame rates - cc->timeline_in = refactor_frame_number(cc->timeline_in, c->cached_fr, sequence->frame_rate); - cc->timeline_out = refactor_frame_number(cc->timeline_out, c->cached_fr, sequence->frame_rate); - cc->clip_in = refactor_frame_number(cc->clip_in, c->cached_fr, sequence->frame_rate); + cc->timeline_in = refactor_frame_number(cc->timeline_in, c->cached_fr, Olive::ActiveSequence->frame_rate); + cc->timeline_out = refactor_frame_number(cc->timeline_out, c->cached_fr, Olive::ActiveSequence->frame_rate); + cc->clip_in = refactor_frame_number(cc->clip_in, c->cached_fr, Olive::ActiveSequence->frame_rate); - cc->timeline_in += sequence->playhead; - cc->timeline_out += sequence->playhead; + cc->timeline_in += Olive::ActiveSequence->playhead; + cc->timeline_out += Olive::ActiveSequence->playhead; cc->track = c->track; paste_start = qMin(paste_start, cc->timeline_in); @@ -1048,8 +1042,8 @@ void Timeline::paste(bool insert) { } if (insert) { split_cache.clear(); - split_all_clips_at_point(ca, sequence->playhead); - ripple_clips(ca, sequence, paste_start, paste_end - paste_start); + split_all_clips_at_point(ca, Olive::ActiveSequence->playhead); + ripple_clips(ca, Olive::ActiveSequence, paste_start, paste_end - paste_start); } else { delete_areas_and_relink(ca, delete_areas, false); } @@ -1069,7 +1063,7 @@ void Timeline::paste(bool insert) { } } - ca->append(new AddClipCommand(sequence, pasted_clips)); + ca->append(new AddClipCommand(Olive::ActiveSequence, pasted_clips)); undo_stack.push(ca); @@ -1086,8 +1080,8 @@ void Timeline::paste(bool insert) { bool skip = false; bool ask_conflict = true; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { for (int j=0;j(clipboard.at(j)); @@ -1156,8 +1150,8 @@ void Timeline::paste(bool insert) { } void Timeline::ripple_to_in_point(bool in, bool ripple) { - if (sequence != nullptr) { - if (sequence->clips.size() > 0) { + if (Olive::ActiveSequence != nullptr) { + if (Olive::ActiveSequence->clips.size() > 0) { // get track count int track_min = INT_MAX; int track_max = INT_MIN; @@ -1169,25 +1163,25 @@ void Timeline::ripple_to_in_point(bool in, bool ripple) { long prev_cut = 0; // find closest in point to playhead - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr) { track_min = qMin(track_min, c->track); track_max = qMax(track_max, c->track); sequence_end = qMax(c->timeline_out, sequence_end); - if (c->timeline_in == sequence->playhead) + if (c->timeline_in == Olive::ActiveSequence->playhead) playhead_falls_on_in = true; - if (c->timeline_out == sequence->playhead) + if (c->timeline_out == Olive::ActiveSequence->playhead) playhead_falls_on_out = true; - if (c->timeline_in > sequence->playhead) + if (c->timeline_in > Olive::ActiveSequence->playhead) next_cut = qMin(c->timeline_in, next_cut); - if (c->timeline_out > sequence->playhead) + if (c->timeline_out > Olive::ActiveSequence->playhead) next_cut = qMin(c->timeline_out, next_cut); - if (c->timeline_in < sequence->playhead) + if (c->timeline_in < Olive::ActiveSequence->playhead) prev_cut = qMax(c->timeline_in, prev_cut); - if (c->timeline_out < sequence->playhead) + if (c->timeline_out < Olive::ActiveSequence->playhead) prev_cut = qMax(c->timeline_out, prev_cut); } } @@ -1197,13 +1191,13 @@ void Timeline::ripple_to_in_point(bool in, bool ripple) { QVector areas; ComboAction* ca = new ComboAction(); bool push_undo = true; - long seek = sequence->playhead; + long seek = Olive::ActiveSequence->playhead; - if ((in && (playhead_falls_on_out || (playhead_falls_on_in && sequence->playhead == 0))) - || (!in && (playhead_falls_on_in || (playhead_falls_on_out && sequence->playhead == sequence_end)))) { // one frame mode + if ((in && (playhead_falls_on_out || (playhead_falls_on_in && Olive::ActiveSequence->playhead == 0))) + || (!in && (playhead_falls_on_in || (playhead_falls_on_out && Olive::ActiveSequence->playhead == sequence_end)))) { // one frame mode if (ripple) { // set up deletion areas based on track count - long in_point = sequence->playhead; + long in_point = Olive::ActiveSequence->playhead; if (!in) { in_point--; seek--; @@ -1221,7 +1215,7 @@ void Timeline::ripple_to_in_point(bool in, bool ripple) { // trim and move clips around the in point delete_areas_and_relink(ca, areas, true); - if (ripple) ripple_clips(ca, sequence, in_point, -1); + if (ripple) ripple_clips(ca, Olive::ActiveSequence, in_point, -1); } else { push_undo = false; } @@ -1232,8 +1226,8 @@ void Timeline::ripple_to_in_point(bool in, bool ripple) { // set up deletion areas based on track count Selection s; if (in) seek = prev_cut; - s.in = in ? prev_cut : sequence->playhead; - s.out = in ? sequence->playhead : next_cut; + s.in = in ? prev_cut : Olive::ActiveSequence->playhead; + s.out = in ? Olive::ActiveSequence->playhead : next_cut; if (s.in == s.out) { push_undo = false; @@ -1245,7 +1239,7 @@ void Timeline::ripple_to_in_point(bool in, bool ripple) { // trim and move clips around the in point delete_areas_and_relink(ca, areas, true); - if (ripple) ripple_clips(ca, sequence, s.in, s.in - s.out); + if (ripple) ripple_clips(ca, Olive::ActiveSequence, s.in, s.in - s.out); } } @@ -1254,7 +1248,7 @@ void Timeline::ripple_to_in_point(bool in, bool ripple) { update_ui(true); - if (seek != sequence->playhead && ripple) panel_sequence_viewer->seek(seek); + if (seek != Olive::ActiveSequence->playhead && ripple) panel_sequence_viewer->seek(seek); } else { delete ca; } @@ -1273,11 +1267,11 @@ bool Timeline::split_selection(ComboAction* ca) { QVector secondary_post_splits; // find clips within selection and split - for (int j=0;jclips.size();j++) { - Clip* clip = sequence->clips.at(j); + for (int j=0;jclips.size();j++) { + Clip* clip = Olive::ActiveSequence->clips.at(j); if (clip != nullptr) { - for (int i=0;iselections.size();i++) { - const Selection& s = sequence->selections.at(i); + for (int i=0;iselections.size();i++) { + const Selection& s = Olive::ActiveSequence->selections.at(i); if (s.track == clip->track) { Clip* post_b = split_clip(ca, true, j, s.out); Clip* post_a = split_clip(ca, post_b == nullptr, j, s.in); @@ -1300,8 +1294,8 @@ bool Timeline::split_selection(ComboAction* ca) { relink_clips_using_ids(pre_splits, post_splits); relink_clips_using_ids(pre_splits, secondary_post_splits); - ca->append(new AddClipCommand(sequence, post_splits)); - ca->append(new AddClipCommand(sequence, secondary_post_splits)); + ca->append(new AddClipCommand(Olive::ActiveSequence, post_splits)); + ca->append(new AddClipCommand(Olive::ActiveSequence, secondary_post_splits)); return true; } @@ -1310,8 +1304,8 @@ bool Timeline::split_selection(ComboAction* ca) { bool Timeline::split_all_clips_at_point(ComboAction* ca, long point) { bool split = false; - for (int j=0;jclips.size();j++) { - Clip* c = sequence->clips.at(j); + for (int j=0;jclips.size();j++) { + Clip* c = Olive::ActiveSequence->clips.at(j); if (c != nullptr) { // always relinks if (split_clip_and_relink(ca, j, point, true)) { @@ -1327,14 +1321,14 @@ void Timeline::split_at_playhead() { bool split_selected = false; split_cache.clear(); - if (sequence->selections.size() > 0) { + if (Olive::ActiveSequence->selections.size() > 0) { // see if whole clips are selected QVector pre_clips; QVector post_clips; - for (int j=0;jclips.size();j++) { - Clip* clip = sequence->clips.at(j); + for (int j=0;jclips.size();j++) { + Clip* clip = Olive::ActiveSequence->clips.at(j); if (clip != nullptr && is_clip_selected(clip, true)) { - Clip* s = split_clip(ca, true, j, sequence->playhead); + Clip* s = split_clip(ca, true, j, Olive::ActiveSequence->playhead); if (s != nullptr) { pre_clips.append(j); post_clips.append(s); @@ -1346,7 +1340,7 @@ void Timeline::split_at_playhead() { if (split_selected) { // relink clips if we split relink_clips_using_ids(pre_clips, post_clips); - ca->append(new AddClipCommand(sequence, post_clips)); + ca->append(new AddClipCommand(Olive::ActiveSequence, post_clips)); } else { // split a selection if not split_selected = split_selection(ca); @@ -1355,7 +1349,7 @@ void Timeline::split_at_playhead() { // if nothing was selected or no selections fell within playhead, simply split at playhead if (!split_selected) { - split_selected = split_all_clips_at_point(ca, sequence->playhead); + split_selected = split_all_clips_at_point(ca, Olive::ActiveSequence->playhead); } if (split_selected) { @@ -1367,13 +1361,13 @@ void Timeline::split_at_playhead() { } void Timeline::deselect_area(long in, long out, int track) { - int len = sequence->selections.size(); + int len = Olive::ActiveSequence->selections.size(); for (int i=0;iselections[i]; + Selection& s = Olive::ActiveSequence->selections[i]; if (s.track == track) { if (s.in >= in && s.out <= out) { // whole selection is in deselect area - sequence->selections.removeAt(i); + Olive::ActiveSequence->selections.removeAt(i); i--; len--; } else if (s.in < in && s.out > out) { @@ -1382,7 +1376,7 @@ void Timeline::deselect_area(long in, long out, int track) { new_sel.in = out; new_sel.out = s.out; new_sel.track = s.track; - sequence->selections.append(new_sel); + Olive::ActiveSequence->selections.append(new_sel); s.out = in; } else if (s.in < in && s.out > in) { @@ -1412,25 +1406,25 @@ bool Timeline::snap_to_timeline(long* l, bool use_playhead, bool use_markers, bo if (snapping) { if (use_playhead && !panel_sequence_viewer->playing) { // snap to playhead - if (snap_to_point(sequence->playhead, l)) return true; + if (snap_to_point(Olive::ActiveSequence->playhead, l)) return true; } // snap to marker if (use_markers) { - for (int i=0;imarkers.size();i++) { - if (snap_to_point(sequence->markers.at(i).frame, l)) return true; + for (int i=0;imarkers.size();i++) { + if (snap_to_point(Olive::ActiveSequence->markers.at(i).frame, l)) return true; } } // snap to in/out - if (use_workarea && sequence->using_workarea) { - if (snap_to_point(sequence->workarea_in, l)) return true; - if (snap_to_point(sequence->workarea_out, l)) return true; + if (use_workarea && Olive::ActiveSequence->using_workarea) { + if (snap_to_point(Olive::ActiveSequence->workarea_in, l)) return true; + if (snap_to_point(Olive::ActiveSequence->workarea_out, l)) return true; } // snap to clip/transition - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr) { if (snap_to_point(c->timeline_in, l)) { return true; @@ -1461,14 +1455,14 @@ void Timeline::set_marker() { QVector clips_selected; bool clip_mode = false; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { // only add markers if the playhead is inside the clip - if (sequence->playhead >= c->timeline_in - && sequence->playhead <= c->timeline_out) { + if (Olive::ActiveSequence->playhead >= c->timeline_in + && Olive::ActiveSequence->playhead <= c->timeline_out) { clips_selected.append(i); } @@ -1485,15 +1479,15 @@ void Timeline::set_marker() { } // pass off to internal set marker function - set_marker_internal(sequence, clips_selected); + set_marker_internal(Olive::ActiveSequence, clips_selected); } void Timeline::toggle_links() { LinkCommand* command = new LinkCommand(); - command->s = sequence; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + command->s = Olive::ActiveSequence; + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { if (!command->clips.contains(i)) command->clips.append(i); @@ -1537,7 +1531,7 @@ void Timeline::decrease_track_height() { } void Timeline::deselect() { - sequence->selections.clear(); + Olive::ActiveSequence->selections.clear(); repaint_timeline(); } @@ -1608,7 +1602,7 @@ void Timeline::setScroll(int s) { } void Timeline::record_btn_click() { - if (project_url.isEmpty()) { + if (Olive::ActiveProjectFilename.isEmpty()) { QMessageBox::critical(this, tr("Unsaved Project"), tr("You must save this project before you can record audio in it."), @@ -1616,7 +1610,7 @@ void Timeline::record_btn_click() { } else { creating = true; creating_object = ADD_OBJ_AUDIO; - mainWindow->statusBar()->showMessage( + Olive::MainWindow->statusBar()->showMessage( tr("Click on the timeline where you want to start recording (drag to limit the recording to a certain timeframe)"), 10000); } @@ -1674,7 +1668,7 @@ void Timeline::resize_move(double z) { } void Timeline::set_sb_max() { - headers->set_scrollbar_max(horizontalScrollBar, sequence->getEndFrame(), editAreas->width() - getScreenPointFromFrame(zoom, 200)); + headers->set_scrollbar_max(horizontalScrollBar, Olive::ActiveSequence->getEndFrame(), editAreas->width() - getScreenPointFromFrame(zoom, 200)); } void Timeline::setup_ui() { diff --git a/panels/viewer.cpp b/panels/viewer.cpp index d2bcbd592..8a2b44fbc 100644 --- a/panels/viewer.cpp +++ b/panels/viewer.cpp @@ -96,7 +96,7 @@ bool Viewer::is_main_sequence() { void Viewer::set_main_sequence() { clean_created_seq(); - set_sequence(true, sequence); + set_sequence(true, Olive::ActiveSequence); } void Viewer::reset_all_audio() { @@ -835,7 +835,7 @@ void Viewer::set_sequence(bool main, Sequence *s) { } main_sequence = main; - seq = (main) ? sequence : s; + seq = (main) ? Olive::ActiveSequence : s; bool null_sequence = (seq == nullptr); diff --git a/playback/audio.cpp b/playback/audio.cpp index 44402a6f6..89c12f5ec 100644 --- a/playback/audio.cpp +++ b/playback/audio.cpp @@ -1,12 +1,12 @@ #include "audio.h" +#include "oliveglobal.h" + #include "project/sequence.h" -#include "io/config.h" -#include "panels/project.h" #include "panels/panels.h" -#include "panels/timeline.h" -#include "panels/viewer.h" + +#include "io/config.h" #include "ui/audiomonitor.h" #include "playback/playback.h" #include "debug.h" @@ -132,7 +132,7 @@ void clear_audio_ibuffer() { } int current_audio_freq() { - return audio_rendering ? sequence->audio_frequency : audio_output->format().sampleRate(); + return audio_rendering ? Olive::ActiveSequence->audio_frequency : audio_output->format().sampleRate(); } qint64 get_buffer_offset_from_frame(double framerate, long frame) { @@ -303,26 +303,31 @@ void write_wave_trailer(QFile& f) { } bool start_recording() { - if (sequence == nullptr) { + if (Olive::ActiveSequence == nullptr) { qCritical() << "No active sequence to record into"; return false; } - QString audio_path = project_url + " " + QCoreApplication::translate("Audio", "Audio"); + QString audio_path = QCoreApplication::translate("Audio", "%1 Audio").arg(Olive::ActiveProjectFilename); QDir audio_dir(audio_path); if (!audio_dir.exists() && !audio_dir.mkpath(".")) { qCritical() << "Failed to create audio directory"; return false; } - QString audio_filename; + QString audio_file_path; int file_number = 0; do { file_number++; - audio_filename = audio_path + "/" + QCoreApplication::translate("Audio", "Recording") + " " + QString::number(file_number) + ".wav"; - } while (QFile(audio_filename).exists()); - output_recording.setFileName(audio_filename); + QString audio_filename = QString("%1.wav").arg( + QCoreApplication::translate("Audio", "Recording %1").arg(QString::number(file_number)) + ); + + audio_file_path = audio_dir.filePath(audio_filename); + } while (QFile(audio_file_path).exists()); + + output_recording.setFileName(audio_file_path); if (!output_recording.open(QFile::WriteOnly)) { qCritical() << "Failed to open output file. Does Olive have permission to write to this directory?"; return false; diff --git a/playback/cacher.cpp b/playback/cacher.cpp index 3506ab07e..37e391d4f 100644 --- a/playback/cacher.cpp +++ b/playback/cacher.cpp @@ -117,7 +117,7 @@ void cache_audio_worker(Clip* c, bool scrubbing, QVector& nests, int play } if (temp_reverse) { - long seq_end = sequence->getEndFrame(); + long seq_end = Olive::ActiveSequence->getEndFrame(); timeline_in = seq_end - timeline_in; timeline_out = seq_end - timeline_out; target_frame = seq_end - target_frame; diff --git a/playback/playback.cpp b/playback/playback.cpp index af4d03f72..b293def72 100644 --- a/playback/playback.cpp +++ b/playback/playback.cpp @@ -432,7 +432,7 @@ bool is_clip_active(Clip* c, long playhead) { void set_sequence(Sequence* s) { panel_effect_controls->clear_effects(true); - sequence = s; + Olive::ActiveSequence = s; panel_sequence_viewer->set_main_sequence(); panel_timeline->update_sequence(); panel_timeline->setFocus(); diff --git a/project/clip.cpp b/project/clip.cpp index faafc8fb4..9e7663a58 100644 --- a/project/clip.cpp +++ b/project/clip.cpp @@ -277,11 +277,13 @@ int Clip::getWidth() { const FootageStream* ms = media->to_footage()->get_stream_from_file_index(track < 0, media_stream); if (ms != nullptr) return ms->video_width; if (sequence != nullptr) return sequence->width; + break; } case MEDIA_TYPE_SEQUENCE: { Sequence* s = media->to_sequence(); return s->width; + break; } } return 0; diff --git a/project/clip.h b/project/clip.h index 82d385437..343ef181b 100644 --- a/project/clip.h +++ b/project/clip.h @@ -7,9 +7,6 @@ #include "marker.h" -#define SKIP_TYPE_DISCARD 0 -#define SKIP_TYPE_SEEK 1 - class Cacher; class Effect; class Transition; diff --git a/project/effect.cpp b/project/effect.cpp index 804d3d630..1409d94cf 100644 --- a/project/effect.cpp +++ b/project/effect.cpp @@ -76,7 +76,7 @@ Effect* create_effect(Clip* c, const EffectMeta* em) { return new Effect(c, em); } else { qCritical() << "Invalid effect data"; - QMessageBox::critical(mainWindow, + QMessageBox::critical(Olive::MainWindow, QCoreApplication::translate("Effect", "Invalid effect"), QCoreApplication::translate("Effect", "No candidate for effect '%1'. This effect may be corrupt. Try reinstalling it or Olive.").arg(em->name)); } @@ -375,7 +375,7 @@ void Effect::field_changed() { void Effect::show_context_menu(const QPoint& pos) { if (meta->type == EFFECT_TYPE_EFFECT) { - QMenu menu(mainWindow); + QMenu menu(Olive::MainWindow); int index = get_index_in_clip(); @@ -438,7 +438,7 @@ void Effect::move_down() { void Effect::save_to_file() { // save effect settings to file - QString file = QFileDialog::getSaveFileName(mainWindow, + QString file = QFileDialog::getSaveFileName(Olive::MainWindow, tr("Save Effect Settings"), QString(), tr("Effect XML Settings %1").arg("(*.xml)")); @@ -458,7 +458,7 @@ void Effect::save_to_file() { file_handle.close(); } else { - QMessageBox::critical(mainWindow, + QMessageBox::critical(Olive::MainWindow, tr("Save Settings Failed"), tr("Failed to open \"%1\" for writing.").arg(file), QMessageBox::Ok); @@ -468,7 +468,7 @@ void Effect::save_to_file() { void Effect::load_from_file() { // load effect settings from file - QString file = QFileDialog::getOpenFileName(mainWindow, + QString file = QFileDialog::getOpenFileName(Olive::MainWindow, tr("Load Effect Settings"), QString(), tr("Effect XML Settings %1").arg("(*.xml)")); @@ -484,7 +484,7 @@ void Effect::load_from_file() { update_ui(false); } else { - QMessageBox::critical(mainWindow, + QMessageBox::critical(Olive::MainWindow, tr("Load Settings Failed"), tr("Failed to open \"%1\" for reading.").arg(file), QMessageBox::Ok); @@ -693,7 +693,7 @@ void Effect::load_from_string(const QByteArray &s) { // pass off to standard loading function load(stream); } else { - QMessageBox::critical(mainWindow, + QMessageBox::critical(Olive::MainWindow, tr("Load Settings Failed"), tr("This settings file doesn't match this effect."), QMessageBox::Ok); diff --git a/project/effectfield.h b/project/effectfield.h index 1fa3bcbfa..d485e4c9b 100644 --- a/project/effectfield.h +++ b/project/effectfield.h @@ -1,13 +1,15 @@ #ifndef EFFECTFIELD_H #define EFFECTFIELD_H -#define EFFECT_FIELD_DOUBLE 0 -#define EFFECT_FIELD_COLOR 1 -#define EFFECT_FIELD_STRING 2 -#define EFFECT_FIELD_BOOL 3 -#define EFFECT_FIELD_COMBO 4 -#define EFFECT_FIELD_FONT 5 -#define EFFECT_FIELD_FILE 6 +enum EffectFieldType { + EFFECT_FIELD_DOUBLE, + EFFECT_FIELD_COLOR, + EFFECT_FIELD_STRING, + EFFECT_FIELD_BOOL, + EFFECT_FIELD_COMBO, + EFFECT_FIELD_FONT, + EFFECT_FIELD_FILE +}; #include #include diff --git a/project/effectgizmo.h b/project/effectgizmo.h index 1eb7e2e28..0b4ed02f9 100644 --- a/project/effectgizmo.h +++ b/project/effectgizmo.h @@ -1,9 +1,11 @@ #ifndef EFFECTGIZMO_H #define EFFECTGIZMO_H -#define GIZMO_TYPE_DOT 0 -#define GIZMO_TYPE_POLY 1 -#define GIZMO_TYPE_TARGET 2 +enum GizmoType { + GIZMO_TYPE_DOT, + GIZMO_TYPE_POLY, + GIZMO_TYPE_TARGET +}; #define GIZMO_DOT_SIZE 2.5 #define GIZMO_TARGET_SIZE 5.0 diff --git a/project/effectrow.cpp b/project/effectrow.cpp index e803364ea..fb3849849 100644 --- a/project/effectrow.cpp +++ b/project/effectrow.cpp @@ -101,7 +101,7 @@ void EffectRow::goto_previous_key() { EffectField* f = field(i); for (int j=0;jkeyframes.size();j++) { long comp = f->keyframes.at(j).time - c->clip_in + c->timeline_in; - if (comp < sequence->playhead) { + if (comp < Olive::ActiveSequence->playhead) { key = qMax(comp, key); } } @@ -117,7 +117,7 @@ void EffectRow::toggle_key() { EffectField* f = field(j); for (int i=0;ikeyframes.size();i++) { long comp = c->timeline_in - c->clip_in + f->keyframes.at(i).time; - if (comp == sequence->playhead) { + if (comp == Olive::ActiveSequence->playhead) { key_fields.append(f); key_field_index.append(i); } @@ -144,7 +144,7 @@ void EffectRow::goto_next_key() { EffectField* f = field(i); for (int j=0;jkeyframes.size();j++) { long comp = f->keyframes.at(j).time - c->clip_in + c->timeline_in; - if (comp > sequence->playhead) { + if (comp > Olive::ActiveSequence->playhead) { key = qMin(comp, key); } } @@ -174,7 +174,7 @@ void EffectRow::add_widget(QWidget* w) { } void EffectRow::set_keyframe_now(ComboAction* ca) { - long time = sequence->playhead-parent_effect->parent_clip->timeline_in+parent_effect->parent_clip->clip_in; + long time = Olive::ActiveSequence->playhead-parent_effect->parent_clip->timeline_in+parent_effect->parent_clip->clip_in; if (!just_made_unsafe_keyframe) { EffectKeyframe key; diff --git a/project/marker.cpp b/project/marker.cpp index 646459cac..985eae67d 100644 --- a/project/marker.cpp +++ b/project/marker.cpp @@ -39,7 +39,7 @@ void set_marker_internal(Sequence* seq, const QVector& clips) { // if (config.set_name_with_marker) is false (set above), ask for a marker name if (!add_marker) { - QInputDialog d(mainWindow); + QInputDialog d(Olive::MainWindow); d.setWindowTitle(QCoreApplication::translate("Marker", "Set Marker")); d.setLabelText(clips.size() > 0 ? QCoreApplication::translate("Marker", "Set clip marker name:") diff --git a/project/media.h b/project/media.h index b917d7495..ff7ea236f 100644 --- a/project/media.h +++ b/project/media.h @@ -6,9 +6,11 @@ #include "project/marker.h" -#define MEDIA_TYPE_FOOTAGE 0 -#define MEDIA_TYPE_SEQUENCE 1 -#define MEDIA_TYPE_FOLDER 2 +enum MediaType { + MEDIA_TYPE_FOOTAGE, + MEDIA_TYPE_SEQUENCE, + MEDIA_TYPE_FOLDER +}; struct Footage; class MediaThrobber; diff --git a/project/projectelements.h b/project/projectelements.h new file mode 100644 index 000000000..e41e27aa5 --- /dev/null +++ b/project/projectelements.h @@ -0,0 +1,15 @@ +#ifndef PROJECTELEMENTS_H +#define PROJECTELEMENTS_H + +// includes elements the user can use in a project +#include "media.h" +#include "footage.h" +#include "sequence.h" + +// includes elements the user can use in a sequence +#include "clip.h" +#include "transition.h" +#include "marker.h" +#include "effect.h" + +#endif // PROJECTELEMENTS_H diff --git a/project/sequence.cpp b/project/sequence.cpp index 6ec6afcf4..bd9eec73b 100644 --- a/project/sequence.cpp +++ b/project/sequence.cpp @@ -111,4 +111,4 @@ void Sequence::getTrackLimits(int* video_tracks, int* audio_tracks) { } // static variable for the currently active sequence -Sequence* sequence = nullptr; +Sequence* Olive::ActiveSequence = nullptr; diff --git a/project/sequence.h b/project/sequence.h index bf62edfd9..0e69b6d97 100644 --- a/project/sequence.h +++ b/project/sequence.h @@ -41,6 +41,8 @@ struct Sequence { }; // static variable for the currently active sequence -extern Sequence* sequence; +namespace Olive { + extern Sequence* ActiveSequence; +} #endif // SEQUENCE_H diff --git a/project/sourcescommon.cpp b/project/sourcescommon.cpp index 0c7f55fcd..ad8707f0f 100644 --- a/project/sourcescommon.cpp +++ b/project/sourcescommon.cpp @@ -13,6 +13,7 @@ #include "io/config.h" #include "dialogs/proxydialog.h" #include "ui/viewerwidget.h" +#include "ui/menuhelper.h" #include "io/proxygenerator.h" #include "mainwindow.h" @@ -61,7 +62,7 @@ void SourcesCommon::show_context_menu(QWidget* parent, const QModelIndexList& it QObject::connect(import_action, SIGNAL(triggered(bool)), project_parent, SLOT(import_dialog())); QMenu* new_menu = menu.addMenu(tr("New")); - mainWindow->make_new_menu(new_menu); + Olive::MenuHelper.make_new_menu(new_menu); QMenu* view_menu = menu.addMenu(tr("View")); @@ -356,7 +357,7 @@ void SourcesCommon::item_renamed(Media* item) { void SourcesCommon::open_create_proxy_dialog() { // open the proxy dialog and send it a list of currently selected footage - ProxyDialog pd(mainWindow, cached_selected_footage); + ProxyDialog pd(Olive::MainWindow, cached_selected_footage); pd.exec(); } @@ -368,7 +369,7 @@ void SourcesCommon::clear_proxies_from_selected() { if (f->proxy && !f->proxy_path.isEmpty()) { if (QFileInfo::exists(f->proxy_path)) { - if (QMessageBox::question(mainWindow, + if (QMessageBox::question(Olive::MainWindow, tr("Delete proxy"), tr("Would you like to delete the proxy file \"%1\" as well?").arg(f->proxy_path), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { @@ -381,9 +382,9 @@ void SourcesCommon::clear_proxies_from_selected() { f->proxy_path.clear(); } - if (sequence != nullptr) { + if (Olive::ActiveSequence != nullptr) { // close all clips so we can delete any proxies requested to be deleted - closeActiveClips(sequence); + closeActiveClips(Olive::ActiveSequence); } // delete proxies requested to be deleted @@ -391,10 +392,10 @@ void SourcesCommon::clear_proxies_from_selected() { QFile::remove(delete_list.at(i)); } - if (sequence != nullptr) { + if (Olive::ActiveSequence != nullptr) { // update viewer (will re-open active clips with original media) panel_sequence_viewer->viewer_widget->frame_update(); } - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } diff --git a/project/transition.cpp b/project/transition.cpp index 0535e75e9..5a3123b6f 100644 --- a/project/transition.cpp +++ b/project/transition.cpp @@ -75,7 +75,7 @@ Transition* get_transition_from_meta(Clip* c, Clip* s, const EffectMeta* em) { } } else { qCritical() << "Invalid transition data"; - QMessageBox::critical(mainWindow, + QMessageBox::critical(Olive::MainWindow, QCoreApplication::translate("transition", "Invalid transition"), QCoreApplication::translate("transition", "No candidate for transition '%1'. This transition may be corrupt. Try reinstalling it or Olive.").arg(em->name) ); diff --git a/project/undo.cpp b/project/undo.cpp index 13c38460d..458a07fa7 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -73,7 +73,7 @@ MoveClipAction::MoveClipAction(Clip *c, long iin, long iout, long iclip_in, int new_clip_in(iclip_in), new_track(itrack), relative(irelative), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void MoveClipAction::undo() { @@ -89,7 +89,7 @@ void MoveClipAction::undo() { clip->track = old_track; } - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void MoveClipAction::redo() { @@ -105,7 +105,7 @@ void MoveClipAction::redo() { clip->track = new_track; } - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } DeleteClipAction::DeleteClipAction(Sequence* s, int clip) : @@ -113,7 +113,7 @@ DeleteClipAction::DeleteClipAction(Sequence* s, int clip) : index(clip), opening_transition(-1), closing_transition(-1), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} DeleteClipAction::~DeleteClipAction() { @@ -144,7 +144,7 @@ void DeleteClipAction::undo() { ref = nullptr; - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void DeleteClipAction::redo() { @@ -184,7 +184,7 @@ void DeleteClipAction::redo() { } } - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } ChangeSequenceAction::ChangeSequenceAction(Sequence* s) : @@ -196,7 +196,7 @@ void ChangeSequenceAction::undo() { } void ChangeSequenceAction::redo() { - old_sequence = sequence; + old_sequence = Olive::ActiveSequence; set_sequence(new_sequence); } @@ -205,7 +205,7 @@ SetTimelineInOutCommand::SetTimelineInOutCommand(Sequence *s, bool enabled, long new_enabled(enabled), new_in(in), new_out(out), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void SetTimelineInOutCommand::undo() { @@ -221,7 +221,7 @@ void SetTimelineInOutCommand::undo() { m->out = old_out; } - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void SetTimelineInOutCommand::redo() { @@ -241,7 +241,7 @@ void SetTimelineInOutCommand::redo() { m->out = new_out; } - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } AddEffectCommand::AddEffectCommand(Clip* c, Effect* e, const EffectMeta *m, int insert_pos) : @@ -250,7 +250,7 @@ AddEffectCommand::AddEffectCommand(Clip* c, Effect* e, const EffectMeta *m, int ref(e), pos(insert_pos), done(false), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} AddEffectCommand::~AddEffectCommand() { @@ -265,7 +265,7 @@ void AddEffectCommand::undo() { clip->effects.removeAt(pos); } done = false; - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void AddEffectCommand::redo() { @@ -278,7 +278,7 @@ void AddEffectCommand::redo() { clip->effects.insert(pos, ref); } done = true; - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } AddTransitionCommand::AddTransitionCommand(Clip* c, Clip *s, Transition* copy, const EffectMeta *itransition, int itype, int ilength) : @@ -288,7 +288,7 @@ AddTransitionCommand::AddTransitionCommand(Clip* c, Clip *s, Transition* copy, c transition(itransition), type(itype), length(ilength), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void AddTransitionCommand::undo() { @@ -303,7 +303,7 @@ void AddTransitionCommand::undo() { if (secondary != nullptr) secondary->opening_transition = old_stransition; } - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void AddTransitionCommand::redo() { @@ -328,27 +328,27 @@ void AddTransitionCommand::redo() { clip->get_closing_transition()->set_length(length); } } - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } ModifyTransitionCommand::ModifyTransitionCommand(Clip* c, int itype, long ilength) : clip(c), type(itype), new_length(ilength), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void ModifyTransitionCommand::undo() { Transition* t = (type == TA_OPENING_TRANSITION) ? clip->get_opening_transition() : clip->get_closing_transition(); t->set_length(old_length); - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void ModifyTransitionCommand::redo() { Transition* t = (type == TA_OPENING_TRANSITION) ? clip->get_opening_transition() : clip->get_closing_transition(); old_length = t->get_true_length(); t->set_length(new_length); - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } DeleteTransitionCommand::DeleteTransitionCommand(Sequence* s, int transition_index) : @@ -357,7 +357,7 @@ DeleteTransitionCommand::DeleteTransitionCommand(Sequence* s, int transition_ind transition(nullptr), otc(nullptr), ctc(nullptr), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} DeleteTransitionCommand::~DeleteTransitionCommand() { @@ -371,7 +371,7 @@ void DeleteTransitionCommand::undo() { if (ctc != nullptr) ctc->closing_transition = index; transition = nullptr; - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void DeleteTransitionCommand::redo() { @@ -392,14 +392,14 @@ void DeleteTransitionCommand::redo() { transition = seq->transitions.at(index); seq->transitions[index] = nullptr; - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } NewSequenceCommand::NewSequenceCommand(Media *s, Media* iparent) : seq(s), parent(iparent), done(false), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) { if (parent == nullptr) parent = project_model.get_root(); } @@ -412,21 +412,21 @@ void NewSequenceCommand::undo() { project_model.removeChild(parent, seq); done = false; - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void NewSequenceCommand::redo() { project_model.appendChild(parent, seq); done = true; - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } AddMediaCommand::AddMediaCommand(Media* iitem, Media *iparent) : item(iitem), parent(iparent), done(false), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} AddMediaCommand::~AddMediaCommand() { @@ -438,20 +438,20 @@ AddMediaCommand::~AddMediaCommand() { void AddMediaCommand::undo() { project_model.removeChild(parent, item); done = false; - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void AddMediaCommand::redo() { project_model.appendChild(parent, item); done = true; - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } DeleteMediaCommand::DeleteMediaCommand(Media* i) : item(i), parent(i->parentItem()), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} DeleteMediaCommand::~DeleteMediaCommand() { @@ -463,21 +463,21 @@ DeleteMediaCommand::~DeleteMediaCommand() { void DeleteMediaCommand::undo() { project_model.appendChild(parent, item); - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); done = false; } void DeleteMediaCommand::redo() { project_model.removeChild(parent, item); - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); done = true; } AddClipCommand::AddClipCommand(Sequence* s, QVector& add) : seq(s), clips(add), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} AddClipCommand::~AddClipCommand() { @@ -498,7 +498,7 @@ void AddClipCommand::undo() { if (c->open) close_clip(c, true); seq->clips.removeLast(); } - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void AddClipCommand::redo() { @@ -525,10 +525,10 @@ void AddClipCommand::redo() { } } } - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } -LinkCommand::LinkCommand() : link(true), old_project_changed(mainWindow->isWindowModified()) {} +LinkCommand::LinkCommand() : link(true), old_project_changed(Olive::MainWindow->isWindowModified()) {} void LinkCommand::undo() { for (int i=0;ilinked = old_links.at(i); } } - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void LinkCommand::redo() { @@ -558,30 +558,30 @@ void LinkCommand::redo() { c->linked.clear(); } } - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } -CheckboxCommand::CheckboxCommand(QCheckBox* b) : box(b), checked(box->isChecked()), done(true), old_project_changed(mainWindow->isWindowModified()) {} +CheckboxCommand::CheckboxCommand(QCheckBox* b) : box(b), checked(box->isChecked()), done(true), old_project_changed(Olive::MainWindow->isWindowModified()) {} CheckboxCommand::~CheckboxCommand() {} void CheckboxCommand::undo() { box->setChecked(!checked); done = false; - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void CheckboxCommand::redo() { if (!done) { box->setChecked(checked); } - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } ReplaceMediaCommand::ReplaceMediaCommand(Media* i, QString s) : item(i), new_filename(s), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) { old_filename = item->to_footage()->url; } @@ -610,20 +610,20 @@ void ReplaceMediaCommand::replace(QString& filename) { void ReplaceMediaCommand::undo() { replace(old_filename); - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void ReplaceMediaCommand::redo() { replace(new_filename); - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } ReplaceClipMediaCommand::ReplaceClipMediaCommand(Media *a, Media *b, bool e) : old_media(a), new_media(b), preserve_clip_ins(e), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void ReplaceClipMediaCommand::replace(bool undo) { @@ -660,17 +660,17 @@ void ReplaceClipMediaCommand::replace(bool undo) { void ReplaceClipMediaCommand::undo() { replace(true); - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void ReplaceClipMediaCommand::redo() { replace(false); update_ui(true); - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } -EffectDeleteCommand::EffectDeleteCommand() : done(false), old_project_changed(mainWindow->isWindowModified()) {} +EffectDeleteCommand::EffectDeleteCommand() : done(false), old_project_changed(Olive::MainWindow->isWindowModified()) {} EffectDeleteCommand::~EffectDeleteCommand() { if (done) { @@ -687,7 +687,7 @@ void EffectDeleteCommand::undo() { } panel_effect_controls->reload_clips(); done = false; - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void EffectDeleteCommand::redo() { @@ -702,16 +702,16 @@ void EffectDeleteCommand::redo() { } panel_effect_controls->reload_clips(); done = true; - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } -MediaMove::MediaMove() : old_project_changed(mainWindow->isWindowModified()) {} +MediaMove::MediaMove() : old_project_changed(Olive::MainWindow->isWindowModified()) {} void MediaMove::undo() { for (int i=0;isetWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void MediaMove::redo() { @@ -722,47 +722,47 @@ void MediaMove::redo() { froms[i] = parent; project_model.moveChild(items.at(i), to); } - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } MediaRename::MediaRename(Media* iitem, QString ito) : item(iitem), from(iitem->get_name()), to(ito), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void MediaRename::undo() { item->set_name(from); - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void MediaRename::redo() { item->set_name(to); - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } KeyframeDelete::KeyframeDelete(EffectField *ifield, int iindex) : field(ifield), index(iindex), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void KeyframeDelete::undo() { field->keyframes.insert(index, deleted_key); - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void KeyframeDelete::redo() { deleted_key = field->keyframes.at(index); field->keyframes.removeAt(index); - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } EffectFieldUndo::EffectFieldUndo(EffectField* f) : field(f), done(true), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) { old_val = field->get_previous_data(); new_val = field->get_current_data(); @@ -771,18 +771,18 @@ EffectFieldUndo::EffectFieldUndo(EffectField* f) : void EffectFieldUndo::undo() { field->set_current_data(old_val); done = false; - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void EffectFieldUndo::redo() { if (!done) { field->set_current_data(new_val); } - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } SetAutoscaleAction::SetAutoscaleAction() : - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void SetAutoscaleAction::undo() { @@ -790,7 +790,7 @@ void SetAutoscaleAction::undo() { clips.at(i)->autoscale = !clips.at(i)->autoscale; } panel_sequence_viewer->viewer_widget->frame_update(); - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void SetAutoscaleAction::redo() { @@ -798,14 +798,14 @@ void SetAutoscaleAction::redo() { clips.at(i)->autoscale = !clips.at(i)->autoscale; } panel_sequence_viewer->viewer_widget->frame_update(); - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } AddMarkerAction::AddMarkerAction(QVector* m, long t, QString n) : active_array(m), time(t), name(n), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void AddMarkerAction::undo() { @@ -815,7 +815,7 @@ void AddMarkerAction::undo() { active_array[0][index].name = old_name; } - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void AddMarkerAction::redo() { @@ -838,37 +838,37 @@ void AddMarkerAction::redo() { active_array[0][index].name = name; } - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } MoveMarkerAction::MoveMarkerAction(Marker* m, long o, long n) : marker(m), old_time(o), new_time(n), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void MoveMarkerAction::undo() { marker->frame = old_time; - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void MoveMarkerAction::redo() { marker->frame = new_time; - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } DeleteMarkerAction::DeleteMarkerAction(QVector *m) : active_array(m), sorted(false), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void DeleteMarkerAction::undo() { for (int i=markers.size()-1;i>=0;i--) { active_array->insert(markers.at(i), copies.at(i)); } - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void DeleteMarkerAction::redo() { @@ -885,55 +885,55 @@ void DeleteMarkerAction::redo() { active_array->removeAt(markers.at(i)); } sorted = true; - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } SetSpeedAction::SetSpeedAction(Clip* c, double speed) : clip(c), old_speed(c->speed), new_speed(speed), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void SetSpeedAction::undo() { clip->speed = old_speed; clip->recalculateMaxLength(); - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void SetSpeedAction::redo() { clip->speed = new_speed; clip->recalculateMaxLength(); - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } SetBool::SetBool(bool* b, bool setting) : boolean(b), old_setting(*b), new_setting(setting), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void SetBool::undo() { *boolean = old_setting; - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void SetBool::redo() { *boolean = new_setting; - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } SetSelectionsCommand::SetSelectionsCommand(Sequence* s) : seq(s), done(true), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void SetSelectionsCommand::undo() { seq->selections = old_data; done = false; - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void SetSelectionsCommand::redo() { @@ -941,30 +941,30 @@ void SetSelectionsCommand::redo() { seq->selections = new_data; done = true; } - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } SetEnableCommand::SetEnableCommand(Clip* c, bool enable) : clip(c), old_val(c->enabled), new_val(enable), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void SetEnableCommand::undo() { clip->enabled = old_val; - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void SetEnableCommand::redo() { clip->enabled = new_val; - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } EditSequenceCommand::EditSequenceCommand(Media* i, Sequence *s) : item(i), seq(s), - old_project_changed(mainWindow->isWindowModified()), + old_project_changed(Olive::MainWindow->isWindowModified()), old_name(s->name), old_width(s->width), old_height(s->height), @@ -982,7 +982,7 @@ void EditSequenceCommand::undo() { seq->audio_layout = old_audio_layout; update(); - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void EditSequenceCommand::redo() { @@ -994,7 +994,7 @@ void EditSequenceCommand::redo() { seq->audio_layout = audio_layout; update(); - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } void EditSequenceCommand::update() { @@ -1005,7 +1005,7 @@ void EditSequenceCommand::update() { if (seq->clips.at(i) != nullptr) seq->clips.at(i)->refresh(); } - if (sequence == seq) { + if (Olive::ActiveSequence == seq) { set_sequence(seq); } } @@ -1014,34 +1014,34 @@ SetInt::SetInt(int* pointer, int new_value) : p(pointer), oldval(*pointer), newval(new_value), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void SetInt::undo() { *p = oldval; - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void SetInt::redo() { *p = newval; - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } SetString::SetString(QString* pointer, QString new_value) : p(pointer), oldval(*pointer), newval(new_value), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void SetString::undo() { *p = oldval; - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void SetString::redo() { *p = newval; - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } void CloseAllClipsCommand::undo() { @@ -1049,7 +1049,7 @@ void CloseAllClipsCommand::undo() { } void CloseAllClipsCommand::redo() { - closeActiveClips(sequence); + closeActiveClips(Olive::ActiveSequence); } UpdateFootageTooltip::UpdateFootageTooltip(Media *i) : @@ -1065,22 +1065,22 @@ void UpdateFootageTooltip::redo() { } MoveEffectCommand::MoveEffectCommand() : - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void MoveEffectCommand::undo() { clip->effects.move(to, from); - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void MoveEffectCommand::redo() { clip->effects.move(from, to); - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } RemoveClipsFromClipboard::RemoveClipsFromClipboard(int index) : pos(index), - old_project_changed(mainWindow->isWindowModified()), + old_project_changed(Olive::MainWindow->isWindowModified()), done(false) {} @@ -1102,7 +1102,7 @@ void RemoveClipsFromClipboard::redo() { } RenameClipCommand::RenameClipCommand() : - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void RenameClipCommand::undo() { @@ -1122,18 +1122,18 @@ void RenameClipCommand::redo() { SetPointer::SetPointer(void **pointer, void *data) : p(pointer), new_data(data), - old_changed(mainWindow->isWindowModified()) + old_changed(Olive::MainWindow->isWindowModified()) {} void SetPointer::undo() { *p = old_data; - mainWindow->setWindowModified(old_changed); + Olive::MainWindow->setWindowModified(old_changed); } void SetPointer::redo() { old_data = *p; *p = new_data; - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } void ReloadEffectsCommand::undo() { @@ -1175,17 +1175,17 @@ SetDouble::SetDouble(double* pointer, double old_value, double new_value) : p(pointer), oldval(old_value), newval(new_value), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void SetDouble::undo() { *p = oldval; - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void SetDouble::redo() { *p = newval; - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } SetQVariant::SetQVariant(QVariant *itarget, const QVariant &iold, const QVariant &inew) : @@ -1206,17 +1206,17 @@ SetLong::SetLong(long *pointer, long old_value, long new_value) : p(pointer), oldval(old_value), newval(new_value), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void SetLong::undo() { *p = oldval; - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void SetLong::redo() { *p = newval; - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } KeyframeFieldSet::KeyframeFieldSet(EffectField *ifield, int ii) : @@ -1224,19 +1224,19 @@ KeyframeFieldSet::KeyframeFieldSet(EffectField *ifield, int ii) : index(ii), key(ifield->keyframes.at(ii)), done(true), - old_project_changed(mainWindow->isWindowModified()) + old_project_changed(Olive::MainWindow->isWindowModified()) {} void KeyframeFieldSet::undo() { field->keyframes.removeAt(index); - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); done = false; } void KeyframeFieldSet::redo() { if (!done) { field->keyframes.insert(index, key); - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } done = true; } diff --git a/ui/audiomonitor.cpp b/ui/audiomonitor.cpp index 114e745b0..de511478a 100644 --- a/ui/audiomonitor.cpp +++ b/ui/audiomonitor.cpp @@ -48,7 +48,7 @@ void AudioMonitor::resizeEvent(QResizeEvent *e) { } void AudioMonitor::paintEvent(QPaintEvent *) { - if (sequence != nullptr && values.size() > 0) { + if (Olive::ActiveSequence != nullptr && values.size() > 0) { QPainter p(this); int channel_x = AUDIO_MONITOR_GAP; int channel_count = values.size(); diff --git a/ui/comboboxex.cpp b/ui/comboboxex.cpp index 8b04dd378..e961a4183 100644 --- a/ui/comboboxex.cpp +++ b/ui/comboboxex.cpp @@ -11,17 +11,17 @@ class ComboBoxExCommand : public QUndoCommand { public: ComboBoxExCommand(ComboBoxEx* obj, int old_index, int new_index) : - combobox(obj), old_val(old_index), new_val(new_index), done(true), old_project_changed(mainWindow->isWindowModified()) {} + combobox(obj), old_val(old_index), new_val(new_index), done(true), old_project_changed(Olive::MainWindow->isWindowModified()) {} void undo() { combobox->setCurrentIndex(old_val); done = false; - mainWindow->setWindowModified(old_project_changed); + Olive::MainWindow->setWindowModified(old_project_changed); } void redo() { if (!done) { combobox->setCurrentIndex(new_val); } - mainWindow->setWindowModified(true); + Olive::MainWindow->setWindowModified(true); } private: ComboBoxEx* combobox; diff --git a/ui/keyframeview.cpp b/ui/keyframeview.cpp index 3e5c4b77a..12d4999f5 100644 --- a/ui/keyframeview.cpp +++ b/ui/keyframeview.cpp @@ -86,13 +86,13 @@ void KeyframeView::paintEvent(QPaintEvent*) { visible_out = 0; for (int j=0;jselected_clips.size();j++) { - Clip* c = sequence->clips.at(panel_effect_controls->selected_clips.at(j)); + Clip* c = Olive::ActiveSequence->clips.at(panel_effect_controls->selected_clips.at(j)); visible_in = qMin(visible_in, c->timeline_in); visible_out = qMax(visible_out, c->timeline_out); } for (int j=0;jselected_clips.size();j++) { - Clip* c = sequence->clips.at(panel_effect_controls->selected_clips.at(j)); + Clip* c = Olive::ActiveSequence->clips.at(panel_effect_controls->selected_clips.at(j)); for (int i=0;ieffects.size();i++) { Effect* e = c->effects.at(i); if (e->container->is_expanded()) { @@ -148,7 +148,7 @@ 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, sequence->playhead-visible_in) - x_scroll; + int playhead_x = getScreenPointFromFrame(panel_effect_controls->zoom, Olive::ActiveSequence->playhead-visible_in) - x_scroll; if (dragging && panel_timeline->snapped) { p.setPen(Qt::white); } else { @@ -356,7 +356,7 @@ void KeyframeView::mouseMoveEvent(QMouseEvent* event) { Clip* c = field->parent_row->parent_effect->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(sequence->playhead, &key_eval)) { + if (panel_timeline->snap_to_point(Olive::ActiveSequence->playhead, &key_eval)) { frame_diff += (key_eval - key_time); break; } diff --git a/ui/menuhelper.cpp b/ui/menuhelper.cpp new file mode 100644 index 000000000..9ad5aaa07 --- /dev/null +++ b/ui/menuhelper.cpp @@ -0,0 +1,23 @@ +#include "menuhelper.h" + +#include "oliveglobal.h" + +#include "mainwindow.h" + +MenuHelper Olive::MenuHelper; + +void MenuHelper::make_new_menu(QMenu *parent) { + parent->addAction(tr("&Project"), Olive::Global.data(), SLOT(new_project()), QKeySequence("Ctrl+N"))->setProperty("id", "newproj"); + parent->addSeparator(); + parent->addAction(tr("&Sequence"), Olive::MainWindow, SLOT(new_sequence()), QKeySequence("Ctrl+Shift+N"))->setProperty("id", "newseq"); + parent->addAction(tr("&Folder"), Olive::MainWindow, SLOT(new_folder()))->setProperty("id", "newfolder"); +} + +void MenuHelper::make_inout_menu(QMenu *parent) { + parent->addAction(tr("Set In Point"), Olive::MainWindow, SLOT(set_in_point()), QKeySequence("I"))->setProperty("id", "setinpoint"); + parent->addAction(tr("Set Out Point"), Olive::MainWindow, SLOT(set_out_point()), QKeySequence("O"))->setProperty("id", "setoutpoint"); + parent->addSeparator(); + parent->addAction(tr("Reset In Point"), Olive::MainWindow, SLOT(clear_in()))->setProperty("id", "resetin"); + parent->addAction(tr("Reset Out Point"), Olive::MainWindow, SLOT(clear_out()))->setProperty("id", "resetout"); + parent->addAction(tr("Clear In/Out Point"), Olive::MainWindow, SLOT(clear_inout()), QKeySequence("G"))->setProperty("id", "clearinout"); +} diff --git a/ui/menuhelper.h b/ui/menuhelper.h new file mode 100644 index 000000000..96d740f45 --- /dev/null +++ b/ui/menuhelper.h @@ -0,0 +1,45 @@ +#ifndef MENUHELPER_H +#define MENUHELPER_H + +#include +#include + +class MenuHelper : public QObject { + Q_OBJECT +public: + /** + * @brief Creates a menu of new items that can be created + * + * Adds the full set of creatable items to a QMenu (e.g. new project, + * new sequence, new folder, etc.) + * + * @param parent + * + * The menu to add items to. + */ + void make_new_menu(QMenu* parent); + + /** + * @brief Creates a menu of options for working with in/out points + * + * Adds a set of options for working with sequence/footage in/out points, + * e.g. setting in/out points, clearing in/out points, etc. + * + * @param parent + * + * The menu to add items to. + */ + void make_inout_menu(QMenu* parent); +private slots: + + +}; + +namespace Olive { + /** + * @brief A global MenuHelper object to assist menu creation throughout Olive. + */ + extern MenuHelper MenuHelper; +} + +#endif // MENUHELPER_H diff --git a/ui/timelineheader.cpp b/ui/timelineheader.cpp index 140872784..25541e464 100644 --- a/ui/timelineheader.cpp +++ b/ui/timelineheader.cpp @@ -8,6 +8,7 @@ #include "project/media.h" #include "panels/viewer.h" #include "io/config.h" +#include "ui/menuhelper.h" #include "debug.h" #include @@ -436,11 +437,11 @@ void TimelineHeader::paintEvent(QPaintEvent*) { void TimelineHeader::show_context_menu(const QPoint &pos) { QMenu menu(this); - mainWindow->make_inout_menu(&menu); + Olive::MenuHelper.make_inout_menu(&menu); menu.addSeparator(); - QAction* center_timecodes = menu.addAction(tr("Center Timecodes"), mainWindow, SLOT(toggle_bool_action())); + QAction* center_timecodes = menu.addAction(tr("Center Timecodes"), Olive::MainWindow, SLOT(toggle_bool_action())); center_timecodes->setCheckable(true); center_timecodes->setChecked(config.center_timeline_timecodes); center_timecodes->setData(reinterpret_cast(&config.center_timeline_timecodes)); diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index 82989339d..785bfee8d 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -68,7 +68,7 @@ TimelineWidget::TimelineWidget(QWidget *parent) : QWidget(parent) { } void TimelineWidget::show_context_menu(const QPoint& pos) { - if (sequence != nullptr) { + if (Olive::ActiveSequence != nullptr) { // hack because sometimes right clicking doesn't trigger mouse release event panel_timeline->rect_select_init = false; panel_timeline->rect_select_proc = false; @@ -77,16 +77,16 @@ void TimelineWidget::show_context_menu(const QPoint& pos) { QAction* undoAction = menu.addAction(tr("&Undo")); QAction* redoAction = menu.addAction(tr("&Redo")); - connect(undoAction, SIGNAL(triggered(bool)), mainWindow, SLOT(undo())); - connect(redoAction, SIGNAL(triggered(bool)), mainWindow, SLOT(redo())); + connect(undoAction, SIGNAL(triggered(bool)), Olive::MainWindow, SLOT(undo())); + connect(redoAction, SIGNAL(triggered(bool)), Olive::MainWindow, SLOT(redo())); undoAction->setEnabled(undo_stack.canUndo()); redoAction->setEnabled(undo_stack.canRedo()); menu.addSeparator(); // collect all the selected clips QVector selected_clips; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { selected_clips.append(c); } @@ -94,11 +94,11 @@ void TimelineWidget::show_context_menu(const QPoint& pos) { if (!selected_clips.isEmpty()) { // clips are selected - menu.addAction(tr("C&ut"), mainWindow, SLOT(cut())); - menu.addAction(tr("Cop&y"), mainWindow, SLOT(copy())); + menu.addAction(tr("C&ut"), Olive::MainWindow, SLOT(cut())); + menu.addAction(tr("Cop&y"), Olive::MainWindow, SLOT(copy())); } - menu.addAction(tr("&Paste"), mainWindow, SLOT(paste())); + menu.addAction(tr("&Paste"), Olive::MainWindow, SLOT(paste())); if (selected_clips.isEmpty()) { // no clips are selected @@ -118,18 +118,18 @@ void TimelineWidget::show_context_menu(const QPoint& pos) { if (!selected_clips.isEmpty()) { menu.addSeparator(); - menu.addAction(tr("&Speed/Duration"), mainWindow, SLOT(open_speed_dialog())); + menu.addAction(tr("&Speed/Duration"), Olive::MainWindow, SLOT(open_speed_dialog())); QAction* autoscaleAction = menu.addAction(tr("Auto-s&cale"), this, SLOT(toggle_autoscale())); autoscaleAction->setCheckable(true); // set autoscale to the first selected clip autoscaleAction->setChecked(selected_clips.at(0)->autoscale); - menu.addAction(tr("Enable/Disable"), mainWindow, SLOT(toggle_enable_clips())); + menu.addAction(tr("Enable/Disable"), Olive::MainWindow, SLOT(toggle_enable_clips())); menu.addAction(tr("Link/Unlink"), panel_timeline, SLOT(toggle_links())); - menu.addAction(tr("&Nest"), mainWindow, SLOT(nest())); + menu.addAction(tr("&Nest"), Olive::MainWindow, SLOT(nest())); // stabilizer option /*int video_clip_count = 0; @@ -173,8 +173,8 @@ void TimelineWidget::show_context_menu(const QPoint& pos) { void TimelineWidget::toggle_autoscale() { SetAutoscaleAction* action = new SetAutoscaleAction(); - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { action->clips.append(c); } @@ -187,16 +187,16 @@ void TimelineWidget::toggle_autoscale() { } void TimelineWidget::tooltip_timer_timeout() { - if (sequence != nullptr) { - if (tooltip_clip < sequence->clips.size()) { - Clip* c = sequence->clips.at(tooltip_clip); + if (Olive::ActiveSequence != nullptr) { + if (tooltip_clip < Olive::ActiveSequence->clips.size()) { + Clip* c = Olive::ActiveSequence->clips.at(tooltip_clip); if (c != nullptr) { QToolTip::showText(QCursor::pos(), tr("%1\nStart: %2\nEnd: %3\nDuration: %4").arg( c->name, - frame_to_timecode(c->timeline_in, config.timecode_view, sequence->frame_rate), - frame_to_timecode(c->timeline_out, config.timecode_view, sequence->frame_rate), - frame_to_timecode(c->getLength(), config.timecode_view, sequence->frame_rate) + frame_to_timecode(c->timeline_in, config.timecode_view, Olive::ActiveSequence->frame_rate), + frame_to_timecode(c->timeline_out, config.timecode_view, Olive::ActiveSequence->frame_rate), + frame_to_timecode(c->getLength(), config.timecode_view, Olive::ActiveSequence->frame_rate) )); } } @@ -206,8 +206,8 @@ void TimelineWidget::tooltip_timer_timeout() { void TimelineWidget::rename_clip() { QVector selected_clips; - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr && is_clip_selected(c, true)) { selected_clips.append(c); } @@ -242,7 +242,7 @@ void TimelineWidget::open_sequence_properties() { } panel_project->get_all_media_from_table(all_top_level_items, sequence_items, MEDIA_TYPE_SEQUENCE); // find all sequences in project for (int i=0;ito_sequence() == sequence) { + if (sequence_items.at(i)->to_sequence() == Olive::ActiveSequence) { NewSequenceDialog nsd(this, sequence_items.at(i)); nsd.exec(); return; @@ -272,7 +272,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { if (event->source() == panel_footage_viewer->viewer_widget) { Sequence* proposed_seq = panel_footage_viewer->seq; - if (proposed_seq != sequence) { // don't allow nesting the same sequence + if (proposed_seq != Olive::ActiveSequence) { // don't allow nesting the same sequence media_list.append(panel_footage_viewer->media); import_init = true; } @@ -314,7 +314,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { event->acceptProposedAction(); long entry_point; - Sequence* seq = sequence; + Sequence* seq = Olive::ActiveSequence; if (seq == nullptr) { // if no sequence, we're going to create a new one using the clips as a reference @@ -338,7 +338,7 @@ void TimelineWidget::dragMoveEvent(QDragMoveEvent *event) { if (panel_timeline->importing) { event->acceptProposedAction(); - if (sequence != nullptr) { + if (Olive::ActiveSequence != nullptr) { QPoint pos = event->pos(); update_ghosts(pos, event->keyboardModifiers() & Qt::ShiftModifier); panel_timeline->move_insert = ((event->keyboardModifiers() & Qt::ControlModifier) && (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->importing)); @@ -424,8 +424,8 @@ void insert_clips(ComboAction* ca) { panel_timeline->split_cache.clear(); - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr) { // don't split any clips that are moving bool found = false; @@ -452,13 +452,13 @@ void insert_clips(ComboAction* ca) { long ripple_length = (latest_new_point - earliest_new_point); - ripple_clips(ca, sequence, earliest_new_point, ripple_length, ignore_clips); + ripple_clips(ca, Olive::ActiveSequence, earliest_new_point, ripple_length, ignore_clips); if (ripple_old_point) { // works for moving later clips earlier but not earlier to later long second_ripple_length = (earliest_old_point - latest_old_point); - ripple_clips(ca, sequence, latest_old_point, second_ripple_length, ignore_clips); + ripple_clips(ca, Olive::ActiveSequence, latest_old_point, second_ripple_length, ignore_clips); if (earliest_old_point < earliest_new_point) { for (int i=0;ighosts.size();i++) { @@ -466,8 +466,8 @@ void insert_clips(ComboAction* ca) { g.in += second_ripple_length; g.out += second_ripple_length; } - for (int i=0;iselections.size();i++) { - Selection& s = sequence->selections[i]; + for (int i=0;iselections.size();i++) { + Selection& s = Olive::ActiveSequence->selections[i]; s.in += second_ripple_length; s.out += second_ripple_length; } @@ -481,7 +481,7 @@ void TimelineWidget::dropEvent(QDropEvent* event) { ComboAction* ca = new ComboAction(); - Sequence* s = sequence; + Sequence* s = Olive::ActiveSequence; // if we're dropping into nothing, create a new sequences based on the clip being dragged if (s == nullptr) { @@ -505,23 +505,23 @@ void TimelineWidget::dropEvent(QDropEvent* event) { } void TimelineWidget::mouseDoubleClickEvent(QMouseEvent *event) { - if (sequence != nullptr) { + if (Olive::ActiveSequence != nullptr) { if (panel_timeline->tool == TIMELINE_TOOL_EDIT) { int clip_index = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); if (clip_index >= 0) { - Clip* clip = sequence->clips.at(clip_index); - if (!(event->modifiers() & Qt::ShiftModifier)) sequence->selections.clear(); + Clip* clip = Olive::ActiveSequence->clips.at(clip_index); + if (!(event->modifiers() & Qt::ShiftModifier)) Olive::ActiveSequence->selections.clear(); Selection s; s.in = clip->timeline_in; s.out = clip->timeline_out; s.track = clip->track; - sequence->selections.append(s); + Olive::ActiveSequence->selections.append(s); update_ui(false); } } else if (panel_timeline->tool == TIMELINE_TOOL_POINTER) { int clip_index = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); if (clip_index >= 0) { - Clip* c = sequence->clips.at(clip_index); + Clip* c = Olive::ActiveSequence->clips.at(clip_index); if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) { set_sequence(c->media->to_sequence()); } @@ -535,7 +535,7 @@ bool isLiveEditing() { } void TimelineWidget::mousePressEvent(QMouseEvent *event) { - if (sequence != nullptr) { + if (Olive::ActiveSequence != nullptr) { int tool = panel_timeline->tool; if (event->button() == Qt::MiddleButton) { tool = TIMELINE_TOOL_HAND; @@ -561,7 +561,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { bool alt = (event->modifiers() & Qt::AltModifier); if (shift) { - panel_timeline->selection_offset = sequence->selections.size(); + panel_timeline->selection_offset = Olive::ActiveSequence->selections.size(); } else { panel_timeline->selection_offset = 0; } @@ -608,7 +608,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { panel_timeline->moving_init = true; } else { if (clip_index >= 0) { - Clip* clip = sequence->clips.at(clip_index); + Clip* clip = Olive::ActiveSequence->clips.at(clip_index); if (clip != nullptr) { if (is_clip_selected(clip, true)) { if (shift) { @@ -616,7 +616,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { if (!alt) { for (int i=0;ilinked.size();i++) { - Clip* link = sequence->clips.at(clip->linked.at(i)); + Clip* link = Olive::ActiveSequence->clips.at(clip->linked.at(i)); panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track); } } @@ -624,7 +624,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track); for (int i=0;ilinked.size();i++) { - Clip* link = sequence->clips.at(clip->linked.at(i)); + Clip* link = Olive::ActiveSequence->clips.at(clip->linked.at(i)); panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track); } @@ -640,12 +640,12 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { s.out = clip->timeline_out; if (clip->get_closing_transition()->secondary_clip != nullptr) s.out += clip->get_closing_transition()->get_true_length(); } - sequence->selections.append(s); + Olive::ActiveSequence->selections.append(s); } } else { // if "shift" is not down if (!shift) { - sequence->selections.clear(); + Olive::ActiveSequence->selections.clear(); } Selection s; @@ -666,7 +666,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { } s.track = clip->track; - sequence->selections.append(s); + Olive::ActiveSequence->selections.append(s); if (config.select_also_seeks) { panel_sequence_viewer->seek(clip->timeline_in); @@ -675,13 +675,13 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { // if alt is not down, select links if (!alt && panel_timeline->transition_select == TA_NO_TRANSITION) { for (int i=0;ilinked.size();i++) { - Clip* link = sequence->clips.at(clip->linked.at(i)); + Clip* link = Olive::ActiveSequence->clips.at(clip->linked.at(i)); if (!is_clip_selected(link, true)) { Selection ss; ss.in = link->timeline_in; ss.out = link->timeline_out; ss.track = link->track; - sequence->selections.append(ss); + Olive::ActiveSequence->selections.append(ss); } } } @@ -692,7 +692,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) { } else { // if "shift" is not down if (!shift) { - sequence->selections.clear(); + Olive::ActiveSequence->selections.clear(); } panel_timeline->rect_select_init = true; @@ -758,7 +758,7 @@ void make_room_for_transition(ComboAction* ca, Clip* c, int type, long transitio void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { QToolTip::hideText(); - if (sequence != nullptr) { + if (Olive::ActiveSequence != nullptr) { bool alt = (event->modifiers() & Qt::AltModifier); bool shift = (event->modifiers() & Qt::ShiftModifier); bool ctrl = (event->modifiers() & Qt::ControlModifier); @@ -772,11 +772,11 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { const Ghost& g = panel_timeline->ghosts.at(0); if (panel_timeline->creating_object == ADD_OBJ_AUDIO) { - mainWindow->statusBar()->clearMessage(); + Olive::MainWindow->statusBar()->clearMessage(); panel_sequence_viewer->cue_recording(qMin(g.in, g.out), qMax(g.in, g.out), g.track); panel_timeline->creating = false; } else if (g.in != g.out) { - Clip* c = new Clip(sequence); + Clip* c = new Clip(Olive::ActiveSequence); c->media = nullptr; c->timeline_in = qMin(g.in, g.out); c->timeline_out = qMax(g.in, g.out); @@ -800,7 +800,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { QVector add; add.append(c); - ca->append(new AddClipCommand(sequence, add)); + ca->append(new AddClipCommand(Olive::ActiveSequence, add)); if (c->track < 0) { // default video effects (before custom effects) @@ -875,9 +875,9 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { ripple_length = first_ghost.old_in - first_ghost.in; ripple_point = first_ghost.old_in; - for (int i=0;iselections.size();i++) { - sequence->selections[i].in += ripple_length; - sequence->selections[i].out += ripple_length; + for (int i=0;iselections.size();i++) { + Olive::ActiveSequence->selections[i].in += ripple_length; + Olive::ActiveSequence->selections[i].out += ripple_length; } } else { // if we're trimming an out-point @@ -900,7 +900,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { } if (!panel_timeline->trim_in_point) ripple_length = -ripple_length; - ripple_clips(ca, sequence, ripple_point, ripple_length, ignore_clips); + ripple_clips(ca, Olive::ActiveSequence, ripple_point, ripple_length, ignore_clips); } if (panel_timeline->tool == TIMELINE_TOOL_POINTER @@ -914,7 +914,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { const Ghost& g = panel_timeline->ghosts.at(i); if (g.old_in != g.in || g.old_out != g.out || g.track != g.old_track || g.clip_in != g.old_clip_in) { // create copy of clip - Clip* c = sequence->clips.at(g.clip)->copy(sequence); + Clip* c = Olive::ActiveSequence->clips.at(g.clip)->copy(Olive::ActiveSequence); c->timeline_in = g.in; c->timeline_out = g.out; @@ -936,7 +936,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { // relink duplicated clips panel_timeline->relink_clips_using_ids(old_clips, new_clips); - ca->append(new AddClipCommand(sequence, new_clips)); + ca->append(new AddClipCommand(Olive::ActiveSequence, new_clips)); } } else { // INSERT if holding ctrl @@ -949,7 +949,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { // step 1 - set clips that are moving to "undeletable" (to avoid step 2 deleting any part of them) const Ghost& g = panel_timeline->ghosts.at(i); - sequence->clips.at(g.clip)->undeletable = true; + Olive::ActiveSequence->clips.at(g.clip)->undeletable = true; if (g.transition != nullptr) { g.transition->parent_clip->undeletable = true; if (g.transition->secondary_clip != nullptr) g.transition->secondary_clip->undeletable = true; @@ -964,7 +964,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { panel_timeline->delete_areas_and_relink(ca, delete_areas, false); for (int i=0;ighosts.size();i++) { const Ghost& g = panel_timeline->ghosts.at(i); - sequence->clips.at(g.clip)->undeletable = false; + Olive::ActiveSequence->clips.at(g.clip)->undeletable = false; if (g.transition != nullptr) { g.transition->parent_clip->undeletable = false; if (g.transition->secondary_clip != nullptr) g.transition->secondary_clip->undeletable = false; @@ -975,7 +975,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { Ghost& g = panel_timeline->ghosts[i]; // step 3 - move clips - Clip* c = sequence->clips.at(g.clip); + Clip* c = Olive::ActiveSequence->clips.at(g.clip); if (g.transition == nullptr) { move_clip(ca, c, (g.in - g.old_in), (g.out - g.old_out), (g.clip_in - g.old_clip_in), (g.track - g.old_track), true, true); @@ -1047,13 +1047,13 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { long transition_start = qMin(g.in, g.out); long transition_end = qMax(g.in, g.out); - Clip* pre = sequence->clips.at(g.clip); + Clip* pre = Olive::ActiveSequence->clips.at(g.clip); Clip* post = pre; make_room_for_transition(ca, pre, panel_timeline->transition_tool_type, transition_start, transition_end, true); if (panel_timeline->transition_tool_post_clip > -1) { - post = sequence->clips.at(panel_timeline->transition_tool_post_clip); + post = Olive::ActiveSequence->clips.at(panel_timeline->transition_tool_post_clip); int opposite_type = (panel_timeline->transition_tool_type == TA_OPENING_TRANSITION) ? TA_CLOSING_TRANSITION : TA_OPENING_TRANSITION; make_room_for_transition( ca, @@ -1123,10 +1123,10 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { } // remove duplicate selections - panel_timeline->clean_up_selections(sequence->selections); + panel_timeline->clean_up_selections(Olive::ActiveSequence->selections); if (selection_command != nullptr) { - selection_command->new_data = sequence->selections; + selection_command->new_data = Olive::ActiveSequence->selections; ca->append(selection_command); selection_command = nullptr; push_undo = true; @@ -1165,7 +1165,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { void TimelineWidget::init_ghosts() { for (int i=0;ighosts.size();i++) { Ghost& g = panel_timeline->ghosts[i]; - Clip* c = sequence->clips.at(g.clip); + Clip* c = Olive::ActiveSequence->clips.at(g.clip); g.track = g.old_track = c->track; g.clip_in = g.old_clip_in = c->clip_in; @@ -1195,8 +1195,8 @@ void TimelineWidget::init_ghosts() { c->recalculateMaxLength(); g.media_length = c->getMaximumLength(); } - for (int i=0;iselections.size();i++) { - Selection& s = sequence->selections[i]; + for (int i=0;iselections.size();i++) { + Selection& s = Olive::ActiveSequence->selections[i]; s.old_in = s.in; s.old_out = s.out; s.old_track = s.track; @@ -1271,7 +1271,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { // if the ghost is attached to a clip, snap its markers too if (panel_timeline->trim_target == -1 && g.clip >= 0) { - Clip* c = sequence->clips.at(g.clip); + Clip* c = Olive::ActiveSequence->clips.at(g.clip); for (int j=0;jget_markers().size();j++) { long marker_real_time = c->get_markers().at(j).frame + c->timeline_in - c->clip_in; fm = marker_real_time + frame_diff; @@ -1291,7 +1291,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { for (int i=0;ighosts.size();i++) { const Ghost& g = panel_timeline->ghosts.at(i); Clip* c = nullptr; - if (g.clip != -1) c = sequence->clips.at(g.clip); + if (g.clip != -1) c = Olive::ActiveSequence->clips.at(g.clip); const FootageStream* ms = nullptr; if (g.clip != -1 && c->media != nullptr && c->media->get_type() == MEDIA_TYPE_FOOTAGE) { @@ -1447,7 +1447,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { validate_transitions(c, panel_timeline->transition_tool_type, frame_diff); } else { Clip* otc = c; // open transition clip - Clip* ctc = sequence->clips.at(panel_timeline->transition_tool_post_clip); // close transition clip + Clip* ctc = Olive::ActiveSequence->clips.at(panel_timeline->transition_tool_post_clip); // close transition clip if (panel_timeline->transition_tool_type == TA_CLOSING_TRANSITION) { // swap @@ -1510,7 +1510,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { g.in = g.old_in + frame_diff; g.out = g.old_out + frame_diff; - if (g.transition != nullptr && g.transition == sequence->clips.at(g.clip)->get_opening_transition()) { + if (g.transition != nullptr && g.transition == Olive::ActiveSequence->clips.at(g.clip)->get_opening_transition()) { g.clip_in = g.old_clip_in + frame_diff; } @@ -1543,8 +1543,8 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { // apply changes to selections if (effective_tool != TIMELINE_TOOL_SLIP && !panel_timeline->importing && !panel_timeline->creating) { - for (int i=0;iselections.size();i++) { - Selection& s = sequence->selections[i]; + for (int i=0;iselections.size();i++) { + Selection& s = Olive::ActiveSequence->selections[i]; if (panel_timeline->trim_target > -1) { if (panel_timeline->trim_in_point) { s.in = s.old_in + frame_diff; @@ -1552,8 +1552,8 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { s.out = s.old_out + frame_diff; } } else if (clips_are_movable) { - for (int i=0;iselections.size();i++) { - Selection& s = sequence->selections[i]; + for (int i=0;iselections.size();i++) { + Selection& s = Olive::ActiveSequence->selections[i]; s.in = s.old_in + frame_diff; s.out = s.old_out + frame_diff; s.track = s.old_track; @@ -1574,9 +1574,9 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { } if (panel_timeline->importing) { - QToolTip::showText(mapToGlobal(mouse_pos), frame_to_timecode(earliest_in_point, config.timecode_view, sequence->frame_rate)); + QToolTip::showText(mapToGlobal(mouse_pos), frame_to_timecode(earliest_in_point, config.timecode_view, Olive::ActiveSequence->frame_rate)); } else { - QString tip = ((frame_diff < 0) ? "-" : "+") + frame_to_timecode(qAbs(frame_diff), config.timecode_view, sequence->frame_rate); + QString tip = ((frame_diff < 0) ? "-" : "+") + frame_to_timecode(qAbs(frame_diff), config.timecode_view, Olive::ActiveSequence->frame_rate); if (panel_timeline->trim_target > -1) { // find which clip is being moved const Ghost* g = nullptr; @@ -1595,7 +1595,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { } else { len += frame_diff; } - tip += frame_to_timecode(len, config.timecode_view, sequence->frame_rate); + tip += frame_to_timecode(len, config.timecode_view, Olive::ActiveSequence->frame_rate); } } QToolTip::showText(mapToGlobal(mouse_pos), tip); @@ -1604,7 +1604,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { tooltip_timer.stop(); - if (sequence != nullptr) { + if (Olive::ActiveSequence != nullptr) { bool alt = (event->modifiers() & Qt::AltModifier); panel_timeline->cursor_frame = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x()); @@ -1619,12 +1619,12 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } if (panel_timeline->selecting) { int selection_count = 1 + qMax(panel_timeline->cursor_track, panel_timeline->drag_track_start) - qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start) + panel_timeline->selection_offset; - if (sequence->selections.size() != selection_count) { - sequence->selections.resize(selection_count); + if (Olive::ActiveSequence->selections.size() != selection_count) { + Olive::ActiveSequence->selections.resize(selection_count); } int minimum_selection_track = qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start); for (int i=panel_timeline->selection_offset;iselections[i]; + Selection& s = Olive::ActiveSequence->selections[i]; s.track = minimum_selection_track + i - panel_timeline->selection_offset; long in = panel_timeline->drag_frame_start; long out = panel_timeline->cursor_frame; @@ -1634,10 +1634,10 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // select linked clips too if (config.edit_tool_selects_links) { - for (int j=0;jclips.size();j++) { - Clip* c = sequence->clips.at(j); - for (int k=0;kselections.size();k++) { - const Selection& s = sequence->selections.at(k); + for (int j=0;jclips.size();j++) { + Clip* c = Olive::ActiveSequence->clips.at(j); + for (int k=0;kselections.size();k++) { + const Selection& s = Olive::ActiveSequence->selections.at(k); if (!(c->timeline_in < s.in && c->timeline_out < s.in) && !(c->timeline_in > s.out && c->timeline_out > s.out) && c->track == s.track) { @@ -1645,8 +1645,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { QVector linked_tracks = panel_timeline->get_tracks_of_linked_clips(j); for (int k=0;kselections.size();l++) { - const Selection& test_sel = sequence->selections.at(l); + for (int l=0;lselections.size();l++) { + const Selection& test_sel = Olive::ActiveSequence->selections.at(l); if (test_sel.track == linked_tracks.at(k) && test_sel.in == s.in && test_sel.out == s.out) { @@ -1659,7 +1659,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { link_sel.in = s.in; link_sel.out = s.out; link_sel.track = linked_tracks.at(k); - sequence->selections.append(link_sel); + Olive::ActiveSequence->selections.append(link_sel); } } @@ -1701,8 +1701,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } else { // set up movement // create ghosts - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr) { Ghost g; g.transition = nullptr; @@ -1712,8 +1712,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // if a whole clip is not selected, maybe just a transition is if (panel_timeline->tool == TIMELINE_TOOL_POINTER && (c->get_opening_transition() != nullptr || c->get_closing_transition() != nullptr)) { // check if any selections contain the whole clip or transition - for (int j=0;jselections.size();j++) { - const Selection& s = sequence->selections.at(j); + for (int j=0;jselections.size();j++) { + const Selection& s = Olive::ActiveSequence->selections.at(j); if (s.track == c->track) { if (selection_contains_transition(s, c, TA_OPENING_TRANSITION)) { g.transition = c->get_opening_transition(); @@ -1750,11 +1750,11 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { int size = panel_timeline->ghosts.size(); if (panel_timeline->tool == TIMELINE_TOOL_ROLLING) { for (int i=0;iclips.at(panel_timeline->ghosts.at(i).clip); + Clip* ghost_clip = Olive::ActiveSequence->clips.at(panel_timeline->ghosts.at(i).clip); // see if any ghosts are touching, in which case flip them for (int k=0;kclips.at(panel_timeline->ghosts.at(k).clip); + Clip* comp_clip = Olive::ActiveSequence->clips.at(panel_timeline->ghosts.at(k).clip); if ((panel_timeline->trim_in_point && comp_clip->timeline_out == ghost_clip->timeline_in) || (!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) { panel_timeline->ghosts[k].trim_in = !panel_timeline->trim_in_point; @@ -1765,9 +1765,9 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { // then look for other clips we're touching for (int i=0;ighosts.at(i); - Clip* ghost_clip = sequence->clips.at(g.clip); - for (int j=0;jclips.size();j++) { - Clip* comp_clip = sequence->clips.at(j); + Clip* ghost_clip = Olive::ActiveSequence->clips.at(g.clip); + for (int j=0;jclips.size();j++) { + Clip* comp_clip = Olive::ActiveSequence->clips.at(j); if (comp_clip->track == ghost_clip->track) { if ((panel_timeline->trim_in_point && comp_clip->timeline_out == ghost_clip->timeline_in) || (!panel_timeline->trim_in_point && comp_clip->timeline_in == ghost_clip->timeline_out)) { @@ -1804,10 +1804,10 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } else if (panel_timeline->tool == TIMELINE_TOOL_SLIDE) { for (int i=0;ighosts.at(i); - Clip* ghost_clip = sequence->clips.at(g.clip); + Clip* ghost_clip = Olive::ActiveSequence->clips.at(g.clip); panel_timeline->ghosts[i].trimming = false; - for (int j=0;jclips.size();j++) { - Clip* c = sequence->clips.at(j); + for (int j=0;jclips.size();j++) { + Clip* c = Olive::ActiveSequence->clips.at(j); if (c != nullptr && c->track == ghost_clip->track) { bool found = false; for (int k=0;kghosts.size();i++) { - Clip* c = sequence->clips.at(panel_timeline->ghosts.at(i).clip); + Clip* c = Olive::ActiveSequence->clips.at(panel_timeline->ghosts.at(i).clip); if (panel_timeline->trim_in_point) { axis = qMin(axis, c->timeline_in); } else { @@ -1847,8 +1847,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } } - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr && !is_clip_selected(c, true)) { bool clip_is_post = (c->timeline_in >= axis); @@ -1874,8 +1874,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } // store selections - selection_command = new SetSelectionsCommand(sequence); - selection_command->old_data = sequence->selections; + selection_command = new SetSelectionsCommand(Olive::ActiveSequence); + selection_command->old_data = Olive::ActiveSequence->selections; panel_timeline->moving_proc = true; } @@ -1923,8 +1923,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { int track_max = qMax(track_start, track_end); QVector selected_clips; - for (int i=0;iclips.size();i++) { - Clip* clip = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* clip = Olive::ActiveSequence->clips.at(i); if (clip != nullptr && clip->track >= track_min && clip->track <= track_max && @@ -1935,7 +1935,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { if (!alt) { for (int j=0;jlinked.size();j++) { - session_clips.append(sequence->clips.at(clip->linked.at(j))); + session_clips.append(Olive::ActiveSequence->clips.at(clip->linked.at(j))); } } @@ -1956,9 +1956,9 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } } - sequence->selections.resize(selected_clips.size() + panel_timeline->selection_offset); + Olive::ActiveSequence->selections.resize(selected_clips.size() + panel_timeline->selection_offset); for (int i=0;iselections[i+panel_timeline->selection_offset]; + Selection& s = Olive::ActiveSequence->selections[i+panel_timeline->selection_offset]; Clip* clip = selected_clips.at(i); s.old_in = s.in = clip->timeline_in; s.old_out = s.out = clip->timeline_out; @@ -2020,8 +2020,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { panel_timeline->trim_target = -1; // loop through current clips in the sequence - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr) { // cache track range @@ -2195,7 +2195,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { if (panel_timeline->transition_tool_proc) { update_ghosts(event->pos(), event->modifiers() & Qt::ShiftModifier); } else { - Clip* c = sequence->clips.at(panel_timeline->transition_tool_pre_clip); + Clip* c = Olive::ActiveSequence->clips.at(panel_timeline->transition_tool_pre_clip); Ghost g; @@ -2212,7 +2212,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } else { int mouse_clip = getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track); if (mouse_clip > -1) { - Clip* c = sequence->clips.at(mouse_clip); + Clip* c = Olive::ActiveSequence->clips.at(mouse_clip); if (same_sign(c->track, panel_timeline->transition_tool_side)) { panel_timeline->transition_tool_pre_clip = mouse_clip; long halfway = c->timeline_in + (c->getLength()/2); @@ -2350,14 +2350,14 @@ void draw_transition(QPainter& p, Clip* c, const QRect& clip_rect, QRect& text_r void TimelineWidget::paintEvent(QPaintEvent*) { // Draw clips - if (sequence != nullptr) { + if (Olive::ActiveSequence != nullptr) { QPainter p(this); // get widget width and height int video_track_limit = 0; int audio_track_limit = 0; - for (int i=0;iclips.size();i++) { - Clip* clip = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* clip = Olive::ActiveSequence->clips.at(i); if (clip != nullptr) { video_track_limit = qMin(video_track_limit, clip->track); audio_track_limit = qMax(audio_track_limit, clip->track); @@ -2380,8 +2380,8 @@ void TimelineWidget::paintEvent(QPaintEvent*) { scrollBar->setMaximum(qMax(0, panel_height - height())); } - for (int i=0;iclips.size();i++) { - Clip* clip = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* clip = Olive::ActiveSequence->clips.at(i); if (clip != nullptr && is_track_visible(clip->track)) { QRect clip_rect(panel_timeline->getTimelineScreenPointFromFrame(clip->timeline_in), getScreenPointFromTrack(clip->track), getScreenPointFromFrame(panel_timeline->zoom, clip->getLength()), panel_timeline->calculate_track_height(clip->track, -1)); QRect text_rect(clip_rect.left() + CLIP_TEXT_PADDING, clip_rect.top() + CLIP_TEXT_PADDING, clip_rect.width() - CLIP_TEXT_PADDING - 1, clip_rect.height() - CLIP_TEXT_PADDING - 1); @@ -2665,8 +2665,8 @@ void TimelineWidget::paintEvent(QPaintEvent*) { } // Draw selections - for (int i=0;iselections.size();i++) { - const Selection& s = sequence->selections.at(i); + for (int i=0;iselections.size();i++) { + const Selection& s = Olive::ActiveSequence->selections.at(i); if (is_track_visible(s.track)) { int selection_y = getScreenPointFromTrack(s.track); int selection_x = panel_timeline->getTimelineScreenPointFromFrame(s.in); @@ -2743,7 +2743,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) { // Draw playhead p.setPen(Qt::red); - int playhead_x = panel_timeline->getTimelineScreenPointFromFrame(sequence->playhead); + int playhead_x = panel_timeline->getTimelineScreenPointFromFrame(Olive::ActiveSequence->playhead); p.drawLine(playhead_x, rect().top(), playhead_x, rect().bottom()); // draw border @@ -2817,8 +2817,8 @@ int TimelineWidget::getScreenPointFromTrack(int track) { } int TimelineWidget::getClipIndexFromCoords(long frame, int track) { - for (int i=0;iclips.size();i++) { - Clip* c = sequence->clips.at(i); + for (int i=0;iclips.size();i++) { + Clip* c = Olive::ActiveSequence->clips.at(i); if (c != nullptr && c->track == track && frame >= c->timeline_in && frame < c->timeline_out) { return i; }