file/folder restructuring
This commit is contained in:
@@ -0,0 +1,290 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamWriter>
|
||||
|
||||
#include "panels/project.h"
|
||||
#include "panels/panels.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
Config olive::CurrentConfig;
|
||||
RuntimeConfig olive::CurrentRuntimeConfig;
|
||||
|
||||
Config::Config()
|
||||
: show_track_lines(true),
|
||||
scroll_zooms(false),
|
||||
edit_tool_selects_links(false),
|
||||
edit_tool_also_seeks(false),
|
||||
select_also_seeks(false),
|
||||
paste_seeks(true),
|
||||
img_seq_formats("jpg|jpeg|bmp|tiff|tif|psd|png|tga|jp2|gif"),
|
||||
rectified_waveforms(false),
|
||||
default_transition_length(30),
|
||||
timecode_view(olive::kTimecodeDrop),
|
||||
show_title_safe_area(false),
|
||||
use_custom_title_safe_ratio(false),
|
||||
custom_title_safe_ratio(1),
|
||||
enable_drag_files_to_timeline(true),
|
||||
autoscale_by_default(false),
|
||||
recording_mode(2),
|
||||
enable_seek_to_import(false),
|
||||
enable_audio_scrubbing(true),
|
||||
drop_on_media_to_replace(true),
|
||||
autoscroll(olive::AUTOSCROLL_PAGE_SCROLL),
|
||||
audio_rate(48000),
|
||||
fast_seeking(false),
|
||||
hover_focus(false),
|
||||
project_view_type(olive::PROJECT_VIEW_TREE),
|
||||
set_name_with_marker(true),
|
||||
show_project_toolbar(false),
|
||||
previous_queue_size(3),
|
||||
previous_queue_type(olive::FRAME_QUEUE_TYPE_FRAMES),
|
||||
upcoming_queue_size(0.5),
|
||||
upcoming_queue_type(olive::FRAME_QUEUE_TYPE_SECONDS),
|
||||
loop(false),
|
||||
seek_also_selects(false),
|
||||
effect_textbox_lines(3),
|
||||
use_software_fallback(false),
|
||||
center_timeline_timecodes(true),
|
||||
waveform_resolution(64),
|
||||
thumbnail_resolution(120),
|
||||
add_default_effects_to_clips(true),
|
||||
invert_timeline_scroll_axes(true)
|
||||
{}
|
||||
|
||||
void Config::load(QString path) {
|
||||
QFile f(path);
|
||||
if (f.exists() && f.open(QIODevice::ReadOnly)) {
|
||||
QXmlStreamReader stream(&f);
|
||||
|
||||
while (!stream.atEnd()) {
|
||||
stream.readNext();
|
||||
if (stream.isStartElement()) {
|
||||
if (stream.name() == "ShowTrackLines") {
|
||||
stream.readNext();
|
||||
show_track_lines = (stream.text() == "1");
|
||||
} else if (stream.name() == "ScrollZooms") {
|
||||
stream.readNext();
|
||||
scroll_zooms = (stream.text() == "1");
|
||||
} else if (stream.name() == "InvertTimelineScrollAxes") {
|
||||
stream.readNext();
|
||||
invert_timeline_scroll_axes = (stream.text() == "1");
|
||||
} else if (stream.name() == "EditToolSelectsLinks") {
|
||||
stream.readNext();
|
||||
edit_tool_selects_links = (stream.text() == "1");
|
||||
} else if (stream.name() == "EditToolAlsoSeeks") {
|
||||
stream.readNext();
|
||||
edit_tool_also_seeks = (stream.text() == "1");
|
||||
} else if (stream.name() == "SelectAlsoSeeks") {
|
||||
stream.readNext();
|
||||
select_also_seeks = (stream.text() == "1");
|
||||
} else if (stream.name() == "PasteSeeks") {
|
||||
stream.readNext();
|
||||
paste_seeks = (stream.text() == "1");
|
||||
} else if (stream.name() == "ImageSequenceFormats") {
|
||||
stream.readNext();
|
||||
img_seq_formats = stream.text().toString();
|
||||
} else if (stream.name() == "RectifiedWaveforms") {
|
||||
stream.readNext();
|
||||
rectified_waveforms = (stream.text() == "1");
|
||||
} else if (stream.name() == "DefaultTransitionLength") {
|
||||
stream.readNext();
|
||||
default_transition_length = stream.text().toInt();
|
||||
} else if (stream.name() == "TimecodeView") {
|
||||
stream.readNext();
|
||||
timecode_view = stream.text().toInt();
|
||||
} else if (stream.name() == "ShowTitleSafeArea") {
|
||||
stream.readNext();
|
||||
show_title_safe_area = (stream.text() == "1");
|
||||
} else if (stream.name() == "UseCustomTitleSafeRatio") {
|
||||
stream.readNext();
|
||||
use_custom_title_safe_ratio = (stream.text() == "1");
|
||||
} else if (stream.name() == "CustomTitleSafeRatio") {
|
||||
stream.readNext();
|
||||
custom_title_safe_ratio = stream.text().toDouble();
|
||||
} else if (stream.name() == "EnableDragFilesToTimeline") {
|
||||
stream.readNext();
|
||||
enable_drag_files_to_timeline = (stream.text() == "1");;
|
||||
} else if (stream.name() == "AutoscaleByDefault") {
|
||||
stream.readNext();
|
||||
autoscale_by_default = (stream.text() == "1");
|
||||
} else if (stream.name() == "RecordingMode") {
|
||||
stream.readNext();
|
||||
recording_mode = stream.text().toInt();
|
||||
} else if (stream.name() == "EnableSeekToImport") {
|
||||
stream.readNext();
|
||||
enable_seek_to_import = (stream.text() == "1");
|
||||
} else if (stream.name() == "AudioScrubbing") {
|
||||
stream.readNext();
|
||||
enable_audio_scrubbing = (stream.text() == "1");
|
||||
} else if (stream.name() == "DropFileOnMediaToReplace") {
|
||||
stream.readNext();
|
||||
drop_on_media_to_replace = (stream.text() == "1");
|
||||
} else if (stream.name() == "Autoscroll") {
|
||||
stream.readNext();
|
||||
autoscroll = stream.text().toInt();
|
||||
} else if (stream.name() == "AudioRate") {
|
||||
stream.readNext();
|
||||
audio_rate = stream.text().toInt();
|
||||
} else if (stream.name() == "FastSeeking") {
|
||||
stream.readNext();
|
||||
fast_seeking = (stream.text() == "1");
|
||||
} else if (stream.name() == "HoverFocus") {
|
||||
stream.readNext();
|
||||
hover_focus = (stream.text() == "1");
|
||||
} else if (stream.name() == "ProjectViewType") {
|
||||
stream.readNext();
|
||||
project_view_type = stream.text().toInt();
|
||||
} else if (stream.name() == "SetNameWithMarker") {
|
||||
stream.readNext();
|
||||
set_name_with_marker = (stream.text() == "1");
|
||||
} else if (stream.name() == "ShowProjectToolbar") {
|
||||
stream.readNext();
|
||||
show_project_toolbar = (stream.text() == "1");
|
||||
} else if (stream.name() == "PreviousFrameQueueSize") {
|
||||
stream.readNext();
|
||||
previous_queue_size = stream.text().toDouble();
|
||||
} else if (stream.name() == "PreviousFrameQueueType") {
|
||||
stream.readNext();
|
||||
previous_queue_type = stream.text().toInt();
|
||||
} else if (stream.name() == "UpcomingFrameQueueSize") {
|
||||
stream.readNext();
|
||||
upcoming_queue_size = stream.text().toDouble();
|
||||
} else if (stream.name() == "UpcomingFrameQueueType") {
|
||||
stream.readNext();
|
||||
upcoming_queue_type = stream.text().toInt();
|
||||
} else if (stream.name() == "Loop") {
|
||||
stream.readNext();
|
||||
loop = (stream.text() == "1");
|
||||
} else if (stream.name() == "SeekAlsoSelects") {
|
||||
stream.readNext();
|
||||
seek_also_selects = (stream.text() == "1");
|
||||
} else if (stream.name() == "CSSPath") {
|
||||
stream.readNext();
|
||||
css_path = stream.text().toString();
|
||||
} else if (stream.name() == "EffectTextboxLines") {
|
||||
stream.readNext();
|
||||
effect_textbox_lines = stream.text().toInt();
|
||||
} else if (stream.name() == "UseSoftwareFallback") {
|
||||
stream.readNext();
|
||||
use_software_fallback = (stream.text() == "1");
|
||||
} else if (stream.name() == "CenterTimelineTimecodes") {
|
||||
stream.readNext();
|
||||
center_timeline_timecodes = (stream.text() == "1");
|
||||
} else if (stream.name() == "PreferredAudioOutput") {
|
||||
stream.readNext();
|
||||
preferred_audio_output = stream.text().toString();
|
||||
} else if (stream.name() == "PreferredAudioInput") {
|
||||
stream.readNext();
|
||||
preferred_audio_input = stream.text().toString();
|
||||
} else if (stream.name() == "LanguageFile") {
|
||||
stream.readNext();
|
||||
language_file = stream.text().toString();
|
||||
} else if (stream.name() == "ThumbnailResolution") {
|
||||
stream.readNext();
|
||||
thumbnail_resolution = stream.text().toInt();
|
||||
} else if (stream.name() == "WaveformResolution") {
|
||||
stream.readNext();
|
||||
waveform_resolution = stream.text().toInt();
|
||||
} else if (stream.name() == "AddDefaultEffectsToClips") {
|
||||
stream.readNext();
|
||||
add_default_effects_to_clips = (stream.text() == "1");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (stream.hasError()) {
|
||||
qCritical() << "Error parsing config XML." << stream.errorString();
|
||||
}
|
||||
|
||||
f.close();
|
||||
}
|
||||
}
|
||||
|
||||
void Config::save(QString path) {
|
||||
QFile f(path);
|
||||
if (!f.open(QIODevice::WriteOnly)) {
|
||||
qCritical() << "Could not save configuration";
|
||||
return;
|
||||
}
|
||||
|
||||
QXmlStreamWriter stream(&f);
|
||||
stream.setAutoFormatting(true);
|
||||
stream.writeStartDocument(); // doc
|
||||
stream.writeStartElement("Configuration"); // configuration
|
||||
|
||||
stream.writeTextElement("Version", QString::number(olive::kSaveVersion));
|
||||
stream.writeTextElement("ShowTrackLines", QString::number(show_track_lines));
|
||||
stream.writeTextElement("ScrollZooms", QString::number(scroll_zooms));
|
||||
stream.writeTextElement("InvertTimelineScrollAxes", QString::number(invert_timeline_scroll_axes));
|
||||
stream.writeTextElement("EditToolSelectsLinks", QString::number(edit_tool_selects_links));
|
||||
stream.writeTextElement("EditToolAlsoSeeks", QString::number(edit_tool_also_seeks));
|
||||
stream.writeTextElement("SelectAlsoSeeks", QString::number(select_also_seeks));
|
||||
stream.writeTextElement("PasteSeeks", QString::number(paste_seeks));
|
||||
stream.writeTextElement("ImageSequenceFormats", img_seq_formats);
|
||||
stream.writeTextElement("RectifiedWaveforms", QString::number(rectified_waveforms));
|
||||
stream.writeTextElement("DefaultTransitionLength", QString::number(default_transition_length));
|
||||
stream.writeTextElement("TimecodeView", QString::number(timecode_view));
|
||||
stream.writeTextElement("ShowTitleSafeArea", QString::number(show_title_safe_area));
|
||||
stream.writeTextElement("UseCustomTitleSafeRatio", QString::number(use_custom_title_safe_ratio));
|
||||
stream.writeTextElement("CustomTitleSafeRatio", QString::number(custom_title_safe_ratio));
|
||||
stream.writeTextElement("EnableDragFilesToTimeline", QString::number(enable_drag_files_to_timeline));
|
||||
stream.writeTextElement("AutoscaleByDefault", QString::number(autoscale_by_default));
|
||||
stream.writeTextElement("RecordingMode", QString::number(recording_mode));
|
||||
stream.writeTextElement("EnableSeekToImport", QString::number(enable_seek_to_import));
|
||||
stream.writeTextElement("AudioScrubbing", QString::number(enable_audio_scrubbing));
|
||||
stream.writeTextElement("DropFileOnMediaToReplace", QString::number(drop_on_media_to_replace));
|
||||
stream.writeTextElement("Autoscroll", QString::number(autoscroll));
|
||||
stream.writeTextElement("AudioRate", QString::number(audio_rate));
|
||||
stream.writeTextElement("FastSeeking", QString::number(fast_seeking));
|
||||
stream.writeTextElement("HoverFocus", QString::number(hover_focus));
|
||||
stream.writeTextElement("ProjectViewType", QString::number(project_view_type));
|
||||
stream.writeTextElement("SetNameWithMarker", QString::number(set_name_with_marker));
|
||||
stream.writeTextElement("ShowProjectToolbar", QString::number(panel_project->toolbar_widget->isVisible()));
|
||||
stream.writeTextElement("PreviousFrameQueueSize", QString::number(previous_queue_size));
|
||||
stream.writeTextElement("PreviousFrameQueueType", QString::number(previous_queue_type));
|
||||
stream.writeTextElement("UpcomingFrameQueueSize", QString::number(upcoming_queue_size));
|
||||
stream.writeTextElement("UpcomingFrameQueueType", QString::number(upcoming_queue_type));
|
||||
stream.writeTextElement("Loop", QString::number(loop));
|
||||
stream.writeTextElement("SeekAlsoSelects", QString::number(seek_also_selects));
|
||||
stream.writeTextElement("CSSPath", css_path);
|
||||
stream.writeTextElement("EffectTextboxLines", QString::number(effect_textbox_lines));
|
||||
stream.writeTextElement("UseSoftwareFallback", QString::number(use_software_fallback));
|
||||
stream.writeTextElement("CenterTimelineTimecodes", QString::number(center_timeline_timecodes));
|
||||
stream.writeTextElement("PreferredAudioOutput", preferred_audio_output);
|
||||
stream.writeTextElement("PreferredAudioInput", preferred_audio_input);
|
||||
stream.writeTextElement("LanguageFile", language_file);
|
||||
stream.writeTextElement("ThumbnailResolution", QString::number(thumbnail_resolution));
|
||||
stream.writeTextElement("WaveformResolution", QString::number(waveform_resolution));
|
||||
stream.writeTextElement("AddDefaultEffectsToClips", QString::number(add_default_effects_to_clips));
|
||||
|
||||
stream.writeEndElement(); // configuration
|
||||
stream.writeEndDocument(); // doc
|
||||
f.close();
|
||||
}
|
||||
|
||||
RuntimeConfig::RuntimeConfig() :
|
||||
shaders_are_enabled(true),
|
||||
disable_blending(false)
|
||||
{}
|
||||
+585
@@ -0,0 +1,585 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace olive {
|
||||
/**
|
||||
* @brief Version identifier for saved projects
|
||||
*
|
||||
* This constant is used to identify what version of Olive a project file was saved with. Every project file
|
||||
* is saved with the current version number and the version is checked whenever an Olive project is loaded to
|
||||
* determine how compatible it'll be with the current version.
|
||||
*
|
||||
* Sometimes this version identifier is used to invoke backwards compatibility in order to keep older project files
|
||||
* able to load, but in this early rapidly developing stage, often backwards compatibility is abandoned. Ideally
|
||||
* in the future, a class should be made that's able to "convert" an older project into one that the current
|
||||
* loading system understands (so that the loading system doesn't get too bloated with backwards compatibility
|
||||
* functions).
|
||||
*/
|
||||
const int kSaveVersion = 190219; // YYMMDD
|
||||
|
||||
/**
|
||||
* @brief Minimum project version that this version of Olive can open
|
||||
*
|
||||
* When loading a project, the project's version number is actually checked whether it is somewhere between
|
||||
* kSaveVersion and this value (inclusive). This is used if the current version of Olive contains backwards
|
||||
* compatibility functionality for older project versions, and is bumped up if such backwards compatibility is
|
||||
* ever removed.
|
||||
*
|
||||
* As stated in kSaveVersion documentation, ideally in the future, a system would be in place to account for all
|
||||
* project version differences and bring them up to date for the current loading algorithm. This means ideally, this
|
||||
* constant stays the same forever, but in this early stage it's not strictly necessary.
|
||||
*/
|
||||
const int kMinimumSaveVersion = 190219; // lowest compatible project version
|
||||
|
||||
/**
|
||||
* @brief The TimecodeType enum
|
||||
*
|
||||
* Frame numbers can be displayed in various different ways. The timecode_to_frame() and frame_to_timecode()
|
||||
* functions (which should be used for all frame <-> timecode conversions) respond to the timecode display type
|
||||
* set in Config::timecode_view corresponding to a value from this enum.
|
||||
*/
|
||||
enum TimecodeType {
|
||||
/** Show frame number as a drop-frame timecode */
|
||||
kTimecodeDrop,
|
||||
|
||||
/** Show frame number as a non-drop-frame timecode */
|
||||
kTimecodeNonDrop,
|
||||
|
||||
/** Show frame number as-is with no modifications */
|
||||
kTimecodeFrames,
|
||||
|
||||
/** Show frame number as milliseconds */
|
||||
kTimecodeMilliseconds
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The RecordingMode enum
|
||||
*
|
||||
* Olive currently supports recording mono or stereo and gives users the option of which mode to use when
|
||||
* recording audio in-app. Audio recording responds to Config::recording_mode to a value from this enum.
|
||||
*/
|
||||
enum RecordingMode {
|
||||
/** Record all audio in mono */
|
||||
RECORD_MODE_MONO,
|
||||
|
||||
/** Record all audio in stereo */
|
||||
RECORD_MODE_STEREO
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The AutoScrollMode enum
|
||||
*
|
||||
* The Timeline in Olive can automatically scroll to follow the playhead when the sequence is playing.
|
||||
* The Timeline will respond to Config::autoscroll set to a value from this enum.
|
||||
*/
|
||||
enum AutoScrollMode {
|
||||
/** Don't auto-scroll, scrolling will not follow the playhead */
|
||||
AUTOSCROLL_NO_SCROLL,
|
||||
|
||||
/** Page auto-scroll (default), if the playhead goes off-screen while playing, the scroll will jump ahead
|
||||
* one "page" to follow it */
|
||||
AUTOSCROLL_PAGE_SCROLL,
|
||||
|
||||
/** Smooth auto-scroll, Olive will scroll to keep the playhead in the center of the screen at all times while
|
||||
* playing */
|
||||
AUTOSCROLL_SMOOTH_SCROLL
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The ProjectView enum
|
||||
*
|
||||
* The media in the Project panel can be displayed as a tree hierarchy or as an icon view. The Project panel
|
||||
* responds to Config::project_view_type set to a value from this enum.
|
||||
*/
|
||||
enum ProjectView {
|
||||
/** Display project media in tree hierarchy */
|
||||
PROJECT_VIEW_TREE,
|
||||
|
||||
/** Display project media in icon browser */
|
||||
PROJECT_VIEW_ICON
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The FrameQueueType enum
|
||||
*
|
||||
* Olive keeps a "frame queue" in memory to allow smoother playback/seeking. In order to give users control over
|
||||
* the amount of memory consumption vs. playback performance, they can control how many frames are cached into
|
||||
* memory. For extra fidelity, they can choose this value as a metric of either frames or seconds.
|
||||
*
|
||||
* The playback engine (playback/playback.h) responds to both Config::previous_queue_type and
|
||||
* Config::upcoming_queue_type set to a value from this enum.
|
||||
*/
|
||||
enum FrameQueueType {
|
||||
/** Queue size value is in frames */
|
||||
FRAME_QUEUE_TYPE_FRAMES,
|
||||
|
||||
/** Queue size value is in seconds */
|
||||
FRAME_QUEUE_TYPE_SECONDS
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The Config struct
|
||||
*
|
||||
* This struct handles any configuration that should persist between restarting Olive. It contains several variables
|
||||
* as well as functions that load and save all the variables to file.
|
||||
*/
|
||||
struct Config {
|
||||
/**
|
||||
* @brief Config Constructor
|
||||
*
|
||||
* Sets all configuration variables to their defaults.
|
||||
*/
|
||||
Config();
|
||||
|
||||
/**
|
||||
* @brief Show track lines
|
||||
*
|
||||
* **TRUE** if the Timeline should show lines between tracks.
|
||||
*/
|
||||
bool show_track_lines;
|
||||
|
||||
/**
|
||||
* @brief The scroll wheel zooms rather than scrolls
|
||||
*
|
||||
* **TRUE** if the scroll wheel should zoom in and out rather than scroll up and down.
|
||||
* The Control key temporarily toggles this setting.
|
||||
*/
|
||||
bool scroll_zooms;
|
||||
|
||||
/**
|
||||
* @brief Edit tool selects links
|
||||
*
|
||||
* **TRUE** if the edit tool should also select links when the user selects a clip.
|
||||
*/
|
||||
bool edit_tool_selects_links;
|
||||
|
||||
/**
|
||||
* @brief Edit tool also seeks
|
||||
*
|
||||
* **TRUE** if using the edit tool should also seek the sequence's playhead
|
||||
*/
|
||||
bool edit_tool_also_seeks;
|
||||
|
||||
/**
|
||||
* @brief Selecting also seeks
|
||||
*
|
||||
* **TRUE** if the playhead should automatically seek to the start of any clip that gets selected
|
||||
*/
|
||||
bool select_also_seeks;
|
||||
|
||||
/**
|
||||
* @brief Paste also seeks
|
||||
*
|
||||
* **TRUE** if the playhead should seek to the end of clips that are pasted
|
||||
*/
|
||||
bool paste_seeks;
|
||||
|
||||
/**
|
||||
* @brief Image sequence formats
|
||||
*
|
||||
* A '|' separated list of file extensions that Olive will perform an image sequence test heuristic on when importing
|
||||
*/
|
||||
QString img_seq_formats;
|
||||
|
||||
/**
|
||||
* @brief Use rectified waveforms
|
||||
*
|
||||
* **TRUE** if Olive should display waveforms as "rectified". Rectified waveforms start at the bottom rather than
|
||||
* from the middle.
|
||||
*/
|
||||
bool rectified_waveforms;
|
||||
|
||||
/**
|
||||
* @brief Default transition length
|
||||
*
|
||||
* The default transition length used when making a transition without the transition tool
|
||||
*/
|
||||
int default_transition_length;
|
||||
|
||||
/**
|
||||
* @brief Timecode display mode
|
||||
*
|
||||
* The display mode with which timecode_to_frame() and frame_to_timecode() will use to convert frame numbers to
|
||||
* more human-readable values.
|
||||
*
|
||||
* Set to a member of enum TimecodeType.
|
||||
*/
|
||||
int timecode_view;
|
||||
|
||||
/**
|
||||
* @brief Show title/action safe area
|
||||
*
|
||||
* **TRUE** if the title/action safe area should be shown on the Viewer.
|
||||
*/
|
||||
bool show_title_safe_area;
|
||||
|
||||
/**
|
||||
* @brief Use custom title/action safe area aspect ratio
|
||||
*
|
||||
* **TRUE** if the title/action save area should use a custom aspect ratio
|
||||
*/
|
||||
bool use_custom_title_safe_ratio;
|
||||
|
||||
/**
|
||||
* @brief Custom title/action safe area aspect ratio
|
||||
*
|
||||
* If Config::use_custom_title_safe_ratio is true, this is the aspect ratio to use.
|
||||
*
|
||||
* Set to the result of an aspect ratio division (i.e. for 4:3 set to 1.333333 (4.0 / 3.0)
|
||||
*/
|
||||
double custom_title_safe_ratio;
|
||||
|
||||
/**
|
||||
* @brief Enable dragging files outside Olive directly into the Timeline
|
||||
*
|
||||
* **TRUE** if the Timeline should respond to files dropped from outside Olive.
|
||||
*/
|
||||
bool enable_drag_files_to_timeline;
|
||||
|
||||
/**
|
||||
* @brief Auto-scale by default
|
||||
*
|
||||
* **TRUE** if clips imported into the timeline should have Clip::autoscale **TRUE** by default. If a Clip is
|
||||
* smaller or larger than the Sequence, auto-scale will automatically resize it to fit to the Sequence boundaries.
|
||||
*/
|
||||
bool autoscale_by_default;
|
||||
|
||||
/**
|
||||
* @brief Recording mode/channel layout
|
||||
*
|
||||
* When recording audio within Olive, use this mode/channel layout (e.g. mono or stereo).
|
||||
*
|
||||
* Set to a member of enum RecordingMode.
|
||||
*/
|
||||
int recording_mode;
|
||||
|
||||
/**
|
||||
* @brief Enable seek to import
|
||||
*
|
||||
* **TRUE** if the playhead should automatically seek to any newly imported clips
|
||||
*/
|
||||
bool enable_seek_to_import;
|
||||
|
||||
/**
|
||||
* @brief Enable audio scrubbing
|
||||
*
|
||||
* **TRUE** if audio should "scrub" as the user drags the playhead around
|
||||
*/
|
||||
bool enable_audio_scrubbing;
|
||||
|
||||
/**
|
||||
* @brief Enable drop on media to replace
|
||||
*
|
||||
* **TRUE** if dropping a file from outside Olive onto a media item in the Project panel should prompt the user
|
||||
* whether the dropped file should replace the media item that the file was dropped on.
|
||||
*/
|
||||
bool drop_on_media_to_replace;
|
||||
|
||||
/**
|
||||
* @brief Auto-scroll mode
|
||||
*
|
||||
* The Timeline behavior regarding scrolling to keep the playhead within view while a Sequence is playing.
|
||||
*
|
||||
* Set to a member of enum AutoScrollMode.
|
||||
*/
|
||||
int autoscroll;
|
||||
|
||||
/**
|
||||
* @brief Current audio sample rate
|
||||
*
|
||||
* The sample rate to set the audio output device to. Also used as the value to resample audio to during playback
|
||||
* (but not during rendering).
|
||||
*/
|
||||
int audio_rate;
|
||||
|
||||
/**
|
||||
* @brief Enable fast seeking
|
||||
*
|
||||
* Olive supports a seek mode that shows frames faster with the risk of briefly showing a "best-effort" frame that
|
||||
* may not be the accurate frame at that point of the Timeline. This does not affect exporting.
|
||||
*
|
||||
* Set to **TRUE** if this mode should be enabled.
|
||||
*/
|
||||
bool fast_seeking;
|
||||
|
||||
/**
|
||||
* @brief Enable hover focus
|
||||
*
|
||||
* Default behavior is panels are focused (and therefore respond to certain keyboard shortcuts)when they are clicked
|
||||
* on, but Olive also supports panels being considered "focused" if the mouse is hovered over them.
|
||||
*
|
||||
* **TRUE** to enable hover focus mode.
|
||||
*/
|
||||
bool hover_focus;
|
||||
|
||||
/**
|
||||
* @brief Project view type
|
||||
*
|
||||
* Whether to show media in the Project panel as a tree hierarchy or as a browser of icons.
|
||||
*
|
||||
* Set to a member of enum ProjectView.
|
||||
*/
|
||||
int project_view_type;
|
||||
|
||||
/**
|
||||
* @brief Ask for a marker name when setting a marker
|
||||
*
|
||||
* **TRUE** if Olive should ask the user to name a marker when setting one. **FALSE** if markers should just be
|
||||
* created without asking.
|
||||
*/
|
||||
bool set_name_with_marker;
|
||||
|
||||
/**
|
||||
* @brief Show the project toolbar
|
||||
*
|
||||
* Olive has an optional toolbar for the Project panel.
|
||||
*
|
||||
* Set to **TRUE** to show it.
|
||||
*/
|
||||
bool show_project_toolbar;
|
||||
|
||||
/**
|
||||
* @brief Previous frame queue size
|
||||
*
|
||||
* Olive caches frames in memory to improve playback performance (see enum FrameQueueType documentation for more
|
||||
* details). This variable states how many frames to keep in memory prior to the playhead (in most cases, frames that
|
||||
* have already been played, but are kept in memory in case the user wants to backtrack at any time).
|
||||
*
|
||||
* This value corresponds to Config::previous_queue_type.
|
||||
*/
|
||||
double previous_queue_size;
|
||||
|
||||
/**
|
||||
* @brief Previous frame queue type
|
||||
*
|
||||
* The metric of which Config::previous_queue_size is using. For example, if Config::previous_queue_size is
|
||||
* 3, this variable states whether that is 3 frames or 3 seconds.
|
||||
*
|
||||
* Set to a member of enum FrameQueueType.
|
||||
*/
|
||||
int previous_queue_type;
|
||||
|
||||
/**
|
||||
* @brief Upcoming frame queue size
|
||||
*
|
||||
* Olive caches frames in memory to improve playback performance (see enum FrameQueueType documentation for more
|
||||
* details). This variable states how many upcoming frames are stored in memory. Generally this value will be higher
|
||||
* than Config::previous_queue_size since the user will be playing forwards most of the time.
|
||||
*
|
||||
* This value corresponds to Config::upcoming_queue_type.
|
||||
*/
|
||||
double upcoming_queue_size;
|
||||
|
||||
/**
|
||||
* @brief Upcoming frame queue type
|
||||
*
|
||||
* The metric of which Config::upcoming_queue_size is using. For example, if Config::upcoming_queue_size is
|
||||
* 3, this variable states whether that is 3 frames or 3 seconds.
|
||||
*
|
||||
* Set to a member of enum FrameQueueType.
|
||||
*/
|
||||
int upcoming_queue_type;
|
||||
|
||||
/**
|
||||
* @brief Loop
|
||||
*
|
||||
* If an in/out point are set on the Sequence (Sequence::using_workarea is **TRUE**), set this to **TRUE** if Olive
|
||||
* should rewind to the in point and start playing again after it reaches the out point repeatedly until the user
|
||||
* pauses.
|
||||
*/
|
||||
bool loop;
|
||||
|
||||
/**
|
||||
* @brief Seeking also selects
|
||||
*
|
||||
* Olive supports automatically selecting clips that the playhead is currently touching for a more efficient workflow.
|
||||
*
|
||||
* **TRUE** if this mode should be enabled.
|
||||
*/
|
||||
bool seek_also_selects;
|
||||
|
||||
/**
|
||||
* @brief CSS Path
|
||||
*
|
||||
* The URL to a CSS file if the user has loaded a custom stylesheet in. **EMPTY** if the user has not set a
|
||||
* stylesheet.
|
||||
*/
|
||||
QString css_path;
|
||||
|
||||
/**
|
||||
* @brief Number of lines that an Effect's textbox has
|
||||
*
|
||||
* The height of a Effect's textbox field in terms of lines.
|
||||
*
|
||||
* Set to a value >= 1
|
||||
*/
|
||||
int effect_textbox_lines;
|
||||
|
||||
/**
|
||||
* @brief Use software fallbacks when possible
|
||||
*
|
||||
* Olive uses a lot of OpenGL-based hardware acceleration for performance. Some older hardware has difficulty
|
||||
* supporting this functionality, so some of it has software-based (not hardware accelerated) fallbacks for these
|
||||
* users.
|
||||
*
|
||||
* **TRUE** if Olive should prefer software fallbacks to hardware acceleration when they're available.
|
||||
*/
|
||||
bool use_software_fallback;
|
||||
|
||||
/**
|
||||
* @brief Center Timeline timecodes
|
||||
*
|
||||
* By default, Olive shows timecodes in the TimelineHeader centered to the corresponding frame point. This may not
|
||||
* always be desirable as, for example, this forces the initial 00:00:00;00 timecode's left half to be cut off.
|
||||
* Olive supports aligning the timecode to the right of the frame rather than the center to address this.
|
||||
*/
|
||||
bool center_timeline_timecodes;
|
||||
|
||||
/**
|
||||
* @brief Preferred audio output device
|
||||
*
|
||||
* Sets the audio device Olive should use to output audio to.
|
||||
*
|
||||
* Set to the name of the audio device or **EMPTY** to try using the default.
|
||||
*/
|
||||
QString preferred_audio_output;
|
||||
|
||||
/**
|
||||
* @brief Preferred audio input device
|
||||
*
|
||||
* Sets the audio device Olive should use to input audio from.
|
||||
*
|
||||
* Set to the name of the audio device or **EMPTY** to try using the default.
|
||||
*/
|
||||
QString preferred_audio_input;
|
||||
|
||||
/**
|
||||
* @brief Language/translation file
|
||||
*
|
||||
* Sets the translation file to load to display Olive in a different language.
|
||||
*
|
||||
* Set to the URL of the language file to load, or **EMPTY** to use default en-US language.
|
||||
*/
|
||||
QString language_file;
|
||||
|
||||
/**
|
||||
* @brief Waveform resolution
|
||||
*
|
||||
* Sets how detailed the waveforms should be in the Timeline. Higher value = more detail.
|
||||
*
|
||||
* Specifically sets how many samples per second should be "cached" for preview. If the waveforms are too blocky,
|
||||
* set this higher. If Timeline performance is slow, set this lower.
|
||||
*/
|
||||
int waveform_resolution;
|
||||
|
||||
/**
|
||||
* @brief Thumbnail resolution
|
||||
*
|
||||
* The vertical pixel height to use for generating thumbnails.
|
||||
*/
|
||||
int thumbnail_resolution;
|
||||
|
||||
/**
|
||||
* @brief Add default effects to clips
|
||||
*
|
||||
* **TRUE** if new clips imported into the Timeline should have a set of default effects (TransformEffect,
|
||||
* VolumeEffect, and PanEffect) added to them by default.
|
||||
*/
|
||||
bool add_default_effects_to_clips;
|
||||
|
||||
/**
|
||||
* @brief Invert Timeline scroll axes
|
||||
*
|
||||
* **TRUE** if scrolling vertically on the Timeline should scroll it horizontally
|
||||
*/
|
||||
bool invert_timeline_scroll_axes;
|
||||
|
||||
/**
|
||||
* @brief Load config from file
|
||||
*
|
||||
* Load configuration parameters from file
|
||||
*
|
||||
* @param path
|
||||
*
|
||||
* URL to the configuration file to load
|
||||
*/
|
||||
void load(QString path);
|
||||
|
||||
/**
|
||||
* @brief Save config to file
|
||||
*
|
||||
* Save current configuration parameters to file
|
||||
*
|
||||
* @param path
|
||||
*
|
||||
* URL to save the configuration file to.
|
||||
*/
|
||||
void save(QString path);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The RuntimeConfig struct
|
||||
*
|
||||
* This struct handles any configuration that's set as a command-line argument to Olive, and shouldn't be persistent
|
||||
* between restarts of Olive.
|
||||
*/
|
||||
struct RuntimeConfig {
|
||||
/**
|
||||
* @brief RuntimeConfig Constructor
|
||||
*
|
||||
* Sets default runtime configuration
|
||||
*/
|
||||
RuntimeConfig();
|
||||
|
||||
/**
|
||||
* @brief Enable shaders
|
||||
*
|
||||
* Debugging tool. Set to **FALSE** to bypass OpenGL shaders.
|
||||
*/
|
||||
bool shaders_are_enabled;
|
||||
|
||||
/**
|
||||
* @brief Disable blending modes
|
||||
*
|
||||
* Some users had difficulty utilizing blending modes (provided by shaders). Set this to **TRUE** to bypass
|
||||
* shader-based blending modes and utilize standard (less versatile) OpenGL blending instead.
|
||||
*/
|
||||
bool disable_blending;
|
||||
|
||||
/**
|
||||
* @brief Load an external translation file
|
||||
*
|
||||
* Overrides Config::language_file and sets the path to a language file to use.
|
||||
*/
|
||||
QString external_translation_file;
|
||||
};
|
||||
|
||||
namespace olive {
|
||||
extern Config CurrentConfig;
|
||||
extern RuntimeConfig CurrentRuntimeConfig;
|
||||
}
|
||||
|
||||
#endif // CONFIG_H
|
||||
@@ -0,0 +1,64 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "crossplatformlib.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
ModulePtr LibLoad(const QString &filename) {
|
||||
#ifdef _WIN32
|
||||
LPCWSTR dll_fn_w = reinterpret_cast<const wchar_t*>(filename.utf16());
|
||||
return LoadLibrary(dll_fn_w);
|
||||
#elif defined(__linux__) || defined(__APPLE__) || defined(__HAIKU__)
|
||||
return dlopen(filename.toUtf8(), RTLD_LAZY);
|
||||
#else
|
||||
qWarning() << "Olive doesn't know how to open dynamic libraries on this platform, external libraries will not be functional";
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
QStringList LibFilter() {
|
||||
#ifdef _WIN32
|
||||
return QStringList("*.dll");
|
||||
#elif defined(__linux__) || defined(__APPLE__) || defined(__HAIKU__)
|
||||
return {"*.so", "*.dylib"};
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
CFBundleRef BundleLoad(const QString &filename) {
|
||||
CFStringRef bundle_str = CFStringCreateWithCString(NULL, filename.toUtf8(), kCFStringEncodingUTF8);
|
||||
CFURLRef bundle_url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, bundle_str, kCFURLPOSIXPathStyle, true);
|
||||
CFBundleRef bundle = NULL;
|
||||
if (bundle_url != NULL) {
|
||||
bundle = CFBundleCreate(kCFAllocatorDefault, bundle_url);
|
||||
} else {
|
||||
qCritical() << "Failed to create VST URL";
|
||||
}
|
||||
CFRelease(bundle_url);
|
||||
CFRelease(bundle_str);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
void BundleClose(CFBundleRef bundle) {
|
||||
CFBundleUnloadExecutable(bundle);
|
||||
CFRelease(bundle);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef CROSSPLATFORMLIB_H
|
||||
#define CROSSPLATFORMLIB_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#define LibAddress GetProcAddress
|
||||
#define LibClose FreeModule
|
||||
#define ModulePtr HMODULE
|
||||
#elif defined(__linux__) || defined(__APPLE__) || defined(__HAIKU__)
|
||||
#include <dlfcn.h>
|
||||
#define LibAddress dlsym
|
||||
#define LibClose dlclose
|
||||
#define ModulePtr void*
|
||||
#endif
|
||||
|
||||
ModulePtr LibLoad(const QString& filename);
|
||||
QStringList LibFilter();
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
class NSWindow;
|
||||
|
||||
CFBundleRef BundleLoad(const QString& filename);
|
||||
void BundleClose(CFBundleRef bundle);
|
||||
#endif
|
||||
|
||||
#endif // CROSSPLATFORMLIB_H
|
||||
@@ -0,0 +1,112 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QDateTime>
|
||||
#include <QStandardPaths>
|
||||
#include <QDir>
|
||||
#include <QMutex>
|
||||
|
||||
#include "dialogs/debugdialog.h"
|
||||
|
||||
QString debug_info;
|
||||
QMutex debug_mutex;
|
||||
QFile debug_file;
|
||||
QTextStream debug_stream;
|
||||
|
||||
void open_debug_file() {
|
||||
QDir debug_dir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
|
||||
debug_dir.mkpath(".");
|
||||
if (debug_dir.exists()) {
|
||||
debug_file.setFileName(debug_dir.path() + "/debug_log");
|
||||
if (debug_file.open(QFile::WriteOnly)) {
|
||||
debug_stream.setDevice(&debug_file);
|
||||
} else {
|
||||
qWarning() << "Couldn't open debug log file, debug log will not be saved";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void close_debug_file()
|
||||
{
|
||||
if (debug_file.isOpen()) {
|
||||
debug_file.close();
|
||||
}
|
||||
}
|
||||
|
||||
void debug_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||
{
|
||||
debug_mutex.lock();
|
||||
const QByteArray localMsg = msg.toLocal8Bit();
|
||||
const QDateTime now = QDateTime::currentDateTime();
|
||||
const QByteArray timeRepr(now.toString(Qt::ISODate).toLocal8Bit());
|
||||
QString msgTag;
|
||||
QString fontColor;
|
||||
switch (type) {
|
||||
case QtDebugMsg:
|
||||
msgTag = "DEBUG";
|
||||
fontColor = "grey";
|
||||
break;
|
||||
case QtInfoMsg:
|
||||
msgTag = "INFO";
|
||||
fontColor = "blue";
|
||||
break;
|
||||
case QtWarningMsg:
|
||||
msgTag = "WARNING";
|
||||
fontColor = "yellow";
|
||||
break;
|
||||
case QtCriticalMsg:
|
||||
msgTag = "ERROR";
|
||||
fontColor = "red";
|
||||
break;
|
||||
case QtFatalMsg:
|
||||
msgTag = "FATAL";
|
||||
fontColor = "red";
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown debug msg type");
|
||||
fflush(stderr);
|
||||
break;
|
||||
}//switch
|
||||
|
||||
/*fprintf(stderr, "%s [%s] %s (%s:%u, %s)\n", timeRepr.data(), msgTag.toLocal8Bit().constData(), localMsg.data(),
|
||||
context.file, context.line, context.function);*/
|
||||
|
||||
fprintf(stderr, "%s [%s] %s\n", timeRepr.data(), msgTag.toLocal8Bit().constData(), localMsg.data());
|
||||
|
||||
if (debug_file.isOpen()) {
|
||||
debug_stream << QString("[%1] %2 (%3:%4, %5)\n")
|
||||
.arg(msgTag, localMsg, context.file, QString::number(context.line), context.function);
|
||||
}
|
||||
debug_info.prepend(QString("<font color='%1'><b>[%2]</b> %3 (%4:%5, %6)</font><br>")
|
||||
.arg(fontColor, msgTag, localMsg, context.file, QString::number(context.line), context.function));
|
||||
fflush(stderr);
|
||||
if (olive::DebugDialog != nullptr && olive::DebugDialog->isVisible()) {
|
||||
QMetaObject::invokeMethod(olive::DebugDialog, "update_log", Qt::QueuedConnection);
|
||||
}
|
||||
debug_mutex.unlock();
|
||||
}
|
||||
|
||||
const QString &get_debug_str()
|
||||
{
|
||||
return debug_info;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
void debug_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &msg);
|
||||
const QString& get_debug_str();
|
||||
void open_debug_file();
|
||||
void close_debug_file();
|
||||
|
||||
#endif // DEBUG_H
|
||||
@@ -0,0 +1,361 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "global/global.h"
|
||||
|
||||
|
||||
#include "panels/panels.h"
|
||||
|
||||
#include "global/path.h"
|
||||
#include "global/config.h"
|
||||
|
||||
|
||||
#include "rendering/audio.h"
|
||||
|
||||
#include "dialogs/demonotice.h"
|
||||
#include "dialogs/preferencesdialog.h"
|
||||
#include "dialogs/exportdialog.h"
|
||||
#include "dialogs/debugdialog.h"
|
||||
#include "dialogs/aboutdialog.h"
|
||||
#include "dialogs/speeddialog.h"
|
||||
#include "dialogs/actionsearch.h"
|
||||
|
||||
#include "timeline/sequence.h"
|
||||
|
||||
#include "ui/mediaiconservice.h"
|
||||
#include "ui/mainwindow.h"
|
||||
#include "ui/updatenotification.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
|
||||
std::unique_ptr<OliveGlobal> 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 (March 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;
|
||||
|
||||
// alloc QTranslator
|
||||
translator = std::unique_ptr<QTranslator>(new QTranslator());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
QString OliveGlobal::get_recent_project_list_file() {
|
||||
return get_data_dir().filePath("recents");
|
||||
}
|
||||
|
||||
void OliveGlobal::load_translation_from_config() {
|
||||
QString language_file = olive::CurrentRuntimeConfig.external_translation_file.isEmpty() ?
|
||||
olive::CurrentConfig.language_file :
|
||||
olive::CurrentRuntimeConfig.external_translation_file;
|
||||
|
||||
// clear runtime language file so if the user sets a different language, we won't load it next time
|
||||
olive::CurrentRuntimeConfig.external_translation_file.clear();
|
||||
|
||||
// remove current translation if there is one
|
||||
QApplication::removeTranslator(translator.get());
|
||||
|
||||
if (!language_file.isEmpty()) {
|
||||
|
||||
// translation files are stored relative to app path (see GitHub issue #454)
|
||||
QString full_language_path = QDir(get_app_path()).filePath(language_file);
|
||||
|
||||
// load translation file
|
||||
if (QFileInfo::exists(full_language_path)
|
||||
&& translator->load(full_language_path)) {
|
||||
QApplication::installTranslator(translator.get());
|
||||
} else {
|
||||
qWarning() << "Failed to load translation file" << full_language_path << ". No language will be loaded.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::new_project() {
|
||||
if (can_close_project()) {
|
||||
// clear effects panel
|
||||
panel_effect_controls->Clear(true);
|
||||
|
||||
// clear project contents (footage, sequences, etc.)
|
||||
panel_project->new_project();
|
||||
|
||||
// clear undo stack
|
||||
olive::UndoStack.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) {
|
||||
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 (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::open_export_dialog() {
|
||||
if (olive::ActiveSequence == nullptr) {
|
||||
QMessageBox::information(olive::MainWindow,
|
||||
tr("No active sequence"),
|
||||
tr("Please open the sequence you wish to export."),
|
||||
QMessageBox::Ok);
|
||||
} else {
|
||||
ExportDialog e(olive::MainWindow);
|
||||
e.exec();
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::finished_initialize() {
|
||||
if (enable_load_project_on_init) {
|
||||
|
||||
// if a project was set as a command line argument, we load it here
|
||||
if (QFileInfo::exists(olive::ActiveProjectFilename)) {
|
||||
open_project_worker(olive::ActiveProjectFilename, false);
|
||||
} else {
|
||||
QMessageBox::critical(olive::MainWindow,
|
||||
tr("Missing Project File"),
|
||||
tr("Specified project '%1' does not exist.").arg(olive::ActiveProjectFilename),
|
||||
QMessageBox::Ok);
|
||||
update_project_filename(nullptr);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// Check for updates
|
||||
olive::update_notifier.check();
|
||||
}
|
||||
|
||||
void OliveGlobal::save_autorecovery_file() {
|
||||
if (olive::MainWindow->isWindowModified()) {
|
||||
panel_project->save_project(true);
|
||||
qInfo() << "Auto-recovery project saved";
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::open_preferences() {
|
||||
panel_sequence_viewer->pause();
|
||||
panel_footage_viewer->pause();
|
||||
|
||||
PreferencesDialog pd(olive::MainWindow);
|
||||
pd.setup_kbd_shortcuts(olive::MainWindow->menuBar());
|
||||
pd.exec();
|
||||
}
|
||||
|
||||
void OliveGlobal::set_sequence(SequencePtr s)
|
||||
{
|
||||
panel_effect_controls->Clear(true);
|
||||
|
||||
olive::ActiveSequence = s;
|
||||
panel_sequence_viewer->set_main_sequence();
|
||||
panel_timeline->update_sequence();
|
||||
panel_timeline->setFocus();
|
||||
}
|
||||
|
||||
void OliveGlobal::open_project_worker(const QString& fn, bool autorecovery) {
|
||||
update_project_filename(fn);
|
||||
panel_project->load_project(fn, autorecovery, true);
|
||||
olive::UndoStack.clear();
|
||||
}
|
||||
|
||||
void OliveGlobal::undo() {
|
||||
// workaround to prevent crash (and also users should never need to do this)
|
||||
if (!panel_timeline->importing) {
|
||||
olive::UndoStack.undo();
|
||||
update_ui(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::redo() {
|
||||
// workaround to prevent crash (and also users should never need to do this)
|
||||
if (!panel_timeline->importing) {
|
||||
olive::UndoStack.redo();
|
||||
update_ui(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::paste() {
|
||||
if (olive::ActiveSequence != nullptr) {
|
||||
panel_timeline->paste(false);
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::paste_insert() {
|
||||
if (olive::ActiveSequence != nullptr) {
|
||||
panel_timeline->paste(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::open_about_dialog() {
|
||||
AboutDialog a(olive::MainWindow);
|
||||
a.exec();
|
||||
}
|
||||
|
||||
void OliveGlobal::open_debug_log() {
|
||||
olive::DebugDialog->show();
|
||||
}
|
||||
|
||||
void OliveGlobal::open_speed_dialog() {
|
||||
if (olive::ActiveSequence != nullptr) {
|
||||
|
||||
QVector<Clip*> selected_clips = olive::ActiveSequence->SelectedClips();
|
||||
|
||||
if (!selected_clips.isEmpty()) {
|
||||
SpeedDialog s(olive::MainWindow, selected_clips);
|
||||
s.exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::clear_undo_stack() {
|
||||
olive::UndoStack.clear();
|
||||
}
|
||||
|
||||
void OliveGlobal::open_action_search() {
|
||||
ActionSearch as(olive::MainWindow);
|
||||
as.exec();
|
||||
}
|
||||
+342
@@ -0,0 +1,342 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef OLIVEGLOBAL_H
|
||||
#define OLIVEGLOBAL_H
|
||||
|
||||
#include <memory>
|
||||
#include "undo/undo.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QFile>
|
||||
#include <QTranslator>
|
||||
|
||||
/**
|
||||
* @brief The Olive Global class
|
||||
*
|
||||
* A resource for various global functions used throughout Olive.
|
||||
*/
|
||||
class OliveGlobal : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* @brief OliveGlobal Constructor
|
||||
*
|
||||
* Creates Olive Global object. Also sets some default runtime settings and the application name.
|
||||
*/
|
||||
OliveGlobal();
|
||||
|
||||
/**
|
||||
* @brief Returns the file dialog filter used when interfacing with Olive project files.
|
||||
*
|
||||
* @return The file filter string used by QFileDialog to limit the files shown to Olive (*.ove) files.
|
||||
*/
|
||||
const QString& get_project_file_filter();
|
||||
|
||||
/**
|
||||
* @brief Change the current active project filename
|
||||
*
|
||||
* Triggered to change the current active project filename. Call this before calling any internal project
|
||||
* saving or loading functions in order to set which file to work with (OliveGlobal::open_project() and
|
||||
* OliveGlobal::save_project_as() do this automatically). Also updates the main window title to reflect the
|
||||
* project filename.
|
||||
*
|
||||
* @param s
|
||||
*
|
||||
* The URL of the project file to work with. Can be an empty string, in which case Olive will treat the project
|
||||
* as an unsaved project.
|
||||
*/
|
||||
void update_project_filename(const QString& s);
|
||||
|
||||
/**
|
||||
* @brief Check whether an auto-recovery file exists and ask the user if they want to load it.
|
||||
*
|
||||
* Usually called on initialization. Checks if an auto-recovery file exists (meaning the last session of Olive
|
||||
* didn't close correctly). If it finds one, asks the user if they want to load it. If so, loads the auto-recovery
|
||||
* project.
|
||||
*/
|
||||
void check_for_autorecovery_file();
|
||||
|
||||
/**
|
||||
* @brief Set the application state depending on if the user is exporting a video
|
||||
*
|
||||
* Some background functions shouldn't run while Olive is exporting a video. This function will disable/enable them
|
||||
* as necessary.
|
||||
*
|
||||
* The current functions are as follows:
|
||||
* * Auto-recovery interval. Olive saves an auto-recovery just before exporting anyway and seeing as the user
|
||||
* cannot make changes while rendering, there's no reason to continue saving auto-recovery files.
|
||||
* * Audio device playback. Olive uses the same internal audio buffer for exporting as it does for playback, but
|
||||
* this buffer does not need to be forwarded to the output device when exporting.
|
||||
*
|
||||
* @param rendering
|
||||
*
|
||||
* **TRUE** if Olive is about to export a video. **FALSE** if Olive has finished exporting.
|
||||
*/
|
||||
void set_rendering_state(bool rendering);
|
||||
|
||||
/**
|
||||
* @brief Set a project to load just after launching
|
||||
*
|
||||
* Called by main() if Olive was called with a project file as a running argument. Sets up Olive to load the
|
||||
* specified project once its finished initializing.
|
||||
*
|
||||
* @param s
|
||||
*
|
||||
* The URL of the project file to load.
|
||||
*/
|
||||
void load_project_on_launch(const QString& s);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the URL of the config file containing the autorecovery projects
|
||||
* @return The URL as a string
|
||||
*/
|
||||
QString get_recent_project_list_file();
|
||||
|
||||
/**
|
||||
* @brief (Re)load translation file from olive::config
|
||||
*/
|
||||
void load_translation_from_config();
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* @brief Undo user's last action
|
||||
*/
|
||||
void undo();
|
||||
|
||||
/**
|
||||
* @brief Redo user's last action
|
||||
*/
|
||||
void redo();
|
||||
|
||||
/**
|
||||
* @brief Paste contents of clipboard
|
||||
*
|
||||
* Pastes contents of clipboard. Seeing as several types of data can be copied into the clipboard, this
|
||||
* function will automatically determine what type of data is in the clipboard and paste it in the correct
|
||||
* location (e.g. clip data will go to the Timeline, effect data will go to Effect Controls).
|
||||
*/
|
||||
void paste();
|
||||
|
||||
/**
|
||||
* @brief Paste contents of clipboard, making space for it when possible
|
||||
*
|
||||
* Pastes contents of clipboard (same as paste()). If the clipboard contains clip data, the clips are cut at the
|
||||
* current playhead and ripple forward to make space for the clips in the clipboard. Can be considered
|
||||
* semi-non-destructive as a result (as opposed to paste() overwriting clips). If the clipboard contains effect
|
||||
* data, the functionality is identical to paste().
|
||||
*/
|
||||
void paste_insert();
|
||||
|
||||
/**
|
||||
* @brief Create new project.
|
||||
*
|
||||
* Confirms whether the current project can be closed, and if so, clears all current project data and resets
|
||||
* program state. Standard `File > New` behavior.
|
||||
*/
|
||||
void new_project();
|
||||
|
||||
/**
|
||||
* @brief Open a project from file.
|
||||
*
|
||||
* Confirms whether the current project can be closed, and if so, shows an open file dialog to allow the user to
|
||||
* select a project file and then triggers a project load with it.
|
||||
*/
|
||||
void open_project();
|
||||
|
||||
/**
|
||||
* @brief Open recent project from list
|
||||
*
|
||||
* Triggers a project load from the internal recent projects list.
|
||||
*
|
||||
* @param index
|
||||
*
|
||||
* Index in the list of the project fille to load
|
||||
*/
|
||||
void open_recent(int index);
|
||||
|
||||
/**
|
||||
* @brief Shows a save file dialog and saves the project as the resulting filename
|
||||
*
|
||||
* Shows a save file dialog for the user to save their current project as a different filename from the current
|
||||
* one. Also triggered by save_project() if the file hasn't been saved yet.
|
||||
*
|
||||
* @return **TRUE** if the user saved the project. **FALSE** if they cancelled out of the save file dialog. Useful
|
||||
* if a user is closing an unsaved project, clicks "Yes" to save, we know if they actually saved or not and won't
|
||||
* continue closing the project if they didn't.
|
||||
*/
|
||||
bool save_project_as();
|
||||
|
||||
/**
|
||||
* @brief Saves the current project to file
|
||||
*
|
||||
* If the project has been saved already, this function will overwrite the project file with the current project
|
||||
* data. Calls save_project_as() if the file has not been saved before.
|
||||
*
|
||||
* @return **TRUE** if the project has been saved before and was successfully overwritten. Otherwise returns the
|
||||
* value of save_project_as(). Useful if the user closing an unsaved project, clicks "Yes" to save, we know if they
|
||||
* actually saved or not and won't continue closing the project if they didn't.
|
||||
*/
|
||||
bool save_project();
|
||||
|
||||
/**
|
||||
* @brief Determine whether the current project can be closed.
|
||||
*
|
||||
* Queried any time the current project is going to be closed (e.g. starting a new project, loading a project,
|
||||
* exiting Olive, etc.) If the project has unsaved changes, this function asks the user whether they want to save or
|
||||
* not. If the user does, calls save_project() (which may in turn call save_project_as() if the project has never
|
||||
* been saved).
|
||||
*
|
||||
* @return **TRUE** if the project can be closed. FALSE if not. If the project does NOT have unsaved changes, always
|
||||
* returns **TRUE**. If it does and the user clicks YES, this returns the result of save_project(). If the user
|
||||
* clicks NO, this returns **TRUE**. If the user clicks CANCEL, this returns **FALSE**.
|
||||
*/
|
||||
bool can_close_project();
|
||||
|
||||
/**
|
||||
* @brief Open the Export dialog to trigger an export of the current sequence.
|
||||
*/
|
||||
void open_export_dialog();
|
||||
|
||||
/**
|
||||
* @brief Open the About Olive dialog.
|
||||
*/
|
||||
void open_about_dialog();
|
||||
|
||||
/**
|
||||
* @brief Open the Debug Log window.
|
||||
*/
|
||||
void open_debug_log();
|
||||
|
||||
/**
|
||||
* @brief Open the Speed/Duration dialog.
|
||||
*/
|
||||
void open_speed_dialog();
|
||||
|
||||
/**
|
||||
* @brief Open the Action Search overlay.
|
||||
*/
|
||||
void open_action_search();
|
||||
|
||||
/**
|
||||
* @brief Clears the current undo stack.
|
||||
*
|
||||
* Clears all current commands in the undo stack. Mostly used for debugging.
|
||||
*/
|
||||
void clear_undo_stack();
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
/**
|
||||
* @brief Opens the Preferences dialog
|
||||
*/
|
||||
void open_preferences();
|
||||
|
||||
/**
|
||||
* @brief Set the current active Sequence
|
||||
*
|
||||
* Call this to change the active Sequence (e.g. when the user double clicks a Sequence in the Project panel).
|
||||
* This will affect panel_timeline, panel_sequence_viewer, and panel_effect_controls and can then be retrieved
|
||||
* using olive::ActiveSequence.
|
||||
*
|
||||
* @param s
|
||||
*
|
||||
* The Sequence to set as the active Sequence.
|
||||
*/
|
||||
void set_sequence(SequencePtr s);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Internal function to handle loading a project from file
|
||||
*
|
||||
* Start loading a project. Doesn't check if the current project can be closed, doesn't check if the project exists.
|
||||
* In most cases, you'll want open_project() to be end-user friendly.
|
||||
*
|
||||
* @param fn
|
||||
*
|
||||
* The URL to the project to load.
|
||||
*
|
||||
* @param autorecovery
|
||||
*
|
||||
* Whether this file is an autorecovery file. If it is, after the load Olive will set the project URL to a new file
|
||||
* beside the original project file so that it does not overwrite the original and so that the user is not working
|
||||
* on the autorecovery project in Olive's application data directory.
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* @brief Internal translator object that interfaces with the currently loaded language file
|
||||
*/
|
||||
std::unique_ptr<QTranslator> translator;
|
||||
|
||||
private slots:
|
||||
|
||||
};
|
||||
|
||||
namespace olive {
|
||||
/**
|
||||
* @brief Object resource for various global functions used throughout Olive
|
||||
*/
|
||||
extern std::unique_ptr<OliveGlobal> 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
|
||||
@@ -0,0 +1,82 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "math.h"
|
||||
|
||||
#include <QtMath>
|
||||
#include <QVector>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
int lerp(int a, int b, double t) {
|
||||
return qRound(((1.0 - t) * a) + (t * b));
|
||||
}
|
||||
|
||||
float float_lerp(float a, float b, float t) {
|
||||
return ((1.0F - t) * a) + (t * b);
|
||||
}
|
||||
|
||||
double double_lerp(double a, double b, double t) {
|
||||
return ((1.0 - t) * a) + (t * b);
|
||||
}
|
||||
|
||||
double quad_from_t(double a, double b, double c, double t) {
|
||||
return qPow(1.0 - t, 2)*a + 2*(1.0 - t)*t*b + qPow(t, 2)*c;
|
||||
}
|
||||
|
||||
double quad_t_from_x(double x, double a, double b, double c) {
|
||||
return (a - b + qSqrt(a*x + c*x - 2*b*x + qPow(b, 2) - a*c))/(a - 2*b + c);
|
||||
// alt: return (a - b - qSqrt(a*x + c*x - 2*b*x + qPow(b, 2) - a*c))/(a - 2*b + c);
|
||||
}
|
||||
|
||||
double cubic_from_t(double a, double b, double c, double d, double t) {
|
||||
return qPow(1.0 - t, 3)*a + 3*qPow(1.0 - t, 2)*t*b + 3*(1.0 - t)*qPow(t, 2)*c + qPow(t, 3)*d;
|
||||
}
|
||||
|
||||
double cubic_t_from_x(double x_target, double a, double b, double c, double d) {
|
||||
double tolerance = 0.0001;
|
||||
|
||||
double lower = 0.0;
|
||||
double upper = 1.0;
|
||||
|
||||
double percent = 0.5;
|
||||
double x = cubic_from_t(a, b, c, d, percent);
|
||||
|
||||
while (qAbs(x_target - x) > tolerance) {
|
||||
if (x_target > x) {
|
||||
lower = percent;
|
||||
} else {
|
||||
upper = percent;
|
||||
}
|
||||
|
||||
percent = (upper + lower) / 2.0;
|
||||
x = cubic_from_t(a, b, c, d, percent);
|
||||
}
|
||||
|
||||
return percent;
|
||||
}
|
||||
|
||||
double amplitude_to_db(double amplitude) {
|
||||
return (20.0*(qLn(amplitude)/qLn(10.0)));
|
||||
}
|
||||
|
||||
double db_to_amplitude(double db) {
|
||||
return qPow(M_E, (db*qLn(10.0))/20.0);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef MATH_H
|
||||
#define MATH_H
|
||||
|
||||
int lerp(int a, int b, double t);
|
||||
float float_lerp(float a, float b, float t);
|
||||
double double_lerp(double a, double b, double t);
|
||||
double quad_from_t(double a, double b, double c, double t);
|
||||
double quad_t_from_x(double x, double a, double b, double c);
|
||||
double cubic_from_t(double a, double b, double c, double d, double t);
|
||||
double cubic_t_from_x(double x_target, double a, double b, double c, double d);
|
||||
double solveCubicBezier(double p0, double p1, double p2, double p3, double x);
|
||||
|
||||
// decibel conversion functions
|
||||
double amplitude_to_db(double amplitude);
|
||||
double db_to_amplitude(double db);
|
||||
|
||||
#endif // MATH_H
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "path.h"
|
||||
|
||||
#include <QStandardPaths>
|
||||
#include <QFileInfo>
|
||||
#include <QCoreApplication>
|
||||
#include <QCryptographicHash>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
QString get_app_path() {
|
||||
return QCoreApplication::applicationDirPath();
|
||||
}
|
||||
|
||||
QDir get_app_dir() {
|
||||
return QDir(get_app_path());
|
||||
}
|
||||
|
||||
QString get_data_path() {
|
||||
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() {
|
||||
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<QString> get_effects_paths() {
|
||||
// returns a list of the effects paths to search
|
||||
|
||||
QList<QString> effects_paths;
|
||||
|
||||
// get current app working directory
|
||||
QDir app_dir = get_app_dir();
|
||||
|
||||
// "effects" subfolder in program folder - best for Windows
|
||||
effects_paths.append(app_dir.filePath("effects"));
|
||||
|
||||
// "Effects" folder one level above the program's directory - best for Mac
|
||||
effects_paths.append(app_dir.filePath("../Effects"));
|
||||
|
||||
// folder in share folder - best for Linux
|
||||
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"));
|
||||
if (!env_path.isEmpty()) effects_paths.append(env_path);
|
||||
|
||||
return 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());
|
||||
|
||||
return QCryptographicHash::hash(cache_file.toUtf8(), QCryptographicHash::Md5).toHex();
|
||||
}
|
||||
|
||||
QList<QString> get_language_paths() {
|
||||
QList<QString> 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(app_dir.filePath("ts"));
|
||||
|
||||
// folder one level above the program's directory - best for Mac
|
||||
language_paths.append(app_dir.filePath("../Translations"));
|
||||
|
||||
// folder in share folder - best for Linux
|
||||
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"));
|
||||
if (!env_path.isEmpty()) language_paths.append(env_path);
|
||||
|
||||
return language_paths;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef PATH_H
|
||||
#define PATH_H
|
||||
|
||||
#include <QString>
|
||||
#include <QDir>
|
||||
|
||||
QString get_app_path();
|
||||
QString get_data_path();
|
||||
QDir get_data_dir();
|
||||
QString get_config_path();
|
||||
QDir get_config_dir();
|
||||
QList<QString> get_effects_paths();
|
||||
QList<QString> get_language_paths();
|
||||
|
||||
// generate hash algorithm used to uniquely identify files
|
||||
QString get_file_hash(const QString& filename);
|
||||
|
||||
#endif // PATH_H
|
||||
Reference in New Issue
Block a user