diff --git a/.gitignore b/.gitignore index 0c3654b81..e4bce1768 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ *.pro.user* Makefile .qmake.stash +effects/frei0r + diff --git a/.travis.yml b/.travis.yml index 7a3e27080..e207f875d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ before_install: - sudo apt-get update -qq install: - - sudo apt-get -y install qt59base qt59multimedia libavformat-dev libavcodec-dev libavfilter-dev libavutil-dev libswscale-dev libswresample-dev + - sudo apt-get -y install qt59base qt59multimedia libavformat-dev libavcodec-dev libavfilter-dev libavutil-dev libswscale-dev libswresample-dev frei0r-plugins-dev frei0r-plugins - source /opt/qt*/bin/qt*-env.sh script: diff --git a/debian/control b/debian/control index e46c0c253..bb50de7f3 100644 --- a/debian/control +++ b/debian/control @@ -2,12 +2,12 @@ Source: olive-editor Section: video Priority: optional Maintainer: Olive Team -Build-Depends: debhelper (>=9), build-essential, qt5-default, qtmultimedia5-dev, libqt5opengl5-dev, libqt5multimedia5-plugins, libavformat-dev, libavcodec-dev, libavutil-dev, libswscale-dev, libswresample-dev, libavfilter-dev, libpostproc-dev, git +Build-Depends: debhelper (>=9), build-essential, qt5-default, qtmultimedia5-dev, libqt5opengl5-dev, libqt5multimedia5-plugins, libavformat-dev, libavcodec-dev, libavutil-dev, libswscale-dev, libswresample-dev, libavfilter-dev, libpostproc-dev, git, frei0r-plugins-dev Standards-Version: 3.9.6 Homepage: https://olivevideoeditor.org/ Package: olive-editor Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends}, libqt5multimedia5-plugins +Depends: ${misc:Depends}, ${shlibs:Depends}, libqt5multimedia5-plugins, frei0r-plugins Description: Nonlinear video editor focused on performance and simplicity diff --git a/effects/internal/frei0reffect.cpp b/effects/internal/frei0reffect.cpp new file mode 100644 index 000000000..a45efcf36 --- /dev/null +++ b/effects/internal/frei0reffect.cpp @@ -0,0 +1,194 @@ +#include "frei0reffect.h" + +#ifndef NOFREI0R + +#include +#include + +#include "project/clip.h" + +typedef f0r_instance_t (*f0rConstructFunc)(unsigned int width, unsigned int height); +typedef int (*f0rInitFunc) (); +typedef void (*f0rDeinitFunc) (); +typedef void (*f0rUpdateFunc) (f0r_instance_t instance, + double time, const uint32_t* inframe, uint32_t* outframe); +typedef void (*f0rDestructFunc)(f0r_instance_t instance); +typedef void (*f0rGetPluginInfo)(f0r_plugin_info_t* info); +typedef void (*f0rSetParamValue) (f0r_instance_t instance, + f0r_param_t param, int param_index); + +Frei0rEffect::Frei0rEffect(Clip *c, const EffectMeta *em) : + Effect(c, em), + open(false) +{ + enable_image = true; + + // Windows DLL loading routine + QString dll_fn = QDir(em->path).filePath(em->filename); + + handle = LibLoad(dll_fn); + if(handle == nullptr) { + QString dll_error; + +#ifdef _WIN32 + DWORD dll_err = GetLastError(); + dll_error = QString::number(dll_err); +#elif __linux__ + dll_error = dlerror(); +#endif + qCritical() << "Failed to load Frei0r plugin" << dll_fn << "-" << dll_error; + + QString msg_err = tr("Failed to load Frei0r plugin \"%1\": %2").arg(dll_fn, dll_error); + +#ifdef _WIN32 + if (dll_err == 193) { +#ifdef _WIN64 + msg_err += "\n\n" + tr("NOTE: You can't load 32-bit Frei0r plugins into a 64-bit build of Olive. Please find a 64-bit version of this plugin or switch to a 32-bit build of Olive."); +#elif _WIN32 + msg_err += "\n\n" + tr("NOTE: You can't load 64-bit Frei0r plugins into a 32-bit build of Olive. Please find a 32-bit version of this plugin or switch to a 64-bit build of Olive."); +#endif + } +#endif + + QMessageBox::critical(nullptr, tr("Error loading Frei0r plugin"), msg_err); + + return; + } + + f0rInitFunc init = reinterpret_cast(LibAddress(handle, "f0r_init")); + init(); + + construct_module(); + + f0r_plugin_info_t info; + f0rGetPluginInfo info_func = reinterpret_cast(LibAddress(handle, "f0r_get_plugin_info")); + info_func(&info); + + param_count = info.num_params; + + get_param_info = reinterpret_cast(LibAddress(handle, "f0r_get_param_info")); + for (int i=0;i= 0 && param_info.type <= F0R_PARAM_STRING) { + EffectRow* row = add_row(param_info.name); + switch (param_info.type) { + case F0R_PARAM_BOOL: + row->add_field(EFFECT_FIELD_BOOL, QString::number(i)); + break; + case F0R_PARAM_DOUBLE: + { + EffectField* f = row->add_field(EFFECT_FIELD_DOUBLE, QString::number(i)); + f->set_double_minimum_value(0); + f->set_double_maximum_value(100); + } + break; + case F0R_PARAM_COLOR: + row->add_field(EFFECT_FIELD_COLOR, QString::number(i)); + break; + case F0R_PARAM_POSITION: + { + EffectField* fx = row->add_field(EFFECT_FIELD_DOUBLE, QString("%1X").arg(QString::number(i))); + fx->set_double_minimum_value(0); + fx->set_double_maximum_value(100); + EffectField* fy = row->add_field(EFFECT_FIELD_DOUBLE, QString("%1Y").arg(QString::number(i))); + fy->set_double_minimum_value(0); + fy->set_double_maximum_value(100); + } + break; + case F0R_PARAM_STRING: + row->add_field(EFFECT_FIELD_STRING, QString::number(i)); + break; + } + } + } +} + +Frei0rEffect::~Frei0rEffect() { + if (handle != nullptr) { + f0rDeinitFunc deinit = reinterpret_cast(LibAddress(handle, "f0r_deinit")); + deinit(); + + LibClose(handle); + } +} + +void Frei0rEffect::process_image(double timecode, uint8_t *input, uint8_t *output, int) { + f0rUpdateFunc update_func = reinterpret_cast(LibAddress(handle, "f0r_update")); + + for (int i=0;i(LibAddress(handle, "f0r_set_param_value")); + switch (param_info.type) { + case F0R_PARAM_BOOL: + { + double b = param_row->field(0)->get_bool_value(timecode); + set_param(instance, &b, i); + } + break; + case F0R_PARAM_DOUBLE: + { + double d = param_row->field(0)->get_double_value(timecode)*0.01; + set_param(instance, &d, i); + } + break; + case F0R_PARAM_COLOR: + { + QColor qcolor = param_row->field(0)->get_color_value(timecode);; + + f0r_param_color fcolor; + fcolor.r = float(qcolor.redF()); + fcolor.g = float(qcolor.greenF()); + fcolor.b = float(qcolor.blueF()); + + set_param(instance, &fcolor, i); + } + break; + case F0R_PARAM_POSITION: + { + f0r_param_position pos; + pos.x = param_row->field(0)->get_double_value(timecode); + pos.y = param_row->field(1)->get_double_value(timecode); + set_param(instance, &pos, i); + } + break; + case F0R_PARAM_STRING: + { + QByteArray bytes = param_row->field(0)->get_string_value(timecode).toUtf8(); + char* byte_data = bytes.data(); + set_param(instance, &byte_data, i); + } + break; + } + } + + update_func(instance, timecode, reinterpret_cast(input), reinterpret_cast(output)); +} + +void Frei0rEffect::refresh() { + destruct_module(); + construct_module(); +} + +void Frei0rEffect::destruct_module() { + if (open) { + f0rDestructFunc destruct = reinterpret_cast(LibAddress(handle, "f0r_destruct")); + destruct(instance); + + open = false; + } +} + +void Frei0rEffect::construct_module() { + f0rConstructFunc construct = reinterpret_cast(LibAddress(handle, "f0r_construct")); + instance = construct(parent_clip->getWidth(), parent_clip->getHeight()); + + open = true; +} + +#endif diff --git a/effects/internal/frei0reffect.h b/effects/internal/frei0reffect.h new file mode 100644 index 000000000..413baf676 --- /dev/null +++ b/effects/internal/frei0reffect.h @@ -0,0 +1,36 @@ +#ifndef FREI0REFFECT_H +#define FREI0REFFECT_H + +#ifndef NOFREI0R + +#include "project/effect.h" + +#include + +#include "io/crossplatformlib.h" + +typedef void (*f0rGetParamInfo)(f0r_param_info_t * info, + int param_index ); + +class Frei0rEffect : public Effect { + Q_OBJECT +public: + Frei0rEffect(Clip* c, const EffectMeta* em); + ~Frei0rEffect(); + + virtual void process_image(double timecode, uint8_t* input, uint8_t* output, int size); + + virtual void refresh(); +private: + ModulePtr handle; + f0r_instance_t instance; + int param_count; + f0rGetParamInfo get_param_info; + void destruct_module(); + void construct_module(); + bool open; +}; + +#endif + +#endif // FREI0REFFECT_H diff --git a/effects/internal/vsthostwin.cpp b/effects/internal/vsthost.cpp similarity index 80% rename from effects/internal/vsthostwin.cpp rename to effects/internal/vsthost.cpp index 0d04513ba..e56393fe8 100644 --- a/effects/internal/vsthostwin.cpp +++ b/effects/internal/vsthost.cpp @@ -1,9 +1,9 @@ -#include "vsthostwin.h" +#include "vsthost.h" + +#ifdef _WIN32 // adapted from http://teragonaudio.com/article/How-to-make-your-own-VST-host.html -#include - #include #include #include @@ -52,20 +52,22 @@ typedef VstInt32 (*processEventsFuncPtr)(VstEvents *events); // Plugin's process() method typedef void (*processFuncPtr)(AEffect *effect, float **inputs, float **outputs, VstInt32 sampleFrames); -void VSTHostWin::loadPlugin() { +void VSTHost::loadPlugin() { QString dll_fn = file_field->get_filename(0, true); - LPCWSTR dll_fn_w = reinterpret_cast(dll_fn.utf16()); - modulePtr = LoadLibrary(dll_fn_w); + modulePtr = LibLoad(dll_fn); if(modulePtr == nullptr) { DWORD dll_err = GetLastError(); - qCritical() << "Failed to load VST" << dll_fn_w << "-" << dll_err; + qCritical() << "Failed to load VST" << dll_fn << "-" << dll_err; + +#ifdef _WIN32 QString msg_err = tr("Failed to load VST plugin \"%1\": %2").arg(dll_fn, QString::number(dll_err)); if (dll_err == 193) { #ifdef _WIN64 msg_err += "\n\n" + tr("NOTE: You can't load 32-bit VST plugins into a 64-bit build of Olive. Please find a 64-bit version of this plugin or switch to a 32-bit build of Olive."); #elif _WIN32 msg_err += "\n\n" + tr("NOTE: You can't load 64-bit VST plugins into a 32-bit build of Olive. Please find a 32-bit version of this plugin or switch to a 64-bit build of Olive."); +#endif #endif } QMessageBox::critical(mainWindow, tr("Error loading VST plugin"), msg_err); @@ -73,20 +75,20 @@ void VSTHostWin::loadPlugin() { } vstPluginFuncPtr mainEntryPoint = - reinterpret_cast(GetProcAddress(modulePtr, "VSTPluginMain")); + reinterpret_cast(LibAddress(modulePtr, "VSTPluginMain")); // Instantiate the plugin plugin = mainEntryPoint(hostCallback); } -void VSTHostWin::freePlugin() { +void VSTHost::freePlugin() { if (plugin != nullptr) { stopPlugin(); - FreeLibrary(modulePtr); + LibClose(modulePtr); plugin = nullptr; } } -bool VSTHostWin::configurePluginCallbacks() { +bool VSTHost::configurePluginCallbacks() { // Check plugin's magic number // If incorrect, then the file either was not loaded properly, is not a // real VST plugin, or is otherwise corrupt. @@ -107,7 +109,7 @@ bool VSTHostWin::configurePluginCallbacks() { return true; } -void VSTHostWin::startPlugin() { +void VSTHost::startPlugin() { dispatcher(plugin, effOpen, 0, 0, nullptr, 0.0f); // Set some default properties @@ -117,37 +119,25 @@ void VSTHostWin::startPlugin() { resumePlugin(); } -void VSTHostWin::stopPlugin() { +void VSTHost::stopPlugin() { suspendPlugin(); dispatcher(plugin, effClose, 0, 0, nullptr, 0); } -void VSTHostWin::resumePlugin() { +void VSTHost::resumePlugin() { dispatcher(plugin, effMainsChanged, 0, 1, nullptr, 0.0f); } -void VSTHostWin::suspendPlugin() { +void VSTHost::suspendPlugin() { dispatcher(plugin, effMainsChanged, 0, 0, nullptr, 0.0f); } -bool VSTHostWin::canPluginDo(char *canDoString) { +bool VSTHost::canPluginDo(char *canDoString) { return (dispatcher(plugin, effCanDo, 0, 0, static_cast(canDoString), 0.0f) > 0); } -void VSTHostWin::initializeIO() { - // inputs and outputs are assumed to be float** and are declared elsewhere, - // most likely the are fields owned by this class. numChannels and blocksize - // are also fields, both should be size_t (or unsigned int, if you prefer). - inputs = new float* [CHANNEL_COUNT]; - outputs = new float* [CHANNEL_COUNT]; - for(int channel = 0; channel < CHANNEL_COUNT; channel++) { - inputs[channel] = new float[BLOCK_SIZE]; - outputs[channel] = new float[BLOCK_SIZE]; - } -} - -void VSTHostWin::processAudio(long numFrames) { +void VSTHost::processAudio(long numFrames) { // Always reset the output array before processing. for (int i=0;iprocessReplacing(plugin, inputs, outputs, numFrames); } -VSTHostWin::VSTHostWin(Clip* c, const EffectMeta *em) : Effect(c, em) { +VSTHost::VSTHost(Clip* c, const EffectMeta *em) : Effect(c, em) { plugin = nullptr; - initializeIO(); + inputs = new float* [CHANNEL_COUNT]; + outputs = new float* [CHANNEL_COUNT]; + for(int channel = 0; channel < CHANNEL_COUNT; channel++) { + inputs[channel] = new float[BLOCK_SIZE]; + outputs[channel] = new float[BLOCK_SIZE]; + } file_field = add_row(tr("Plugin"), true, false)->add_field(EFFECT_FIELD_FILE, "filename"); connect(file_field, SIGNAL(changed()), this, SLOT(change_plugin())); @@ -178,11 +173,18 @@ VSTHostWin::VSTHostWin(Clip* c, const EffectMeta *em) : Effect(c, em) { connect(dialog, SIGNAL(finished(int)), this, SLOT(uncheck_show_button())); } -VSTHostWin::~VSTHostWin() { +VSTHost::~VSTHost() { + for(int channel = 0; channel < CHANNEL_COUNT; channel++) { + delete [] inputs[channel]; + delete [] outputs[channel]; + } + delete [] outputs; + delete [] inputs; + freePlugin(); } -void VSTHostWin::process_audio(double, double, quint8* samples, int nb_bytes, int) { +void VSTHost::process_audio(double, double, quint8* samples, int nb_bytes, int) { if (plugin != nullptr) { int interval = BLOCK_SIZE*4; for (int i=0;isetVisible(show); } -void VSTHostWin::uncheck_show_button() { +void VSTHost::uncheck_show_button() { show_interface_btn->setChecked(false); } -void VSTHostWin::change_plugin() { +void VSTHost::change_plugin() { freePlugin(); loadPlugin(); if (plugin != nullptr) { @@ -258,9 +260,11 @@ void VSTHostWin::change_plugin() { dialog->setFixedWidth(eRect->right); dialog->setFixedHeight(eRect->bottom); } else { - FreeLibrary(modulePtr); + LibClose(modulePtr); plugin = nullptr; } } show_interface_btn->setEnabled(plugin != nullptr); } + +#endif diff --git a/effects/internal/vsthostwin.h b/effects/internal/vsthost.h similarity index 82% rename from effects/internal/vsthostwin.h rename to effects/internal/vsthost.h index cf057cfee..13a99a816 100644 --- a/effects/internal/vsthostwin.h +++ b/effects/internal/vsthost.h @@ -1,8 +1,12 @@ #ifndef VSTHOSTWIN_H #define VSTHOSTWIN_H +#ifdef _WIN32 + #include "project/effect.h" +#include "io/crossplatformlib.h" + #include // Plugin's dispatcher function @@ -11,11 +15,11 @@ typedef VstIntPtr (*dispatcherFuncPtr)(AEffect *effect, VstInt32 opCode, VstInt3 struct AEffect; class QDialog; -class VSTHostWin : public Effect { +class VSTHost : public Effect { Q_OBJECT public: - VSTHostWin(Clip* c, const EffectMeta* em); - ~VSTHostWin(); + VSTHost(Clip* c, const EffectMeta* em); + ~VSTHost(); void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); void custom_load(QXmlStreamReader& stream); @@ -37,13 +41,14 @@ private: void resumePlugin(); void suspendPlugin(); bool canPluginDo(char *canDoString); - void initializeIO(); void processAudio(long numFrames); float** inputs; float** outputs; QDialog* dialog; QPushButton* show_interface_btn; - HMODULE modulePtr; + ModulePtr modulePtr; }; +#endif + #endif // VSTHOSTWIN_H diff --git a/icons/add-button-disabled.png b/icons/add-button-disabled.png index c44add8f8..c7b22ddb4 100644 Binary files a/icons/add-button-disabled.png and b/icons/add-button-disabled.png differ diff --git a/icons/add-button.png b/icons/add-button.png index 728bd7be3..a2f82c462 100644 Binary files a/icons/add-button.png and b/icons/add-button.png differ diff --git a/icons/add-button.svg b/icons/add-button.svg new file mode 100644 index 000000000..b51a08205 --- /dev/null +++ b/icons/add-button.svg @@ -0,0 +1,823 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/icons/add-effect.png b/icons/add-effect.png index 10125a31d..7b16cb66f 100644 Binary files a/icons/add-effect.png and b/icons/add-effect.png differ diff --git a/icons/add-effect.svg b/icons/add-effect.svg new file mode 100644 index 000000000..5074e60c0 --- /dev/null +++ b/icons/add-effect.svg @@ -0,0 +1,840 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/add-transition.png b/icons/add-transition.png index 833f29706..0f2b1ba3d 100644 Binary files a/icons/add-transition.png and b/icons/add-transition.png differ diff --git a/icons/add-transition.svg b/icons/add-transition.svg new file mode 100644 index 000000000..a04cf2948 --- /dev/null +++ b/icons/add-transition.svg @@ -0,0 +1,824 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/icons/arrow-disabled.png b/icons/arrow-disabled.png index b0e6d8efb..d9a767f21 100644 Binary files a/icons/arrow-disabled.png and b/icons/arrow-disabled.png differ diff --git a/icons/arrow.png b/icons/arrow.png index 1016612d6..3d352903c 100644 Binary files a/icons/arrow.png and b/icons/arrow.png differ diff --git a/icons/arrow.svg b/icons/arrow.svg new file mode 100644 index 000000000..f5253dc8f --- /dev/null +++ b/icons/arrow.svg @@ -0,0 +1,129 @@ + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/icons/audiosource.png b/icons/audiosource.png index 54ec5b0cf..3ec977438 100644 Binary files a/icons/audiosource.png and b/icons/audiosource.png differ diff --git a/icons/audiosource.svg b/icons/audiosource.svg new file mode 100644 index 000000000..15aba5f6c --- /dev/null +++ b/icons/audiosource.svg @@ -0,0 +1,818 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/icons/beam-disabled.png b/icons/beam-disabled.png index 91f3ebd4c..3344af772 100644 Binary files a/icons/beam-disabled.png and b/icons/beam-disabled.png differ diff --git a/icons/beam.png b/icons/beam.png index c056807fb..a1563674f 100644 Binary files a/icons/beam.png and b/icons/beam.png differ diff --git a/icons/beam.svg b/icons/beam.svg new file mode 100644 index 000000000..830514e4a --- /dev/null +++ b/icons/beam.svg @@ -0,0 +1,170 @@ + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/clock.png b/icons/clock.png index da7b5763a..2bc896a29 100644 Binary files a/icons/clock.png and b/icons/clock.png differ diff --git a/icons/clock.svg b/icons/clock.svg new file mode 100644 index 000000000..672f1b4a2 --- /dev/null +++ b/icons/clock.svg @@ -0,0 +1,824 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/icons/diamond.png b/icons/diamond.png index aa3e74a83..ea6c47136 100644 Binary files a/icons/diamond.png and b/icons/diamond.png differ diff --git a/icons/diamond.svg b/icons/diamond.svg new file mode 100644 index 000000000..523802d5e --- /dev/null +++ b/icons/diamond.svg @@ -0,0 +1,818 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/icons/dirup-disabled.png b/icons/dirup-disabled.png index f23fa3f68..7dd3e7bf1 100644 Binary files a/icons/dirup-disabled.png and b/icons/dirup-disabled.png differ diff --git a/icons/dirup.png b/icons/dirup.png index f67b44672..e15f49fb0 100644 Binary files a/icons/dirup.png and b/icons/dirup.png differ diff --git a/icons/dirup.svg b/icons/dirup.svg new file mode 100644 index 000000000..d1f268c63 --- /dev/null +++ b/icons/dirup.svg @@ -0,0 +1,11031 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/icons/error.png b/icons/error.png index 34eb2de38..31d167335 100644 Binary files a/icons/error.png and b/icons/error.png differ diff --git a/icons/error.svg b/icons/error.svg new file mode 100644 index 000000000..19397e15d --- /dev/null +++ b/icons/error.svg @@ -0,0 +1,11031 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/icons/ff-disabled.png b/icons/ff-disabled.png index 50ecb1538..aa530c75f 100644 Binary files a/icons/ff-disabled.png and b/icons/ff-disabled.png differ diff --git a/icons/ff.png b/icons/ff.png index f7c7b3a01..965d06b4e 100644 Binary files a/icons/ff.png and b/icons/ff.png differ diff --git a/icons/ff.svg b/icons/ff.svg new file mode 100644 index 000000000..feb801b45 --- /dev/null +++ b/icons/ff.svg @@ -0,0 +1,824 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/icons/folder.png b/icons/folder.png index 8b51987b4..a6dcda3a0 100644 Binary files a/icons/folder.png and b/icons/folder.png differ diff --git a/icons/folder.svg b/icons/folder.svg new file mode 100644 index 000000000..b9adcd958 --- /dev/null +++ b/icons/folder.svg @@ -0,0 +1,11032 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/icons/hand-disabled.png b/icons/hand-disabled.png index ec80df67a..0e115c99c 100644 Binary files a/icons/hand-disabled.png and b/icons/hand-disabled.png differ diff --git a/icons/hand.png b/icons/hand.png index 31cfea6fb..42134e130 100644 Binary files a/icons/hand.png and b/icons/hand.png differ diff --git a/icons/hand.svg b/icons/hand.svg new file mode 100644 index 000000000..9e8c63594 --- /dev/null +++ b/icons/hand.svg @@ -0,0 +1,826 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/icons/icons.qrc b/icons/icons.qrc index a2981fd4c..157879efd 100644 --- a/icons/icons.qrc +++ b/icons/icons.qrc @@ -1,63 +1,75 @@ - - - play.png - ff.png - next.png - pause.png - prev.png - rew.png - arrow.png - beam.png - razor.png - audiosource.png - videosource.png - imagesource.png - ripple.png - rolling.png - slip.png - ff-disabled.png - next-disabled.png - pause-disabled.png - play-disabled.png - prev-disabled.png - rew-disabled.png - arrow-disabled.png - beam-disabled.png - razor-disabled.png - ripple-disabled.png - rolling-disabled.png - slip-disabled.png - slide.png - slide-disabled.png - throbber.png - magnet.png - magnet-disabled.png - zoomin.png - zoomin-disabled.png - zoomout.png - zoomout-disabled.png - add-transition.png - add-effect.png - olive-splash.png - add-button.png - add-button-disabled.png - clock.png - sequence.png - folder.png - record.png - record-disabled.png - transition-tool.png - transition-tool-disabled.png - error.png - dirup.png - dirup-disabled.png - diamond.png - tri-down.png - tri-left.png - tri-right.png - tri-up.png - hand.png - hand-disabled.png - olive64.png - - + + + play.png + ff.png + next.png + pause.png + prev.png + rew.png + arrow.png + beam.png + razor.png + audiosource.png + videosource.png + imagesource.png + ripple.png + rolling.png + slip.png + ff-disabled.png + next-disabled.png + pause-disabled.png + play-disabled.png + prev-disabled.png + rew-disabled.png + arrow-disabled.png + beam-disabled.png + razor-disabled.png + ripple-disabled.png + rolling-disabled.png + slip-disabled.png + slide.png + slide-disabled.png + throbber.png + magnet.png + magnet-disabled.png + zoomin.png + zoomin-disabled.png + zoomout.png + zoomout-disabled.png + add-transition.png + add-effect.png + olive-splash.png + add-button.png + add-button-disabled.png + clock.png + sequence.png + folder.png + record.png + record-disabled.png + transition-tool.png + transition-tool-disabled.png + error.png + dirup.png + dirup-disabled.png + diamond.png + tri-down.png + tri-left.png + tri-right.png + tri-up.png + hand.png + hand-disabled.png + treeview.png + treeview-disabled.png + iconview.png + iconview-disabled.png + open.png + open-disabled.png + save.png + save-disabled.png + undo.png + undo-disabled.png + redo.png + redo-disabled.png + olive64.png + + diff --git a/icons/iconview-disabled.png b/icons/iconview-disabled.png new file mode 100644 index 000000000..8752a2f72 Binary files /dev/null and b/icons/iconview-disabled.png differ diff --git a/icons/iconview.png b/icons/iconview.png new file mode 100644 index 000000000..9a81cf3eb Binary files /dev/null and b/icons/iconview.png differ diff --git a/icons/iconview.svg b/icons/iconview.svg new file mode 100644 index 000000000..127462da8 --- /dev/null +++ b/icons/iconview.svg @@ -0,0 +1,847 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + diff --git a/icons/imagesource.png b/icons/imagesource.png index 734a16657..794e91b69 100644 Binary files a/icons/imagesource.png and b/icons/imagesource.png differ diff --git a/icons/imagesource.svg b/icons/imagesource.svg new file mode 100644 index 000000000..70c8183a3 --- /dev/null +++ b/icons/imagesource.svg @@ -0,0 +1,11044 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + diff --git a/icons/magnet-disabled.png b/icons/magnet-disabled.png index 4f19588b2..0a2b0522e 100644 Binary files a/icons/magnet-disabled.png and b/icons/magnet-disabled.png differ diff --git a/icons/magnet.png b/icons/magnet.png index d5fbf13a3..d4760acea 100644 Binary files a/icons/magnet.png and b/icons/magnet.png differ diff --git a/icons/magnet.svg b/icons/magnet.svg new file mode 100644 index 000000000..d9cc47a3b --- /dev/null +++ b/icons/magnet.svg @@ -0,0 +1,11076 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/new-disabled.png b/icons/new-disabled.png new file mode 100644 index 000000000..1f2a976a3 Binary files /dev/null and b/icons/new-disabled.png differ diff --git a/icons/new.png b/icons/new.png new file mode 100644 index 000000000..ddb69f86f Binary files /dev/null and b/icons/new.png differ diff --git a/icons/new.svg b/icons/new.svg new file mode 100644 index 000000000..82429f30b --- /dev/null +++ b/icons/new.svg @@ -0,0 +1,11040 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/icons/next-disabled.png b/icons/next-disabled.png index 49e21fe20..1e4ad364d 100644 Binary files a/icons/next-disabled.png and b/icons/next-disabled.png differ diff --git a/icons/next.png b/icons/next.png index a36b72c7d..160542719 100644 Binary files a/icons/next.png and b/icons/next.png differ diff --git a/icons/next.svg b/icons/next.svg new file mode 100644 index 000000000..799097592 --- /dev/null +++ b/icons/next.svg @@ -0,0 +1,824 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/icons/open-disabled.png b/icons/open-disabled.png new file mode 100644 index 000000000..0319c825e Binary files /dev/null and b/icons/open-disabled.png differ diff --git a/icons/open.png b/icons/open.png new file mode 100644 index 000000000..e68a7ad8b Binary files /dev/null and b/icons/open.png differ diff --git a/icons/open.svg b/icons/open.svg new file mode 100644 index 000000000..765e28a68 --- /dev/null +++ b/icons/open.svg @@ -0,0 +1,11052 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + diff --git a/icons/pause-disabled.png b/icons/pause-disabled.png index 75046c8ef..1f2b0e3c0 100644 Binary files a/icons/pause-disabled.png and b/icons/pause-disabled.png differ diff --git a/icons/pause.png b/icons/pause.png index 2f5dd9725..b055c92e9 100644 Binary files a/icons/pause.png and b/icons/pause.png differ diff --git a/icons/pause.svg b/icons/pause.svg new file mode 100644 index 000000000..77cbdbaa6 --- /dev/null +++ b/icons/pause.svg @@ -0,0 +1,824 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/icons/play-disabled.png b/icons/play-disabled.png index c135ad1c9..04204e3eb 100644 Binary files a/icons/play-disabled.png and b/icons/play-disabled.png differ diff --git a/icons/play.png b/icons/play.png index 8e059c5d6..cd069a796 100644 Binary files a/icons/play.png and b/icons/play.png differ diff --git a/icons/play.svg b/icons/play.svg new file mode 100644 index 000000000..d5a89a53c --- /dev/null +++ b/icons/play.svg @@ -0,0 +1,818 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/icons/prev-disabled.png b/icons/prev-disabled.png index db5a44fe1..179e4e830 100644 Binary files a/icons/prev-disabled.png and b/icons/prev-disabled.png differ diff --git a/icons/prev.png b/icons/prev.png index 25518f45d..c56efc0cf 100644 Binary files a/icons/prev.png and b/icons/prev.png differ diff --git a/icons/prev.svg b/icons/prev.svg new file mode 100644 index 000000000..2f84badf0 --- /dev/null +++ b/icons/prev.svg @@ -0,0 +1,824 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/icons/razor-disabled.png b/icons/razor-disabled.png index 8e69b117d..9ac9298a3 100644 Binary files a/icons/razor-disabled.png and b/icons/razor-disabled.png differ diff --git a/icons/razor.png b/icons/razor.png index 3a53fa62d..7234af9e1 100644 Binary files a/icons/razor.png and b/icons/razor.png differ diff --git a/icons/razor.svg b/icons/razor.svg new file mode 100644 index 000000000..9fe5aa1b4 --- /dev/null +++ b/icons/razor.svg @@ -0,0 +1,821 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/icons/record-disabled.png b/icons/record-disabled.png index 9510d9c8c..fb76cd5cb 100644 Binary files a/icons/record-disabled.png and b/icons/record-disabled.png differ diff --git a/icons/record.png b/icons/record.png index 87e09bfd8..4ea654c0d 100644 Binary files a/icons/record.png and b/icons/record.png differ diff --git a/icons/record.svg b/icons/record.svg new file mode 100644 index 000000000..a69eb2141 --- /dev/null +++ b/icons/record.svg @@ -0,0 +1,818 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/icons/redo-disabled.png b/icons/redo-disabled.png new file mode 100644 index 000000000..4c33a0991 Binary files /dev/null and b/icons/redo-disabled.png differ diff --git a/icons/redo.png b/icons/redo.png new file mode 100644 index 000000000..5ca9146d2 Binary files /dev/null and b/icons/redo.png differ diff --git a/icons/redo.svg b/icons/redo.svg new file mode 100644 index 000000000..aa1ee9e75 --- /dev/null +++ b/icons/redo.svg @@ -0,0 +1,128 @@ + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/icons/rew-disabled.png b/icons/rew-disabled.png index 216e22fcf..0b07237e1 100644 Binary files a/icons/rew-disabled.png and b/icons/rew-disabled.png differ diff --git a/icons/rew.png b/icons/rew.png index ab84058f9..e8c065175 100644 Binary files a/icons/rew.png and b/icons/rew.png differ diff --git a/icons/rew.svg b/icons/rew.svg new file mode 100644 index 000000000..69ed415b5 --- /dev/null +++ b/icons/rew.svg @@ -0,0 +1,824 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/icons/ripple-disabled.png b/icons/ripple-disabled.png index 79cc89bb2..61a74950a 100644 Binary files a/icons/ripple-disabled.png and b/icons/ripple-disabled.png differ diff --git a/icons/ripple.png b/icons/ripple.png index 1a13de403..f41c08c58 100644 Binary files a/icons/ripple.png and b/icons/ripple.png differ diff --git a/icons/ripple.svg b/icons/ripple.svg new file mode 100644 index 000000000..c9969a42d --- /dev/null +++ b/icons/ripple.svg @@ -0,0 +1,11044 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + diff --git a/icons/rolling-disabled.png b/icons/rolling-disabled.png index cbcb24132..e720a2710 100644 Binary files a/icons/rolling-disabled.png and b/icons/rolling-disabled.png differ diff --git a/icons/rolling.png b/icons/rolling.png index ace97caad..ffc6f5109 100644 Binary files a/icons/rolling.png and b/icons/rolling.png differ diff --git a/icons/rolling.svg b/icons/rolling.svg new file mode 100644 index 000000000..ada28aa60 --- /dev/null +++ b/icons/rolling.svg @@ -0,0 +1,11055 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/save-disabled.png b/icons/save-disabled.png new file mode 100644 index 000000000..03983fb54 Binary files /dev/null and b/icons/save-disabled.png differ diff --git a/icons/save.png b/icons/save.png new file mode 100644 index 000000000..ab4b3f22a Binary files /dev/null and b/icons/save.png differ diff --git a/icons/save.svg b/icons/save.svg new file mode 100644 index 000000000..840663468 --- /dev/null +++ b/icons/save.svg @@ -0,0 +1,143 @@ + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + diff --git a/icons/sequence.png b/icons/sequence.png index b09483a06..6585a6762 100644 Binary files a/icons/sequence.png and b/icons/sequence.png differ diff --git a/icons/sequence.svg b/icons/sequence.svg new file mode 100644 index 000000000..49390f8fb --- /dev/null +++ b/icons/sequence.svg @@ -0,0 +1,11047 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + diff --git a/icons/slide-disabled.png b/icons/slide-disabled.png index 6bdb6f879..fd832fcb5 100644 Binary files a/icons/slide-disabled.png and b/icons/slide-disabled.png differ diff --git a/icons/slide.png b/icons/slide.png index 72c9fe376..2c5425ae7 100644 Binary files a/icons/slide.png and b/icons/slide.png differ diff --git a/icons/slide.svg b/icons/slide.svg new file mode 100644 index 000000000..1c03d11a5 --- /dev/null +++ b/icons/slide.svg @@ -0,0 +1,11051 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + diff --git a/icons/slip-disabled.png b/icons/slip-disabled.png index 57012f76f..d7d0169aa 100644 Binary files a/icons/slip-disabled.png and b/icons/slip-disabled.png differ diff --git a/icons/slip.png b/icons/slip.png index 32d0b81ba..044de026a 100644 Binary files a/icons/slip.png and b/icons/slip.png differ diff --git a/icons/slip.svg b/icons/slip.svg new file mode 100644 index 000000000..853534591 --- /dev/null +++ b/icons/slip.svg @@ -0,0 +1,11048 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + diff --git a/icons/transition-tool-disabled.png b/icons/transition-tool-disabled.png index e8313318c..a6e188b79 100644 Binary files a/icons/transition-tool-disabled.png and b/icons/transition-tool-disabled.png differ diff --git a/icons/transition-tool.png b/icons/transition-tool.png index c4d7bdcb5..81b6efe82 100644 Binary files a/icons/transition-tool.png and b/icons/transition-tool.png differ diff --git a/icons/transition-tool.svg b/icons/transition-tool.svg new file mode 100644 index 000000000..590aaee7a --- /dev/null +++ b/icons/transition-tool.svg @@ -0,0 +1,829 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + diff --git a/icons/treeview-disabled.png b/icons/treeview-disabled.png new file mode 100644 index 000000000..be95cb9f0 Binary files /dev/null and b/icons/treeview-disabled.png differ diff --git a/icons/treeview.png b/icons/treeview.png new file mode 100644 index 000000000..24e16bd2c Binary files /dev/null and b/icons/treeview.png differ diff --git a/icons/treeview.svg b/icons/treeview.svg new file mode 100644 index 000000000..bda0c0248 --- /dev/null +++ b/icons/treeview.svg @@ -0,0 +1,836 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + + + diff --git a/icons/tri-down.png b/icons/tri-down.png index e2b953eb4..d088299a6 100644 Binary files a/icons/tri-down.png and b/icons/tri-down.png differ diff --git a/icons/tri-down.svg b/icons/tri-down.svg new file mode 100644 index 000000000..a87e7229e --- /dev/null +++ b/icons/tri-down.svg @@ -0,0 +1,818 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/icons/tri-left.png b/icons/tri-left.png index 361eadb88..59a484229 100644 Binary files a/icons/tri-left.png and b/icons/tri-left.png differ diff --git a/icons/tri-left.svg b/icons/tri-left.svg new file mode 100644 index 000000000..0a13f9f5e --- /dev/null +++ b/icons/tri-left.svg @@ -0,0 +1,818 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/icons/tri-right.png b/icons/tri-right.png index a597a9d92..789a7cca3 100644 Binary files a/icons/tri-right.png and b/icons/tri-right.png differ diff --git a/icons/tri-right.svg b/icons/tri-right.svg new file mode 100644 index 000000000..8c1ac39c8 --- /dev/null +++ b/icons/tri-right.svg @@ -0,0 +1,818 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/icons/tri-up.png b/icons/tri-up.png index 8c7ff0feb..06de48079 100644 Binary files a/icons/tri-up.png and b/icons/tri-up.png differ diff --git a/icons/tri-up.svg b/icons/tri-up.svg new file mode 100644 index 000000000..da669c0c9 --- /dev/null +++ b/icons/tri-up.svg @@ -0,0 +1,818 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/icons/undo-disabled.png b/icons/undo-disabled.png new file mode 100644 index 000000000..8667795e2 Binary files /dev/null and b/icons/undo-disabled.png differ diff --git a/icons/undo.png b/icons/undo.png new file mode 100644 index 000000000..e043e73c7 Binary files /dev/null and b/icons/undo.png differ diff --git a/icons/undo.svg b/icons/undo.svg new file mode 100644 index 000000000..065384d5a --- /dev/null +++ b/icons/undo.svg @@ -0,0 +1,128 @@ + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/icons/videosource.png b/icons/videosource.png index 784f8c361..d96e9eee2 100644 Binary files a/icons/videosource.png and b/icons/videosource.png differ diff --git a/icons/videosource.svg b/icons/videosource.svg new file mode 100644 index 000000000..b5915de82 --- /dev/null +++ b/icons/videosource.svg @@ -0,0 +1,819 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + diff --git a/icons/zoomin-disabled.png b/icons/zoomin-disabled.png index ad008a3f5..203c82938 100644 Binary files a/icons/zoomin-disabled.png and b/icons/zoomin-disabled.png differ diff --git a/icons/zoomin.png b/icons/zoomin.png index cc49cdebf..f0a5f979c 100644 Binary files a/icons/zoomin.png and b/icons/zoomin.png differ diff --git a/icons/zoomin.svg b/icons/zoomin.svg new file mode 100644 index 000000000..475be8ff0 --- /dev/null +++ b/icons/zoomin.svg @@ -0,0 +1,822 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/icons/zoomout-disabled.png b/icons/zoomout-disabled.png index a2b254cda..fc2aebb70 100644 Binary files a/icons/zoomout-disabled.png and b/icons/zoomout-disabled.png differ diff --git a/icons/zoomout.png b/icons/zoomout.png index 60a07a488..ba1f1b3e6 100644 Binary files a/icons/zoomout.png and b/icons/zoomout.png differ diff --git a/icons/zoomout.svg b/icons/zoomout.svg new file mode 100644 index 000000000..c3f928aa1 --- /dev/null +++ b/icons/zoomout.svg @@ -0,0 +1,824 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Martin Ruskov + + + http://commons.wikimedia.org/wiki/Tango_icon + + + + + + + + + + + + + + + + + + diff --git a/io/avtogl.cpp b/io/avtogl.cpp index 895612c6b..3b2e39c4e 100644 --- a/io/avtogl.cpp +++ b/io/avtogl.cpp @@ -5,15 +5,15 @@ extern "C" { } enum QOpenGLTexture::PixelFormat get_gl_pix_fmt_from_av(int format) { - switch (format) { + /*switch (format) { case AV_PIX_FMT_RGB24: return QOpenGLTexture::RGB; - } + }*/ return QOpenGLTexture::RGBA; } enum QOpenGLTexture::TextureFormat get_gl_tex_fmt_from_av(int format) { - switch (format) { + /*switch (format) { case AV_PIX_FMT_RGB24: return QOpenGLTexture::RGB8_UNorm; - } + }*/ return QOpenGLTexture::RGBA8_UNorm; } diff --git a/io/config.h b/io/config.h index 9a6806216..6ab3078bc 100644 --- a/io/config.h +++ b/io/config.h @@ -3,7 +3,7 @@ #include -#define SAVE_VERSION 190104 // YYMMDD +#define SAVE_VERSION 190120 // YYMMDD #define MIN_SAVE_VERSION 190104 // lowest compatible project version #define TIMECODE_DROP 0 @@ -63,7 +63,7 @@ struct Config { bool seek_also_selects; QString css_path; int effect_textbox_lines; - bool use_software_fallback; + bool use_software_fallback; void load(QString path); void save(QString path); diff --git a/io/crossplatformlib.cpp b/io/crossplatformlib.cpp new file mode 100644 index 000000000..217635f2a --- /dev/null +++ b/io/crossplatformlib.cpp @@ -0,0 +1,23 @@ +#include "crossplatformlib.h" + +#include + +ModulePtr LibLoad(const QString &filename) { +#ifdef _WIN32 + LPCWSTR dll_fn_w = reinterpret_cast(filename.utf16()); + return LoadLibrary(dll_fn_w); +#elif defined(__linux__) || defined(__APPLE__) + 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__) + return {"*.so", "*.dylib"}; +#endif +} diff --git a/io/crossplatformlib.h b/io/crossplatformlib.h new file mode 100644 index 000000000..d186f554b --- /dev/null +++ b/io/crossplatformlib.h @@ -0,0 +1,21 @@ +#ifndef CROSSPLATFORMLIB_H +#define CROSSPLATFORMLIB_H + +#include + +#ifdef _WIN32 + #include + #define LibAddress GetProcAddress + #define LibClose FreeModule + #define ModulePtr HMODULE +#elif defined(__linux__) || defined(__APPLE__) + #include + #define LibAddress dlsym + #define LibClose dlclose + #define ModulePtr void* +#endif + +ModulePtr LibLoad(const QString& filename); +QStringList LibFilter(); + +#endif // CROSSPLATFORMLIB_H diff --git a/io/exportthread.cpp b/io/exportthread.cpp index 5e4f1a34e..f6b6dc134 100644 --- a/io/exportthread.cpp +++ b/io/exportthread.cpp @@ -489,5 +489,7 @@ void ExportThread::run() { } void ExportThread::wake() { + mutex.lock(); waitCond.wakeAll(); + mutex.unlock(); } diff --git a/io/loadthread.cpp b/io/loadthread.cpp index 64d87ff9a..2da9aaf27 100644 --- a/io/loadthread.cpp +++ b/io/loadthread.cpp @@ -18,7 +18,6 @@ #include "debug.h" #include -#include #include struct TransitionData { @@ -35,11 +34,21 @@ LoadThread::LoadThread(LoadDialog* l, bool a) : ld(l), autorecovery(a), cancelle connect(this, SIGNAL(error()), this, SLOT(error_func())); connect(this, SIGNAL(start_create_dual_transition(const TransitionData*,Clip*,Clip*,const EffectMeta*)), this, SLOT(create_dual_transition(const TransitionData*,Clip*,Clip*,const EffectMeta*))); connect(this, SIGNAL(start_create_effect_ui(QXmlStreamReader*, Clip*, int, const QString*, const EffectMeta*, long, bool)), this, SLOT(create_effect_ui(QXmlStreamReader*, Clip*, int, const QString*, const EffectMeta*, long, bool))); + connect(this, SIGNAL(start_question(const QString&, const QString &, int)), this, SLOT(question_func(const QString &, const QString &, int))); } -const EffectMeta* get_meta_from_name(const QString& name) { +const EffectMeta* get_meta_from_name(const QString& input) { + int split_index = input.indexOf('/'); + QString category; + if (split_index > -1) { + category = input.left(split_index); + } + QString name = input.mid(split_index + 1); + for (int j=0;j SAVE_VERSION) { - if (QMessageBox::warning( - mainWindow, - tr("Version Mismatch"), - tr("This project was saved in a different version of Olive and may not be fully compatible with this version. Would you like to attempt loading it anyway?"), - QMessageBox::Yes, - QMessageBox::No) == QMessageBox::No) { + if (proj_version < MIN_SAVE_VERSION || proj_version > SAVE_VERSION) { + emit start_question( + tr("Version Mismatch"), + tr("This project was saved in a different version of Olive and may not be fully compatible with this version. Would you like to attempt loading it anyway?"), + QMessageBox::Yes | QMessageBox::No + ); + waitCond.wait(&mutex); + if (question_btn == QMessageBox::No) { show_err = false; return false; } @@ -444,11 +454,14 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) { if (!found) { correct_clip->linked.removeAt(j); j--; - if (QMessageBox::warning(mainWindow, - tr("Invalid Clip Link"), - tr("This project contains an invalid clip link. It may be corrupt. Would you like to continue loading it?"), - QMessageBox::Yes, - QMessageBox::No) == QMessageBox::No) { + + emit start_question( + tr("Invalid Clip Link"), + tr("This project contains an invalid clip link. It may be corrupt. Would you like to continue loading it?"), + QMessageBox::Yes | QMessageBox::No + ); + waitCond.wait(&mutex); + if (question_btn == QMessageBox::No) { delete s; return false; } @@ -565,10 +578,14 @@ void LoadThread::run() { cont = !cancelled; // find project file version - cont = load_worker(file, stream, LOAD_TYPE_VERSION); + if (cont) { + cont = load_worker(file, stream, LOAD_TYPE_VERSION); + } // find project's internal URL - cont = load_worker(file, stream, LOAD_TYPE_URL); + if (cont) { + cont = load_worker(file, stream, LOAD_TYPE_URL); + } // load folders first if (cont) { @@ -605,7 +622,6 @@ void LoadThread::run() { xml_error = true; emit error(); cont = false; - } else { // attach nested sequence clips to their sequences for (int i=0;istart_preview_generator(loaded_media_items.at(i), true); } + } else { + error_str = tr("User aborted loading"); + emit error(); } file.close(); @@ -638,6 +657,15 @@ void LoadThread::cancel() { cancelled = true; } +void LoadThread::question_func(const QString &title, const QString &text, int buttons) { + question_btn = QMessageBox::warning( + mainWindow, + title, + text, + static_cast(buttons)); + waitCond.wakeAll(); +} + void LoadThread::error_func() { if (xml_error) { qCritical() << "Error parsing XML." << error_str; diff --git a/io/loadthread.h b/io/loadthread.h index f591fb966..3aba462ce 100644 --- a/io/loadthread.h +++ b/io/loadthread.h @@ -6,6 +6,7 @@ #include #include #include +#include class Media; struct Footage; @@ -23,12 +24,14 @@ public: void run(); void cancel(); signals: + void start_question(const QString &title, const QString &text, int buttons); void success(); void error(); void start_create_effect_ui(QXmlStreamReader* stream, Clip* c, int type, const QString *effect_name, const EffectMeta* meta, long effect_length, bool effect_enabled); void start_create_dual_transition(const TransitionData* td, Clip* primary, Clip* secondary, const EffectMeta* meta); void report_progress(int p); private slots: + void question_func(const QString &title, const QString &text, int buttons); void error_func(); void success_func(); void create_effect_ui(QXmlStreamReader* stream, Clip* c, int type, const QString *effect_name, const EffectMeta* meta, long effect_length, bool effect_enabled); @@ -67,6 +70,8 @@ private: bool cancelled; bool xml_error; + + QMessageBox::StandardButton question_btn; }; #endif // LOADTHREAD_H diff --git a/io/path.cpp b/io/path.cpp index 2d24812f0..79248904d 100644 --- a/io/path.cpp +++ b/io/path.cpp @@ -32,3 +32,12 @@ QString get_config_path() { return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); } } + +QList get_effects_paths() { + QList effects_paths; + effects_paths.append(get_app_dir() + "/effects"); + effects_paths.append(get_app_dir() + "/../share/olive-editor/effects"); + QString env_path(qgetenv("OLIVE_EFFECTS_PATH")); + if (!env_path.isEmpty()) effects_paths.append(env_path); + return effects_paths; +} diff --git a/io/path.h b/io/path.h index 9eff9033f..2e2f6d841 100644 --- a/io/path.h +++ b/io/path.h @@ -6,5 +6,6 @@ QString get_app_dir(); QString get_data_path(); QString get_config_path(); +QList get_effects_paths(); #endif // PATH_H diff --git a/io/previewgenerator.cpp b/io/previewgenerator.cpp index 621a6b3ff..50507896e 100644 --- a/io/previewgenerator.cpp +++ b/io/previewgenerator.cpp @@ -217,6 +217,10 @@ void PreviewGenerator::finalize_media() { } } +void thumb_data_cleanup(void *info) { + delete [] static_cast(info); +} + void PreviewGenerator::generate_waveform() { SwsContext* sws_ctx; SwrContext* swr_ctx; @@ -277,7 +281,7 @@ void PreviewGenerator::generate_waveform() { if (!s->preview_done) { int dstH = 120; int dstW = dstH * ((float)temp_frame->width/(float)temp_frame->height); - uint8_t* imgData = new uint8_t[dstW*dstH*4]; + uint8_t* data = new uint8_t[dstW*dstH*4]; sws_ctx = sws_getContext( temp_frame->width, @@ -294,9 +298,9 @@ void PreviewGenerator::generate_waveform() { int linesize[AV_NUM_DATA_POINTERS]; linesize[0] = dstW*4; - sws_scale(sws_ctx, temp_frame->data, temp_frame->linesize, 0, temp_frame->height, &imgData, linesize); + sws_scale(sws_ctx, temp_frame->data, temp_frame->linesize, 0, temp_frame->height, &data, linesize); - s->video_preview = QImage(imgData, dstW, dstH, linesize[0], QImage::Format_RGBA8888); + s->video_preview = QImage(data, dstW, dstH, linesize[0], QImage::Format_RGBA8888, thumb_data_cleanup); s->make_square_thumb(); // is video interlaced? @@ -311,8 +315,6 @@ void PreviewGenerator::generate_waveform() { avcodec_close(codec_ctx[packet->stream_index]); codec_ctx[packet->stream_index] = nullptr; } - - delete[] imgData; } media_lengths[packet->stream_index]++; } else if (fmt_ctx->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { @@ -403,6 +405,7 @@ void PreviewGenerator::generate_waveform() { for (unsigned int i=0;inb_streams;i++) { if (codec_ctx[i] != nullptr) { avcodec_close(codec_ctx[i]); + avcodec_free_context(&codec_ctx[i]); } } if (retrieve_duration) { @@ -417,10 +420,7 @@ void PreviewGenerator::generate_waveform() { finalize_media(); } delete [] media_lengths; - - if (codec_ctx != NULL) { - avcodec_free_context(codec_ctx); - } + delete [] codec_ctx; } QString PreviewGenerator::get_thumbnail_path(const QString& hash, const FootageStream& ms) { diff --git a/main.cpp b/main.cpp index 2b15e5bac..d11e9886d 100644 --- a/main.cpp +++ b/main.cpp @@ -20,9 +20,7 @@ int main(int argc, char *argv[]) { bool launch_fullscreen = false; QString load_proj; -#ifndef NODEBUG - qInstallMessageHandler(debug_message_handler); -#endif + bool use_internal_logger = true; if (argc > 1) { for (int i=1;i #include #include +#include #include "panels/panels.h" #include "project/effect.h" @@ -52,6 +53,7 @@ EffectControls::EffectControls(QWidget *parent) : lblMultipleClipsSelected->setVisible(false); + connect(keyframeView, SIGNAL(wheel_event_signal(QWheelEvent*)), effects_area, SLOT(receive_wheel_event(QWheelEvent*))); connect(horizontalScrollBar, SIGNAL(valueChanged(int)), headers, SLOT(set_scroll(int))); connect(horizontalScrollBar, SIGNAL(resize_move(double)), keyframeView, SLOT(resize_move(double))); connect(horizontalScrollBar, SIGNAL(valueChanged(int)), keyframeView, SLOT(set_x_scroll(int))); @@ -155,6 +157,8 @@ void EffectControls::show_effect_menu(int type, int subtype) { effects_loaded.lock(); QMenu effects_menu(this); + effects_menu.setToolTipsVisible(true); + for (int i=0;isetText(em.name); action->setData(reinterpret_cast(&em)); + if (!em.tooltip.isEmpty()) { + action->setToolTip(em.tooltip); + } QMenu* parent = &effects_menu; if (!em.category.isEmpty()) { @@ -178,6 +185,7 @@ void EffectControls::show_effect_menu(int type, int subtype) { } if (!found) { parent = new QMenu(&effects_menu); + parent->setToolTipsVisible(true); parent->setTitle(em.category); bool found = false; @@ -433,7 +441,17 @@ void EffectControls::setup_ui() { hlayout->addWidget(splitter); - setWidget(contents); + setWidget(contents); +} + +void EffectControls::update_scrollbar() { + verticalScrollBar->setMaximum(qMax(0, effects_area->height() - keyframeView->height() - headers->height())); + verticalScrollBar->setPageStep(verticalScrollBar->height()); +} + +void EffectControls::queue_post_update() { + keyframeView->update(); + update_scrollbar(); } void EffectControls::load_effects() { @@ -463,10 +481,10 @@ void EffectControls::load_effects() { } if (selected_clips.size() > 0) { setWindowTitle(panel_name + sequence->clips.at(selected_clips.at(0))->name); - verticalScrollBar->setMaximum(qMax(0, effects_area->sizeHint().height() - headers->height() + scrollArea->horizontalScrollBar()->height()/* - keyframeView->height() - headers->height()*/)); keyframeView->setEnabled(true); headers->setVisible(true); - keyframeView->update(); + + QTimer::singleShot(50, this, SLOT(queue_post_update())); } } } @@ -526,7 +544,7 @@ void EffectControls::audio_transition_click() { } void EffectControls::resizeEvent(QResizeEvent*) { - verticalScrollBar->setMaximum(qMax(0, effects_area->height() - keyframeView->height() - headers->height())); + update_scrollbar(); } bool EffectControls::is_focused() { @@ -550,8 +568,6 @@ EffectsArea::EffectsArea(QWidget* parent) : QWidget(parent) {} -void EffectsArea::resizeEvent(QResizeEvent*) { -// parent_widget->setMinimumWidth(sizeHint().width()); -// parent_widget->resize(sizeHint().width(), parent_widget->height()); -// parent_widget->updateGeometry(); +void EffectsArea::receive_wheel_event(QWheelEvent *e) { + QApplication::sendEvent(this, e); } diff --git a/panels/effectcontrols.h b/panels/effectcontrols.h index 67d88e819..cce0b2dda 100644 --- a/panels/effectcontrols.h +++ b/panels/effectcontrols.h @@ -19,12 +19,14 @@ class QScrollBar; class QHBoxLayout; class EffectsArea : public QWidget { + Q_OBJECT public: - EffectsArea(QWidget* parent = 0); - void resizeEvent(QResizeEvent *event); + EffectsArea(QWidget* parent = 0); QScrollArea* parent_widget; KeyframeView* keyframe_area; TimelineHeader* header; +public slots: + void receive_wheel_event(QWheelEvent* e); }; class EffectControls : public QDockWidget @@ -65,6 +67,9 @@ private slots: void audio_transition_click(); void deselect_all_effects(QWidget*); + + void update_scrollbar(); + void queue_post_update(); protected: void resizeEvent(QResizeEvent *event); private: diff --git a/panels/grapheditor.cpp b/panels/grapheditor.cpp index 4444bb302..7d13a905d 100644 --- a/panels/grapheditor.cpp +++ b/panels/grapheditor.cpp @@ -59,13 +59,13 @@ GraphEditor::GraphEditor(QWidget* parent) : QDockWidget(parent), row(nullptr) { left_tool_layout->addStretch(); linear_button = new QPushButton(tr("Linear")); - linear_button->setProperty("type", KEYFRAME_TYPE_LINEAR); + linear_button->setProperty("type", EFFECT_KEYFRAME_LINEAR); linear_button->setCheckable(true); bezier_button = new QPushButton(tr("Bezier")); - bezier_button->setProperty("type", KEYFRAME_TYPE_BEZIER); + bezier_button->setProperty("type", EFFECT_KEYFRAME_BEZIER); bezier_button->setCheckable(true); hold_button = new QPushButton(tr("Hold")); - hold_button->setProperty("type", KEYFRAME_TYPE_HOLD); + hold_button->setProperty("type", EFFECT_KEYFRAME_HOLD); hold_button->setCheckable(true); center_tool_layout->addStretch(); @@ -162,9 +162,8 @@ void GraphEditor::set_row(EffectRow *r) { slider_button->setCheckable(true); slider_button->setChecked(field->is_enabled()); slider_button->setIcon(QIcon(":/icons/record.png")); - slider_button->setProperty("field", i); - slider_button->setIconSize(QSize(8, 8)); - slider_button->setMaximumSize(QSize(12, 12)); + slider_button->setProperty("field", i); + slider_button->setIconSize(slider_button->iconSize()*0.5); connect(slider_button, SIGNAL(toggled(bool)), this, SLOT(set_field_visibility(bool))); slider_proxy_buttons.append(slider_button); value_layout->addWidget(slider_button); @@ -216,11 +215,11 @@ void GraphEditor::select_all() { void GraphEditor::set_key_button_enabled(bool e, int type) { linear_button->setEnabled(e); - linear_button->setChecked(type == KEYFRAME_TYPE_LINEAR); + linear_button->setChecked(type == EFFECT_KEYFRAME_LINEAR); bezier_button->setEnabled(e); - bezier_button->setChecked(type == KEYFRAME_TYPE_BEZIER); + bezier_button->setChecked(type == EFFECT_KEYFRAME_BEZIER); hold_button->setEnabled(e); - hold_button->setChecked(type == KEYFRAME_TYPE_HOLD); + hold_button->setChecked(type == EFFECT_KEYFRAME_HOLD); } void GraphEditor::passthrough_slider_value() { diff --git a/panels/panels.cpp b/panels/panels.cpp index ddd283679..bb51363b5 100644 --- a/panels/panels.cpp +++ b/panels/panels.cpp @@ -9,6 +9,7 @@ #include "project/transition.h" #include "io/config.h" #include "grapheditor.h" +#include "project/effectloaders.h" #include "debug.h" #include diff --git a/panels/project.cpp b/panels/project.cpp index de617adbd..fb6deffb8 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -83,41 +83,67 @@ Project::Project(QWidget *parent) : toolbar->setSpacing(0); toolbar_widget->setLayout(toolbar); - QPushButton* toolbar_new = new QPushButton("New"); - toolbar_new->setIcon(QIcon(":/icons/tri-down.png")); - toolbar_new->setIconSize(QSize(8, 8)); + QPushButton* toolbar_new = new QPushButton(toolbar_widget); + QIcon icon1; + icon1.addFile(QStringLiteral(":/icons/add-button.png"), QSize(), QIcon::Normal, QIcon::On); + icon1.addFile(QStringLiteral(":/icons/add-button-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolbar_new->setIcon(icon1); toolbar_new->setToolTip("New"); connect(toolbar_new, SIGNAL(clicked(bool)), this, SLOT(make_new_menu())); toolbar->addWidget(toolbar_new); - QPushButton* toolbar_open = new QPushButton("Open"); + QPushButton* toolbar_open = new QPushButton(toolbar_widget); + QIcon icon2; + icon2.addFile(QStringLiteral(":/icons/open.png"), QSize(), QIcon::Normal, QIcon::On); + 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())); toolbar->addWidget(toolbar_open); - QPushButton* toolbar_save = new QPushButton("Save"); + QPushButton* toolbar_save = new QPushButton(toolbar_widget); + QIcon icon3; + icon3.addFile(QStringLiteral(":/icons/save.png"), QSize(), QIcon::Normal, QIcon::On); + 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())); toolbar->addWidget(toolbar_save); - QPushButton* toolbar_undo = new QPushButton("Undo"); + QPushButton* toolbar_undo = new QPushButton(toolbar_widget); + QIcon icon4; + icon4.addFile(QStringLiteral(":/icons/undo.png"), QSize(), QIcon::Normal, QIcon::On); + 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())); toolbar->addWidget(toolbar_undo); - QPushButton* toolbar_redo = new QPushButton("Redo"); + QPushButton* toolbar_redo = new QPushButton(toolbar_widget); + QIcon icon5; + icon5.addFile(QStringLiteral(":/icons/redo.png"), QSize(), QIcon::Normal, QIcon::On); + 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())); toolbar->addWidget(toolbar_redo); toolbar->addStretch(); - QPushButton* toolbar_tree_view = new QPushButton("Tree View"); - toolbar_tree_view->setToolTip("Tree View"); - connect(toolbar_tree_view, SIGNAL(clicked(bool)), this, SLOT(set_tree_view())); - toolbar->addWidget(toolbar_tree_view); + QPushButton* toolbar_tree_view = new QPushButton(toolbar_widget); + QIcon icon6; + icon6.addFile(QStringLiteral(":/icons/treeview.png"), QSize(), QIcon::Normal, QIcon::On); + icon6.addFile(QStringLiteral(":/icons/treeview-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolbar_tree_view->setIcon(icon6); + toolbar_tree_view->setToolTip("Tree View"); + connect(toolbar_tree_view, SIGNAL(clicked(bool)), this, SLOT(set_tree_view())); + toolbar->addWidget(toolbar_tree_view); - QPushButton* toolbar_icon_view = new QPushButton("Icon View"); + QPushButton* toolbar_icon_view = new QPushButton(toolbar_widget); + QIcon icon7; + icon7.addFile(QStringLiteral(":/icons/iconview.png"), QSize(), QIcon::Normal, QIcon::On); + icon7.addFile(QStringLiteral(":/icons/iconview-disabled.png"), QSize(), QIcon::Disabled, QIcon::On); + toolbar_icon_view->setIcon(icon7); toolbar_icon_view->setToolTip("Icon View"); connect(toolbar_icon_view, SIGNAL(clicked(bool)), this, SLOT(set_icon_view())); toolbar->addWidget(toolbar_icon_view); diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 6216ed0bb..939bc649c 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -778,6 +778,7 @@ bool selection_contains_transition(const Selection& s, Clip* c, int type) { void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& areas) { clean_up_selections(areas); + panel_effect_controls->clear_effects(true); QVector pre_clips; QVector post_clips; @@ -829,6 +830,7 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& area } } } + deselect_area(s.in, s.out, s.track); } relink_clips_using_ids(pre_clips, post_clips); ca->append(new AddClipCommand(sequence, post_clips)); @@ -1758,6 +1760,7 @@ void Timeline::setup_ui() { editAreaLayout->setSpacing(0); editAreaLayout->setContentsMargins(0, 0, 0, 0); QSplitter* splitter = new QSplitter(editAreas); + splitter->setChildrenCollapsible(false); splitter->setOrientation(Qt::Vertical); QWidget* videoContainer = new QWidget(splitter); QHBoxLayout* videoContainerLayout = new QHBoxLayout(videoContainer); diff --git a/panels/viewer.cpp b/panels/viewer.cpp index 3f212c691..c296be36e 100644 --- a/panels/viewer.cpp +++ b/panels/viewer.cpp @@ -560,8 +560,7 @@ void Viewer::setup_ui() { QHBoxLayout* current_timecode_container_layout = new QHBoxLayout(current_timecode_container); current_timecode_container_layout->setSpacing(0); current_timecode_container_layout->setMargin(0); - current_timecode_slider = new LabelSlider(current_timecode_container); - current_timecode_container_layout->addWidget(current_timecode_slider); + current_timecode_slider = new LabelSlider(current_timecode_container); lower_control_layout->addWidget(current_timecode_container); QWidget* playback_controls = new QWidget(lower_controls); @@ -616,7 +615,6 @@ void Viewer::setup_ui() { QHBoxLayout* end_timecode_layout = new QHBoxLayout(end_timecode_container); end_timecode_layout->setSpacing(0); end_timecode_layout->setMargin(0); - end_timecode = new QLabel(end_timecode_container); end_timecode->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); diff --git a/playback/audio.cpp b/playback/audio.cpp index 19e2f656f..87be6a646 100644 --- a/playback/audio.cpp +++ b/playback/audio.cpp @@ -33,7 +33,7 @@ bool audio_rendering = false; bool recording = false; qint8 audio_ibuffer[audio_ibuffer_size]; -int audio_ibuffer_read = 0; +unsigned long audio_ibuffer_read = 0; long audio_ibuffer_frame = 0; double audio_ibuffer_timecode = 0; @@ -114,9 +114,9 @@ int current_audio_freq() { return audio_rendering ? sequence->audio_frequency : audio_output->format().sampleRate(); } -int get_buffer_offset_from_frame(double framerate, long frame) { +unsigned long get_buffer_offset_from_frame(double framerate, long frame) { if (frame >= audio_ibuffer_frame) { - return qFloor(((double) (frame - audio_ibuffer_frame)/framerate)*current_audio_freq())*av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)*av_get_channel_layout_nb_channels(AV_CH_LAYOUT_STEREO); + return static_cast(((double(frame - audio_ibuffer_frame)/framerate)*current_audio_freq())*av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)*av_get_channel_layout_nb_channels(AV_CH_LAYOUT_STEREO)); } else { qWarning() << "Invalid values passed to get_buffer_offset_from_frame"; return 0; @@ -166,9 +166,9 @@ void AudioSenderThread::run() { int AudioSenderThread::send_audio_to_output(int offset, int max) { // send audio to device - int actual_write = audio_io_device->write((const char*) audio_ibuffer+offset, max); + unsigned long actual_write = audio_io_device->write((const char*) audio_ibuffer+offset, max); - int audio_ibuffer_limit = audio_ibuffer_read + actual_write; + unsigned long audio_ibuffer_limit = audio_ibuffer_read + actual_write; // send samples to audio monitor cache // TODO make this work for the footage viewer - currently, enabling it causes crash due to an ASSERT @@ -185,19 +185,20 @@ int AudioSenderThread::send_audio_to_output(int offset, int max) { } int channel_count = av_get_channel_layout_nb_channels(s->audio_layout); long sample_cache_playhead = panel_timeline->audio_monitor->sample_cache_offset + (panel_timeline->audio_monitor->sample_cache.size()/channel_count); - int next_buffer_offset, buffer_offset_adjusted, i; - int buffer_offset = get_buffer_offset_from_frame(s->frame_rate, sample_cache_playhead); + unsigned long next_buffer_offset, buffer_offset_adjusted; + int i; + unsigned long buffer_offset = get_buffer_offset_from_frame(s->frame_rate, sample_cache_playhead); if (samples.size() != channel_count) samples.resize(channel_count); samples.fill(0); // TODO: I don't like this, but i'm not sure if there's a smarter way to do it - while (buffer_offset < audio_ibuffer_limit) { + while (static_cast(buffer_offset) < audio_ibuffer_limit) { sample_cache_playhead++; - next_buffer_offset = qMin(get_buffer_offset_from_frame(s->frame_rate, sample_cache_playhead), audio_ibuffer_limit); + next_buffer_offset = qMin(get_buffer_offset_from_frame(s->frame_rate, sample_cache_playhead), static_cast(audio_ibuffer_limit)); while (buffer_offset < next_buffer_offset) { for (i=0;i& nests) { if (frame->nb_samples == 0) { break; } else { - long buffer_timeline_out = get_buffer_offset_from_frame(c->sequence->frame_rate, timeline_out); + unsigned long buffer_timeline_out = get_buffer_offset_from_frame(c->sequence->frame_rate, timeline_out); + audio_write_lock.lock(); while (c->frame_sample_index < nb_bytes @@ -767,7 +768,7 @@ void open_clip_worker(Clip* clip) { }*/ enum AVPixelFormat valid_pix_fmts[] = { - AV_PIX_FMT_RGB24, +// AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_NONE }; diff --git a/playback/playback.cpp b/playback/playback.cpp index 4e16d8d54..4495023e3 100644 --- a/playback/playback.cpp +++ b/playback/playback.cpp @@ -255,26 +255,35 @@ void get_clip_frame(Clip* c, long playhead, bool& texture_failed) { int nb_components = av_pix_fmt_desc_get(static_cast(c->pix_fmt))->nb_components; glPixelStorei(GL_UNPACK_ROW_LENGTH, target_frame->linesize[0]/nb_components); - bool copied = false; - uint8_t* data = target_frame->data[0]; + // 2 data buffers to ping-pong between + bool using_db_1 = true; + uint8_t* data_buffer_1 = target_frame->data[0]; + uint8_t* data_buffer_2 = nullptr; + int frame_size; for (int i=0;ieffects.size();i++) { Effect* e = c->effects.at(i); - if (e->enable_image) { - if (!copied) { + if (e->enable_image && e->is_enabled()) { + if (data_buffer_1 == target_frame->data[0]) { frame_size = target_frame->linesize[0]*target_frame->height; - data = new uint8_t[frame_size]; - memcpy(data, target_frame->data[0], frame_size); - copied = true; + + data_buffer_1 = new uint8_t[frame_size]; + data_buffer_2 = new uint8_t[frame_size]; + + memcpy(data_buffer_1, target_frame->data[0], frame_size); } - e->process_image(get_timecode(c, playhead), data, frame_size); + e->process_image(get_timecode(c, playhead), using_db_1 ? data_buffer_1 : data_buffer_2, using_db_1 ? data_buffer_2 : data_buffer_1, frame_size); + using_db_1 = !using_db_1; } } - c->texture->setData(0, get_gl_pix_fmt_from_av(c->pix_fmt), QOpenGLTexture::UInt8, data); + c->texture->setData(0, get_gl_pix_fmt_from_av(c->pix_fmt), QOpenGLTexture::UInt8, using_db_1 ? data_buffer_1 : data_buffer_2); - if (copied) delete [] data; + if (data_buffer_1 != target_frame->data[0]) { + delete [] data_buffer_1; + delete [] data_buffer_2; + } glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } diff --git a/project/clip.h b/project/clip.h index 69e757d5f..99e896472 100644 --- a/project/clip.h +++ b/project/clip.h @@ -33,17 +33,17 @@ class QOpenGLTexture; struct Clip { - Clip(Sequence* s); + Clip(Sequence* s); ~Clip(); - Clip* copy(Sequence* s); - void reset_audio(); + Clip* copy(Sequence* s); + void reset_audio(); void reset(); void refresh(); - long get_clip_in_with_transition(); + long get_clip_in_with_transition(); long get_timeline_in_with_transition(); long get_timeline_out_with_transition(); long getLength(); - double getMediaFrameRate(); + double getMediaFrameRate(); long getMaximumLength(); void recalculateMaxLength(); int getWidth(); @@ -56,39 +56,39 @@ struct Clip void queue_remove_earliest(); // timeline variables (should be copied in copy()) - bool enabled; - long clip_in; - long timeline_in; - long timeline_out; - int track; + bool enabled; + long clip_in; + long timeline_in; + long timeline_out; + int track; QString name; - quint8 color_r; - quint8 color_g; - quint8 color_b; - Media* media; - int media_stream; + quint8 color_r; + quint8 color_g; + quint8 color_b; + Media* media; + int media_stream; double speed; - double cached_fr; + double cached_fr; bool reverse; bool maintain_audio_pitch; bool autoscale; // other variables (should be deep copied/duplicated in copy()) - QList effects; - QVector linked; - int opening_transition; - Transition* get_opening_transition(); - int closing_transition; - Transition* get_closing_transition(); + QList effects; + QVector linked; + int opening_transition; + Transition* get_opening_transition(); + int closing_transition; + Transition* get_closing_transition(); // media handling - AVFormatContext* formatCtx; - AVStream* stream; - AVCodec* codec; - AVCodecContext* codecCtx; - AVPacket* pkt; + AVFormatContext* formatCtx; + AVStream* stream; + AVCodec* codec; + AVCodecContext* codecCtx; + AVPacket* pkt; AVFrame* frame; - AVDictionary* opts; + AVDictionary* opts; long calculated_length; // temporary variables @@ -96,23 +96,23 @@ struct Clip bool undeletable; bool reached_end; bool pkt_written; - bool open; - bool finished_opening; - bool replaced; + bool open; + bool finished_opening; + bool replaced; bool ignore_reverse; int pix_fmt; // caching functions bool use_existing_frame; - bool multithreaded; + bool multithreaded; Cacher* cacher; - QWaitCondition can_cache; + QWaitCondition can_cache; int max_queue_size; QVector queue; QMutex queue_lock; - QMutex lock; + QMutex lock; QMutex open_lock; - int64_t last_invalid_ts; + int64_t last_invalid_ts; // converters/filters AVFilterGraph* filter_graph; @@ -121,15 +121,15 @@ struct Clip // video playback variables QOpenGLFramebufferObject** fbo; - QOpenGLTexture* texture; + QOpenGLTexture* texture; long texture_frame; // audio playback variables int64_t reverse_target; - int frame_sample_index; - int audio_buffer_write; - bool audio_reset; - bool audio_just_reset; + int frame_sample_index; + unsigned long audio_buffer_write; + bool audio_reset; + bool audio_just_reset; long audio_target_frame; }; diff --git a/project/effect.cpp b/project/effect.cpp index 8812364a3..ddf2748ad 100644 --- a/project/effect.cpp +++ b/project/effect.cpp @@ -29,9 +29,10 @@ #include "effects/internal/shakeeffect.h" #include "effects/internal/cornerpineffect.h" #ifdef _WIN32 -#include "effects/internal/vsthostwin.h" +#include "effects/internal/vsthost.h" #endif #include "effects/internal/fillleftrighteffect.h" +#include "effects/internal/frei0reffect.h" #include #include @@ -49,10 +50,7 @@ bool shaders_are_enabled = true; QVector effects; Effect* create_effect(Clip* c, const EffectMeta* em) { - if (!em->filename.isEmpty()) { - // load effect from file - return new Effect(c, em); - } else if (em->internal >= 0 && em->internal < EFFECT_INTERNAL_COUNT) { + if (em->internal >= 0 && em->internal < EFFECT_INTERNAL_COUNT) { // must be an internal effect switch (em->internal) { case EFFECT_INTERNAL_TRANSFORM: return new TransformEffect(c, em); @@ -67,9 +65,15 @@ Effect* create_effect(Clip* c, const EffectMeta* em) { case EFFECT_INTERNAL_CORNERPIN: return new CornerPinEffect(c, em); case EFFECT_INTERNAL_FILLLEFTRIGHT: return new FillLeftRightEffect(c, em); #ifdef _WIN32 - case EFFECT_INTERNAL_VST: return new VSTHostWin(c, em); + case EFFECT_INTERNAL_VST: return new VSTHost(c, em); +#endif +#ifndef NOFREI0R + case EFFECT_INTERNAL_FREI0R: return new Frei0rEffect(c, em); #endif } + } else if (!em->filename.isEmpty()) { + // load effect from file + return new Effect(c, em); } else { qCritical() << "Invalid effect data"; QMessageBox::critical(mainWindow, @@ -88,180 +92,6 @@ const EffectMeta* get_internal_meta(int internal_id, int type) { return nullptr; } -void load_internal_effects() { - if (!shaders_are_enabled) qWarning() << "Shaders are disabled, some effects may be nonfunctional"; - - EffectMeta em; - - // internal effects - em.type = EFFECT_TYPE_EFFECT; - em.subtype = EFFECT_TYPE_AUDIO; - - em.name = "Volume"; - em.internal = EFFECT_INTERNAL_VOLUME; - effects.append(em); - - em.name = "Pan"; - em.internal = EFFECT_INTERNAL_PAN; - effects.append(em); - -#ifdef _WIN32 - em.name = "VST Plugin 2.x"; - em.internal = EFFECT_INTERNAL_VST; - effects.append(em); -#endif - - em.name = "Tone"; - em.internal = EFFECT_INTERNAL_TONE; - effects.append(em); - - em.name = "Noise"; - em.internal = EFFECT_INTERNAL_NOISE; - effects.append(em); - - em.name = "Fill Left/Right"; - em.internal = EFFECT_INTERNAL_FILLLEFTRIGHT; - effects.append(em); - - em.subtype = EFFECT_TYPE_VIDEO; - - em.name = "Transform"; - em.category = "Distort"; - em.internal = EFFECT_INTERNAL_TRANSFORM; - effects.append(em); - - em.name = "Corner Pin"; - em.internal = EFFECT_INTERNAL_CORNERPIN; - effects.append(em); - - /*em.name = "Mask"; - em.internal = EFFECT_INTERNAL_MASK; - effects.append(em);*/ - - em.name = "Shake"; - em.internal = EFFECT_INTERNAL_SHAKE; - effects.append(em); - - em.name = "Text"; - em.category = "Render"; - em.internal = EFFECT_INTERNAL_TEXT; - effects.append(em); - - em.name = "Timecode"; - em.internal = EFFECT_INTERNAL_TIMECODE; - effects.append(em); - - em.name = "Solid"; - em.internal = EFFECT_INTERNAL_SOLID; - effects.append(em); - - // internal transitions - em.type = EFFECT_TYPE_TRANSITION; - em.category = ""; - - em.name = "Cross Dissolve"; - em.internal = TRANSITION_INTERNAL_CROSSDISSOLVE; - effects.append(em); - - em.subtype = EFFECT_TYPE_AUDIO; - - em.name = "Linear Fade"; - em.internal = TRANSITION_INTERNAL_LINEARFADE; - effects.append(em); - - em.name = "Exponential Fade"; - em.internal = TRANSITION_INTERNAL_EXPONENTIALFADE; - effects.append(em); - - em.name = "Logarithmic Fade"; - em.internal = TRANSITION_INTERNAL_LOGARITHMICFADE; - effects.append(em); -} - -QList get_effects_paths() { - QList effects_paths; - effects_paths.append(get_app_dir() + "/effects"); - effects_paths.append(get_app_dir() + "/../share/olive-editor/effects"); - QString env_path(qgetenv("OLIVE_EFFECTS_PATH")); - if (!env_path.isEmpty()) effects_paths.append(env_path); - return effects_paths; -} - -void load_shader_effects() { - QList effects_paths = get_effects_paths(); - - for (int h=0;h entries = effects_dir.entryList(QStringList("*.xml"), QDir::Files); - for (int i=0;istart(); -} - -EffectInit::EffectInit() { - panel_effect_controls->effects_loaded.lock(); -} - -void EffectInit::run() { - qInfo() << "Initializing effects..."; - load_internal_effects(); - load_shader_effects(); - load_vst_effects(); - panel_effect_controls->effects_loaded.unlock(); - qInfo() << "Finished initializing effects"; -} - Effect::Effect(Clip* c, const EffectMeta *em) : parent_clip(c), meta(em), @@ -290,7 +120,7 @@ Effect::Effect(Clip* c, const EffectMeta *em) : // set up UI from effect file container->setText(em->name); - if (!em->filename.isEmpty()) { + if (!em->filename.isEmpty() && em->internal == -1) { QFile effect_file(em->filename); if (effect_file.open(QFile::ReadOnly)) { QXmlStreamReader reader(&effect_file); @@ -530,7 +360,7 @@ EffectGizmo *Effect::gizmo(int i) { return gizmos.at(i); } -int Effect::gizmo_count(){ +int Effect::gizmo_count() { return gizmos.size(); } @@ -735,7 +565,7 @@ void Effect::load(QXmlStreamReader& stream) { void Effect::custom_load(QXmlStreamReader &) {} void Effect::save(QXmlStreamWriter& stream) { - stream.writeAttribute("name", meta->name); + stream.writeAttribute("name", meta->category + "/" + meta->name); stream.writeAttribute("enabled", QString::number(is_enabled())); for (int i=0;irelease(); - bound = false; + bound = false; } -void Effect::process_image(double, uint8_t *, int) {} +void Effect::process_image(double, uint8_t *, uint8_t *, int){} Effect* Effect::copy(Clip* c) { Effect* copy = create_effect(c, meta); diff --git a/project/effect.h b/project/effect.h index 330426b2c..6779501c4 100644 --- a/project/effect.h +++ b/project/effect.h @@ -1,4 +1,4 @@ -#ifndef EFFECT_H +#ifndef EFFECT_H #define EFFECT_H #include @@ -29,6 +29,7 @@ struct EffectMeta { QString category; QString filename; QString path; + QString tooltip; int internal; int type; int subtype; @@ -38,38 +39,40 @@ extern bool shaders_are_enabled; extern QVector effects; double log_volume(double linear); -void init_effects(); Effect* create_effect(Clip* c, const EffectMeta *em); const EffectMeta* get_internal_meta(int internal_id, int type); -#define EFFECT_TYPE_INVALID 0 -#define EFFECT_TYPE_VIDEO 1 -#define EFFECT_TYPE_AUDIO 2 -#define EFFECT_TYPE_EFFECT 3 -#define EFFECT_TYPE_TRANSITION 4 +enum EffectType { + EFFECT_TYPE_INVALID, + EFFECT_TYPE_VIDEO, + EFFECT_TYPE_AUDIO, + EFFECT_TYPE_EFFECT, + EFFECT_TYPE_TRANSITION +}; -#define EFFECT_KEYFRAME_LINEAR 0 -#define EFFECT_KEYFRAME_HOLD 1 -#define EFFECT_KEYFRAME_BEZIER 2 +enum EffectKeyframeType { + EFFECT_KEYFRAME_LINEAR, + EFFECT_KEYFRAME_BEZIER, + EFFECT_KEYFRAME_HOLD +}; -#define EFFECT_INTERNAL_TRANSFORM 0 -#define EFFECT_INTERNAL_TEXT 1 -#define EFFECT_INTERNAL_SOLID 2 -#define EFFECT_INTERNAL_NOISE 3 -#define EFFECT_INTERNAL_VOLUME 4 -#define EFFECT_INTERNAL_PAN 5 -#define EFFECT_INTERNAL_TONE 6 -#define EFFECT_INTERNAL_SHAKE 7 -#define EFFECT_INTERNAL_TIMECODE 8 -#define EFFECT_INTERNAL_MASK 9 -#define EFFECT_INTERNAL_FILLLEFTRIGHT 10 -#define EFFECT_INTERNAL_VST 11 -#define EFFECT_INTERNAL_CORNERPIN 12 -#define EFFECT_INTERNAL_COUNT 13 - -#define KEYFRAME_TYPE_LINEAR 0 -#define KEYFRAME_TYPE_BEZIER 1 -#define KEYFRAME_TYPE_HOLD 2 +enum EffectInternal { + EFFECT_INTERNAL_TRANSFORM, + EFFECT_INTERNAL_TEXT, + EFFECT_INTERNAL_SOLID, + EFFECT_INTERNAL_NOISE, + EFFECT_INTERNAL_VOLUME, + EFFECT_INTERNAL_PAN, + EFFECT_INTERNAL_TONE, + EFFECT_INTERNAL_SHAKE, + EFFECT_INTERNAL_TIMECODE, + EFFECT_INTERNAL_MASK, + EFFECT_INTERNAL_FILLLEFTRIGHT, + EFFECT_INTERNAL_VST, + EFFECT_INTERNAL_CORNERPIN, + EFFECT_INTERNAL_FREI0R, + EFFECT_INTERNAL_COUNT +}; struct GLTextureCoords { int grid_size; @@ -156,7 +159,7 @@ public: const char* ffmpeg_filter; - virtual void process_image(double timecode, uint8_t* data, int size); + virtual void process_image(double timecode, uint8_t* input, uint8_t* output, int size); virtual void process_shader(double timecode, GLTextureCoords&); virtual void process_coords(double timecode, GLTextureCoords& coords, int data); virtual GLuint process_superimpose(double timecode); diff --git a/project/effectfield.cpp b/project/effectfield.cpp index c0b15c04a..942e4ede2 100644 --- a/project/effectfield.cpp +++ b/project/effectfield.cpp @@ -86,53 +86,53 @@ EffectField::EffectField(EffectRow *parent, int t, const QString &i) : connect(efc, SIGNAL(changed()), this, SLOT(ui_element_change())); } break; - } + } } double EffectField::get_validated_keyframe_handle(int key, bool post) { - int comp_key = -1; + int comp_key = -1; - // find keyframe before or after this one - for (int i=0;i keyframes.at(key).time) == post) - && (comp_key == -1 - || ((keyframes.at(i).time < keyframes.at(comp_key).time) == post))) { - // compare with next keyframe for post or previous frame for pre - comp_key = i; - } - } + // find keyframe before or after this one + for (int i=0;i keyframes.at(key).time) == post) + && (comp_key == -1 + || ((keyframes.at(i).time < keyframes.at(comp_key).time) == post))) { + // compare with next keyframe for post or previous frame for pre + comp_key = i; + } + } - double adjusted_key = post ? keyframes.at(key).post_handle_x : keyframes.at(key).pre_handle_x; + double adjusted_key = post ? keyframes.at(key).post_handle_x : keyframes.at(key).pre_handle_x; - // if this is the earliest/latest keyframe, no validation is required - if (comp_key == -1) { - return adjusted_key; - } + // if this is the earliest/latest keyframe, no validation is required + if (comp_key == -1) { + return adjusted_key; + } - double comp = keyframes.at(comp_key).time - keyframes.at(key).time; + double comp = keyframes.at(comp_key).time - keyframes.at(key).time; - // if comp keyframe is bezier, validate with its accompanying handle - if (keyframes.at(comp_key).type == KEYFRAME_TYPE_BEZIER) { - double relative_comp_handle = comp + (post ? keyframes.at(comp_key).pre_handle_x : keyframes.at(comp_key).post_handle_x); - // return an average - if ((post && keyframes.at(key).post_handle_x > relative_comp_handle) - || (!post && keyframes.at(key).pre_handle_x < relative_comp_handle)) { - adjusted_key = (adjusted_key + relative_comp_handle)*0.5; - } - } + // if comp keyframe is bezier, validate with its accompanying handle + if (keyframes.at(comp_key).type == EFFECT_KEYFRAME_BEZIER) { + double relative_comp_handle = comp + (post ? keyframes.at(comp_key).pre_handle_x : keyframes.at(comp_key).post_handle_x); + // return an average + if ((post && keyframes.at(key).post_handle_x > relative_comp_handle) + || (!post && keyframes.at(key).pre_handle_x < relative_comp_handle)) { + adjusted_key = (adjusted_key + relative_comp_handle)*0.5; + } + } - // don't let handle go beyond the compare keyframe's time - if (post == (adjusted_key > comp)) { - return comp; - } + // don't let handle go beyond the compare keyframe's time + if (post == (adjusted_key > comp)) { + return comp; + } - if (post == (adjusted_key < 0)) { - return 0; - } + if (post == (adjusted_key < 0)) { + return 0; + } - // original value is valid - return adjusted_key; + // original value is valid + return adjusted_key; } QVariant EffectField::get_previous_data() { @@ -162,7 +162,7 @@ QVariant EffectField::get_current_data() { } double EffectField::frameToTimecode(long frame) { - return ((double) frame / parent_row->parent_effect->parent_clip->sequence->frame_rate); + return (double(frame) / parent_row->parent_effect->parent_clip->sequence->frame_rate); } long EffectField::timecodeToFrame(double timecode) { @@ -242,22 +242,22 @@ QVariant EffectField::validate_keyframe_data(double timecode, bool async) { double before_dbl = before_key.data.toDouble(); double after_dbl = after_key.data.toDouble(); - if (before_key.type == KEYFRAME_TYPE_HOLD) { + if (before_key.type == EFFECT_KEYFRAME_HOLD) { // hold value = before_dbl; - } else if (before_key.type == KEYFRAME_TYPE_BEZIER || after_key.type == KEYFRAME_TYPE_BEZIER) { + } else if (before_key.type == EFFECT_KEYFRAME_BEZIER || after_key.type == EFFECT_KEYFRAME_BEZIER) { // bezier interpolation - if (before_key.type == KEYFRAME_TYPE_BEZIER && after_key.type == KEYFRAME_TYPE_BEZIER) { + if (before_key.type == EFFECT_KEYFRAME_BEZIER && after_key.type == EFFECT_KEYFRAME_BEZIER) { // cubic bezier - double t = cubic_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, before_key.time+get_validated_keyframe_handle(before_keyframe, true), after_key.time+get_validated_keyframe_handle(after_keyframe, false), after_key.time); + double t = cubic_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, before_key.time+get_validated_keyframe_handle(before_keyframe, true), after_key.time+get_validated_keyframe_handle(after_keyframe, false), after_key.time); value = cubic_from_t(before_dbl, before_dbl+before_key.post_handle_y, after_dbl+after_key.pre_handle_y, after_dbl, t); - } else if (after_key.type == KEYFRAME_TYPE_LINEAR) { // quadratic bezier + } else if (after_key.type == EFFECT_KEYFRAME_LINEAR) { // quadratic bezier // last keyframe is the bezier one - double t = quad_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, before_key.time+get_validated_keyframe_handle(before_keyframe, true), after_key.time); + double t = quad_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, before_key.time+get_validated_keyframe_handle(before_keyframe, true), after_key.time); value = quad_from_t(before_dbl, before_dbl+before_key.post_handle_y, after_dbl, t); } else { // this keyframe is the bezier one - double t = quad_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, after_key.time+get_validated_keyframe_handle(after_keyframe, false), after_key.time); + double t = quad_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, after_key.time+get_validated_keyframe_handle(after_keyframe, false), after_key.time); value = quad_from_t(before_dbl, after_dbl+after_key.pre_handle_y, after_dbl, t); } } else { diff --git a/project/effectloaders.cpp b/project/effectloaders.cpp new file mode 100644 index 000000000..b434eda86 --- /dev/null +++ b/project/effectloaders.cpp @@ -0,0 +1,245 @@ +#include "effectloaders.h" + +#include "project/effect.h" +#include "project/transition.h" +#include "io/path.h" +#include "panels/panels.h" +#include "panels/effectcontrols.h" +#include "io/crossplatformlib.h" + +#include +#include + +#include + +#ifndef NOFREI0R +#include +typedef void (*f0rGetPluginInfo)(f0r_plugin_info_t* info); +#endif + +void load_internal_effects() { + if (!shaders_are_enabled) qWarning() << "Shaders are disabled, some effects may be nonfunctional"; + + EffectMeta em; + + // internal effects + em.type = EFFECT_TYPE_EFFECT; + em.subtype = EFFECT_TYPE_AUDIO; + + em.name = "Volume"; + em.internal = EFFECT_INTERNAL_VOLUME; + effects.append(em); + + em.name = "Pan"; + em.internal = EFFECT_INTERNAL_PAN; + effects.append(em); + +#ifdef _WIN32 + em.name = "VST Plugin 2.x"; + em.internal = EFFECT_INTERNAL_VST; + effects.append(em); +#endif + + em.name = "Tone"; + em.internal = EFFECT_INTERNAL_TONE; + effects.append(em); + + em.name = "Noise"; + em.internal = EFFECT_INTERNAL_NOISE; + effects.append(em); + + em.name = "Fill Left/Right"; + em.internal = EFFECT_INTERNAL_FILLLEFTRIGHT; + effects.append(em); + + em.subtype = EFFECT_TYPE_VIDEO; + + em.name = "Transform"; + em.category = "Distort"; + em.internal = EFFECT_INTERNAL_TRANSFORM; + effects.append(em); + + em.name = "Corner Pin"; + em.internal = EFFECT_INTERNAL_CORNERPIN; + effects.append(em); + + /*em.name = "Mask"; + em.internal = EFFECT_INTERNAL_MASK; + effects.append(em);*/ + + em.name = "Shake"; + em.internal = EFFECT_INTERNAL_SHAKE; + effects.append(em); + + em.name = "Text"; + em.category = "Render"; + em.internal = EFFECT_INTERNAL_TEXT; + effects.append(em); + + em.name = "Timecode"; + em.internal = EFFECT_INTERNAL_TIMECODE; + effects.append(em); + + em.name = "Solid"; + em.internal = EFFECT_INTERNAL_SOLID; + effects.append(em); + + // internal transitions + em.type = EFFECT_TYPE_TRANSITION; + em.category = ""; + + em.name = "Cross Dissolve"; + em.internal = TRANSITION_INTERNAL_CROSSDISSOLVE; + effects.append(em); + + em.subtype = EFFECT_TYPE_AUDIO; + + em.name = "Linear Fade"; + em.internal = TRANSITION_INTERNAL_LINEARFADE; + effects.append(em); + + em.name = "Exponential Fade"; + em.internal = TRANSITION_INTERNAL_EXPONENTIALFADE; + effects.append(em); + + em.name = "Logarithmic Fade"; + em.internal = TRANSITION_INTERNAL_LOGARITHMICFADE; + effects.append(em); +} + +void load_shader_effects() { + QList effects_paths = get_effects_paths(); + + for (int h=0;h entries = effects_dir.entryList(QStringList("*.xml"), QDir::Files); + for (int i=0;istart(); +} + +#ifndef NOFREI0R +void load_frei0r_effects_worker(const QString& dir, EffectMeta& em, QVector& loaded_names) { + QDir search_dir(dir); + if (search_dir.exists()) { + QList entry_list = search_dir.entryList(LibFilter(), QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot); + for (int j=0;j(LibAddress(effect, "f0r_get_plugin_info")); + if (get_info_func != nullptr) { + f0r_plugin_info_t info; + get_info_func(&info); + + if (!loaded_names.contains(info.name) + && info.plugin_type == F0R_PLUGIN_TYPE_FILTER + && info.color_model == F0R_COLOR_MODEL_RGBA8888) { + em.name = info.name; + em.path = dir; + em.filename = entry_list.at(j); + em.tooltip = QString("%1\n%2\n%3\n%4").arg(em.name, info.author, info.explanation, em.filename); + + loaded_names.append(em.name); + + effects.append(em); + } +// qDebug() << "Found:" << info.name << "by" << info.author; + } + LibClose(effect); + } +// qDebug() << search_dir.filePath(entry_list.at(j)); + } + } + } +} + +void load_frei0r_effects() { + QList effect_dirs = get_effects_paths(); + + // add defined paths for frei0r plugins on unix +#if defined(__APPLE__) || defined(__linux__) + effect_dirs.prepend("/usr/lib/frei0r-1"); + effect_dirs.prepend("/usr/local/lib/frei0r-1"); + effect_dirs.prepend(QDir::homePath() + "/.frei0r-1/lib"); +#endif + + QVector loaded_names; + + // search for paths + EffectMeta em; + em.category = "Frei0r"; + em.type = EFFECT_TYPE_EFFECT; + em.subtype = EFFECT_TYPE_VIDEO; + em.internal = EFFECT_INTERNAL_FREI0R; + + for (int i=0;ieffects_loaded.lock(); +} + +void EffectInit::run() { + qInfo() << "Initializing effects..."; + load_internal_effects(); + load_shader_effects(); +#ifndef NOFREI0R + load_frei0r_effects(); +#endif + panel_effect_controls->effects_loaded.unlock(); + qInfo() << "Finished initializing effects"; +} diff --git a/project/effectloaders.h b/project/effectloaders.h new file mode 100644 index 000000000..3d88cf64e --- /dev/null +++ b/project/effectloaders.h @@ -0,0 +1,8 @@ +#ifndef EFFECTLOADERS_H +#define EFFECTLOADERS_H + +#include + +void init_effects(); + +#endif // EFFECTLOADERS_H diff --git a/project/effectrow.cpp b/project/effectrow.cpp index d40c77bcf..8a378cd51 100644 --- a/project/effectrow.cpp +++ b/project/effectrow.cpp @@ -197,7 +197,7 @@ void EffectRow::set_keyframe_now(ComboAction* ca) { } } if (exist_key == -1) { - key.type = (f->keyframes.size() == 0) ? KEYFRAME_TYPE_LINEAR : f->keyframes.at(closest_key).type; + key.type = (f->keyframes.size() == 0) ? EFFECT_KEYFRAME_LINEAR : f->keyframes.at(closest_key).type; key.data = f->get_current_data();//f->keyframes.at(closest_key).data; unsafe_keys[i] = f->keyframes.size(); f->keyframes.append(key); diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index be32acb53..cf7350087 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -33,6 +33,7 @@ parts: - qtmultimedia5-dev - libavformat-dev - libavfilter-dev + - frei0r-plugins-dev stage-packages: - ffmpeg - libqt5multimedia5 @@ -40,14 +41,11 @@ parts: - libpulse0 - libslang2 - libglu1-mesa + - frei0r-plugins override-build: | - qmake olive.pro + qmake PREFIX=$SNAPCRAFT_PART_INSTALL make - mkdir -p $SNAPCRAFT_PART_INSTALL/bin/effects - cp olive-editor $SNAPCRAFT_PART_INSTALL/bin - cp effects/*.xml $SNAPCRAFT_PART_INSTALL/bin/effects - cp effects/*.frag $SNAPCRAFT_PART_INSTALL/bin/effects - cp effects/*.vert $SNAPCRAFT_PART_INSTALL/bin/effects + make install snapcraftctl set-version $(git rev-parse --short HEAD) desktop-qt5: build-packages: diff --git a/ui/collapsiblewidget.cpp b/ui/collapsiblewidget.cpp index fce861a11..324f8627d 100644 --- a/ui/collapsiblewidget.cpp +++ b/ui/collapsiblewidget.cpp @@ -31,7 +31,7 @@ CollapsibleWidget::CollapsibleWidget(QWidget* parent) : QWidget(parent) { enabled_check->setChecked(true); header = new QLabel(); collapse_button = new QPushButton(); - collapse_button->setIconSize(QSize(8, 8)); + collapse_button->setIconSize(collapse_button->iconSize()*0.5); collapse_button->setStyleSheet("QPushButton { border: none; }"); setText(tr("")); title_bar_layout->addWidget(collapse_button); diff --git a/ui/graphview.cpp b/ui/graphview.cpp index 30cee5707..9fb8377f1 100644 --- a/ui/graphview.cpp +++ b/ui/graphview.cpp @@ -238,33 +238,33 @@ void GraphView::paintEvent(QPaintEvent *) { } else { const EffectKeyframe& last_key = field->keyframes.at(sorted_keys.at(j-1)); - double pre_handle = field->get_validated_keyframe_handle(sorted_keys.at(j), false); - double last_post_handle = field->get_validated_keyframe_handle(sorted_keys.at(j-1), true); + double pre_handle = field->get_validated_keyframe_handle(sorted_keys.at(j), false); + double last_post_handle = field->get_validated_keyframe_handle(sorted_keys.at(j-1), true); - if (last_key.type == KEYFRAME_TYPE_HOLD) { + if (last_key.type == EFFECT_KEYFRAME_HOLD) { // hold p.drawLine(last_key_x, last_key_y, key_x, last_key_y); p.drawLine(key_x, last_key_y, key_x, key_y); - } else if (last_key.type == KEYFRAME_TYPE_BEZIER || key.type == KEYFRAME_TYPE_BEZIER) { + } else if (last_key.type == EFFECT_KEYFRAME_BEZIER || key.type == EFFECT_KEYFRAME_BEZIER) { QPainterPath bezier_path; bezier_path.moveTo(last_key_x, last_key_y); - if (last_key.type == KEYFRAME_TYPE_BEZIER && key.type == KEYFRAME_TYPE_BEZIER) { + if (last_key.type == EFFECT_KEYFRAME_BEZIER && key.type == EFFECT_KEYFRAME_BEZIER) { // cubic bezier bezier_path.cubicTo( - QPointF(last_key_x+last_post_handle*zoom, last_key_y-last_key.post_handle_y*zoom), - QPointF(key_x+pre_handle*zoom, key_y-key.pre_handle_y*zoom), + QPointF(last_key_x+last_post_handle*zoom, last_key_y-last_key.post_handle_y*zoom), + QPointF(key_x+pre_handle*zoom, key_y-key.pre_handle_y*zoom), QPointF(key_x, key_y) ); - } else if (key.type == KEYFRAME_TYPE_LINEAR) { // quadratic bezier + } else if (key.type == EFFECT_KEYFRAME_LINEAR) { // quadratic bezier // last keyframe is the bezier one bezier_path.quadTo( - QPointF(last_key_x+last_post_handle*zoom, last_key_y-last_key.post_handle_y*zoom), + QPointF(last_key_x+last_post_handle*zoom, last_key_y-last_key.post_handle_y*zoom), QPointF(key_x, key_y) ); } else { // this keyframe is the bezier one bezier_path.quadTo( - QPointF(key_x+pre_handle*zoom, key_y-key.pre_handle_y*zoom), + QPointF(key_x+pre_handle*zoom, key_y-key.pre_handle_y*zoom), QPointF(key_x, key_y) ); } @@ -286,7 +286,7 @@ void GraphView::paintEvent(QPaintEvent *) { int key_x = get_screen_x(key.time); int key_y = get_screen_y(key.data.toDouble()); - if (key.type == KEYFRAME_TYPE_BEZIER) { + if (key.type == EFFECT_KEYFRAME_BEZIER) { p.setPen(Qt::gray); // pre handle line @@ -612,24 +612,24 @@ void GraphView::mouseMoveEvent(QMouseEvent *event) { && event->pos().x() <= key_x) { QRect mouse_rect(event->pos().x()-BEZIER_LINE_SIZE, event->pos().y()-BEZIER_LINE_SIZE, BEZIER_LINE_SIZE+BEZIER_LINE_SIZE, BEZIER_LINE_SIZE+BEZIER_LINE_SIZE); // NOTE: FILTHY copy/paste from paintEvent - if (last_key.type == KEYFRAME_TYPE_HOLD) { + if (last_key.type == EFFECT_KEYFRAME_HOLD) { // hold if (event->pos().y() >= last_key_y-BEZIER_LINE_SIZE && event->pos().y() <= last_key_y+BEZIER_LINE_SIZE) { // dout << "make an HOLD key on field" << i << "after key" << j; click_add = true; } - } else if (last_key.type == KEYFRAME_TYPE_BEZIER || key.type == KEYFRAME_TYPE_BEZIER) { + } else if (last_key.type == EFFECT_KEYFRAME_BEZIER || key.type == EFFECT_KEYFRAME_BEZIER) { QPainterPath bezier_path; bezier_path.moveTo(last_key_x, last_key_y); - if (last_key.type == KEYFRAME_TYPE_BEZIER && key.type == KEYFRAME_TYPE_BEZIER) { + if (last_key.type == EFFECT_KEYFRAME_BEZIER && key.type == EFFECT_KEYFRAME_BEZIER) { // cubic bezier bezier_path.cubicTo( QPointF(last_key_x+last_key.post_handle_x*zoom, last_key_y-last_key.post_handle_y*zoom), QPointF(key_x+key.pre_handle_x*zoom, key_y-key.pre_handle_y*zoom), QPointF(key_x, key_y) ); - } else if (key.type == KEYFRAME_TYPE_LINEAR) { // quadratic bezier + } else if (key.type == EFFECT_KEYFRAME_LINEAR) { // quadratic bezier // last keyframe is the bezier one bezier_path.quadTo( QPointF(last_key_x+last_key.post_handle_x*zoom, last_key_y-last_key.post_handle_y*zoom), diff --git a/ui/keyframedrawing.cpp b/ui/keyframedrawing.cpp index 53229e46c..2621472b7 100644 --- a/ui/keyframedrawing.cpp +++ b/ui/keyframedrawing.cpp @@ -14,16 +14,16 @@ void draw_keyframe(QPainter &p, int type, int x, int y, bool darker, int r, int p.setBrush(QColor(r, g, b)); switch (type) { - case KEYFRAME_TYPE_LINEAR: + case EFFECT_KEYFRAME_LINEAR: { QPoint points[KEYFRAME_POINT_COUNT] = {QPoint(x-KEYFRAME_SIZE, y), QPoint(x, y-KEYFRAME_SIZE), QPoint(x+KEYFRAME_SIZE, y), QPoint(x, y+KEYFRAME_SIZE)}; p.drawPolygon(points, KEYFRAME_POINT_COUNT); } break; - case KEYFRAME_TYPE_BEZIER: + case EFFECT_KEYFRAME_BEZIER: p.drawEllipse(QPoint(x, y), KEYFRAME_SIZE, KEYFRAME_SIZE); break; - case KEYFRAME_TYPE_HOLD: + case EFFECT_KEYFRAME_HOLD: p.drawRect(QRect(x - KEYFRAME_SIZE, y - KEYFRAME_SIZE, KEYFRAME_SIZE*2, KEYFRAME_SIZE*2)); break; } diff --git a/ui/keyframenavigator.cpp b/ui/keyframenavigator.cpp index 8115ed42f..228314d4c 100644 --- a/ui/keyframenavigator.cpp +++ b/ui/keyframenavigator.cpp @@ -6,52 +6,40 @@ #include KeyframeNavigator::KeyframeNavigator(QWidget *parent) : QWidget(parent) { - int icon_size_val = 8*QApplication::desktop()->devicePixelRatio(); - int clock_size_val = 12*QApplication::desktop()->devicePixelRatio(); - int button_size_val = 20*QApplication::desktop()->devicePixelRatio(); - - QSize icon_size(icon_size_val, icon_size_val); - QSize clock_size(clock_size_val, clock_size_val); - QSize button_size(button_size_val, button_size_val); - key_controls = new QHBoxLayout(); key_controls->setSpacing(0); key_controls->setMargin(0); - //key_controls->addStretch(); + key_controls->addStretch(); setLayout(key_controls); left_key_nav = new QPushButton(); - left_key_nav->setIcon(QIcon(":/icons/tri-left.png")); - left_key_nav->setMaximumSize(button_size); - left_key_nav->setIconSize(icon_size); + left_key_nav->setIcon(QIcon(":/icons/tri-left.png")); + left_key_nav->setIconSize(left_key_nav->iconSize()*0.5); left_key_nav->setVisible(false); key_controls->addWidget(left_key_nav); connect(left_key_nav, SIGNAL(clicked(bool)), this, SIGNAL(goto_previous_key())); connect(left_key_nav, SIGNAL(clicked(bool)), this, SIGNAL(clicked())); key_addremove = new QPushButton(); - key_addremove->setIcon(QIcon(":/icons/diamond.png")); - key_addremove->setMaximumSize(button_size); - key_addremove->setIconSize(QSize(8, 8)); + key_addremove->setIcon(QIcon(":/icons/diamond.png")); + key_addremove->setIconSize(key_addremove->iconSize()*0.5); key_addremove->setVisible(false); key_controls->addWidget(key_addremove); connect(key_addremove, SIGNAL(clicked(bool)), this, SIGNAL(toggle_key())); connect(key_addremove, SIGNAL(clicked(bool)), this, SIGNAL(clicked())); right_key_nav = new QPushButton(); - right_key_nav->setIcon(QIcon(":/icons/tri-right.png")); - right_key_nav->setMaximumSize(button_size); - right_key_nav->setIconSize(icon_size); + right_key_nav->setIcon(QIcon(":/icons/tri-right.png")); + right_key_nav->setIconSize(right_key_nav->iconSize()*0.5); right_key_nav->setVisible(false); key_controls->addWidget(right_key_nav); connect(right_key_nav, SIGNAL(clicked(bool)), this, SIGNAL(goto_next_key())); connect(right_key_nav, SIGNAL(clicked(bool)), this, SIGNAL(clicked())); keyframe_enable = new QPushButton(QIcon(":/icons/clock.png"), ""); - keyframe_enable->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); - keyframe_enable->setMaximumSize(button_size); - keyframe_enable->setIconSize(clock_size); + keyframe_enable->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); + keyframe_enable->setIconSize(keyframe_enable->iconSize()*0.75); keyframe_enable->setCheckable(true); keyframe_enable->setToolTip(tr("Enable Keyframes")); connect(keyframe_enable, SIGNAL(clicked(bool)), this, SIGNAL(keyframe_enabled_changed(bool))); diff --git a/ui/keyframeview.cpp b/ui/keyframeview.cpp index 014029b08..8cfb38f0c 100644 --- a/ui/keyframeview.cpp +++ b/ui/keyframeview.cpp @@ -50,12 +50,12 @@ void KeyframeView::show_context_menu(const QPoint& pos) { if (selected_fields.size() > 0) { QMenu menu(this); - QAction* linear = menu.addAction(tr("Linear")); - linear->setData(KEYFRAME_TYPE_LINEAR); - QAction* bezier = menu.addAction(tr("Bezier")); - bezier->setData(KEYFRAME_TYPE_BEZIER); - QAction* hold = menu.addAction(tr("Hold")); - hold->setData(KEYFRAME_TYPE_HOLD); + QAction* linear = menu.addAction(tr("Linear")); + linear->setData(EFFECT_KEYFRAME_LINEAR); + QAction* bezier = menu.addAction(tr("Bezier")); + bezier->setData(EFFECT_KEYFRAME_BEZIER); + QAction* hold = menu.addAction(tr("Hold")); + hold->setData(EFFECT_KEYFRAME_HOLD); menu.addSeparator(); menu.addAction("Graph Editor"); @@ -167,7 +167,11 @@ void KeyframeView::paintEvent(QPaintEvent*) { /*if (mouseover && mouseover_row < rowY.size()) { draw_keyframe(p, getScreenPointFromFrame(panel_effect_controls->zoom, mouseover_frame - visible_in), rowY.at(mouseover_row), true); - }*/ + }*/ +} + +void KeyframeView::wheelEvent(QWheelEvent *e) { + emit wheel_event_signal(e); } bool KeyframeView::keyframeIsSelected(EffectField *field, int keyframe) { @@ -199,9 +203,9 @@ void KeyframeView::set_y_scroll(int s) { } void KeyframeView::resize_move(double d) { - panel_effect_controls->zoom *= d; - header->update_zoom(panel_effect_controls->zoom); - update(); + panel_effect_controls->zoom *= d; + header->update_zoom(panel_effect_controls->zoom); + update(); } void KeyframeView::mousePressEvent(QMouseEvent *event) { diff --git a/ui/keyframeview.h b/ui/keyframeview.h index 51bbd361d..984a3b541 100644 --- a/ui/keyframeview.h +++ b/ui/keyframeview.h @@ -21,6 +21,8 @@ public: long visible_in; long visible_out; +signals: + void wheel_event_signal(QWheelEvent*); public slots: void set_x_scroll(int); void set_y_scroll(int); @@ -36,6 +38,7 @@ private: void mouseMoveEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent *event); void paintEvent(QPaintEvent *event); + void wheelEvent(QWheelEvent* e); bool mousedown; bool dragging; bool keys_selected; diff --git a/ui/timelineheader.cpp b/ui/timelineheader.cpp index 89be63626..3b4858e6a 100644 --- a/ui/timelineheader.cpp +++ b/ui/timelineheader.cpp @@ -320,7 +320,6 @@ void TimelineHeader::paintEvent(QPaintEvent*) { int textWidth = 0; int lastTextBoundary = INT_MIN; - int i = 0; int lastLineX = INT_MIN; int sublineCount = 1; @@ -337,6 +336,9 @@ void TimelineHeader::paintEvent(QPaintEvent*) { int text_x, fullTextWidth; QString timecode; + // find where to start drawing lines (lineX algorithm reversed if lineX = 0) + int i = qFloor(double(scroll)/zoom/interval); + while (true) { long frame = qRound(interval*i); int lineX = qRound(frame*zoom) - scroll; @@ -375,7 +377,6 @@ void TimelineHeader::paintEvent(QPaintEvent*) { lastLineX = lineX; } - // TODO wastes cycles here, could just bring it up to 0 i++; }