various UI reimplementations from 0.1.x
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "filefunctions.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QCryptographicHash>
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
@@ -73,3 +74,22 @@ QString GetMediaCacheLocation()
|
||||
|
||||
return media_cache_dir.absolutePath();
|
||||
}
|
||||
|
||||
QString GetConfigurationLocation()
|
||||
{
|
||||
if (IsPortable()) {
|
||||
return GetApplicationPath();
|
||||
} else {
|
||||
return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsPortable()
|
||||
{
|
||||
return QFileInfo::exists(QDir(GetApplicationPath()).filePath("portable"));
|
||||
}
|
||||
|
||||
QString GetApplicationPath()
|
||||
{
|
||||
return QCoreApplication::applicationDirPath();
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
bool IsPortable();
|
||||
|
||||
QString GetUniqueFileIdentifier(const QString& filename);
|
||||
|
||||
QString GetMediaIndexLocation();
|
||||
@@ -31,4 +33,8 @@ QString GetMediaIndexFilename(const QString& filename);
|
||||
|
||||
QString GetMediaCacheLocation();
|
||||
|
||||
QString GetConfigurationLocation();
|
||||
|
||||
QString GetApplicationPath();
|
||||
|
||||
#endif // FILEFUNCTIONS_H
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
#include <QtMath>
|
||||
|
||||
#include "config/config.h"
|
||||
|
||||
QString padded(int arg, int padding) {
|
||||
return QString("%1").arg(arg, padding, 10, QChar('0'));
|
||||
}
|
||||
@@ -91,3 +93,8 @@ int64_t olive::time_to_timestamp(const rational &time, const rational &timebase)
|
||||
{
|
||||
return qRound64(time.toDouble() * timebase.flipped().toDouble());
|
||||
}
|
||||
|
||||
olive::TimecodeDisplay olive::CurrentTimecodeDisplay()
|
||||
{
|
||||
return static_cast<olive::TimecodeDisplay>(Config::Current()["TimecodeDisplay"].toInt());
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ enum TimecodeDisplay {
|
||||
kMilliseconds
|
||||
};
|
||||
|
||||
TimecodeDisplay CurrentTimecodeDisplay();
|
||||
|
||||
/**
|
||||
* @brief Convert a timestamp (according to a rational timebase) to a user-friendly string representation
|
||||
*/
|
||||
|
||||
@@ -17,5 +17,6 @@
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
config/config.h
|
||||
config/config.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QMessageBox>
|
||||
#include <QXmlStreamWriter>
|
||||
|
||||
#include "core.h"
|
||||
#include "common/filefunctions.h"
|
||||
|
||||
Config Config::current_config_;
|
||||
|
||||
Config::Config()
|
||||
{
|
||||
SetDefaults();
|
||||
}
|
||||
|
||||
QString Config::GetConfigFilePath()
|
||||
{
|
||||
return QDir(GetConfigurationLocation()).filePath("config.xml");
|
||||
}
|
||||
|
||||
Config &Config::Current()
|
||||
{
|
||||
return current_config_;
|
||||
}
|
||||
|
||||
void Config::SetDefaults()
|
||||
{
|
||||
config_map_.clear();
|
||||
config_map_["TimecodeDisplay"] = olive::kTimecodeFrames;
|
||||
config_map_["DefaultStillLength"] = QVariant::fromValue(rational(2));
|
||||
}
|
||||
|
||||
void Config::Load()
|
||||
{
|
||||
QFile config_file(GetConfigFilePath());
|
||||
|
||||
if (!config_file.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!config_file.open(QFile::ReadOnly)) {
|
||||
qWarning() << QCoreApplication::translate("Config", "Failed to load application settings. This session will use "
|
||||
"defaults.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset to defaults
|
||||
current_config_.SetDefaults();
|
||||
|
||||
QXmlStreamReader reader(&config_file);
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNext();
|
||||
|
||||
if (!reader.isStartElement()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QString key = reader.name().toString();
|
||||
|
||||
reader.readNext();
|
||||
QString value = reader.text().toString();
|
||||
|
||||
if (key == "Configuration") {
|
||||
// First element, ignore
|
||||
} else if (key == "Version") {
|
||||
if (!value.contains(".")) {
|
||||
qDebug() << "This is a 0.1.x config file, upconvert";
|
||||
}
|
||||
} else {
|
||||
current_config_[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (reader.hasError()) {
|
||||
QMessageBox::critical(olive::core.main_window(),
|
||||
QCoreApplication::translate("Config", "Error loading settings"),
|
||||
QCoreApplication::translate("Config", "Failed to load application settings. This session will "
|
||||
"use defaults."),
|
||||
QMessageBox::Ok);
|
||||
current_config_.SetDefaults();
|
||||
}
|
||||
|
||||
config_file.close();
|
||||
}
|
||||
|
||||
void Config::Save()
|
||||
{
|
||||
QFile config_file(GetConfigFilePath());
|
||||
|
||||
if (!config_file.open(QFile::WriteOnly)) {
|
||||
QMessageBox::critical(olive::core.main_window(),
|
||||
QCoreApplication::translate("Config", "Error saving settings"),
|
||||
QCoreApplication::translate("Config", "Failed to save application settings. The application "
|
||||
"may lack write permissions to this location."),
|
||||
QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
QXmlStreamWriter writer(&config_file);
|
||||
|
||||
writer.writeStartDocument();
|
||||
|
||||
writer.writeStartElement("Configuration");
|
||||
|
||||
// Anything after the hyphen is considered "unimportant" information
|
||||
writer.writeTextElement("Version", QCoreApplication::applicationVersion().split('-').first());
|
||||
|
||||
QMapIterator<QString, QVariant> iterator(current_config_.config_map_);
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
writer.writeTextElement(iterator.key(), iterator.value().toString());
|
||||
}
|
||||
|
||||
writer.writeEndElement(); // Configuration
|
||||
|
||||
writer.writeEndDocument();
|
||||
|
||||
config_file.close();
|
||||
}
|
||||
|
||||
QVariant Config::operator[](const QString &key) const
|
||||
{
|
||||
return config_map_[key];
|
||||
}
|
||||
|
||||
QVariant &Config::operator[](const QString &key)
|
||||
{
|
||||
return config_map_[key];
|
||||
}
|
||||
+25
-5
@@ -21,14 +21,34 @@
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
#include "common/timecodefunctions.h"
|
||||
|
||||
/**
|
||||
* @brief Temporary variables that will definitely be configurable but aren't yet
|
||||
*/
|
||||
class Config {
|
||||
public:
|
||||
static Config& Current();
|
||||
|
||||
const olive::TimecodeDisplay kTimecodeDisplay = olive::kTimecodeFrames;
|
||||
void SetDefaults();
|
||||
|
||||
const rational kDefaultImageLength = 2;
|
||||
static void Load();
|
||||
|
||||
static void Save();
|
||||
|
||||
QVariant operator[](const QString&) const;
|
||||
|
||||
QVariant& operator[](const QString&);
|
||||
|
||||
private:
|
||||
Config();
|
||||
|
||||
QMap<QString, QVariant> config_map_;
|
||||
|
||||
static Config current_config_;
|
||||
|
||||
static QString GetConfigFilePath();
|
||||
};
|
||||
|
||||
#endif // CONFIG_H
|
||||
|
||||
+15
-2
@@ -25,11 +25,14 @@
|
||||
#include <QDebug>
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QMessageBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QStyleFactory>
|
||||
|
||||
#include "config/config.h"
|
||||
#include "dialog/about/about.h"
|
||||
#include "dialog/sequence/sequence.h"
|
||||
#include "dialog/preferences/preferences.h"
|
||||
#include "panel/panelmanager.h"
|
||||
#include "panel/project/project.h"
|
||||
#include "project/item/footage/footage.h"
|
||||
@@ -85,6 +88,9 @@ void Core::Start()
|
||||
// Declare custom types for Qt signal/slot syste
|
||||
DeclareTypesForQt();
|
||||
|
||||
// Load application config
|
||||
Config::Load();
|
||||
|
||||
|
||||
//
|
||||
// Start GUI (FIXME CLI mode)
|
||||
@@ -193,6 +199,12 @@ void Core::DialogImportShow()
|
||||
}
|
||||
}
|
||||
|
||||
void Core::DialogPreferencesShow()
|
||||
{
|
||||
PreferencesDialog pd(main_window_, main_window_->menuBar());
|
||||
pd.exec();
|
||||
}
|
||||
|
||||
void Core::CreateNewFolder()
|
||||
{
|
||||
// Locate the most recently focused Project panel (assume that's the panel the user wants to import into)
|
||||
@@ -344,7 +356,8 @@ void Core::DeclareTypesForQt()
|
||||
void Core::StartGUI(bool full_screen)
|
||||
{
|
||||
// Set UI style
|
||||
olive::style::AppSetDefault();
|
||||
qApp->setStyle(QStyleFactory::create("Fusion"));
|
||||
StyleManager::SetStyle(StyleManager::DefaultStyle());
|
||||
|
||||
// Set up shared menus
|
||||
olive::menu_shared.Initialize();
|
||||
|
||||
@@ -124,6 +124,11 @@ public slots:
|
||||
*/
|
||||
void DialogImportShow();
|
||||
|
||||
/**
|
||||
* @brief Show Preferences dialog
|
||||
*/
|
||||
void DialogPreferencesShow();
|
||||
|
||||
/**
|
||||
* @brief Create a new folder in the currently active project
|
||||
*/
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
add_subdirectory(about)
|
||||
add_subdirectory(actionsearch)
|
||||
add_subdirectory(preferences)
|
||||
add_subdirectory(sequence)
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2019 Olive Team
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
add_subdirectory(tabs)
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
dialog/preferences/keysequenceeditor.h
|
||||
dialog/preferences/keysequenceeditor.cpp
|
||||
dialog/preferences/preferences.h
|
||||
dialog/preferences/preferences.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
@@ -0,0 +1,48 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "keysequenceeditor.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
KeySequenceEditor::KeySequenceEditor(QWidget* parent, QAction* a)
|
||||
: QKeySequenceEdit(parent), action(a) {
|
||||
setKeySequence(action->shortcut());
|
||||
}
|
||||
|
||||
void KeySequenceEditor::set_action_shortcut() {
|
||||
action->setShortcut(keySequence());
|
||||
}
|
||||
|
||||
void KeySequenceEditor::reset_to_default() {
|
||||
setKeySequence(action->property("default").toString());
|
||||
}
|
||||
|
||||
QString KeySequenceEditor::action_name() {
|
||||
return action->property("id").toString();
|
||||
}
|
||||
|
||||
QString KeySequenceEditor::export_shortcut() {
|
||||
QString ks = keySequence().toString();
|
||||
if (ks != action->property("default")) {
|
||||
return action->property("id").toString() + "\t" + ks;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef KEYSEQUENCEEDITOR_H
|
||||
#define KEYSEQUENCEEDITOR_H
|
||||
|
||||
#include <QKeySequenceEdit>
|
||||
|
||||
/**
|
||||
* @brief The KeySequenceEditor class
|
||||
*
|
||||
* Simple derived class of QKeySequenceEdit that attaches to a QAction and provides functions for transferring
|
||||
* keyboard shortcuts to and from it.
|
||||
*/
|
||||
class KeySequenceEditor : public QKeySequenceEdit {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* @brief KeySequenceEditor Constructor
|
||||
*
|
||||
* @param parent
|
||||
*
|
||||
* QWidget parent.
|
||||
*
|
||||
* @param a
|
||||
*
|
||||
* The QAction to link to. This cannot be changed throughout the lifetime of a KeySequenceEditor.
|
||||
*/
|
||||
KeySequenceEditor(QWidget *parent, QAction* a);
|
||||
|
||||
/**
|
||||
* @brief Sets the attached QAction's shortcut to the shortcut entered in this field.
|
||||
*
|
||||
* This is not done automatically in case the user cancels out of the Preferences dialog, in which case the
|
||||
* expectation is that the changes made will not be saved. Therefore, this needs to be triggered manually when
|
||||
* PreferencesDialog saves.
|
||||
*/
|
||||
void set_action_shortcut();
|
||||
|
||||
/**
|
||||
* @brief Set this shortcut back to the QAction's default shortcut
|
||||
*
|
||||
* Each QAction contains the default shortcut in its `property("default")` and can be used to restore the default
|
||||
* "hard-coded" shortcut with this function.
|
||||
*
|
||||
* This function does not save the default shortcut back into the QAction, it simply loads the default shortcut from
|
||||
* the QAction into this edit field. To save it into the QAction, it's necessary to call set_action_shortcut() after
|
||||
* calling this function.
|
||||
*/
|
||||
void reset_to_default();
|
||||
|
||||
/**
|
||||
* @brief Return attached QAction's unique ID
|
||||
*
|
||||
* Each of Olive's menu actions has a unique string ID (that, unlike the text, is not translated) for matching with
|
||||
* an external shortcut configuration file. The ID is stored in the QAction's `property("id")`. This function returns
|
||||
* that ID.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* The QAction's unique ID.
|
||||
*/
|
||||
QString action_name();
|
||||
|
||||
/**
|
||||
* @brief Serialize this shortcut entry into a string that can be saved to a file
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* A string serialization of this shortcut. The format is "[ID]\t[SEQUENCE]" where [ID] is the attached QAction's
|
||||
* unique identifier and [SEQUENCE] is the current keyboard shortcut in the field (NOT necessarily the shortcut in
|
||||
* the QAction). If the entered shortcut is the same as the QAction's default shortcut, the return value is empty
|
||||
* because a default shortcut does not need to be saved to a file.
|
||||
*/
|
||||
QString export_shortcut();
|
||||
private:
|
||||
/**
|
||||
* @brief Internal reference to the linked QAction
|
||||
*/
|
||||
QAction* action;
|
||||
};
|
||||
|
||||
#endif // KEYSEQUENCEEDITOR_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 Olive Team
|
||||
Copyright (C) 2019 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -21,24 +21,12 @@
|
||||
#ifndef PREFERENCESDIALOG_H
|
||||
#define PREFERENCESDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QKeySequenceEdit>
|
||||
#include <QMenuBar>
|
||||
#include <QLineEdit>
|
||||
#include <QComboBox>
|
||||
#include <QRadioButton>
|
||||
#include <QTreeWidget>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QMenu>
|
||||
#include <QCheckBox>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QSpinBox>
|
||||
#include <OpenColorIO/OpenColorIO.h>
|
||||
namespace OCIO = OCIO_NAMESPACE::v1;
|
||||
#include <QDialog>
|
||||
#include <QMenuBar>
|
||||
#include <QTabWidget>
|
||||
|
||||
#include "timeline/sequence.h"
|
||||
|
||||
class KeySequenceEditor;
|
||||
#include "tabs/preferencestab.h"
|
||||
|
||||
/**
|
||||
* @brief The PreferencesDialog class
|
||||
@@ -58,7 +46,7 @@ public:
|
||||
*
|
||||
* QWidget parent. Usually MainWindow.
|
||||
*/
|
||||
explicit PreferencesDialog(QWidget *parent = nullptr);
|
||||
explicit PreferencesDialog(QWidget *parent, QMenuBar* main_menu_bar);
|
||||
|
||||
private slots:
|
||||
/**
|
||||
@@ -66,215 +54,12 @@ private slots:
|
||||
*/
|
||||
virtual void accept() override;
|
||||
|
||||
/**
|
||||
* @brief Reset all selected shortcuts in keyboard_tree to their defaults
|
||||
*/
|
||||
void reset_default_shortcut();
|
||||
|
||||
/**
|
||||
* @brief Reset all shortcuts indiscriminately to their defaults
|
||||
*
|
||||
* This is safe to call directly as it'll ask the user if they wish to do so before it resets.
|
||||
*/
|
||||
void reset_all_shortcuts();
|
||||
|
||||
/**
|
||||
* @brief Shows/hides shortcut entries according to a shortcut query.
|
||||
*
|
||||
* This function can be directly connected to QLineEdit::textChanged() for simplicity.
|
||||
*
|
||||
* @param s
|
||||
*
|
||||
* The search query to compare shortcut names to.
|
||||
*
|
||||
* @param parent
|
||||
*
|
||||
* This is used as the function calls itself recursively to traverse the menu item hierarchy. This should be left as
|
||||
* nullptr when called externally.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Value used as function calls itself recursively to determine if a menu parent has any children that are not hidden.
|
||||
* If so, TRUE is returned so the parent is shown too (even if it doesn't match the search query). If not, FALSE is
|
||||
* returned so the parent is hidden.
|
||||
*/
|
||||
bool refine_shortcut_list(const QString &s, QTreeWidgetItem* parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Show a file dialog to load an external shortcut preset from file
|
||||
*/
|
||||
void load_shortcut_file();
|
||||
|
||||
/**
|
||||
* @brief Show a file dialog to save an external shortcut preset from file
|
||||
*/
|
||||
void save_shortcut_file();
|
||||
|
||||
/**
|
||||
* @brief Delete all previews (waveform and thumbnail cache)
|
||||
*/
|
||||
void delete_all_previews();
|
||||
|
||||
// Browse for file functionns
|
||||
/**
|
||||
* @brief Show a file dialog to browse for an external CSS file to load for styling the application.
|
||||
*/
|
||||
void browse_css_file();
|
||||
void browse_ocio_config();
|
||||
|
||||
// OCIO function
|
||||
void update_ocio_view_menu();
|
||||
void update_ocio_view_menu(OCIO::ConstConfigRcPtr config);
|
||||
void update_ocio_config(const QString&);
|
||||
|
||||
/**
|
||||
* @brief Shows a NewSequenceDialog attached to default_sequence
|
||||
*/
|
||||
void edit_default_sequence_settings();
|
||||
|
||||
private:
|
||||
void AddTab(PreferencesTab* tab, const QString& title);
|
||||
|
||||
/**
|
||||
* @brief Create and arrange all UI widgets
|
||||
*/
|
||||
void setup_ui();
|
||||
QTabWidget* tab_widget_;
|
||||
|
||||
/**
|
||||
* @brief Populate keyboard shortcut panel with keyboard shortcuts from the menu bar
|
||||
*
|
||||
* @param menu
|
||||
*
|
||||
* A reference to the main application's menu bar. Usually MainWindow::menuBar().
|
||||
*/
|
||||
void setup_kbd_shortcuts(QMenuBar* menu);
|
||||
|
||||
/**
|
||||
* @brief Internal function called by setup_kbd_shortcuts() to traverse down the menu bar's hierarchy and populate the
|
||||
* shortcut panel.
|
||||
*
|
||||
* This function will call itself recursively as it finds submenus belong to the menu provided. It will also create
|
||||
* QTreeWidgetItems as children of the parent item provided, either using them as parents themselves for submenus
|
||||
* or attaching a KeySequenceEditor to them for shortcut editing.
|
||||
*
|
||||
* @param menu
|
||||
*
|
||||
* The current menu to traverse down.
|
||||
*
|
||||
* @param parent
|
||||
*
|
||||
* The parent item to add QTreeWidgetItems to.
|
||||
*/
|
||||
void setup_kbd_shortcut_worker(QMenu* menu, QTreeWidgetItem* parent);
|
||||
|
||||
enum PreviewDeleteTypes {
|
||||
DELETE_NONE,
|
||||
DELETE_THUMBNAILS,
|
||||
DELETE_WAVEFORMS,
|
||||
DELETE_BOTH
|
||||
};
|
||||
|
||||
// used to delete previews
|
||||
// type can be: 't' for thumbnails, 'w' for waveforms, or 1 for all
|
||||
/**
|
||||
* @brief Delete disk cached preview files (thumbnails, waveforms, etc.)
|
||||
*
|
||||
* @param type
|
||||
*
|
||||
* The types of previews to delete.
|
||||
*/
|
||||
void delete_previews(PreviewDeleteTypes type);
|
||||
|
||||
void populate_ocio_menus(OCIO::ConstConfigRcPtr config);
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing the CSS filename
|
||||
*/
|
||||
QLineEdit* custom_css_fn;
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing the list of extensions to detect image sequences from
|
||||
*/
|
||||
QLineEdit* imgSeqFormatEdit;
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing the recording channels
|
||||
*/
|
||||
QComboBox* recordingComboBox;
|
||||
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing keyboard shortcuts
|
||||
*/
|
||||
QTreeWidget* keyboard_tree;
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing the upcoming queue size
|
||||
*/
|
||||
QDoubleSpinBox* upcoming_queue_spinbox;
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing the upcoming queue type
|
||||
*/
|
||||
QComboBox* upcoming_queue_type;
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing the previous queue size
|
||||
*/
|
||||
QDoubleSpinBox* previous_queue_spinbox;
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing the previous queue type
|
||||
*/
|
||||
QComboBox* previous_queue_type;
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing the size of textboxes in the EffectControls panel
|
||||
*/
|
||||
QSpinBox* effect_textbox_lines_field;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the output audio device
|
||||
*/
|
||||
QComboBox* audio_output_devices;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the input audio device
|
||||
*/
|
||||
QComboBox* audio_input_devices;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the audio sampling rates
|
||||
*/
|
||||
QComboBox* audio_sample_rate;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the UI language
|
||||
*/
|
||||
QComboBox* language_combobox;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the resolution of the thumbnails to generate
|
||||
*/
|
||||
QSpinBox* thumbnail_res_spinbox;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the resolution of the waveforms to generate
|
||||
*/
|
||||
QSpinBox* waveform_res_spinbox;
|
||||
|
||||
QCheckBox* enable_color_management;
|
||||
QLineEdit* ocio_config_file;
|
||||
QComboBox* ocio_default_input;
|
||||
QComboBox* ocio_display;
|
||||
QComboBox* ocio_view;
|
||||
QComboBox* ocio_look;
|
||||
QComboBox* playback_bit_depth;
|
||||
QComboBox* export_bit_depth;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the current UI style
|
||||
*/
|
||||
QComboBox* ui_style;
|
||||
QList<PreferencesTab*> tabs_;
|
||||
|
||||
/**
|
||||
* @brief Stored default Sequence object
|
||||
@@ -282,38 +67,7 @@ private:
|
||||
* Default Sequence settings are loaded into an actual Sequence object that can be loaded into NewSequenceDialog
|
||||
* for the sake of familiarity with the user.
|
||||
*/
|
||||
Sequence default_sequence;
|
||||
|
||||
/**
|
||||
* @brief List of keyboard shortcut actions that can be triggered (links with key_shortcut_items and
|
||||
* key_shortcut_fields)
|
||||
*/
|
||||
QVector<QAction*> key_shortcut_actions;
|
||||
|
||||
/**
|
||||
* @brief List of keyboard shortcut items in keyboard_tree corresponding to existing actions (links with
|
||||
* key_shortcut_actions and key_shortcut_fields)
|
||||
*/
|
||||
QVector<QTreeWidgetItem*> key_shortcut_items;
|
||||
|
||||
/**
|
||||
* @brief List of keyboard shortcut editing fields in keyboard_tree corresponding to existing actions (links with
|
||||
* key_shortcut_actions and key_shortcut_fields)
|
||||
*/
|
||||
QVector<KeySequenceEditor*> key_shortcut_fields;
|
||||
|
||||
/**
|
||||
* @brief Tests an OpenColorIO configuration file to determine whether it's valid and throws a messagebox if not
|
||||
*
|
||||
* @param url
|
||||
*
|
||||
* URL to the OpenColorIO configuration file.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* A OCIO::ConstConfigRcPtr config pointer if the configuration file is valid, nullptr if not.
|
||||
*/
|
||||
OCIO::ConstConfigRcPtr TestOCIOConfig(const QString& url);
|
||||
//Sequence default_sequence;
|
||||
|
||||
/**
|
||||
* @brief Add an automated QCheckBox+boolean value pair
|
||||
@@ -355,78 +109,4 @@ private:
|
||||
QVector<bool> bool_restart_required;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The KeySequenceEditor class
|
||||
*
|
||||
* Simple derived class of QKeySequenceEdit that attaches to a QAction and provides functions for transferring
|
||||
* keyboard shortcuts to and from it.
|
||||
*/
|
||||
class KeySequenceEditor : public QKeySequenceEdit {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* @brief KeySequenceEditor Constructor
|
||||
*
|
||||
* @param parent
|
||||
*
|
||||
* QWidget parent.
|
||||
*
|
||||
* @param a
|
||||
*
|
||||
* The QAction to link to. This cannot be changed throughout the lifetime of a KeySequenceEditor.
|
||||
*/
|
||||
KeySequenceEditor(QWidget *parent, QAction* a);
|
||||
|
||||
/**
|
||||
* @brief Sets the attached QAction's shortcut to the shortcut entered in this field.
|
||||
*
|
||||
* This is not done automatically in case the user cancels out of the Preferences dialog, in which case the
|
||||
* expectation is that the changes made will not be saved. Therefore, this needs to be triggered manually when
|
||||
* PreferencesDialog saves.
|
||||
*/
|
||||
void set_action_shortcut();
|
||||
|
||||
/**
|
||||
* @brief Set this shortcut back to the QAction's default shortcut
|
||||
*
|
||||
* Each QAction contains the default shortcut in its `property("default")` and can be used to restore the default
|
||||
* "hard-coded" shortcut with this function.
|
||||
*
|
||||
* This function does not save the default shortcut back into the QAction, it simply loads the default shortcut from
|
||||
* the QAction into this edit field. To save it into the QAction, it's necessary to call set_action_shortcut() after
|
||||
* calling this function.
|
||||
*/
|
||||
void reset_to_default();
|
||||
|
||||
/**
|
||||
* @brief Return attached QAction's unique ID
|
||||
*
|
||||
* Each of Olive's menu actions has a unique string ID (that, unlike the text, is not translated) for matching with
|
||||
* an external shortcut configuration file. The ID is stored in the QAction's `property("id")`. This function returns
|
||||
* that ID.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* The QAction's unique ID.
|
||||
*/
|
||||
QString action_name();
|
||||
|
||||
/**
|
||||
* @brief Serialize this shortcut entry into a string that can be saved to a file
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* A string serialization of this shortcut. The format is "[ID]\t[SEQUENCE]" where [ID] is the attached QAction's
|
||||
* unique identifier and [SEQUENCE] is the current keyboard shortcut in the field (NOT necessarily the shortcut in
|
||||
* the QAction). If the entered shortcut is the same as the QAction's default shortcut, the return value is empty
|
||||
* because a default shortcut does not need to be saved to a file.
|
||||
*/
|
||||
QString export_shortcut();
|
||||
private:
|
||||
/**
|
||||
* @brief Internal reference to the linked QAction
|
||||
*/
|
||||
QAction* action;
|
||||
};
|
||||
|
||||
#endif // PREFERENCESDIALOG_H
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2019 Olive Team
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
dialog/preferences/tabs/preferencesgeneraltab.h
|
||||
dialog/preferences/tabs/preferencesgeneraltab.cpp
|
||||
dialog/preferences/tabs/preferencesbehaviortab.h
|
||||
dialog/preferences/tabs/preferencesbehaviortab.cpp
|
||||
dialog/preferences/tabs/preferencesappearancetab.h
|
||||
dialog/preferences/tabs/preferencesappearancetab.cpp
|
||||
dialog/preferences/tabs/preferencesplaybacktab.h
|
||||
dialog/preferences/tabs/preferencesplaybacktab.cpp
|
||||
dialog/preferences/tabs/preferencesaudiotab.h
|
||||
dialog/preferences/tabs/preferencesaudiotab.cpp
|
||||
dialog/preferences/tabs/preferenceskeyboardtab.h
|
||||
dialog/preferences/tabs/preferenceskeyboardtab.cpp
|
||||
dialog/preferences/tabs/preferencescolormanagementtab.h
|
||||
dialog/preferences/tabs/preferencescolormanagementtab.cpp
|
||||
dialog/preferences/tabs/preferencestab.h
|
||||
dialog/preferences/tabs/preferencestab.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
@@ -0,0 +1,51 @@
|
||||
#include "preferencesappearancetab.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
|
||||
PreferencesAppearanceTab::PreferencesAppearanceTab()
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
|
||||
QGridLayout* appearance_layout = new QGridLayout();
|
||||
layout->addLayout(appearance_layout);
|
||||
|
||||
int row = 0;
|
||||
|
||||
// Appearance -> Theme
|
||||
appearance_layout->addWidget(new QLabel(tr("Theme")), row, 0);
|
||||
|
||||
style_ = new QComboBox();
|
||||
|
||||
style_list_ = StyleManager::ListInternal();
|
||||
|
||||
foreach (StyleDescriptor s, style_list_) {
|
||||
style_->addItem(s.name(), s.path());
|
||||
|
||||
if (s.path() == Config::Current()["Style"]) {
|
||||
style_->setCurrentIndex(style_->count()-1);
|
||||
}
|
||||
}
|
||||
|
||||
appearance_layout->addWidget(style_, row, 1, 1, 2);
|
||||
|
||||
row++;
|
||||
|
||||
layout->addStretch();
|
||||
}
|
||||
|
||||
void PreferencesAppearanceTab::Accept()
|
||||
{
|
||||
QString style_path = style_->currentData().toString();
|
||||
StyleManager::SetStyle(style_path);
|
||||
Config::Current()["Style"] = style_path;
|
||||
|
||||
if (style_->currentIndex() < style_list_.size()) {
|
||||
// This is an internal style, set accordingly
|
||||
|
||||
} else {
|
||||
StyleManager::SetStyle(style_->currentData().toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef PREFERENCESAPPEARANCETAB_H
|
||||
#define PREFERENCESAPPEARANCETAB_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QLineEdit>
|
||||
|
||||
#include "preferencestab.h"
|
||||
#include "ui/style/style.h"
|
||||
|
||||
class PreferencesAppearanceTab : public PreferencesTab
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesAppearanceTab();
|
||||
|
||||
virtual void Accept() override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Show a file dialog to browse for an external CSS file to load for styling the application.
|
||||
*/
|
||||
void BrowseForCSS();
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the current UI style
|
||||
*/
|
||||
QComboBox* style_;
|
||||
|
||||
/**
|
||||
* @brief List of internal styles
|
||||
*/
|
||||
QList<StyleDescriptor> style_list_;
|
||||
|
||||
QString custom_style_path_;
|
||||
};
|
||||
|
||||
#endif // PREFERENCESAPPEARANCETAB_H
|
||||
@@ -0,0 +1,93 @@
|
||||
#include "preferencesaudiotab.h"
|
||||
|
||||
#include <QAudioDeviceInfo>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
|
||||
#include "config/config.h"
|
||||
|
||||
PreferencesAudioTab::PreferencesAudioTab()
|
||||
{
|
||||
QGridLayout* audio_tab_layout = new QGridLayout(this);
|
||||
|
||||
int row = 0;
|
||||
|
||||
// Audio -> Output Device
|
||||
|
||||
audio_tab_layout->addWidget(new QLabel(tr("Output Device:")), row, 0);
|
||||
|
||||
audio_output_devices = new QComboBox();
|
||||
audio_output_devices->addItem(tr("Default"), "");
|
||||
|
||||
// list all available audio output devices
|
||||
QList<QAudioDeviceInfo> devs = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
|
||||
bool found_preferred_device = false;
|
||||
for (int i=0;i<devs.size();i++) {
|
||||
audio_output_devices->addItem(devs.at(i).deviceName(), devs.at(i).deviceName());
|
||||
if (!found_preferred_device
|
||||
&& devs.at(i).deviceName() == Config::Current()["AudioOutput"]) {
|
||||
audio_output_devices->setCurrentIndex(audio_output_devices->count()-1);
|
||||
found_preferred_device = true;
|
||||
}
|
||||
}
|
||||
|
||||
audio_tab_layout->addWidget(audio_output_devices, row, 1);
|
||||
|
||||
row++;
|
||||
|
||||
// Audio -> Input Device
|
||||
|
||||
audio_tab_layout->addWidget(new QLabel(tr("Input Device:")), row, 0);
|
||||
|
||||
audio_input_devices = new QComboBox();
|
||||
audio_input_devices->addItem(tr("Default"), "");
|
||||
|
||||
// list all available audio input devices
|
||||
devs = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
|
||||
found_preferred_device = false;
|
||||
for (int i=0;i<devs.size();i++) {
|
||||
audio_input_devices->addItem(devs.at(i).deviceName(), devs.at(i).deviceName());
|
||||
if (!found_preferred_device
|
||||
&& devs.at(i).deviceName() == Config::Current()["AudioInput"]) {
|
||||
audio_input_devices->setCurrentIndex(audio_input_devices->count()-1);
|
||||
found_preferred_device = true;
|
||||
}
|
||||
}
|
||||
|
||||
audio_tab_layout->addWidget(audio_input_devices, row, 1);
|
||||
|
||||
row++;
|
||||
|
||||
// Audio -> Sample Rate
|
||||
|
||||
audio_tab_layout->addWidget(new QLabel(tr("Sample Rate:")), row, 0);
|
||||
|
||||
audio_sample_rate = new QComboBox();
|
||||
/*combobox_audio_sample_rates(audio_sample_rate);
|
||||
for (int i=0;i<audio_sample_rate->count();i++) {
|
||||
if (audio_sample_rate->itemData(i).toInt() == olive::config.audio_rate) {
|
||||
audio_sample_rate->setCurrentIndex(i);
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
audio_tab_layout->addWidget(audio_sample_rate, row, 1);
|
||||
|
||||
row++;
|
||||
|
||||
// Audio -> Audio Recording
|
||||
audio_tab_layout->addWidget(new QLabel(tr("Audio Recording:"), this), row, 0);
|
||||
|
||||
recordingComboBox = new QComboBox();
|
||||
recordingComboBox->addItem(tr("Mono"));
|
||||
recordingComboBox->addItem(tr("Stereo"));
|
||||
// recordingComboBox->setCurrentIndex(olive::config.recording_mode - 1);
|
||||
audio_tab_layout->addWidget(recordingComboBox, row, 1);
|
||||
|
||||
row++;
|
||||
}
|
||||
|
||||
void PreferencesAudioTab::Accept()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef PREFERENCESAUDIOTAB_H
|
||||
#define PREFERENCESAUDIOTAB_H
|
||||
|
||||
#include <QComboBox>
|
||||
|
||||
#include "preferencestab.h"
|
||||
|
||||
class PreferencesAudioTab : public PreferencesTab
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesAudioTab();
|
||||
|
||||
virtual void Accept() override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief UI widget for selecting the output audio device
|
||||
*/
|
||||
QComboBox* audio_output_devices;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the input audio device
|
||||
*/
|
||||
QComboBox* audio_input_devices;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the audio sampling rates
|
||||
*/
|
||||
QComboBox* audio_sample_rate;
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing the recording channels
|
||||
*/
|
||||
QComboBox* recordingComboBox;
|
||||
|
||||
};
|
||||
|
||||
#endif // PREFERENCESAUDIOTAB_H
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "preferencesbehaviortab.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
PreferencesBehaviorTab::PreferencesBehaviorTab()
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
|
||||
behavior_tree_ = new QTreeWidget();
|
||||
layout->addWidget(behavior_tree_);
|
||||
|
||||
behavior_tree_->setHeaderLabel(tr("Behavior"));
|
||||
behavior_tree_->setRootIsDecorated(false);
|
||||
|
||||
AddItem(tr("Add Default Effects to New Clips"));
|
||||
AddItem(tr("Automatically Seek to the Beginning When Playing at the End of a Sequence"));
|
||||
AddItem(tr("Selecting Also Seeks"));
|
||||
AddItem(tr("Edit Tool Also Seeks"));
|
||||
AddItem(tr("Edit Tool Selects Links"));
|
||||
AddItem(tr("Seek Also Selects"));
|
||||
AddItem(tr("Seek to the End of Pastes"));
|
||||
AddItem(tr("Scroll Wheel Zooms"));
|
||||
AddItem(tr("Invert Timeline Scroll Axes"));
|
||||
AddItem(tr("Enable Drag Files to Timeline"));
|
||||
AddItem(tr("Auto-Scale By Default"));
|
||||
AddItem(tr("Auto-Seek to Imported Clips"));
|
||||
AddItem(tr("Audio Scrubbing"));
|
||||
AddItem(tr("Drop Files on Media to Replace"));
|
||||
AddItem(tr("Enable Hover Focus"));
|
||||
AddItem(tr("Ask For Name When Setting Marker"));
|
||||
|
||||
//scroll_wheel_zooms->setToolTip(tr("Hold CTRL to toggle this setting"));
|
||||
}
|
||||
|
||||
void PreferencesBehaviorTab::Accept()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PreferencesBehaviorTab::AddItem(const QString &text, const QString& tooltip)
|
||||
{
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem({text});
|
||||
item->setToolTip(0, tooltip);
|
||||
item->setCheckState(0, Qt::Unchecked);
|
||||
behavior_tree_->addTopLevelItem(item);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef PREFERENCESBEHAVIORTAB_H
|
||||
#define PREFERENCESBEHAVIORTAB_H
|
||||
|
||||
#include <QTreeWidget>
|
||||
|
||||
#include "preferencestab.h"
|
||||
|
||||
class PreferencesBehaviorTab : public PreferencesTab
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesBehaviorTab();
|
||||
|
||||
virtual void Accept() override;
|
||||
|
||||
private:
|
||||
void AddItem(const QString& text, const QString &tooltip = QString());
|
||||
|
||||
QTreeWidget* behavior_tree_;
|
||||
};
|
||||
|
||||
#endif // PREFERENCESBEHAVIORTAB_H
|
||||
@@ -0,0 +1,213 @@
|
||||
#include "preferencescolormanagementtab.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QGridLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
|
||||
PreferencesColorManagementTab::PreferencesColorManagementTab()
|
||||
{
|
||||
QGridLayout* color_management_layout = new QGridLayout(this);
|
||||
|
||||
int row = 0;
|
||||
|
||||
QGroupBox* opencolorio_groupbox = new QGroupBox();
|
||||
QGridLayout* opencolorio_groupbox_layout = new QGridLayout(opencolorio_groupbox);
|
||||
|
||||
// COLOR MANAGEMENT -> OpenColorIO Config File
|
||||
opencolorio_groupbox_layout->addWidget(new QLabel(tr("OpenColorIO Config File:")), 0, 0);
|
||||
|
||||
ocio_config_file = new QLineEdit();
|
||||
// ocio_config_file->setText(olive::config.ocio_config_path);
|
||||
connect(ocio_config_file, SIGNAL(textChanged(const QString &)), this, SLOT(update_ocio_config(const QString&)));
|
||||
opencolorio_groupbox_layout->addWidget(ocio_config_file, 0, 1, 1, 4);
|
||||
|
||||
QPushButton* ocio_config_browse_btn = new QPushButton(tr("Browse"));
|
||||
connect(ocio_config_browse_btn, SIGNAL(clicked(bool)), this, SLOT(browse_ocio_config()));
|
||||
opencolorio_groupbox_layout->addWidget(ocio_config_browse_btn, 0, 5);
|
||||
|
||||
// COLOR MANAGEMENT -> Default Input Color Space
|
||||
ocio_default_input = new QComboBox();
|
||||
opencolorio_groupbox_layout->addWidget(new QLabel(tr("Default Input Color Space:")), 1, 0);
|
||||
opencolorio_groupbox_layout->addWidget(ocio_default_input, 1, 1, 1, 5);
|
||||
|
||||
// COLOR MANAGEMENT -> Display
|
||||
ocio_display = new QComboBox();
|
||||
connect(ocio_display, SIGNAL(currentIndexChanged(int)), this, SLOT(update_ocio_view_menu()));
|
||||
opencolorio_groupbox_layout->addWidget(new QLabel(tr("Display:")), 2, 0);
|
||||
opencolorio_groupbox_layout->addWidget(ocio_display, 2, 1);
|
||||
|
||||
// COLOR MANAGEMENT -> View
|
||||
ocio_view = new QComboBox();
|
||||
opencolorio_groupbox_layout->addWidget(new QLabel(tr("View:")), 2, 2);
|
||||
opencolorio_groupbox_layout->addWidget(ocio_view, 2, 3);
|
||||
|
||||
// COLOR MANAGEMENT -> Look
|
||||
ocio_look = new QComboBox();
|
||||
opencolorio_groupbox_layout->addWidget(new QLabel(tr("Look:")), 2, 4);
|
||||
opencolorio_groupbox_layout->addWidget(ocio_look, 2, 5);
|
||||
|
||||
color_management_layout->addWidget(opencolorio_groupbox, row, 0);
|
||||
|
||||
row++;
|
||||
|
||||
// COLOR MANAGEMENT -> Bit Depth
|
||||
QGroupBox* bit_depth_groupbox = new QGroupBox(tr("Bit Depth"));
|
||||
QGridLayout* bit_depth_groupbox_layout = new QGridLayout(bit_depth_groupbox);
|
||||
|
||||
// COLOR MANAGEMENT -> Bit Depth -> Playback
|
||||
playback_bit_depth = new QComboBox();
|
||||
/*for (int i=0;i<olive::pixel_formats.size();i++) {
|
||||
playback_bit_depth->addItem(olive::pixel_formats.at(i).name, i);
|
||||
}
|
||||
playback_bit_depth->setCurrentIndex(olive::config.playback_bit_depth);*/
|
||||
bit_depth_groupbox_layout->addWidget(new QLabel(tr("Playback (Offline):")), 0, 0);
|
||||
bit_depth_groupbox_layout->addWidget(playback_bit_depth, 0, 1);
|
||||
|
||||
// COLOR MANAGEMENT -> Bit Depth -> Export
|
||||
export_bit_depth = new QComboBox();
|
||||
/*for (int i=0;i<olive::pixel_formats.size();i++) {
|
||||
export_bit_depth->addItem(olive::pixel_formats.at(i).name, i);
|
||||
}
|
||||
export_bit_depth->setCurrentIndex(olive::config.export_bit_depth);*/
|
||||
bit_depth_groupbox_layout->addWidget(new QLabel(tr("Export (Online):")), 0, 2);
|
||||
bit_depth_groupbox_layout->addWidget(export_bit_depth, 0, 3);
|
||||
|
||||
color_management_layout->addWidget(bit_depth_groupbox, row, 0);
|
||||
|
||||
//row++;
|
||||
|
||||
populate_ocio_menus(OCIO::GetCurrentConfig());
|
||||
}
|
||||
|
||||
void PreferencesColorManagementTab::Accept()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PreferencesColorManagementTab::populate_ocio_menus(OCIO::ConstConfigRcPtr config)
|
||||
{
|
||||
if (!config) {
|
||||
|
||||
// Just clear everything
|
||||
ocio_display->clear();
|
||||
ocio_default_input->clear();
|
||||
ocio_view->clear();
|
||||
ocio_look->clear();
|
||||
|
||||
} else {
|
||||
|
||||
// Get input color spaces for setting the default input color space
|
||||
ocio_default_input->clear();
|
||||
for (int i=0;i<config->getNumColorSpaces();i++) {
|
||||
QString colorspace = config->getColorSpaceNameByIndex(i);
|
||||
|
||||
ocio_default_input->addItem(colorspace);
|
||||
|
||||
/*if (colorspace == olive::config.ocio_default_input_colorspace) {
|
||||
ocio_default_input->setCurrentIndex(i);
|
||||
}*/
|
||||
}
|
||||
|
||||
// Get current display name (if the config is empty, get the current default display)
|
||||
/*QString current_display = olive::config.ocio_display;
|
||||
if (current_display.isEmpty()) {
|
||||
current_display = config->getDefaultDisplay();
|
||||
}*/
|
||||
|
||||
// Populate the display menu
|
||||
ocio_display->clear();
|
||||
for (int i=0;i<config->getNumDisplays();i++) {
|
||||
ocio_display->addItem(config->getDisplay(i));
|
||||
|
||||
// Check if this index is the currently selected
|
||||
/*if (config->getDisplay(i) == current_display) {
|
||||
ocio_display->setCurrentIndex(i);
|
||||
}*/
|
||||
}
|
||||
|
||||
update_ocio_view_menu(config);
|
||||
|
||||
// Populate the look menu
|
||||
ocio_look->clear();
|
||||
ocio_look->addItem(tr("(None)"), QString());
|
||||
for (int i=0;i<config->getNumLooks();i++) {
|
||||
const char* look = config->getLookNameByIndex(i);
|
||||
|
||||
ocio_look->addItem(look, look);
|
||||
|
||||
/*if (look == olive::config.ocio_look) {
|
||||
ocio_look->setCurrentIndex(i+1);
|
||||
}*/
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
OCIO::ConstConfigRcPtr PreferencesColorManagementTab::TestOCIOConfig(const QString &url)
|
||||
{
|
||||
// Check whether OCIO can load it
|
||||
OCIO::ConstConfigRcPtr config;
|
||||
try {
|
||||
config = OCIO::Config::CreateFromFile(url.toUtf8());
|
||||
} catch (OCIO::Exception& e) {
|
||||
QMessageBox::critical(this,
|
||||
tr("OpenColorIO Config Error"),
|
||||
tr("Failed to set OpenColorIO configuration: %1").arg(e.what()),
|
||||
QMessageBox::Ok);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
void PreferencesColorManagementTab::update_ocio_view_menu(OCIO::ConstConfigRcPtr config)
|
||||
{
|
||||
|
||||
// Get views for the current display set in `ocio_display`
|
||||
QString display = ocio_display->currentText();
|
||||
|
||||
// Get current view
|
||||
/*QString current_view = olive::config.ocio_view;
|
||||
if (current_view.isEmpty()) {
|
||||
current_view = config->getDefaultView(display.toUtf8());
|
||||
}*/
|
||||
|
||||
// Populate the view menu
|
||||
int ocio_view_count = config->getNumViews(display.toUtf8());
|
||||
ocio_view->clear();
|
||||
for (int i=0;i<ocio_view_count;i++) {
|
||||
const char* view = config->getView(display.toUtf8(), i);
|
||||
|
||||
ocio_view->addItem(view);
|
||||
|
||||
/*if (current_view == view) {
|
||||
ocio_view->setCurrentIndex(i);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesColorManagementTab::update_ocio_config(const QString &s)
|
||||
{
|
||||
OCIO::ConstConfigRcPtr file_config;
|
||||
|
||||
if (!s.isEmpty() && QFileInfo::exists(s)) {
|
||||
file_config = TestOCIOConfig(s);
|
||||
}
|
||||
|
||||
populate_ocio_menus(file_config);
|
||||
}
|
||||
|
||||
void PreferencesColorManagementTab::browse_ocio_config()
|
||||
{
|
||||
QString fn = QFileDialog::getOpenFileName(this, tr("Browse for OpenColorIO configuration"));
|
||||
if (!fn.isEmpty()) {
|
||||
ocio_config_file->setText(fn);
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesColorManagementTab::update_ocio_view_menu()
|
||||
{
|
||||
update_ocio_view_menu(OCIO::GetCurrentConfig());
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#ifndef PREFERENCESCOLORMANAGEMENTTAB_H
|
||||
#define PREFERENCESCOLORMANAGEMENTTAB_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QLineEdit>
|
||||
#include <OpenColorIO/OpenColorIO.h>
|
||||
namespace OCIO = OCIO_NAMESPACE::v1;
|
||||
|
||||
#include "preferencestab.h"
|
||||
|
||||
class PreferencesColorManagementTab : public PreferencesTab
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesColorManagementTab();
|
||||
|
||||
virtual void Accept() override;
|
||||
|
||||
private slots:
|
||||
// OCIO function
|
||||
void browse_ocio_config();
|
||||
void update_ocio_view_menu();
|
||||
void update_ocio_view_menu(OCIO::ConstConfigRcPtr config);
|
||||
void update_ocio_config(const QString&);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Tests an OpenColorIO configuration file to determine whether it's valid and throws a messagebox if not
|
||||
*
|
||||
* @param url
|
||||
*
|
||||
* URL to the OpenColorIO configuration file.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* A OCIO::ConstConfigRcPtr config pointer if the configuration file is valid, nullptr if not.
|
||||
*/
|
||||
OCIO::ConstConfigRcPtr TestOCIOConfig(const QString& url);
|
||||
|
||||
void populate_ocio_menus(OCIO::ConstConfigRcPtr config);
|
||||
|
||||
QLineEdit* ocio_config_file;
|
||||
QComboBox* ocio_default_input;
|
||||
QComboBox* ocio_display;
|
||||
QComboBox* ocio_view;
|
||||
QComboBox* ocio_look;
|
||||
QComboBox* playback_bit_depth;
|
||||
QComboBox* export_bit_depth;
|
||||
};
|
||||
|
||||
#endif // PREFERENCESCOLORMANAGEMENTTAB_H
|
||||
@@ -0,0 +1,110 @@
|
||||
#include "preferencesgeneraltab.h"
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
|
||||
PreferencesGeneralTab::PreferencesGeneralTab()
|
||||
{
|
||||
QGridLayout* general_layout = new QGridLayout(this);
|
||||
|
||||
int row = 0;
|
||||
|
||||
// General -> Language
|
||||
general_layout->addWidget(new QLabel(tr("Language:")), row, 0);
|
||||
|
||||
language_combobox = new QComboBox();
|
||||
|
||||
// add default language (en-US)
|
||||
language_combobox->addItem(QLocale::languageToString(QLocale("en-US").language()));
|
||||
|
||||
/*
|
||||
// add languages from file
|
||||
QList<QString> translation_paths = get_language_paths();
|
||||
|
||||
// iterate through all language search paths
|
||||
for (int j=0;j<translation_paths.size();j++) {
|
||||
QDir translation_dir(translation_paths.at(j));
|
||||
if (translation_dir.exists()) {
|
||||
QStringList translation_files = translation_dir.entryList({"*.qm"}, QDir::Files | QDir::NoDotAndDotDot);
|
||||
for (int i=0;i<translation_files.size();i++) {
|
||||
// get path of translation relative to the application path
|
||||
QString locale_full_path = translation_dir.filePath(translation_files.at(i));
|
||||
QString locale_relative_path = QDir(get_app_path()).relativeFilePath(locale_full_path);
|
||||
|
||||
QFileInfo locale_file(translation_files.at(i));
|
||||
QString locale_file_basename = locale_file.baseName();
|
||||
QString locale_str = locale_file_basename.mid(locale_file_basename.lastIndexOf('_')+1);
|
||||
language_combobox->addItem(QLocale(locale_str).nativeLanguageName(), locale_relative_path);
|
||||
|
||||
if (olive::config.language_file == locale_relative_path) {
|
||||
language_combobox->setCurrentIndex(language_combobox->count() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
general_layout->addWidget(language_combobox, row, 1, 1, 4);
|
||||
|
||||
row++;
|
||||
|
||||
// General -> Thumbnail and Waveform Resolution
|
||||
general_layout->addWidget(new QLabel(tr("Thumbnail Resolution:"), this), row, 0);
|
||||
|
||||
thumbnail_res_spinbox = new QSpinBox(this);
|
||||
thumbnail_res_spinbox->setMinimum(0);
|
||||
thumbnail_res_spinbox->setMaximum(INT_MAX);
|
||||
//thumbnail_res_spinbox->setValue(olive::config.thumbnail_resolution);
|
||||
general_layout->addWidget(thumbnail_res_spinbox, row, 1);
|
||||
|
||||
general_layout->addWidget(new QLabel(tr("Waveform Resolution:"), this), row, 2);
|
||||
|
||||
waveform_res_spinbox = new QSpinBox(this);
|
||||
waveform_res_spinbox->setMinimum(0);
|
||||
waveform_res_spinbox->setMaximum(INT_MAX);
|
||||
//waveform_res_spinbox->setValue(olive::config.waveform_resolution);
|
||||
general_layout->addWidget(waveform_res_spinbox, row, 3);
|
||||
|
||||
QPushButton* delete_preview_btn = new QPushButton(tr("Delete Previews"));
|
||||
general_layout->addWidget(delete_preview_btn, row, 4);
|
||||
//connect(delete_preview_btn, SIGNAL(clicked(bool)), this, SLOT(delete_all_previews()));
|
||||
|
||||
row++;
|
||||
|
||||
QHBoxLayout* misc_general = new QHBoxLayout();
|
||||
|
||||
// General -> Use Software Fallbacks When Possible
|
||||
QCheckBox* use_software_fallbacks_checkbox = new QCheckBox(tr("Use Software Fallbacks When Possible"));
|
||||
//AddBoolPair(use_software_fallbacks_checkbox, &olive::config.use_software_fallback, true);
|
||||
misc_general->addWidget(use_software_fallbacks_checkbox);
|
||||
|
||||
// General -> Don't Use Proxies When Exporting
|
||||
QCheckBox* dont_use_proxies_when_exporting = new QCheckBox(tr("Don't Use Proxies When Exporting"));
|
||||
dont_use_proxies_when_exporting->setToolTip(tr("Use originals instead of proxies when exporting"));
|
||||
//AddBoolPair(dont_use_proxies_when_exporting, &olive::config.dont_use_proxies_on_export);
|
||||
misc_general->addWidget(dont_use_proxies_when_exporting);
|
||||
|
||||
// General -> Default Sequence Settings
|
||||
QPushButton* default_sequence_settings = new QPushButton(tr("Default Sequence Settings"));
|
||||
connect(default_sequence_settings, SIGNAL(clicked(bool)), this, SLOT(edit_default_sequence_settings()));
|
||||
misc_general->addWidget(default_sequence_settings);
|
||||
|
||||
general_layout->addLayout(misc_general, row, 0, 1, 5);
|
||||
|
||||
row++;
|
||||
}
|
||||
|
||||
void PreferencesGeneralTab::Accept()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PreferencesGeneralTab::edit_default_sequence_settings()
|
||||
{
|
||||
/*NewSequenceDialog nsd(this, nullptr, &default_sequence);
|
||||
nsd.SetNameEditable(false);
|
||||
nsd.exec();*/
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#ifndef PREFERENCESGENERALTAB_H
|
||||
#define PREFERENCESGENERALTAB_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QSpinBox>
|
||||
|
||||
#include "preferencestab.h"
|
||||
|
||||
class PreferencesGeneralTab : public PreferencesTab
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesGeneralTab();
|
||||
|
||||
virtual void Accept() override;
|
||||
|
||||
private slots:
|
||||
/**
|
||||
* @brief Shows a NewSequenceDialog attached to default_sequence
|
||||
*/
|
||||
void edit_default_sequence_settings();
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief UI widget for selecting the UI language
|
||||
*/
|
||||
QComboBox* language_combobox;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the resolution of the thumbnails to generate
|
||||
*/
|
||||
QSpinBox* thumbnail_res_spinbox;
|
||||
|
||||
/**
|
||||
* @brief UI widget for selecting the resolution of the waveforms to generate
|
||||
*/
|
||||
QSpinBox* waveform_res_spinbox;
|
||||
|
||||
};
|
||||
|
||||
#endif // PREFERENCESGENERALTAB_H
|
||||
@@ -0,0 +1,214 @@
|
||||
#include "preferenceskeyboardtab.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
PreferencesKeyboardTab::PreferencesKeyboardTab(QMenuBar *menubar)
|
||||
{
|
||||
QVBoxLayout* shortcut_layout = new QVBoxLayout(this);
|
||||
|
||||
QLineEdit* key_search_line = new QLineEdit();
|
||||
key_search_line->setPlaceholderText(tr("Search for action or shortcut"));
|
||||
connect(key_search_line, SIGNAL(textChanged(const QString &)), this, SLOT(refine_shortcut_list(const QString &)));
|
||||
|
||||
shortcut_layout->addWidget(key_search_line);
|
||||
|
||||
keyboard_tree = new QTreeWidget();
|
||||
QTreeWidgetItem* tree_header = keyboard_tree->headerItem();
|
||||
tree_header->setText(0, tr("Action"));
|
||||
tree_header->setText(1, tr("Shortcut"));
|
||||
shortcut_layout->addWidget(keyboard_tree);
|
||||
|
||||
QHBoxLayout* reset_shortcut_layout = new QHBoxLayout();
|
||||
|
||||
QPushButton* import_shortcut_button = new QPushButton(tr("Import"));
|
||||
reset_shortcut_layout->addWidget(import_shortcut_button);
|
||||
connect(import_shortcut_button, SIGNAL(clicked(bool)), this, SLOT(load_shortcut_file()));
|
||||
|
||||
QPushButton* export_shortcut_button = new QPushButton(tr("Export"));
|
||||
reset_shortcut_layout->addWidget(export_shortcut_button);
|
||||
connect(export_shortcut_button, SIGNAL(clicked(bool)), this, SLOT(save_shortcut_file()));
|
||||
|
||||
reset_shortcut_layout->addStretch();
|
||||
|
||||
QPushButton* reset_selected_shortcut_button = new QPushButton(tr("Reset Selected"));
|
||||
reset_shortcut_layout->addWidget(reset_selected_shortcut_button);
|
||||
connect(reset_selected_shortcut_button, SIGNAL(clicked(bool)), this, SLOT(reset_default_shortcut()));
|
||||
|
||||
QPushButton* reset_all_shortcut_button = new QPushButton(tr("Reset All"));
|
||||
reset_shortcut_layout->addWidget(reset_all_shortcut_button);
|
||||
connect(reset_all_shortcut_button, SIGNAL(clicked(bool)), this, SLOT(reset_all_shortcuts()));
|
||||
|
||||
shortcut_layout->addLayout(reset_shortcut_layout);
|
||||
|
||||
setup_kbd_shortcuts(menubar);
|
||||
}
|
||||
|
||||
void PreferencesKeyboardTab::Accept()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PreferencesKeyboardTab::setup_kbd_shortcuts(QMenuBar* menubar) {
|
||||
QList<QAction*> menus = menubar->actions();
|
||||
|
||||
for (int i=0;i<menus.size();i++) {
|
||||
QMenu* menu = menus.at(i)->menu();
|
||||
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem(keyboard_tree);
|
||||
item->setText(0, menu->title().replace("&", ""));
|
||||
|
||||
keyboard_tree->addTopLevelItem(item);
|
||||
|
||||
setup_kbd_shortcut_worker(menu, item);
|
||||
}
|
||||
|
||||
for (int i=0;i<key_shortcut_items.size();i++) {
|
||||
if (!key_shortcut_actions.at(i)->property("id").isNull()) {
|
||||
KeySequenceEditor* editor = new KeySequenceEditor(keyboard_tree, key_shortcut_actions.at(i));
|
||||
keyboard_tree->setItemWidget(key_shortcut_items.at(i), 1, editor);
|
||||
key_shortcut_fields.append(editor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesKeyboardTab::setup_kbd_shortcut_worker(QMenu* menu, QTreeWidgetItem* parent) {
|
||||
QList<QAction*> actions = menu->actions();
|
||||
for (int i=0;i<actions.size();i++) {
|
||||
QAction* a = actions.at(i);
|
||||
|
||||
if (!a->isSeparator() && a->property("keyignore").isNull()) {
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem(parent);
|
||||
item->setText(0, a->text().replace("&", ""));
|
||||
|
||||
parent->addChild(item);
|
||||
|
||||
if (a->menu() != nullptr) {
|
||||
item->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
|
||||
setup_kbd_shortcut_worker(a->menu(), item);
|
||||
} else {
|
||||
key_shortcut_items.append(item);
|
||||
key_shortcut_actions.append(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesKeyboardTab::reset_default_shortcut() {
|
||||
QList<QTreeWidgetItem*> items = keyboard_tree->selectedItems();
|
||||
for (int i=0;i<items.size();i++) {
|
||||
QTreeWidgetItem* item = keyboard_tree->selectedItems().at(i);
|
||||
static_cast<KeySequenceEditor*>(keyboard_tree->itemWidget(item, 1))->reset_to_default();
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesKeyboardTab::reset_all_shortcuts() {
|
||||
if (QMessageBox::question(
|
||||
this,
|
||||
tr("Confirm Reset All Shortcuts"),
|
||||
tr("Are you sure you wish to reset all keyboard shortcuts to their defaults?"),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
for (int i=0;i<key_shortcut_fields.size();i++) {
|
||||
key_shortcut_fields.at(i)->reset_to_default();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PreferencesKeyboardTab::refine_shortcut_list(const QString &s, QTreeWidgetItem* parent) {
|
||||
if (parent == nullptr) {
|
||||
for (int i=0;i<keyboard_tree->topLevelItemCount();i++) {
|
||||
refine_shortcut_list(s, keyboard_tree->topLevelItem(i));
|
||||
}
|
||||
} else {
|
||||
parent->setExpanded(!s.isEmpty());
|
||||
|
||||
bool all_children_are_hidden = !s.isEmpty();
|
||||
|
||||
for (int i=0;i<parent->childCount();i++) {
|
||||
QTreeWidgetItem* item = parent->child(i);
|
||||
if (item->childCount() > 0) {
|
||||
all_children_are_hidden = refine_shortcut_list(s, item);
|
||||
} else {
|
||||
item->setHidden(false);
|
||||
if (s.isEmpty()) {
|
||||
all_children_are_hidden = false;
|
||||
} else {
|
||||
QString shortcut;
|
||||
if (keyboard_tree->itemWidget(item, 1) != nullptr) {
|
||||
shortcut = static_cast<QKeySequenceEdit*>(keyboard_tree->itemWidget(item, 1))->keySequence().toString();
|
||||
}
|
||||
if (item->text(0).contains(s, Qt::CaseInsensitive) || shortcut.contains(s, Qt::CaseInsensitive)) {
|
||||
all_children_are_hidden = false;
|
||||
} else {
|
||||
item->setHidden(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parent->text(0).contains(s, Qt::CaseInsensitive)) all_children_are_hidden = false;
|
||||
|
||||
parent->setHidden(all_children_are_hidden);
|
||||
|
||||
return all_children_are_hidden;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PreferencesKeyboardTab::load_shortcut_file() {
|
||||
QString fn = QFileDialog::getOpenFileName(this, tr("Import Keyboard Shortcuts"));
|
||||
if (!fn.isEmpty()) {
|
||||
QFile f(fn);
|
||||
if (f.exists() && f.open(QFile::ReadOnly)) {
|
||||
QByteArray ba = f.readAll();
|
||||
f.close();
|
||||
for (int i=0;i<key_shortcut_fields.size();i++) {
|
||||
int index = ba.indexOf(key_shortcut_fields.at(i)->action_name());
|
||||
if (index == 0 || (index > 0 && ba.at(index-1) == '\n')) {
|
||||
while (index < ba.size() && ba.at(index) != '\t') index++;
|
||||
QString ks;
|
||||
index++;
|
||||
while (index < ba.size() && ba.at(index) != '\n') {
|
||||
ks.append(ba.at(index));
|
||||
index++;
|
||||
}
|
||||
key_shortcut_fields.at(i)->setKeySequence(ks);
|
||||
} else {
|
||||
key_shortcut_fields.at(i)->reset_to_default();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("Error saving shortcuts"),
|
||||
tr("Failed to open file for reading")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesKeyboardTab::save_shortcut_file() {
|
||||
QString fn = QFileDialog::getSaveFileName(this, tr("Export Keyboard Shortcuts"));
|
||||
if (!fn.isEmpty()) {
|
||||
QFile f(fn);
|
||||
if (f.open(QFile::WriteOnly)) {
|
||||
bool start = true;
|
||||
for (int i=0;i<key_shortcut_fields.size();i++) {
|
||||
QString s = key_shortcut_fields.at(i)->export_shortcut();
|
||||
if (!s.isEmpty()) {
|
||||
if (!start) f.write("\n");
|
||||
f.write(s.toUtf8());
|
||||
start = false;
|
||||
}
|
||||
}
|
||||
f.close();
|
||||
QMessageBox::information(this, tr("Export Shortcuts"), tr("Shortcuts exported successfully"));
|
||||
} else {
|
||||
QMessageBox::critical(this, tr("Error saving shortcuts"), tr("Failed to open file for writing"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
#ifndef PREFERENCESKEYBOARDTAB_H
|
||||
#define PREFERENCESKEYBOARDTAB_H
|
||||
|
||||
#include <QMenuBar>
|
||||
#include <QTreeWidget>
|
||||
|
||||
#include "preferencestab.h"
|
||||
#include "../keysequenceeditor.h"
|
||||
|
||||
class PreferencesKeyboardTab : public PreferencesTab
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesKeyboardTab(QMenuBar* menubar);
|
||||
|
||||
virtual void Accept() override;
|
||||
|
||||
private slots:
|
||||
/**
|
||||
* @brief Show a file dialog to load an external shortcut preset from file
|
||||
*/
|
||||
void load_shortcut_file();
|
||||
|
||||
/**
|
||||
* @brief Show a file dialog to save an external shortcut preset from file
|
||||
*/
|
||||
void save_shortcut_file();
|
||||
|
||||
/**
|
||||
* @brief Reset all selected shortcuts in keyboard_tree to their defaults
|
||||
*/
|
||||
void reset_default_shortcut();
|
||||
|
||||
/**
|
||||
* @brief Reset all shortcuts indiscriminately to their defaults
|
||||
*
|
||||
* This is safe to call directly as it'll ask the user if they wish to do so before it resets.
|
||||
*/
|
||||
void reset_all_shortcuts();
|
||||
|
||||
/**
|
||||
* @brief Shows/hides shortcut entries according to a shortcut query.
|
||||
*
|
||||
* This function can be directly connected to QLineEdit::textChanged() for simplicity.
|
||||
*
|
||||
* @param s
|
||||
*
|
||||
* The search query to compare shortcut names to.
|
||||
*
|
||||
* @param parent
|
||||
*
|
||||
* This is used as the function calls itself recursively to traverse the menu item hierarchy. This should be left as
|
||||
* nullptr when called externally.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Value used as function calls itself recursively to determine if a menu parent has any children that are not hidden.
|
||||
* If so, TRUE is returned so the parent is shown too (even if it doesn't match the search query). If not, FALSE is
|
||||
* returned so the parent is hidden.
|
||||
*/
|
||||
bool refine_shortcut_list(const QString &s, QTreeWidgetItem* parent = nullptr);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Populate keyboard shortcut panel with keyboard shortcuts from the menu bar
|
||||
*
|
||||
* @param menu
|
||||
*
|
||||
* A reference to the main application's menu bar. Usually MainWindow::menuBar().
|
||||
*/
|
||||
void setup_kbd_shortcuts(QMenuBar* menu);
|
||||
|
||||
/**
|
||||
* @brief Internal function called by setup_kbd_shortcuts() to traverse down the menu bar's hierarchy and populate the
|
||||
* shortcut panel.
|
||||
*
|
||||
* This function will call itself recursively as it finds submenus belong to the menu provided. It will also create
|
||||
* QTreeWidgetItems as children of the parent item provided, either using them as parents themselves for submenus
|
||||
* or attaching a KeySequenceEditor to them for shortcut editing.
|
||||
*
|
||||
* @param menu
|
||||
*
|
||||
* The current menu to traverse down.
|
||||
*
|
||||
* @param parent
|
||||
*
|
||||
* The parent item to add QTreeWidgetItems to.
|
||||
*/
|
||||
void setup_kbd_shortcut_worker(QMenu* menu, QTreeWidgetItem* parent);
|
||||
|
||||
/**
|
||||
* @brief UI widget for editing keyboard shortcuts
|
||||
*/
|
||||
QTreeWidget* keyboard_tree;
|
||||
|
||||
/**
|
||||
* @brief List of keyboard shortcut actions that can be triggered (links with key_shortcut_items and
|
||||
* key_shortcut_fields)
|
||||
*/
|
||||
QVector<QAction*> key_shortcut_actions;
|
||||
|
||||
/**
|
||||
* @brief List of keyboard shortcut items in keyboard_tree corresponding to existing actions (links with
|
||||
* key_shortcut_actions and key_shortcut_fields)
|
||||
*/
|
||||
QVector<QTreeWidgetItem*> key_shortcut_items;
|
||||
|
||||
/**
|
||||
* @brief List of keyboard shortcut editing fields in keyboard_tree corresponding to existing actions (links with
|
||||
* key_shortcut_actions and key_shortcut_fields)
|
||||
*/
|
||||
QVector<KeySequenceEditor*> key_shortcut_fields;
|
||||
};
|
||||
|
||||
#endif // PREFERENCESKEYBOARDTAB_H
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "preferencesplaybacktab.h"
|
||||
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
PreferencesPlaybackTab::PreferencesPlaybackTab()
|
||||
{
|
||||
}
|
||||
|
||||
void PreferencesPlaybackTab::Accept()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef PREFERENCESPLAYBACKTAB_H
|
||||
#define PREFERENCESPLAYBACKTAB_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDoubleSpinBox>
|
||||
|
||||
#include "preferencestab.h"
|
||||
|
||||
class PreferencesPlaybackTab : public PreferencesTab
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesPlaybackTab();
|
||||
|
||||
virtual void Accept() override;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // PREFERENCESPLAYBACKTAB_H
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "preferencestab.h"
|
||||
|
||||
PreferencesTab::PreferencesTab()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef PREFERENCESTAB_H
|
||||
#define PREFERENCESTAB_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "config/config.h"
|
||||
|
||||
class PreferencesTab : public QWidget
|
||||
{
|
||||
public:
|
||||
PreferencesTab();
|
||||
|
||||
virtual void Accept() = 0;
|
||||
};
|
||||
|
||||
#endif // PREFERENCESTAB_H
|
||||
@@ -57,6 +57,8 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
QString app_version = "0.2.0";
|
||||
#ifdef GITHASH
|
||||
// Anything after the hyphen is considered "unimportant" information. Text BEFORE the hyphen is used in version
|
||||
// checking project files and config files
|
||||
app_version.append("-");
|
||||
app_version.append(GITHASH);
|
||||
#endif
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
Folder::Folder()
|
||||
{
|
||||
set_icon(olive::icon::Folder);
|
||||
}
|
||||
|
||||
Item::Type Folder::type() const
|
||||
@@ -36,3 +35,8 @@ bool Folder::CanHaveChildren() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
QIcon Folder::icon()
|
||||
{
|
||||
return olive::icon::Folder;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ public:
|
||||
|
||||
virtual bool CanHaveChildren() const override;
|
||||
|
||||
virtual QIcon icon() override;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
@@ -43,8 +43,6 @@ void Footage::set_status(const Footage::Status &status)
|
||||
{
|
||||
status_ = status;
|
||||
|
||||
UpdateIcon();
|
||||
|
||||
UpdateTooltip();
|
||||
}
|
||||
|
||||
@@ -116,6 +114,38 @@ void Footage::set_decoder(const QString &id)
|
||||
decoder_ = id;
|
||||
}
|
||||
|
||||
QIcon Footage::icon()
|
||||
{
|
||||
switch (status_) {
|
||||
case kUnprobed:
|
||||
case kUnindexed:
|
||||
// FIXME Set a waiting icon
|
||||
return QIcon();
|
||||
case kReady:
|
||||
if (HasStreamsOfType(Stream::kVideo)) {
|
||||
|
||||
// Prioritize the video icon
|
||||
return olive::icon::Video;
|
||||
|
||||
} else if (HasStreamsOfType(Stream::kAudio)) {
|
||||
|
||||
// Otherwise assume it's audio only
|
||||
return olive::icon::Audio;
|
||||
|
||||
} else if (HasStreamsOfType(Stream::kImage)) {
|
||||
|
||||
// Otherwise assume it's an image
|
||||
return olive::icon::Image;
|
||||
|
||||
}
|
||||
/* fall through */
|
||||
case kInvalid:
|
||||
return olive::icon::Error;
|
||||
}
|
||||
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
void Footage::ClearStreams()
|
||||
{
|
||||
if (streams_.empty()) {
|
||||
@@ -138,41 +168,6 @@ bool Footage::HasStreamsOfType(const Stream::Type type)
|
||||
return false;
|
||||
}
|
||||
|
||||
void Footage::UpdateIcon()
|
||||
{
|
||||
switch (status_) {
|
||||
case kUnprobed:
|
||||
case kUnindexed:
|
||||
// FIXME Set a waiting icon
|
||||
set_icon(QIcon());
|
||||
break;
|
||||
case kReady:
|
||||
if (HasStreamsOfType(Stream::kVideo)) {
|
||||
|
||||
// Prioritize the video icon
|
||||
set_icon(olive::icon::Video);
|
||||
break;
|
||||
|
||||
} else if (HasStreamsOfType(Stream::kAudio)) {
|
||||
|
||||
// Otherwise assume it's audio only
|
||||
set_icon(olive::icon::Audio);
|
||||
break;
|
||||
|
||||
} else if (HasStreamsOfType(Stream::kImage)) {
|
||||
|
||||
// Otherwise assume it's an image
|
||||
set_icon(olive::icon::Image);
|
||||
break;
|
||||
|
||||
}
|
||||
/* fall through */
|
||||
case kInvalid:
|
||||
set_icon(olive::icon::Error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Footage::UpdateTooltip()
|
||||
{
|
||||
switch (status_) {
|
||||
|
||||
@@ -205,6 +205,8 @@ public:
|
||||
*/
|
||||
void set_decoder(const QString& id);
|
||||
|
||||
virtual QIcon icon() override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Internal function to delete all Stream children and empty the array
|
||||
|
||||
@@ -101,16 +101,6 @@ void Item::set_tooltip(const QString &t)
|
||||
tooltip_ = t;
|
||||
}
|
||||
|
||||
const QIcon &Item::icon()
|
||||
{
|
||||
return icon_;
|
||||
}
|
||||
|
||||
void Item::set_icon(const QIcon &icon)
|
||||
{
|
||||
icon_ = icon;
|
||||
}
|
||||
|
||||
Item *Item::parent() const
|
||||
{
|
||||
return parent_;
|
||||
|
||||
@@ -92,8 +92,7 @@ public:
|
||||
const QString& tooltip() const;
|
||||
void set_tooltip(const QString& t);
|
||||
|
||||
const QIcon& icon();
|
||||
void set_icon(const QIcon& icon);
|
||||
virtual QIcon icon() = 0;
|
||||
|
||||
Item *parent() const;
|
||||
const Item* root() const;
|
||||
@@ -111,8 +110,6 @@ private:
|
||||
|
||||
QString name_;
|
||||
|
||||
QIcon icon_;
|
||||
|
||||
QString tooltip_;
|
||||
|
||||
};
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
Sequence::Sequence()
|
||||
{
|
||||
set_icon(olive::icon::Sequence);
|
||||
}
|
||||
|
||||
Item::Type Sequence::type() const
|
||||
@@ -33,6 +32,11 @@ Item::Type Sequence::type() const
|
||||
return kSequence;
|
||||
}
|
||||
|
||||
QIcon Sequence::icon()
|
||||
{
|
||||
return olive::icon::Sequence;
|
||||
}
|
||||
|
||||
const int &Sequence::video_width()
|
||||
{
|
||||
return video_width_;
|
||||
|
||||
@@ -38,6 +38,8 @@ public:
|
||||
*/
|
||||
virtual Type type() const override;
|
||||
|
||||
virtual QIcon icon() override;
|
||||
|
||||
/* VIDEO GETTER/SETTER FUNCTIONS */
|
||||
|
||||
const int& video_width();
|
||||
|
||||
@@ -123,7 +123,7 @@ QIcon olive::icon::Create(const QString& theme, const QString &name)
|
||||
QIcon icon;
|
||||
|
||||
for (int i=0;i<ICON_SIZE_COUNT;i++) {
|
||||
icon.addFile(QString(":/style/%1/png/%2.%3.png").arg(theme, name, QString::number(ICON_SIZES[i])),
|
||||
icon.addFile(QString("%1/png/%2.%3.png").arg(theme, name, QString::number(ICON_SIZES[i])),
|
||||
QSize(ICON_SIZES[i], ICON_SIZES[i]));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<RCC>
|
||||
<qresource prefix="/style/olive-dark">
|
||||
<file>palette.ini</file>
|
||||
<file>style.css</file>
|
||||
<file>png/add-button.16.png</file>
|
||||
<file>png/add-button.32.png</file>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
[All]
|
||||
AlternateBase=#353535
|
||||
Base=#191919
|
||||
BrightText=#FF0000
|
||||
Button=#353535
|
||||
ButtonText=#FFFFFF
|
||||
Disabled-ButtonText=#808080
|
||||
Highlight=#2A82DA
|
||||
HighlightedText=#FFFFFF
|
||||
Link=#2A82DA
|
||||
Text=#FFFFFF
|
||||
ToolTipBase=#191919
|
||||
ToolTipText=#FFFFFF
|
||||
Window=#353535
|
||||
WindowText=#FFFFFF
|
||||
|
||||
[Disabled]
|
||||
ButtonText=#808080
|
||||
@@ -18,56 +18,6 @@
|
||||
|
||||
***/
|
||||
|
||||
/***
|
||||
|
||||
Olive Dark - Qt CSS Theme
|
||||
|
||||
A fairly basic CSS style for the Olive Video Editor/Qt Fusion.
|
||||
|
||||
The primary colors are:
|
||||
|
||||
Main: #353535
|
||||
Text: #ffffff
|
||||
Disabled Text: #808080
|
||||
Highlight: #2a82da
|
||||
Highlight Text: #ffffff
|
||||
Dark: #191919
|
||||
|
||||
**/
|
||||
|
||||
/* Default widget colors */
|
||||
QWidget, QMenu::separator {
|
||||
/* Main */
|
||||
background: #353535;
|
||||
|
||||
/* Text */
|
||||
color: #ffffff;
|
||||
|
||||
/* Highlight */
|
||||
selection-background-color: #2a82da;
|
||||
|
||||
/* Highlight Text */
|
||||
selection-color: #ffffff;
|
||||
}
|
||||
|
||||
/* Default disabled colors */
|
||||
QWidget::disabled {
|
||||
/* Disabled Text */
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
/* Default link color */
|
||||
a {
|
||||
/* Highlight */
|
||||
color: #2a82da;
|
||||
}
|
||||
|
||||
/* All of these widgets' backgrounds are dark */
|
||||
QTreeView, QListView, QLineEdit, QMenu, QProgressBar, QPushButton::checked, NodeView, QComboBox, QSpinBox {
|
||||
/* Dark */
|
||||
background: #191919;
|
||||
}
|
||||
|
||||
/* Node styling */
|
||||
NodeViewItemWidget {
|
||||
qproperty-titlebarColor: #4040a0;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<RCC>
|
||||
<qresource prefix="/style/olive-light">
|
||||
<file>palette.ini</file>
|
||||
<file>style.css</file>
|
||||
<file>png/add-button.16.png</file>
|
||||
<file>png/add-button.32.png</file>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
[All]
|
||||
AlternateBase=#D0D0D0
|
||||
Base=#F0F0F0
|
||||
BrightText=#FF0000
|
||||
Button=#D0D0D0
|
||||
ButtonText=#000000
|
||||
Highlight=#2A82DA
|
||||
HighlightedText=#FFFFFF
|
||||
Link=#2A82DA
|
||||
Text=#000000
|
||||
ToolTipBase=#FFFFFF
|
||||
ToolTipText=#000000
|
||||
Window=#D0D0D0
|
||||
WindowText=#000000
|
||||
|
||||
[Disabled]
|
||||
ButtonText=#D0D0D0
|
||||
@@ -18,56 +18,6 @@
|
||||
|
||||
***/
|
||||
|
||||
/***
|
||||
|
||||
Olive Light - Qt CSS Theme
|
||||
|
||||
A fairly basic CSS style for the Olive Video Editor/Qt Fusion.
|
||||
|
||||
The primary colors are:
|
||||
|
||||
Main: #d0d0d0
|
||||
Text: #000000
|
||||
Disabled Text: #808080
|
||||
Highlight: #2a82da
|
||||
Highlight Text: #ffffff
|
||||
Dark: #ffffff
|
||||
|
||||
**/
|
||||
|
||||
/* Default widget colors */
|
||||
QWidget, QMenu::separator {
|
||||
/* Main */
|
||||
background: #d0d0d0;
|
||||
|
||||
/* Text */
|
||||
color: #000000;
|
||||
|
||||
/* Highlight */
|
||||
selection-background-color: #2a82da;
|
||||
|
||||
/* Highlight Text */
|
||||
selection-color: #ffffff;
|
||||
}
|
||||
|
||||
/* Default disabled colors */
|
||||
QWidget::disabled {
|
||||
/* Disabled Text */
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
/* Default link color */
|
||||
a {
|
||||
/* Highlight */
|
||||
color: #2a82da;
|
||||
}
|
||||
|
||||
/* All of these widgets' backgrounds are dark */
|
||||
QTreeView, QListView, QLineEdit, QMenu, QProgressBar, QPushButton::checked, NodeView, QComboBox, QSpinBox {
|
||||
/* Dark */
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
/* Node styling */
|
||||
NodeViewItemWidget {
|
||||
qproperty-titlebarColor: #a0a0ff;
|
||||
|
||||
+133
-9
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QPalette>
|
||||
#include <QStyle>
|
||||
#include <QStyleFactory>
|
||||
@@ -29,28 +30,151 @@
|
||||
|
||||
#include "ui/icons/icons.h"
|
||||
|
||||
void olive::style::AppSetDefault()
|
||||
QList<StyleDescriptor> StyleManager::ListInternal()
|
||||
{
|
||||
// FIXME: Fixed theme, allow the user to set this in-app
|
||||
SetOliveStyle("olive-dark");
|
||||
QList<StyleDescriptor> style_list;
|
||||
|
||||
style_list.append(StyleDescriptor(tr("Olive Dark"), ":/style/olive-dark"));
|
||||
style_list.append(StyleDescriptor(tr("Olive Light"), ":/style/olive-light"));
|
||||
|
||||
return style_list;
|
||||
}
|
||||
|
||||
void olive::style::SetOliveStyle(const QString &style_name)
|
||||
QPalette StyleManager::ParsePalette(const QString& ini_path)
|
||||
{
|
||||
qApp->setStyle(QStyleFactory::create("Fusion"));
|
||||
QSettings ini(ini_path, QSettings::IniFormat);
|
||||
QPalette palette;
|
||||
|
||||
ParsePaletteGroup(&ini, &palette, QPalette::All);
|
||||
ParsePaletteGroup(&ini, &palette, QPalette::Active);
|
||||
ParsePaletteGroup(&ini, &palette, QPalette::Inactive);
|
||||
ParsePaletteGroup(&ini, &palette, QPalette::Disabled);
|
||||
|
||||
return palette;
|
||||
}
|
||||
|
||||
void StyleManager::ParsePaletteGroup(QSettings *ini, QPalette *palette, QPalette::ColorGroup group)
|
||||
{
|
||||
QString group_name;
|
||||
|
||||
switch (group) {
|
||||
case QPalette::All:
|
||||
group_name = "All";
|
||||
break;
|
||||
case QPalette::Active:
|
||||
group_name = "Active";
|
||||
break;
|
||||
case QPalette::Inactive:
|
||||
group_name = "Inactive";
|
||||
break;
|
||||
case QPalette::Disabled:
|
||||
group_name = "Disabled";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
ini->beginGroup(group_name);
|
||||
|
||||
QStringList keys = ini->childKeys();
|
||||
foreach (QString k, keys) {
|
||||
ParsePaletteColor(ini, palette, group, k);
|
||||
}
|
||||
|
||||
ini->endGroup();
|
||||
}
|
||||
|
||||
void StyleManager::ParsePaletteColor(QSettings *ini, QPalette *palette, QPalette::ColorGroup group, const QString &role_name)
|
||||
{
|
||||
QPalette::ColorRole role;
|
||||
|
||||
if (!QString::compare(role_name, "Window", Qt::CaseInsensitive)) {
|
||||
role = QPalette::Window;
|
||||
} else if (!QString::compare(role_name, "WindowText", Qt::CaseInsensitive)) {
|
||||
role = QPalette::WindowText;
|
||||
} else if (!QString::compare(role_name, "Base", Qt::CaseInsensitive)) {
|
||||
role = QPalette::Base;
|
||||
} else if (!QString::compare(role_name, "AlternateBase", Qt::CaseInsensitive)) {
|
||||
role = QPalette::AlternateBase;
|
||||
} else if (!QString::compare(role_name, "ToolTipBase", Qt::CaseInsensitive)) {
|
||||
role = QPalette::ToolTipBase;
|
||||
} else if (!QString::compare(role_name, "ToolTipText", Qt::CaseInsensitive)) {
|
||||
role = QPalette::ToolTipText;
|
||||
} else if (!QString::compare(role_name, "PlaceholderText", Qt::CaseInsensitive)) {
|
||||
role = QPalette::PlaceholderText;
|
||||
} else if (!QString::compare(role_name, "Text", Qt::CaseInsensitive)) {
|
||||
role = QPalette::Text;
|
||||
} else if (!QString::compare(role_name, "Button", Qt::CaseInsensitive)) {
|
||||
role = QPalette::Button;
|
||||
} else if (!QString::compare(role_name, "ButtonText", Qt::CaseInsensitive)) {
|
||||
role = QPalette::ButtonText;
|
||||
} else if (!QString::compare(role_name, "BrightText", Qt::CaseInsensitive)) {
|
||||
role = QPalette::BrightText;
|
||||
} else if (!QString::compare(role_name, "Highlight", Qt::CaseInsensitive)) {
|
||||
role = QPalette::Highlight;
|
||||
} else if (!QString::compare(role_name, "HighlightedText", Qt::CaseInsensitive)) {
|
||||
role = QPalette::HighlightedText;
|
||||
} else if (!QString::compare(role_name, "Link", Qt::CaseInsensitive)) {
|
||||
role = QPalette::Link;
|
||||
} else if (!QString::compare(role_name, "LinkVisited", Qt::CaseInsensitive)) {
|
||||
role = QPalette::LinkVisited;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
palette->setColor(group, role, QColor(ini->value(role_name).toString()));
|
||||
}
|
||||
|
||||
StyleDescriptor StyleManager::DefaultStyle()
|
||||
{
|
||||
return ListInternal().first();
|
||||
}
|
||||
|
||||
void StyleManager::SetStyle(const StyleDescriptor &style)
|
||||
{
|
||||
SetStyle(style.path());
|
||||
}
|
||||
|
||||
void StyleManager::SetStyle(const QString &style_path)
|
||||
{
|
||||
// Load all icons for this style (icons must be loaded first because the style change below triggers the icon change)
|
||||
olive::icon::LoadAll(style_path);
|
||||
|
||||
// Set palette for this
|
||||
QString palette_file = QString("%1/palette.ini").arg(style_path);
|
||||
if (QFileInfo::exists(palette_file)) {
|
||||
qApp->setPalette(ParsePalette(palette_file));
|
||||
} else {
|
||||
qApp->setPalette(qApp->style()->standardPalette());
|
||||
}
|
||||
|
||||
// Set CSS style for this
|
||||
QFile css_file(QString(":/style/%1/style.css").arg(style_name));
|
||||
QFile css_file(QString("%1/style.css").arg(style_path));
|
||||
|
||||
if (css_file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
if (css_file.exists() && css_file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
// Read in entire CSS from file and set as the application stylesheet
|
||||
QTextStream css_ts(&css_file);
|
||||
|
||||
qApp->setStyleSheet(css_ts.readAll());
|
||||
|
||||
css_file.close();
|
||||
} else {
|
||||
qApp->setStyleSheet(QString());
|
||||
}
|
||||
}
|
||||
|
||||
// Load all icons for this style
|
||||
olive::icon::LoadAll(style_name);
|
||||
StyleDescriptor::StyleDescriptor(const QString &name, const QString &path) :
|
||||
name_(name),
|
||||
path_(path)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &StyleDescriptor::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
const QString &StyleDescriptor::path() const
|
||||
{
|
||||
return path_;
|
||||
}
|
||||
|
||||
+29
-13
@@ -21,23 +21,39 @@
|
||||
#ifndef STYLEMANAGER_H
|
||||
#define STYLEMANAGER_H
|
||||
|
||||
#include <QSettings>
|
||||
#include <QWidget>
|
||||
|
||||
namespace olive {
|
||||
namespace style {
|
||||
class StyleDescriptor {
|
||||
public:
|
||||
StyleDescriptor(const QString& name, const QString& path);
|
||||
|
||||
/**
|
||||
* @brief Sets the application style to "Olive Default"
|
||||
*
|
||||
* This function should probably be replaced (or at least renamed) later as alternative styles are reimplemented.
|
||||
* At the moment, this is a convenience function for setting to "Olive Default" which is a cross-platform default
|
||||
* style used in Olive.
|
||||
*/
|
||||
void AppSetDefault();
|
||||
const QString& name() const;
|
||||
const QString& path() const;
|
||||
|
||||
void SetOliveStyle(const QString& style_name);
|
||||
private:
|
||||
QString name_;
|
||||
QString path_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
class StyleManager : public QObject {
|
||||
public:
|
||||
StyleManager();
|
||||
|
||||
static StyleDescriptor DefaultStyle();
|
||||
|
||||
static void SetStyle(const StyleDescriptor& style);
|
||||
|
||||
static void SetStyle(const QString& style_path);
|
||||
|
||||
static QList<StyleDescriptor> ListInternal();
|
||||
|
||||
private:
|
||||
static QPalette ParsePalette(const QString& ini_path);
|
||||
|
||||
static void ParsePaletteGroup(QSettings* ini, QPalette* palette, QPalette::ColorGroup group);
|
||||
|
||||
static void ParsePaletteColor(QSettings* ini, QPalette* palette, QPalette::ColorGroup group, const QString& role_name);
|
||||
};
|
||||
|
||||
#endif // STYLEMANAGER_H
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
add_subdirectory(columnedgridlayout)
|
||||
add_subdirectory(flowlayout)
|
||||
add_subdirectory(footagecombobox)
|
||||
add_subdirectory(menu)
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2019 Olive Team
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
widget/columnedgridlayout/columnedgridlayout.h
|
||||
widget/columnedgridlayout/columnedgridlayout.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "columnedgridlayout.h"
|
||||
|
||||
ColumnedGridLayout::ColumnedGridLayout(QWidget* parent,
|
||||
int maximum_columns) :
|
||||
QGridLayout (parent),
|
||||
maximum_columns_(maximum_columns)
|
||||
{
|
||||
}
|
||||
|
||||
void ColumnedGridLayout::Add(QWidget *widget)
|
||||
{
|
||||
if (maximum_columns_ > 0) {
|
||||
|
||||
int row = count() / maximum_columns_;
|
||||
int column = count() % maximum_columns_;
|
||||
|
||||
addWidget(widget, row, column);
|
||||
|
||||
} else {
|
||||
|
||||
addWidget(widget);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int ColumnedGridLayout::MaximumColumns() const
|
||||
{
|
||||
return maximum_columns_;
|
||||
}
|
||||
|
||||
void ColumnedGridLayout::SetMaximumColumns(int maximum_columns)
|
||||
{
|
||||
maximum_columns_ = maximum_columns;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef COLUMNEDGRIDLAYOUT_H
|
||||
#define COLUMNEDGRIDLAYOUT_H
|
||||
|
||||
#include <QGridLayout>
|
||||
|
||||
/**
|
||||
* @brief The ColumnedGridLayout class
|
||||
*
|
||||
* A simple derivative of QGridLayout that provides a automatic row/column layout based on a specified maximum
|
||||
* column count.
|
||||
*/
|
||||
class ColumnedGridLayout : public QGridLayout
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ColumnedGridLayout(QWidget* parent = nullptr,
|
||||
int maximum_columns = 0);
|
||||
|
||||
void Add(QWidget* widget);
|
||||
int MaximumColumns() const;
|
||||
void SetMaximumColumns(int maximum_columns);
|
||||
|
||||
private:
|
||||
int maximum_columns_;
|
||||
};
|
||||
|
||||
#endif // COLUMNEDGRIDLAYOUT_H
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#include "playbackcontrols.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QEvent>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
#include "common/timecodefunctions.h"
|
||||
@@ -63,28 +65,24 @@ PlaybackControls::PlaybackControls(QWidget *parent) :
|
||||
lower_middle_layout->addStretch();
|
||||
|
||||
// Go To Start Button
|
||||
QPushButton* go_to_start_btn = new QPushButton();
|
||||
go_to_start_btn->setIcon(olive::icon::GoToStart);
|
||||
lower_middle_layout->addWidget(go_to_start_btn);
|
||||
connect(go_to_start_btn, SIGNAL(clicked(bool)), this, SIGNAL(BeginClicked()));
|
||||
go_to_start_btn_ = new QPushButton();
|
||||
lower_middle_layout->addWidget(go_to_start_btn_);
|
||||
connect(go_to_start_btn_, SIGNAL(clicked(bool)), this, SIGNAL(BeginClicked()));
|
||||
|
||||
// Prev Frame Button
|
||||
QPushButton* prev_frame_btn = new QPushButton();
|
||||
prev_frame_btn->setIcon(olive::icon::PrevFrame);
|
||||
lower_middle_layout->addWidget(prev_frame_btn);
|
||||
connect(prev_frame_btn, SIGNAL(clicked(bool)), this, SIGNAL(PrevFrameClicked()));
|
||||
prev_frame_btn_ = new QPushButton();
|
||||
lower_middle_layout->addWidget(prev_frame_btn_);
|
||||
connect(prev_frame_btn_, SIGNAL(clicked(bool)), this, SIGNAL(PrevFrameClicked()));
|
||||
|
||||
// Play/Pause Button
|
||||
playpause_stack_ = new QStackedWidget();
|
||||
lower_middle_layout->addWidget(playpause_stack_);
|
||||
|
||||
play_btn_ = new QPushButton();
|
||||
play_btn_->setIcon(olive::icon::Play);
|
||||
playpause_stack_->addWidget(play_btn_);
|
||||
connect(play_btn_, SIGNAL(clicked(bool)), this, SIGNAL(PlayClicked()));
|
||||
|
||||
pause_btn_ = new QPushButton();
|
||||
pause_btn_->setIcon(olive::icon::Pause);
|
||||
playpause_stack_->addWidget(pause_btn_);
|
||||
connect(pause_btn_, SIGNAL(clicked(bool)), this, SIGNAL(PauseClicked()));
|
||||
|
||||
@@ -93,16 +91,14 @@ PlaybackControls::PlaybackControls(QWidget *parent) :
|
||||
playpause_stack_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
|
||||
|
||||
// Next Frame Button
|
||||
QPushButton* next_frame_btn = new QPushButton();
|
||||
next_frame_btn->setIcon(olive::icon::NextFrame);
|
||||
lower_middle_layout->addWidget(next_frame_btn);
|
||||
connect(next_frame_btn, SIGNAL(clicked(bool)), this, SIGNAL(NextFrameClicked()));
|
||||
next_frame_btn_ = new QPushButton();
|
||||
lower_middle_layout->addWidget(next_frame_btn_);
|
||||
connect(next_frame_btn_, SIGNAL(clicked(bool)), this, SIGNAL(NextFrameClicked()));
|
||||
|
||||
// Go To End Button
|
||||
QPushButton* go_to_end_btn = new QPushButton();
|
||||
go_to_end_btn->setIcon(olive::icon::GoToEnd);
|
||||
lower_middle_layout->addWidget(go_to_end_btn);
|
||||
connect(go_to_end_btn, SIGNAL(clicked(bool)), this, SIGNAL(EndClicked()));
|
||||
go_to_end_btn_ = new QPushButton();
|
||||
lower_middle_layout->addWidget(go_to_end_btn_);
|
||||
connect(go_to_end_btn_, SIGNAL(clicked(bool)), this, SIGNAL(EndClicked()));
|
||||
|
||||
lower_middle_layout->addStretch();
|
||||
|
||||
@@ -119,6 +115,8 @@ PlaybackControls::PlaybackControls(QWidget *parent) :
|
||||
lower_right_layout->addStretch();
|
||||
end_tc_lbl_ = new QLabel("00:00:00;00");
|
||||
lower_right_layout->addWidget(end_tc_lbl_);
|
||||
|
||||
UpdateIcons();
|
||||
}
|
||||
|
||||
void PlaybackControls::SetTimecodeEnabled(bool enabled)
|
||||
@@ -136,7 +134,9 @@ void PlaybackControls::SetTime(const int64_t &r)
|
||||
{
|
||||
Q_ASSERT(time_base_.denominator() != 0);
|
||||
|
||||
cur_tc_lbl_->setText(olive::timestamp_to_timecode(r, time_base_, kTimecodeDisplay));
|
||||
cur_tc_lbl_->setText(olive::timestamp_to_timecode(r,
|
||||
time_base_,
|
||||
olive::CurrentTimecodeDisplay()));
|
||||
}
|
||||
|
||||
void PlaybackControls::ShowPauseButton()
|
||||
@@ -149,3 +149,22 @@ void PlaybackControls::ShowPlayButton()
|
||||
{
|
||||
playpause_stack_->setCurrentWidget(play_btn_);
|
||||
}
|
||||
|
||||
void PlaybackControls::changeEvent(QEvent *e)
|
||||
{
|
||||
QWidget::changeEvent(e);
|
||||
|
||||
if (e->type() == QEvent::StyleChange) {
|
||||
UpdateIcons();
|
||||
}
|
||||
}
|
||||
|
||||
void PlaybackControls::UpdateIcons()
|
||||
{
|
||||
go_to_start_btn_->setIcon(olive::icon::GoToStart);
|
||||
prev_frame_btn_->setIcon(olive::icon::PrevFrame);
|
||||
play_btn_->setIcon(olive::icon::Play);
|
||||
pause_btn_->setIcon(olive::icon::Pause);
|
||||
next_frame_btn_->setIcon(olive::icon::NextFrame);
|
||||
go_to_end_btn_->setIcon(olive::icon::GoToEnd);
|
||||
}
|
||||
|
||||
@@ -84,7 +84,12 @@ signals:
|
||||
*/
|
||||
void EndClicked();
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent *) override;
|
||||
|
||||
private:
|
||||
void UpdateIcons();
|
||||
|
||||
QWidget* lower_left_container_;
|
||||
QWidget* lower_right_container_;
|
||||
|
||||
@@ -93,8 +98,12 @@ private:
|
||||
|
||||
rational time_base_;
|
||||
|
||||
QPushButton* go_to_start_btn_;
|
||||
QPushButton* prev_frame_btn_;
|
||||
QPushButton* play_btn_;
|
||||
QPushButton* pause_btn_;
|
||||
QPushButton* next_frame_btn_;
|
||||
QPushButton* go_to_end_btn_;
|
||||
|
||||
QStackedWidget* playpause_stack_;
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ ProjectExplorerNavigation::ProjectExplorerNavigation(QWidget *parent) :
|
||||
// Create "directory up" button
|
||||
dir_up_btn_ = new QPushButton(this);
|
||||
dir_up_btn_->setEnabled(false);
|
||||
dir_up_btn_->setIcon(olive::icon::DirUp);
|
||||
dir_up_btn_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
|
||||
layout->addWidget(dir_up_btn_);
|
||||
connect(dir_up_btn_, SIGNAL(clicked(bool)), this, SIGNAL(DirectoryUpClicked()));
|
||||
@@ -49,14 +48,12 @@ ProjectExplorerNavigation::ProjectExplorerNavigation(QWidget *parent) :
|
||||
// Create size slider
|
||||
size_slider_ = new QSlider(this);
|
||||
size_slider_->setOrientation(Qt::Horizontal);
|
||||
size_slider_->setMinimum(olive::kProjectIconSizeMinimum);
|
||||
size_slider_->setMaximum(olive::kProjectIconSizeMaximum);
|
||||
size_slider_->setValue(olive::kProjectIconSizeDefault);
|
||||
size_slider_->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
|
||||
layout->addWidget(size_slider_);
|
||||
connect(size_slider_, SIGNAL(valueChanged(int)), this, SIGNAL(SizeChanged(int)));
|
||||
|
||||
Retranslate();
|
||||
UpdateIcons();
|
||||
}
|
||||
|
||||
void ProjectExplorerNavigation::set_text(const QString &s)
|
||||
@@ -78,6 +75,8 @@ void ProjectExplorerNavigation::changeEvent(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
Retranslate();
|
||||
} else if (e->type() == QEvent::StyleChange) {
|
||||
UpdateIcons();
|
||||
}
|
||||
QWidget::changeEvent(e);
|
||||
}
|
||||
@@ -86,3 +85,11 @@ void ProjectExplorerNavigation::Retranslate()
|
||||
{
|
||||
dir_up_btn_->setToolTip(tr("Go to parent folder"));
|
||||
}
|
||||
|
||||
void ProjectExplorerNavigation::UpdateIcons()
|
||||
{
|
||||
dir_up_btn_->setIcon(olive::icon::DirUp);
|
||||
size_slider_->setMinimum(olive::kProjectIconSizeMinimum);
|
||||
size_slider_->setMaximum(olive::kProjectIconSizeMaximum);
|
||||
size_slider_->setValue(olive::kProjectIconSizeDefault);
|
||||
}
|
||||
|
||||
@@ -99,6 +99,8 @@ protected:
|
||||
private:
|
||||
void Retranslate();
|
||||
|
||||
void UpdateIcons();
|
||||
|
||||
QPushButton* dir_up_btn_;
|
||||
|
||||
QLabel* dir_lbl_;
|
||||
|
||||
@@ -34,27 +34,22 @@ ProjectToolbar::ProjectToolbar(QWidget *parent) :
|
||||
layout->setMargin(0);
|
||||
|
||||
new_button_ = new QPushButton();
|
||||
new_button_->setIcon(olive::icon::New);
|
||||
connect(new_button_, SIGNAL(clicked(bool)), this, SIGNAL(NewClicked()));
|
||||
layout->addWidget(new_button_);
|
||||
|
||||
open_button_ = new QPushButton();
|
||||
open_button_->setIcon(olive::icon::Open);
|
||||
connect(open_button_, SIGNAL(clicked(bool)), this, SIGNAL(OpenClicked()));
|
||||
layout->addWidget(open_button_);
|
||||
|
||||
save_button_ = new QPushButton();
|
||||
save_button_->setIcon(olive::icon::Save);
|
||||
connect(save_button_, SIGNAL(clicked(bool)), this, SIGNAL(SaveClicked()));
|
||||
layout->addWidget(save_button_);
|
||||
|
||||
undo_button_ = new QPushButton();
|
||||
undo_button_->setIcon(olive::icon::Undo);
|
||||
connect(undo_button_, SIGNAL(clicked(bool)), this, SIGNAL(UndoClicked()));
|
||||
layout->addWidget(undo_button_);
|
||||
|
||||
redo_button_ = new QPushButton();
|
||||
redo_button_->setIcon(olive::icon::Redo);
|
||||
connect(redo_button_, SIGNAL(clicked(bool)), this, SIGNAL(RedoClicked()));
|
||||
layout->addWidget(redo_button_);
|
||||
|
||||
@@ -64,19 +59,16 @@ ProjectToolbar::ProjectToolbar(QWidget *parent) :
|
||||
layout->addWidget(search_field_);
|
||||
|
||||
tree_button_ = new QPushButton();
|
||||
tree_button_->setIcon(olive::icon::TreeView);
|
||||
tree_button_->setCheckable(true);
|
||||
connect(tree_button_, SIGNAL(clicked(bool)), this, SLOT(ViewButtonClicked()));
|
||||
layout->addWidget(tree_button_);
|
||||
|
||||
list_button_ = new QPushButton();
|
||||
list_button_->setIcon(olive::icon::ListView);
|
||||
list_button_->setCheckable(true);
|
||||
connect(list_button_, SIGNAL(clicked(bool)), this, SLOT(ViewButtonClicked()));
|
||||
layout->addWidget(list_button_);
|
||||
|
||||
icon_button_ = new QPushButton();
|
||||
icon_button_->setIcon(olive::icon::IconView);
|
||||
icon_button_->setCheckable(true);
|
||||
connect(icon_button_, SIGNAL(clicked(bool)), this, SLOT(ViewButtonClicked()));
|
||||
layout->addWidget(icon_button_);
|
||||
@@ -89,6 +81,7 @@ ProjectToolbar::ProjectToolbar(QWidget *parent) :
|
||||
view_button_group->addButton(icon_button_);
|
||||
|
||||
Retranslate();
|
||||
UpdateIcons();
|
||||
}
|
||||
|
||||
void ProjectToolbar::SetView(olive::ProjectViewType type)
|
||||
@@ -110,6 +103,8 @@ void ProjectToolbar::changeEvent(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
Retranslate();
|
||||
} else if (e->type() == QEvent::StyleChange) {
|
||||
UpdateIcons();
|
||||
}
|
||||
QWidget::changeEvent(e);
|
||||
}
|
||||
@@ -129,6 +124,18 @@ void ProjectToolbar::Retranslate()
|
||||
icon_button_->setToolTip(tr("Switch to Icon View"));
|
||||
}
|
||||
|
||||
void ProjectToolbar::UpdateIcons()
|
||||
{
|
||||
new_button_->setIcon(olive::icon::New);
|
||||
open_button_->setIcon(olive::icon::Open);
|
||||
save_button_->setIcon(olive::icon::Save);
|
||||
undo_button_->setIcon(olive::icon::Undo);
|
||||
redo_button_->setIcon(olive::icon::Redo);
|
||||
tree_button_->setIcon(olive::icon::TreeView);
|
||||
list_button_->setIcon(olive::icon::ListView);
|
||||
icon_button_->setIcon(olive::icon::IconView);
|
||||
}
|
||||
|
||||
void ProjectToolbar::ViewButtonClicked()
|
||||
{
|
||||
// Determine which view button triggered this slot and emit a signal accordingly
|
||||
|
||||
@@ -61,6 +61,7 @@ signals:
|
||||
|
||||
private:
|
||||
void Retranslate();
|
||||
void UpdateIcons();
|
||||
|
||||
QPushButton* new_button_;
|
||||
QPushButton* open_button_;
|
||||
|
||||
@@ -51,6 +51,7 @@ TimelineView::TimelineView(QWidget *parent) :
|
||||
setAlignment(Qt::AlignLeft | Qt::AlignTop);
|
||||
setDragMode(RubberBandDrag);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
setBackgroundRole(QPalette::Window);
|
||||
|
||||
connect(&scene_, SIGNAL(changed(const QList<QRectF>&)), this, SLOT(UpdateSceneRect()));
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ void TimelineView::ImportTool::DragEnter(QDragEnterEvent *event)
|
||||
|
||||
if (stream->type() == Stream::kImage) {
|
||||
// Stream is essentially length-less - use config's default image length
|
||||
footage_duration = kDefaultImageLength;
|
||||
footage_duration = Config::Current()["DefaultStillLength"].value<rational>();
|
||||
} else {
|
||||
// Use duration from file
|
||||
footage_duration = rational(stream->timebase().numerator() * stream->duration(),
|
||||
@@ -151,7 +151,7 @@ void TimelineView::ImportTool::DragMove(QDragMoveEvent *event)
|
||||
int64_t earliest_timestamp = olive::time_to_timestamp(earliest_ghost, parent()->timebase_);
|
||||
QString tooltip_text = olive::timestamp_to_timecode(earliest_timestamp,
|
||||
parent()->timebase_,
|
||||
kTimecodeDisplay);
|
||||
olive::CurrentTimecodeDisplay());
|
||||
QToolTip::showText(QCursor::pos(),
|
||||
tooltip_text,
|
||||
parent());
|
||||
|
||||
@@ -279,7 +279,7 @@ void TimelineView::PointerTool::ProcessDrag(const QPoint &mouse_pos)
|
||||
int64_t earliest_timestamp = olive::time_to_timestamp(time_movement, parent()->timebase_);
|
||||
QString tooltip_text = olive::timestamp_to_timecode(earliest_timestamp,
|
||||
parent()->timebase_,
|
||||
kTimecodeDisplay,
|
||||
olive::CurrentTimecodeDisplay(),
|
||||
true);
|
||||
QToolTip::showText(QCursor::pos(),
|
||||
tooltip_text,
|
||||
|
||||
@@ -58,7 +58,7 @@ void TimelineView::SlipTool::ProcessDrag(const QPoint &mouse_pos)
|
||||
int64_t earliest_timestamp = olive::time_to_timestamp(time_movement, parent()->timebase_);
|
||||
QString tooltip_text = olive::timestamp_to_timecode(earliest_timestamp,
|
||||
parent()->timebase_,
|
||||
kTimecodeDisplay,
|
||||
olive::CurrentTimecodeDisplay(),
|
||||
true);
|
||||
QToolTip::showText(QCursor::pos(),
|
||||
tooltip_text,
|
||||
|
||||
@@ -156,7 +156,7 @@ void TimeRuler::paintEvent(QPaintEvent *)
|
||||
if (text_visible_) {
|
||||
QFontMetrics fm = p.fontMetrics();
|
||||
double width_of_second = scale_;
|
||||
int average_text_width = QFontMetricsWidth(&fm, olive::timestamp_to_timecode(0, timebase_, kTimecodeDisplay));
|
||||
int average_text_width = QFontMetricsWidth(&fm, olive::timestamp_to_timecode(0, timebase_, olive::CurrentTimecodeDisplay()));
|
||||
half_average_text_width = average_text_width/2;
|
||||
while (width_of_second * text_skip < average_text_width) {
|
||||
text_skip++;
|
||||
@@ -202,7 +202,7 @@ void TimeRuler::paintEvent(QPaintEvent *)
|
||||
|
||||
// Try to draw text here
|
||||
if (text_visible_ && sec%text_skip == 0) {
|
||||
QString timecode_string = olive::timestamp_to_timecode(sec, timebase_, kTimecodeDisplay);
|
||||
QString timecode_string = olive::timestamp_to_timecode(sec, timebase_, olive::CurrentTimecodeDisplay());
|
||||
|
||||
int text_x = i;
|
||||
|
||||
|
||||
@@ -34,24 +34,25 @@ Toolbar::Toolbar(QWidget *parent) :
|
||||
layout_->setMargin(0);
|
||||
|
||||
// Create standard tool buttons
|
||||
btn_pointer_tool_ = CreateToolButton(olive::icon::ToolPointer, olive::tool::kPointer);
|
||||
btn_edit_tool_ = CreateToolButton(olive::icon::ToolEdit, olive::tool::kEdit);
|
||||
btn_ripple_tool_ = CreateToolButton(olive::icon::ToolRipple, olive::tool::kRipple);
|
||||
btn_rolling_tool_ = CreateToolButton(olive::icon::ToolRolling, olive::tool::kRolling);
|
||||
btn_razor_tool_ = CreateToolButton(olive::icon::ToolRazor, olive::tool::kRazor);
|
||||
btn_slip_tool_ = CreateToolButton(olive::icon::ToolSlip, olive::tool::kSlip);
|
||||
btn_slide_tool_ = CreateToolButton(olive::icon::ToolSlide, olive::tool::kSlide);
|
||||
btn_hand_tool_ = CreateToolButton(olive::icon::ToolHand, olive::tool::kHand);
|
||||
btn_zoom_tool_ = CreateToolButton(olive::icon::ZoomIn, olive::tool::kZoom);
|
||||
btn_record_ = CreateToolButton(olive::icon::Record, olive::tool::kRecord);
|
||||
btn_transition_tool_ = CreateToolButton(olive::icon::ToolTransition, olive::tool::kTransition);
|
||||
btn_add_ = CreateToolButton(olive::icon::Add, olive::tool::kAdd);
|
||||
btn_pointer_tool_ = CreateToolButton(olive::tool::kPointer);
|
||||
btn_edit_tool_ = CreateToolButton(olive::tool::kEdit);
|
||||
btn_ripple_tool_ = CreateToolButton(olive::tool::kRipple);
|
||||
btn_rolling_tool_ = CreateToolButton(olive::tool::kRolling);
|
||||
btn_razor_tool_ = CreateToolButton(olive::tool::kRazor);
|
||||
btn_slip_tool_ = CreateToolButton(olive::tool::kSlip);
|
||||
btn_slide_tool_ = CreateToolButton(olive::tool::kSlide);
|
||||
btn_hand_tool_ = CreateToolButton(olive::tool::kHand);
|
||||
btn_zoom_tool_ = CreateToolButton(olive::tool::kZoom);
|
||||
btn_record_ = CreateToolButton(olive::tool::kRecord);
|
||||
btn_transition_tool_ = CreateToolButton(olive::tool::kTransition);
|
||||
btn_add_ = CreateToolButton(olive::tool::kAdd);
|
||||
|
||||
// Create snapping button, which is not actually a tool, it's a toggle option
|
||||
btn_snapping_toggle_ = CreateNonToolButton(olive::icon::Snapping);
|
||||
btn_snapping_toggle_ = CreateNonToolButton();
|
||||
connect(btn_snapping_toggle_, SIGNAL(clicked(bool)), this, SLOT(SnappingButtonClicked(bool)));
|
||||
|
||||
Retranslate();
|
||||
UpdateIcons();
|
||||
}
|
||||
|
||||
void Toolbar::SetTool(const olive::tool::Tool& tool)
|
||||
@@ -74,6 +75,8 @@ void Toolbar::changeEvent(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
Retranslate();
|
||||
} else if (e->type() == QEvent::StyleChange) {
|
||||
UpdateIcons();
|
||||
}
|
||||
QWidget::changeEvent(e);
|
||||
}
|
||||
@@ -95,10 +98,27 @@ void Toolbar::Retranslate()
|
||||
btn_snapping_toggle_->setToolTip(tr("Toggle Snapping"));
|
||||
}
|
||||
|
||||
ToolbarButton* Toolbar::CreateToolButton(const QIcon &icon, const olive::tool::Tool& tool)
|
||||
void Toolbar::UpdateIcons()
|
||||
{
|
||||
btn_pointer_tool_->setIcon(olive::icon::ToolPointer);
|
||||
btn_edit_tool_->setIcon(olive::icon::ToolEdit);
|
||||
btn_ripple_tool_->setIcon(olive::icon::ToolRipple);
|
||||
btn_rolling_tool_->setIcon(olive::icon::ToolRolling);
|
||||
btn_razor_tool_->setIcon(olive::icon::ToolRazor);
|
||||
btn_slip_tool_->setIcon(olive::icon::ToolSlip);
|
||||
btn_slide_tool_->setIcon(olive::icon::ToolSlide);
|
||||
btn_hand_tool_->setIcon(olive::icon::ToolHand);
|
||||
btn_zoom_tool_->setIcon(olive::icon::ZoomIn);
|
||||
btn_record_->setIcon(olive::icon::Record);
|
||||
btn_transition_tool_->setIcon(olive::icon::ToolTransition);
|
||||
btn_add_->setIcon(olive::icon::Add);
|
||||
btn_snapping_toggle_->setIcon(olive::icon::Snapping);
|
||||
}
|
||||
|
||||
ToolbarButton* Toolbar::CreateToolButton(const olive::tool::Tool& tool)
|
||||
{
|
||||
// Create a ToolbarButton object
|
||||
ToolbarButton* b = new ToolbarButton(this, icon, tool);
|
||||
ToolbarButton* b = new ToolbarButton(this, tool);
|
||||
|
||||
// Add it to the layout
|
||||
layout_->addWidget(b);
|
||||
@@ -112,10 +132,10 @@ ToolbarButton* Toolbar::CreateToolButton(const QIcon &icon, const olive::tool::T
|
||||
return b;
|
||||
}
|
||||
|
||||
ToolbarButton *Toolbar::CreateNonToolButton(const QIcon &icon)
|
||||
ToolbarButton *Toolbar::CreateNonToolButton()
|
||||
{
|
||||
// Create a ToolbarButton object
|
||||
ToolbarButton* b = new ToolbarButton(this, icon, olive::tool::kNone);
|
||||
ToolbarButton* b = new ToolbarButton(this, olive::tool::kNone);
|
||||
|
||||
// Add it to the layout
|
||||
layout_->addWidget(b);
|
||||
|
||||
@@ -112,6 +112,11 @@ private:
|
||||
*/
|
||||
void Retranslate();
|
||||
|
||||
/**
|
||||
* @brief Update icons after a style change
|
||||
*/
|
||||
void UpdateIcons();
|
||||
|
||||
/**
|
||||
* @brief Internal convenience function for creating tool buttons quickly
|
||||
*
|
||||
@@ -125,7 +130,7 @@ private:
|
||||
*
|
||||
* The created ToolbarButton. The button parent is automatically set to `this`.
|
||||
*/
|
||||
ToolbarButton* CreateToolButton(const QIcon &icon, const olive::tool::Tool& tool);
|
||||
ToolbarButton* CreateToolButton(const olive::tool::Tool& tool);
|
||||
|
||||
/**
|
||||
* @brief Internal convenience function for creating buttons quickly
|
||||
@@ -138,7 +143,7 @@ private:
|
||||
*
|
||||
* The created ToolbarButton. The button parent is automatically set to `this`.
|
||||
*/
|
||||
ToolbarButton* CreateNonToolButton(const QIcon &icon);
|
||||
ToolbarButton* CreateNonToolButton();
|
||||
|
||||
/**
|
||||
* @brief Internal layout used for buttons
|
||||
|
||||
@@ -20,12 +20,11 @@
|
||||
|
||||
#include "toolbarbutton.h"
|
||||
|
||||
ToolbarButton::ToolbarButton(QWidget *parent, const QIcon &icon, const olive::tool::Tool &tool) :
|
||||
ToolbarButton::ToolbarButton(QWidget *parent, const olive::tool::Tool &tool) :
|
||||
QPushButton(parent),
|
||||
tool_(tool)
|
||||
{
|
||||
setCheckable(true);
|
||||
setIcon(icon);
|
||||
}
|
||||
|
||||
const olive::tool::Tool &ToolbarButton::tool()
|
||||
|
||||
@@ -38,15 +38,11 @@ public:
|
||||
*
|
||||
* QWidget parent. Almost always an instance of Toolbar.
|
||||
*
|
||||
* @param icon
|
||||
*
|
||||
* Icon to set this QWidget to.
|
||||
*
|
||||
* @param tool
|
||||
*
|
||||
* Tool object. Must be a member of enum olive::tool::Tool, including kNone if this button does not represent a tool.
|
||||
*/
|
||||
ToolbarButton(QWidget* parent, const QIcon& icon, const olive::tool::Tool& tool);
|
||||
ToolbarButton(QWidget* parent, const olive::tool::Tool& tool);
|
||||
|
||||
/**
|
||||
* @brief Retrieve tool ID that this button represents
|
||||
|
||||
@@ -49,7 +49,7 @@ MainMenu::MainMenu(QMainWindow *parent) :
|
||||
file_menu_->addSeparator();
|
||||
file_export_item_ = file_menu_->AddItem("export", nullptr, nullptr, "Ctrl+M");
|
||||
file_menu_->addSeparator();
|
||||
file_exit_item_ = file_menu_->AddItem("exit", nullptr, nullptr);
|
||||
file_exit_item_ = file_menu_->AddItem("exit", parent, SLOT(close()), "Ctrl+Q");
|
||||
|
||||
//
|
||||
// EDIT MENU
|
||||
@@ -289,7 +289,7 @@ MainMenu::MainMenu(QMainWindow *parent) :
|
||||
|
||||
tools_menu_->addSeparator();
|
||||
|
||||
tools_preferences_item_ = tools_menu_->AddItem("prefs", nullptr, nullptr, "Ctrl+,");
|
||||
tools_preferences_item_ = tools_menu_->AddItem("prefs", &olive::core, SLOT(DialogPreferencesShow()), "Ctrl+,");
|
||||
|
||||
//
|
||||
// HELP MENU
|
||||
|
||||
Reference in New Issue
Block a user