diff --git a/dialogs/preferencesdialog.cpp b/dialogs/preferencesdialog.cpp index b7df9ddaa..a730d6bb5 100644 --- a/dialogs/preferencesdialog.cpp +++ b/dialogs/preferencesdialog.cpp @@ -1,6 +1,7 @@ #include "preferencesdialog.h" #include "io/config.h" +#include "mainwindow.h" #include #include @@ -108,6 +109,13 @@ void PreferencesDialog::setup_kbd_shortcuts(QMenuBar* menubar) { } void PreferencesDialog::save() { + if (!custom_css_fn->text().isEmpty() && !QFileInfo::exists(custom_css_fn->text())) { + QMessageBox::critical(this, "Invalid CSS File", "CSS file '" + custom_css_fn->text() + "' does not exist."); + return; + } + + config.css_path = custom_css_fn->text(); + mainWindow->load_css_from_file(config.css_path); config.recording_mode = recordingComboBox->currentIndex() + 1; config.img_seq_formats = imgSeqFormatEdit->text(); config.fast_seeking = fastSeekButton->isChecked(); @@ -230,7 +238,14 @@ void PreferencesDialog::save_shortcut_file() { } else { QMessageBox::critical(this, "Error saving shortcuts", "Failed to open file for writing"); } - } + } +} + +void PreferencesDialog::browse_css_file() { + QString fn = QFileDialog::getOpenFileName(this, "Browse for CSS file"); + if (!fn.isEmpty()) { + custom_css_fn->setText(fn); + } } void PreferencesDialog::setup_ui() { @@ -240,19 +255,29 @@ void PreferencesDialog::setup_ui() { QTabWidget* general_tab = new QTabWidget(); QGridLayout* general_layout = new QGridLayout(general_tab); - general_layout->addWidget(new QLabel("Image sequence formats:"), 0, 0, 1, 1); + general_layout->addWidget(new QLabel("Custom CSS:"), 0, 0, 1, 1); + + custom_css_fn = new QLineEdit(general_tab); + custom_css_fn->setText(config.css_path); + general_layout->addWidget(custom_css_fn, 0, 1, 1, 1); + + QPushButton* custom_css_browse = new QPushButton("Browse", general_tab); + connect(custom_css_browse, SIGNAL(clicked(bool)), this, SLOT(browse_css_file())); + general_layout->addWidget(custom_css_browse, 0, 2, 1, 1); + + general_layout->addWidget(new QLabel("Image sequence formats:"), 1, 0, 1, 1); imgSeqFormatEdit = new QLineEdit(general_tab); - general_layout->addWidget(imgSeqFormatEdit, 0, 1, 1, 1); + general_layout->addWidget(imgSeqFormatEdit, 1, 1, 1, 2); - general_layout->addWidget(new QLabel("Audio Recording:"), 1, 0, 1, 1); + general_layout->addWidget(new QLabel("Audio Recording:"), 2, 0, 1, 1); recordingComboBox = new QComboBox(general_tab); recordingComboBox->addItem("Mono"); recordingComboBox->addItem("Stereo"); - general_layout->addWidget(recordingComboBox, 1, 1, 1, 1); + general_layout->addWidget(recordingComboBox, 2, 1, 1, 2); tabWidget->addTab(general_tab, "General"); QWidget* behavior_tab = new QWidget(); diff --git a/dialogs/preferencesdialog.h b/dialogs/preferencesdialog.h index 5647997f5..0b1344c71 100644 --- a/dialogs/preferencesdialog.h +++ b/dialogs/preferencesdialog.h @@ -42,11 +42,13 @@ private slots: bool refine_shortcut_list(const QString &, QTreeWidgetItem* parent = NULL); void load_shortcut_file(); void save_shortcut_file(); + void browse_css_file(); private: void setup_ui(); void setup_kbd_shortcut_worker(QMenu* menu, QTreeWidgetItem* parent); + QLineEdit* custom_css_fn; QLineEdit* imgSeqFormatEdit; QComboBox* recordingComboBox; QRadioButton* accurateSeekButton; diff --git a/io/config.cpp b/io/config.cpp index 1da1a8c46..18d0bc540 100644 --- a/io/config.cpp +++ b/io/config.cpp @@ -46,7 +46,7 @@ Config::Config() upcoming_queue_type(FRAME_QUEUE_TYPE_SECONDS), loop(true), pause_at_out_point(true), - seek_also_selects(false) + seek_also_selects(false) {} void Config::load(QString path) { @@ -162,7 +162,10 @@ void Config::load(QString path) { } else if (stream.name() == "SeekAlsoSelects") { stream.readNext(); seek_also_selects = (stream.text() == "1"); - } + } else if (stream.name() == "CSSPath") { + stream.readNext(); + css_path = stream.text().toString(); + } } } if (stream.hasError()) { @@ -220,7 +223,8 @@ void Config::save(QString path) { stream.writeTextElement("UpcomingFrameQueueType", QString::number(upcoming_queue_type)); stream.writeTextElement("Loop", QString::number(loop)); stream.writeTextElement("PauseAtOutPoint", QString::number(pause_at_out_point)); - stream.writeTextElement("SeekAlsoSelects", QString::number(seek_also_selects)); + stream.writeTextElement("SeekAlsoSelects", QString::number(seek_also_selects)); + stream.writeTextElement("CSSPath", css_path); stream.writeEndElement(); // configuration stream.writeEndDocument(); // doc diff --git a/io/config.h b/io/config.h index 542443b4b..9983839d9 100644 --- a/io/config.h +++ b/io/config.h @@ -61,6 +61,7 @@ struct Config { bool loop; bool pause_at_out_point; bool seek_also_selects; + QString css_path; void load(QString path); void save(QString path); diff --git a/main.cpp b/main.cpp index 995e29357..11668c0ae 100644 --- a/main.cpp +++ b/main.cpp @@ -2,6 +2,7 @@ #include #include "debug.h" +#include "project/effect.h" extern "C" { #include @@ -24,17 +25,20 @@ int main(int argc, char *argv[]) { if (argc > 1) { for (int i=1;isetStyle(QStyleFactory::create("Fusion")); - setStyleSheet("QPushButton::checked { background: rgb(25, 25, 25); }"); + setStyleSheet(DEFAULT_CSS); QPalette darkPalette; darkPalette.setColor(QPalette::Window, QColor(53,53,53)); @@ -197,7 +198,11 @@ MainWindow::MainWindow(QWidget *parent, const QString &an) : config_fn = config_path + "/config.xml"; if (QFileInfo::exists(config_fn)) { config.load(config_fn); - } + + if (!config.css_path.isEmpty()) { + load_css_from_file(config.css_path); + } + } } alloc_panels(this); @@ -330,7 +335,18 @@ void MainWindow::save_shortcuts(const QString& fn) { shortcut_file_io.close(); } else { qCritical() << "Failed to save shortcut file"; - } + } +} + +void MainWindow::load_css_from_file(const QString &fn) { + QFile css_file(fn); + if (css_file.exists() && css_file.open(QFile::ReadOnly)) { + setStyleSheet(css_file.readAll()); + css_file.close(); + } else { + // set default stylesheet + setStyleSheet(DEFAULT_CSS); + } } void MainWindow::show_about() { diff --git a/mainwindow.h b/mainwindow.h index d4a3a6025..490c75097 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -23,6 +23,8 @@ public: void load_shortcuts(const QString &fn, bool first = false); void save_shortcuts(const QString &fn); + void load_css_from_file(const QString& fn); + public slots: void undo(); void redo(); diff --git a/project/effect.cpp b/project/effect.cpp index de62ec7c9..14400133e 100644 --- a/project/effect.cpp +++ b/project/effect.cpp @@ -44,6 +44,7 @@ #include #include +bool shaders_are_enabled = true; QVector effects; Effect* create_effect(Clip* c, const EffectMeta* em) { @@ -85,6 +86,8 @@ const EffectMeta* get_internal_meta(int internal_id, int type) { } void load_internal_effects() { + qWarning() << "Shaders are disabled, some effects may be nonfunctional"; + EffectMeta em; // internal effects @@ -785,8 +788,8 @@ void Effect::open() { if (isOpen) { qWarning() << "Tried to open an effect that was already open"; close(); - } - if (enable_shader) { + } + if (shaders_are_enabled && enable_shader) { if (QOpenGLContext::currentContext() == NULL) { qWarning() << "No current context to create a shader program for - will retry next repaint"; } else { @@ -848,7 +851,11 @@ void Effect::startEffect() { open(); qWarning() << "Tried to start a closed effect - opening"; } - if (enable_shader && glslProgram->isLinked()) bound = glslProgram->bind(); + if (shaders_are_enabled + && enable_shader + && glslProgram->isLinked()) { + bound = glslProgram->bind(); + } } void Effect::endEffect() { diff --git a/project/effect.h b/project/effect.h index 21e0f381b..413df6d9f 100644 --- a/project/effect.h +++ b/project/effect.h @@ -34,6 +34,7 @@ struct EffectMeta { int subtype; }; +extern bool shaders_are_enabled; extern QVector effects; double log_volume(double linear); diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index 3783b563f..f8adf8313 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -431,9 +431,9 @@ void ViewerWidget::process_effect(Clip* c, Effect* e, double timecode, GLTexture if (e->enable_coords) { e->process_coords(timecode, coords, data); } - if (e->enable_shader || e->enable_superimpose) { + if ((e->enable_shader && shaders_are_enabled) || e->enable_superimpose) { e->startEffect(); - if (e->enable_shader && e->is_glsl_linked()) { + if ((e->enable_shader && shaders_are_enabled) && e->is_glsl_linked()) { e->process_shader(timecode, coords); composite_texture = draw_clip(c->fbo[fbo_switcher], composite_texture, true); fbo_switcher = !fbo_switcher;