style: unify identifier naming per updated conventions

Automated with clang-tidy readability-identifier-naming (config added to
.clang-tidy) plus scripted passes, per the updated rules now documented
in CONTRIBUTING.md:

- types (class/struct/enum/alias/template params): PascalCase
- functions, variables, members: snake_case (incl. rational -> Rational)
- private/protected members: trailing underscore; static member
  variables likewise (instance_, available_themes_)
- constants and enum values: snake_case (kLinear -> k_linear,
  F32P -> f32p); ALL_CAPS reserved for macros
- macros: OAK_ prefix (OLIVE_ADD_TEST/OLIVE_ASSERT/OLIVE_CONFIG ->
  OAK_ADD_TEST/OAK_ASSERT/OAK_CONFIG, GL_PREAMBLE -> OAK_GL_PREAMBLE,
  include guards -> OAK_*)
- file names: all lowercase (Current/Plugin/OliveHost/OliveClip/
  OlivePluginInstance -> current/plugin/olivehost/oliveclip/
  oliveplugininstance)
- getters share the member name sans underscore, setters set_foo()
- Qt and third-party (OpenFX) virtual overrides and framework callbacks
  keep their original names (exempt in .clang-tidy)

Manual follow-ups required where automation could not reach:
- string-based QMetaObject/SIGNAL/SLOT references updated to renamed
  methods (AddTask, CreatedFile, DeleteSpecificFile, moveSelectionUp, ...)
- macro bodies referencing renamed methods (OLIVE_CONFIG,
  NODE_DEFAULT_DESTRUCTOR, MANAGEDDISPLAYWIDGET_*)
- self-shadowing locals renamed where signals/methods became same-named
  (size_changed, worker_count, selected_items, import param, filters)
- third_party OFX member/namespace usages restored (OFX::Host::*,
  _created, _clipPrefsDirty, createInstance, clearPersistentMessage)
- STL protocol aliases restored (const_iterator) with .clang-tidy
  ignore rules; qHash overloads restored

Full build and test suite pass: ctest 4/4, ~1960 gtest cases green.
This commit is contained in:
2026-07-19 16:10:54 +08:00
parent cb1718a103
commit bb40b4923e
1014 changed files with 44257 additions and 44220 deletions
+151 -151
View File
@@ -42,13 +42,13 @@ namespace
{
// Bridges, history and multicam widgets all talk to the Core singleton
void EnsureAppSingletons()
void ensure_app_singletons()
{
if (!olive::Core::instance()) {
new olive::Core(olive::Core::CoreParams()); // intentionally leaked
}
if (!olive::DiskManager::instance()) {
olive::DiskManager::CreateInstance();
olive::DiskManager::create_instance();
}
}
@@ -56,12 +56,12 @@ class DummyTask : public Task {
public:
DummyTask()
{
SetTitle(QStringLiteral("Test Task"));
SetError(QStringLiteral("boom"));
set_title(QStringLiteral("Test Task"));
set_error(QStringLiteral("boom"));
}
protected:
virtual bool Run() override
virtual bool run() override
{
return true;
}
@@ -74,7 +74,7 @@ public:
{
}
virtual Project *GetRelevantProject() const override
virtual Project *get_relevant_project() const override
{
return nullptr;
}
@@ -95,8 +95,8 @@ private:
};
// NodeTreeView stores these on its items (mirrors the private constants)
const int kItemTypeRole = Qt::UserRole;
const int kItemInputReferenceRole = Qt::UserRole + 1;
const int k_item_type_role = Qt::UserRole;
const int k_item_input_reference_role = Qt::UserRole + 1;
} // namespace
@@ -104,14 +104,14 @@ class WidgetPanelsTest : public ::testing::Test {
protected:
void SetUp() override
{
ColorManager::SetUpDefaultConfig();
EnsureAppSingletons();
ColorManager::set_up_default_config();
ensure_app_singletons();
project_ = std::make_unique<Project>();
project_->Initialize();
project_->initialize();
}
template <typename T> T *AddNode()
template <typename T> T *add_node()
{
auto *node = new T();
node->setParent(project_.get());
@@ -123,33 +123,33 @@ protected:
TEST_F(WidgetPanelsTest, NodeTableSelectNodesCreatesTopLevelItems)
{
auto *solid = AddNode<SolidGenerator>();
auto *solid = add_node<SolidGenerator>();
NodeTableView view;
EXPECT_EQ(view.topLevelItemCount(), 0);
view.SelectNodes({ solid });
view.select_nodes({ solid });
ASSERT_EQ(view.topLevelItemCount(), 1);
EXPECT_EQ(view.topLevelItem(0)->text(0), solid->GetLabelAndName());
EXPECT_EQ(view.topLevelItem(0)->text(0), solid->get_label_and_name());
auto *math = AddNode<MathNode>();
view.SelectNodes({ math });
auto *math = add_node<MathNode>();
view.select_nodes({ math });
EXPECT_EQ(view.topLevelItemCount(), 2);
view.DeselectNodes({ solid });
view.deselect_nodes({ solid });
EXPECT_EQ(view.topLevelItemCount(), 1);
view.DeselectNodes({ math });
view.deselect_nodes({ math });
EXPECT_EQ(view.topLevelItemCount(), 0);
}
TEST_F(WidgetPanelsTest, NodeTableSetTimePopulatesInputRows)
{
auto *solid = AddNode<SolidGenerator>();
solid->Retranslate();
auto *solid = add_node<SolidGenerator>();
solid->retranslate();
NodeTableView view;
view.SelectNodes({ solid });
view.select_nodes({ solid });
QTreeWidgetItem *top = view.topLevelItem(0);
ASSERT_NE(top, nullptr);
@@ -161,52 +161,52 @@ TEST_F(WidgetPanelsTest, NodeTableSetTimePopulatesInputRows)
QTreeWidgetItem *color_row = nullptr;
for (int i = 0; i < top->childCount(); i++) {
if (top->child(i)->data(0, Qt::UserRole).toString() ==
SolidGenerator::kColorInput) {
SolidGenerator::k_color_input) {
color_row = top->child(i);
break;
}
}
ASSERT_NE(color_row, nullptr);
EXPECT_EQ(color_row->text(0), solid->GetInputName(SolidGenerator::kColorInput));
EXPECT_EQ(color_row->text(0), solid->get_input_name(SolidGenerator::k_color_input));
// The value row shows the data type name and the split RGBA columns
ASSERT_EQ(color_row->childCount(), 1);
QTreeWidgetItem *value_row = color_row->child(0);
EXPECT_EQ(value_row->text(0),
NodeValue::GetPrettyDataTypeName(NodeValue::kColor));
NodeValue::get_pretty_data_type_name(NodeValue::k_color));
EXPECT_FALSE(value_row->text(1).isEmpty());
for (int col = 2; col <= 5; col++) {
EXPECT_FALSE(value_row->text(col).isEmpty()) << "column" << col;
}
// Re-evaluating at another time keeps the same structure
view.SetTime(rational(1));
view.set_time(Rational(1));
EXPECT_EQ(top->childCount(), 2);
EXPECT_EQ(color_row->childCount(), 1);
}
TEST_F(WidgetPanelsTest, NodeTreeSetNodesBuildsInputHierarchy)
{
auto *math = AddNode<MathNode>();
math->Retranslate();
auto *math = add_node<MathNode>();
math->retranslate();
NodeTreeView view;
view.SetNodes({ math });
view.set_nodes({ math });
ASSERT_EQ(view.topLevelItemCount(), 1);
QTreeWidgetItem *node_item = view.topLevelItem(0);
EXPECT_EQ(node_item->data(0, kItemTypeRole).toInt(), 0); // kItemTypeNode
EXPECT_EQ(node_item->data(0, k_item_type_role).toInt(), 0); // kItemTypeNode
// All four inputs are visible: the base-class enabled checkbox, the
// method combo, and the two float params
ASSERT_EQ(node_item->childCount(), 4);
const QStringList expected_inputs = { Node::kEnabledInput, MathNode::kMethodIn,
MathNode::kParamAIn, MathNode::kParamBIn };
const QStringList expected_inputs = { Node::k_enabled_input, MathNode::k_method_in,
MathNode::k_param_a_in, MathNode::k_param_b_in };
for (int i = 0; i < expected_inputs.size(); i++) {
QTreeWidgetItem *input_item = node_item->child(i);
EXPECT_EQ(input_item->data(0, kItemTypeRole).toInt(), 1); // kItemTypeInput
EXPECT_EQ(input_item->data(0, k_item_type_role).toInt(), 1); // kItemTypeInput
const NodeKeyframeTrackReference ref =
input_item->data(0, kItemInputReferenceRole)
input_item->data(0, k_item_input_reference_role)
.value<NodeKeyframeTrackReference>();
EXPECT_EQ(ref.input().node(), math);
EXPECT_EQ(ref.input().input(), expected_inputs.at(i));
@@ -215,11 +215,11 @@ TEST_F(WidgetPanelsTest, NodeTreeSetNodesBuildsInputHierarchy)
TEST_F(WidgetPanelsTest, NodeTreeOnlyShowKeyframableFiltersInputs)
{
auto *math = AddNode<MathNode>();
auto *math = add_node<MathNode>();
NodeTreeView view;
view.SetOnlyShowKeyframable(true);
view.SetNodes({ math });
view.set_only_show_keyframable(true);
view.set_nodes({ math });
// The method combo is flagged not-keyframable; enabled and the two
// float params remain
@@ -228,30 +228,30 @@ TEST_F(WidgetPanelsTest, NodeTreeOnlyShowKeyframableFiltersInputs)
// Of a bare viewer's inputs only "enabled" is keyframable, so it is the
// sole row left standing
auto *viewer = AddNode<ViewerOutput>();
view.SetNodes({ viewer });
auto *viewer = add_node<ViewerOutput>();
view.set_nodes({ viewer });
ASSERT_EQ(view.topLevelItemCount(), 1);
EXPECT_EQ(view.topLevelItem(0)->childCount(), 1);
// Without the filter its buffer inputs show up as well
view.SetOnlyShowKeyframable(false);
view.SetNodes({ viewer });
view.set_only_show_keyframable(false);
view.set_nodes({ viewer });
ASSERT_EQ(view.topLevelItemCount(), 1);
EXPECT_EQ(view.topLevelItem(0)->childCount(), 3);
}
TEST_F(WidgetPanelsTest, NodeTreeCheckboxesToggleEnableStateAndEmit)
{
auto *math = AddNode<MathNode>();
auto *math = add_node<MathNode>();
NodeTreeView view;
view.SetCheckBoxesEnabled(true);
view.SetNodes({ math });
view.set_check_boxes_enabled(true);
view.set_nodes({ math });
Node *node_signal_node = nullptr;
bool node_signal_enabled = true;
int node_emissions = 0;
QObject::connect(&view, &NodeTreeView::NodeEnableChanged,
QObject::connect(&view, &NodeTreeView::node_enable_changed,
[&node_signal_node, &node_signal_enabled,
&node_emissions](Node *n, bool e) {
node_signal_node = n;
@@ -262,7 +262,7 @@ TEST_F(WidgetPanelsTest, NodeTreeCheckboxesToggleEnableStateAndEmit)
NodeKeyframeTrackReference input_signal_ref;
bool input_signal_enabled = true;
int input_emissions = 0;
QObject::connect(&view, &NodeTreeView::InputEnableChanged,
QObject::connect(&view, &NodeTreeView::input_enable_changed,
[&input_signal_ref, &input_signal_enabled,
&input_emissions](const NodeKeyframeTrackReference &ref,
bool e) {
@@ -280,32 +280,32 @@ TEST_F(WidgetPanelsTest, NodeTreeCheckboxesToggleEnableStateAndEmit)
EXPECT_EQ(node_emissions, 1);
EXPECT_EQ(node_signal_node, math);
EXPECT_FALSE(node_signal_enabled);
EXPECT_FALSE(view.IsNodeEnabled(math));
EXPECT_FALSE(view.is_node_enabled(math));
// Re-checking restores it
node_item->setCheckState(0, Qt::Checked);
EXPECT_EQ(node_emissions, 2);
EXPECT_TRUE(node_signal_enabled);
EXPECT_TRUE(view.IsNodeEnabled(math));
EXPECT_TRUE(view.is_node_enabled(math));
// Same behavior on input rows
QTreeWidgetItem *input_item = node_item->child(0);
ASSERT_NE(input_item, nullptr);
input_item->setCheckState(0, Qt::Unchecked);
EXPECT_EQ(input_emissions, 1);
EXPECT_EQ(input_signal_ref.input().input(), Node::kEnabledInput);
EXPECT_EQ(input_signal_ref.input().input(), Node::k_enabled_input);
EXPECT_FALSE(input_signal_enabled);
EXPECT_FALSE(view.IsInputEnabled(input_signal_ref));
EXPECT_FALSE(view.is_input_enabled(input_signal_ref));
}
TEST_F(WidgetPanelsTest, NodeTreeKeyframeTracksBecomeRows)
{
auto *solid = AddNode<SolidGenerator>();
solid->Retranslate();
auto *solid = add_node<SolidGenerator>();
solid->retranslate();
NodeTreeView view;
view.SetShowKeyframeTracksAsRows(true);
view.SetNodes({ solid });
view.set_show_keyframe_tracks_as_rows(true);
view.set_nodes({ solid });
QTreeWidgetItem *node_item = view.topLevelItem(0);
ASSERT_NE(node_item, nullptr);
@@ -321,15 +321,15 @@ TEST_F(WidgetPanelsTest, NodeTreeKeyframeTracksBecomeRows)
EXPECT_EQ(color_item->child(i)->text(0), track_names.at(i));
const NodeKeyframeTrackReference ref =
color_item->child(i)
->data(0, kItemInputReferenceRole)
->data(0, k_item_input_reference_role)
.value<NodeKeyframeTrackReference>();
EXPECT_EQ(ref.track(), i);
}
// A single-track float input stays a single row
auto *math = AddNode<MathNode>();
math->Retranslate();
view.SetNodes({ math });
auto *math = add_node<MathNode>();
math->retranslate();
view.set_nodes({ math });
QTreeWidgetItem *param_item =
view.topLevelItem(0)->child(2); // after enabled and the method combo
ASSERT_NE(param_item, nullptr);
@@ -339,10 +339,10 @@ TEST_F(WidgetPanelsTest, NodeTreeKeyframeTracksBecomeRows)
TEST_F(WidgetPanelsTest, BridgeCreatesSliderForFloatInput)
{
auto *math = AddNode<MathNode>();
auto *math = add_node<MathNode>();
QWidget parent;
NodeParamViewWidgetBridge bridge(NodeInput(math, MathNode::kParamAIn), &parent);
NodeParamViewWidgetBridge bridge(NodeInput(math, MathNode::k_param_a_in), &parent);
ASSERT_EQ(bridge.widgets().size(), 1);
EXPECT_NE(qobject_cast<FloatSlider *>(bridge.widgets().first()), nullptr);
@@ -350,10 +350,10 @@ TEST_F(WidgetPanelsTest, BridgeCreatesSliderForFloatInput)
TEST_F(WidgetPanelsTest, BridgeCreatesColorButtonForColorInput)
{
auto *solid = AddNode<SolidGenerator>();
auto *solid = add_node<SolidGenerator>();
QWidget parent;
NodeParamViewWidgetBridge bridge(NodeInput(solid, SolidGenerator::kColorInput),
NodeParamViewWidgetBridge bridge(NodeInput(solid, SolidGenerator::k_color_input),
&parent);
ASSERT_EQ(bridge.widgets().size(), 1);
@@ -362,25 +362,25 @@ TEST_F(WidgetPanelsTest, BridgeCreatesColorButtonForColorInput)
TEST_F(WidgetPanelsTest, BridgeCreatesComboBoxForComboInput)
{
auto *math = AddNode<MathNode>();
math->Retranslate();
auto *math = add_node<MathNode>();
math->retranslate();
QWidget parent;
NodeParamViewWidgetBridge bridge(NodeInput(math, MathNode::kMethodIn), &parent);
NodeParamViewWidgetBridge bridge(NodeInput(math, MathNode::k_method_in), &parent);
ASSERT_EQ(bridge.widgets().size(), 1);
auto *combo = qobject_cast<QComboBox *>(bridge.widgets().first());
ASSERT_NE(combo, nullptr);
EXPECT_EQ(combo->count(), math->GetComboBoxStrings(MathNode::kMethodIn).size());
EXPECT_EQ(combo->count(), math->get_combo_box_strings(MathNode::k_method_in).size());
EXPECT_GT(combo->count(), 0);
}
TEST_F(WidgetPanelsTest, BridgeCreatesCheckBoxForBooleanInput)
{
auto *clip = AddNode<ClipBlock>();
auto *clip = add_node<ClipBlock>();
QWidget parent;
NodeParamViewWidgetBridge bridge(NodeInput(clip, ClipBlock::kReverseInput),
NodeParamViewWidgetBridge bridge(NodeInput(clip, ClipBlock::k_reverse_input),
&parent);
ASSERT_EQ(bridge.widgets().size(), 1);
@@ -389,40 +389,40 @@ TEST_F(WidgetPanelsTest, BridgeCreatesCheckBoxForBooleanInput)
TEST_F(WidgetPanelsTest, BridgeUpdatesWidgetWhenNodeValueChanges)
{
auto *math = AddNode<MathNode>();
auto *viewer = AddNode<ViewerOutput>();
auto *math = add_node<MathNode>();
auto *viewer = add_node<ViewerOutput>();
QWidget parent;
NodeParamViewWidgetBridge bridge(NodeInput(math, MathNode::kParamAIn), &parent);
NodeParamViewWidgetBridge bridge(NodeInput(math, MathNode::k_param_a_in), &parent);
auto *slider = qobject_cast<FloatSlider *>(bridge.widgets().first());
ASSERT_NE(slider, nullptr);
EXPECT_DOUBLE_EQ(slider->GetValue(), 0.0);
EXPECT_DOUBLE_EQ(slider->get_value(), 0.0);
// The bridge only refreshes widgets for value changes at the playhead
// of a connected time target
bridge.SetTimeTarget(viewer);
bridge.set_time_target(viewer);
math->SetStandardValue(MathNode::kParamAIn, 2.5);
EXPECT_DOUBLE_EQ(slider->GetValue(), 2.5);
math->set_standard_value(MathNode::k_param_a_in, 2.5);
EXPECT_DOUBLE_EQ(slider->get_value(), 2.5);
}
TEST_F(WidgetPanelsTest, BridgePushesUndoCommandWhenWidgetChanges)
{
auto *math = AddNode<MathNode>();
math->Retranslate();
ASSERT_EQ(math->GetStandardValue(MathNode::kMethodIn).toInt(), 0);
auto *math = add_node<MathNode>();
math->retranslate();
ASSERT_EQ(math->get_standard_value(MathNode::k_method_in).toInt(), 0);
QWidget parent;
NodeParamViewWidgetBridge bridge(NodeInput(math, MathNode::kMethodIn), &parent);
NodeParamViewWidgetBridge bridge(NodeInput(math, MathNode::k_method_in), &parent);
auto *combo = qobject_cast<QComboBox *>(bridge.widgets().first());
ASSERT_NE(combo, nullptr);
ASSERT_GT(combo->count(), 1);
combo->setCurrentIndex(1);
EXPECT_EQ(math->GetStandardValue(MathNode::kMethodIn).toInt(), 1);
EXPECT_EQ(math->get_standard_value(MathNode::k_method_in).toInt(), 1);
Core::instance()->undo_stack()->undo();
EXPECT_EQ(math->GetStandardValue(MathNode::kMethodIn).toInt(), 0);
EXPECT_EQ(math->get_standard_value(MathNode::k_method_in).toInt(), 0);
Core::instance()->undo_stack()->clear();
}
@@ -431,7 +431,7 @@ TEST(TaskView, TaskLifecycleUpdatesItems)
TaskView view(nullptr);
DummyTask task;
view.AddTask(&task);
view.add_task(&task);
auto *item = view.findChild<TaskViewItem *>();
ASSERT_NE(item, nullptr);
@@ -449,12 +449,12 @@ TEST(TaskView, TaskLifecycleUpdatesItems)
// Progress signals drive the progress bar
auto *bar = item->findChild<QProgressBar *>();
ASSERT_NE(bar, nullptr);
emit task.ProgressChanged(0.5);
emit task.progress_changed(0.5);
EXPECT_EQ(bar->value(), 50);
// The cancel button relays the task through TaskCancelled
Task *cancelled = nullptr;
QObject::connect(&view, &TaskView::TaskCancelled,
QObject::connect(&view, &TaskView::task_cancelled,
[&cancelled](Task *t) { cancelled = t; });
auto *cancel_button = item->findChild<QPushButton *>();
ASSERT_NE(cancel_button, nullptr);
@@ -462,7 +462,7 @@ TEST(TaskView, TaskLifecycleUpdatesItems)
EXPECT_EQ(cancelled, &task);
// Failure swaps in the error label
view.TaskFailed(&task);
view.task_failed(&task);
bool found_error = false;
foreach (QLabel *label, item->findChildren<QLabel *>()) {
if (label->text().contains(QStringLiteral("boom"))) {
@@ -473,14 +473,14 @@ TEST(TaskView, TaskLifecycleUpdatesItems)
EXPECT_TRUE(found_error);
// Removal deletes the item once deferred deletions are processed
view.RemoveTask(&task);
view.remove_task(&task);
QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
EXPECT_EQ(view.findChild<TaskViewItem *>(), nullptr);
}
TEST(HistoryWidget, ReflectsAndDrivesUndoStack)
{
EnsureAppSingletons();
ensure_app_singletons();
UndoStack *stack = Core::instance()->undo_stack();
stack->clear();
@@ -501,21 +501,21 @@ TEST(HistoryWidget, ReflectsAndDrivesUndoStack)
QItemSelectionModel::ClearAndSelect |
QItemSelectionModel::Rows);
EXPECT_EQ(counter, 1);
EXPECT_TRUE(stack->CanRedo());
EXPECT_TRUE(stack->can_redo());
// Moving to the second entry redoes everything again
widget.selectionModel()->setCurrentIndex(stack->index(2, 0),
QItemSelectionModel::ClearAndSelect |
QItemSelectionModel::Rows);
EXPECT_EQ(counter, 2);
EXPECT_FALSE(stack->CanRedo());
EXPECT_FALSE(stack->can_redo());
// Moving back to the sentinel row undoes both commands
widget.selectionModel()->setCurrentIndex(stack->index(0, 0),
QItemSelectionModel::ClearAndSelect |
QItemSelectionModel::Rows);
EXPECT_EQ(counter, 0);
EXPECT_TRUE(stack->CanRedo());
EXPECT_TRUE(stack->can_redo());
stack->clear();
}
@@ -523,135 +523,135 @@ TEST(HistoryWidget, ReflectsAndDrivesUndoStack)
TEST(TimelineSelections, ShiftTimeMovesAllRanges)
{
TimelineWidgetSelections sel;
const Track::Reference video0(Track::kVideo, 0);
const Track::Reference video0(Track::k_video, 0);
sel.insert(video0,
TimeRangeList({ TimeRange(rational(0), rational(10)) }));
TimeRangeList({ TimeRange(Rational(0), Rational(10)) }));
sel.ShiftTime(rational(5));
sel.shift_time(Rational(5));
const TimeRangeList list = sel.value(video0);
ASSERT_EQ(list.size(), 1);
EXPECT_EQ(list.first().in(), rational(5));
EXPECT_EQ(list.first().out(), rational(15));
EXPECT_EQ(list.first().in(), Rational(5));
EXPECT_EQ(list.first().out(), Rational(15));
}
TEST(TimelineSelections, ShiftTracksReindexesMatchingTypeOnly)
{
TimelineWidgetSelections sel;
sel.insert(Track::Reference(Track::kVideo, 0),
TimeRangeList({ TimeRange(rational(0), rational(10)) }));
sel.insert(Track::Reference(Track::kVideo, 1),
TimeRangeList({ TimeRange(rational(0), rational(10)) }));
sel.insert(Track::Reference(Track::kAudio, 0),
TimeRangeList({ TimeRange(rational(0), rational(10)) }));
sel.insert(Track::Reference(Track::k_video, 0),
TimeRangeList({ TimeRange(Rational(0), Rational(10)) }));
sel.insert(Track::Reference(Track::k_video, 1),
TimeRangeList({ TimeRange(Rational(0), Rational(10)) }));
sel.insert(Track::Reference(Track::k_audio, 0),
TimeRangeList({ TimeRange(Rational(0), Rational(10)) }));
sel.ShiftTracks(Track::kVideo, 2);
sel.shift_tracks(Track::k_video, 2);
EXPECT_FALSE(sel.contains(Track::Reference(Track::kVideo, 0)));
EXPECT_FALSE(sel.contains(Track::Reference(Track::kVideo, 1)));
EXPECT_TRUE(sel.contains(Track::Reference(Track::kVideo, 2)));
EXPECT_TRUE(sel.contains(Track::Reference(Track::kVideo, 3)));
EXPECT_TRUE(sel.contains(Track::Reference(Track::kAudio, 0)));
EXPECT_FALSE(sel.contains(Track::Reference(Track::k_video, 0)));
EXPECT_FALSE(sel.contains(Track::Reference(Track::k_video, 1)));
EXPECT_TRUE(sel.contains(Track::Reference(Track::k_video, 2)));
EXPECT_TRUE(sel.contains(Track::Reference(Track::k_video, 3)));
EXPECT_TRUE(sel.contains(Track::Reference(Track::k_audio, 0)));
}
TEST(TimelineSelections, TrimInAndOutAdjustRangeEnds)
{
TimelineWidgetSelections in_sel;
const Track::Reference video0(Track::kVideo, 0);
const Track::Reference video0(Track::k_video, 0);
in_sel.insert(video0,
TimeRangeList({ TimeRange(rational(0), rational(10)) }));
in_sel.TrimIn(rational(2));
EXPECT_EQ(in_sel.value(video0).first().in(), rational(2));
EXPECT_EQ(in_sel.value(video0).first().out(), rational(10));
TimeRangeList({ TimeRange(Rational(0), Rational(10)) }));
in_sel.trim_in(Rational(2));
EXPECT_EQ(in_sel.value(video0).first().in(), Rational(2));
EXPECT_EQ(in_sel.value(video0).first().out(), Rational(10));
TimelineWidgetSelections out_sel;
out_sel.insert(video0,
TimeRangeList({ TimeRange(rational(0), rational(10)) }));
out_sel.TrimOut(rational(-3));
EXPECT_EQ(out_sel.value(video0).first().in(), rational(0));
EXPECT_EQ(out_sel.value(video0).first().out(), rational(7));
TimeRangeList({ TimeRange(Rational(0), Rational(10)) }));
out_sel.trim_out(Rational(-3));
EXPECT_EQ(out_sel.value(video0).first().in(), Rational(0));
EXPECT_EQ(out_sel.value(video0).first().out(), Rational(7));
}
TEST(TimelineSelections, SubtractSplitsAndIgnoresForeignTracks)
{
TimelineWidgetSelections ours;
const Track::Reference video0(Track::kVideo, 0);
const Track::Reference video0(Track::k_video, 0);
ours.insert(video0,
TimeRangeList({ TimeRange(rational(0), rational(10)) }));
TimeRangeList({ TimeRange(Rational(0), Rational(10)) }));
TimelineWidgetSelections theirs;
theirs.insert(video0,
TimeRangeList({ TimeRange(rational(3), rational(5)) }));
theirs.insert(Track::Reference(Track::kAudio, 0),
TimeRangeList({ TimeRange(rational(0), rational(99)) }));
TimeRangeList({ TimeRange(Rational(3), Rational(5)) }));
theirs.insert(Track::Reference(Track::k_audio, 0),
TimeRangeList({ TimeRange(Rational(0), Rational(99)) }));
TimelineWidgetSelections result = ours.Subtracted(theirs);
TimelineWidgetSelections result = ours.subtracted(theirs);
// The original is untouched by the const version
EXPECT_EQ(ours.value(video0).size(), 1);
const TimeRangeList remaining = result.value(video0);
ASSERT_EQ(remaining.size(), 2);
EXPECT_EQ(remaining.at(0), TimeRange(rational(0), rational(3)));
EXPECT_EQ(remaining.at(1), TimeRange(rational(5), rational(10)));
EXPECT_EQ(remaining.at(0), TimeRange(Rational(0), Rational(3)));
EXPECT_EQ(remaining.at(1), TimeRange(Rational(5), Rational(10)));
// In-place Subtract drops the subtracted span as well
ours.Subtract(theirs);
ours.subtract(theirs);
EXPECT_EQ(ours.value(video0).size(), 2);
}
TEST(NodeViewScene, AddAndRemoveContexts)
{
ColorManager::SetUpDefaultConfig();
ColorManager::set_up_default_config();
Project project;
project.Initialize();
project.initialize();
auto *folder = new Folder();
folder->setParent(&project);
NodeViewScene scene;
EXPECT_TRUE(scene.context_map().isEmpty());
NodeViewContext *ctx = scene.AddContext(folder);
NodeViewContext *ctx = scene.add_context(folder);
ASSERT_NE(ctx, nullptr);
EXPECT_TRUE(scene.context_map().contains(folder));
EXPECT_EQ(ctx->GetContext(), folder);
EXPECT_EQ(ctx->get_context(), folder);
EXPECT_TRUE(scene.items().contains(ctx));
// Re-adding the same node returns the existing context item
EXPECT_EQ(scene.AddContext(folder), ctx);
EXPECT_EQ(scene.add_context(folder), ctx);
EXPECT_EQ(scene.context_map().size(), 1);
scene.RemoveContext(folder);
scene.remove_context(folder);
EXPECT_TRUE(scene.context_map().isEmpty());
}
TEST(NodeViewScene, FlowDirectionControlsOrientation)
{
NodeViewScene scene;
EXPECT_EQ(scene.GetFlowDirection(), NodeViewCommon::kLeftToRight);
EXPECT_EQ(scene.GetFlowOrientation(), Qt::Horizontal);
EXPECT_EQ(scene.get_flow_direction(), NodeViewCommon::k_left_to_right);
EXPECT_EQ(scene.get_flow_orientation(), Qt::Horizontal);
scene.SetFlowDirection(NodeViewCommon::kTopToBottom);
EXPECT_EQ(scene.GetFlowDirection(), NodeViewCommon::kTopToBottom);
EXPECT_EQ(scene.GetFlowOrientation(), Qt::Vertical);
scene.set_flow_direction(NodeViewCommon::k_top_to_bottom);
EXPECT_EQ(scene.get_flow_direction(), NodeViewCommon::k_top_to_bottom);
EXPECT_EQ(scene.get_flow_orientation(), Qt::Vertical);
}
class MulticamWidgetTest : public ::testing::Test {
protected:
void SetUp() override
{
ColorManager::SetUpDefaultConfig();
EnsureAppSingletons();
ColorManager::set_up_default_config();
ensure_app_singletons();
// The display widget pulls the render backend off RenderManager,
// which the bare Core singleton does not create (Core::Start()
// would); viewer_display_repro_test does the same
created_render_manager_ = (RenderManager::instance() == nullptr);
if (created_render_manager_) {
RenderManager::CreateInstance();
RenderManager::create_instance();
}
project_ = std::make_unique<Project>();
project_->Initialize();
project_->initialize();
}
void TearDown() override
@@ -661,7 +661,7 @@ protected:
// Leave the singleton the way we found it: render suites check
// RenderManager::instance() for null in their own teardowns
if (created_render_manager_) {
RenderManager::DestroyInstance();
RenderManager::destroy_instance();
created_render_manager_ = false;
}
}
@@ -673,8 +673,8 @@ protected:
TEST_F(MulticamWidgetTest, ConstructionCreatesDisplay)
{
MulticamWidget widget;
EXPECT_NE(widget.GetDisplayWidget(), nullptr);
EXPECT_EQ(widget.GetConnectedNode(), nullptr);
EXPECT_NE(widget.get_display_widget(), nullptr);
EXPECT_EQ(widget.get_connected_node(), nullptr);
}
TEST_F(MulticamWidgetTest, SwitchWithoutTimestampAppliesImmediately)
@@ -687,8 +687,8 @@ TEST_F(MulticamWidgetTest, SwitchWithoutTimestampAppliesImmediately)
clip->setParent(project_.get());
MulticamWidget widget;
widget.SetMulticamNode(viewer, node, clip, rational());
EXPECT_EQ(widget.GetConnectedNode(), viewer);
widget.set_multicam_node(viewer, node, clip, Rational());
EXPECT_EQ(widget.get_connected_node(), viewer);
}
TEST_F(MulticamWidgetTest, FutureSwitchWaitsForPlayheadToAdvance)
@@ -703,14 +703,14 @@ TEST_F(MulticamWidgetTest, FutureSwitchWaitsForPlayheadToAdvance)
clip->setParent(project_.get());
MulticamWidget widget;
widget.SetMulticamNode(viewer_a, node, clip, rational());
ASSERT_EQ(widget.GetConnectedNode(), viewer_a);
widget.set_multicam_node(viewer_a, node, clip, Rational());
ASSERT_EQ(widget.get_connected_node(), viewer_a);
// A switch stamped for a later time is queued, not applied
widget.SetMulticamNode(viewer_b, node, clip, rational(5));
EXPECT_EQ(widget.GetConnectedNode(), viewer_a);
widget.set_multicam_node(viewer_b, node, clip, Rational(5));
EXPECT_EQ(widget.get_connected_node(), viewer_a);
// Once playback time advances, the queued switch takes effect
viewer_a->SetPlayhead(rational(1));
EXPECT_EQ(widget.GetConnectedNode(), viewer_b);
viewer_a->set_playhead(Rational(1));
EXPECT_EQ(widget.get_connected_node(), viewer_b);
}