app: migrate all engine access to the C ABI facade (nm U _ZN5olive = 0)
Every app module now reaches liboakengine exclusively through oakengine_* C calls, EngineEventBridge subscriptions and app-side handle headers (cliphandle/keyframehandle/nodevaluehandle/oakvaluehelper). Direct C++ command construction, engine signal connect()s, and engine type usage in MOC-visible signatures are gone: 557 -> 0 undefined olive:: symbols in oak-editor.
This commit is contained in:
@@ -38,10 +38,12 @@
|
||||
#include "projectexplorerundo.h"
|
||||
#include "oakengine/footage.h"
|
||||
#include "oakengine/node.h"
|
||||
#include "task/taskmanager.h"
|
||||
#include "oakengine/task.h"
|
||||
#include "oakengine/videoparams.h"
|
||||
#include "oakengine/project.h"
|
||||
#include "oakengine/undo.h"
|
||||
#include "widget/menu/menu.h"
|
||||
#include "widget/menu/menushared.h"
|
||||
#include "node/nodeundo.h"
|
||||
#include "window/mainwindow/mainwindow.h"
|
||||
#include "window/mainwindow/mainwindowundo.h"
|
||||
#include "widget/timelinewidget/timelinewidget.h"
|
||||
@@ -56,7 +58,11 @@ QVector<Footage *> get_selected_proxy_footage(const QVector<Node *> &items)
|
||||
QVector<Footage *> footage;
|
||||
for (Node *node : items) {
|
||||
Footage *candidate = dynamic_cast<Footage *>(node);
|
||||
if (!candidate || !candidate->get_first_enabled_video_stream().is_valid() ||
|
||||
oak_video_params _vp;
|
||||
if (!candidate ||
|
||||
oakengine_viewer_get_first_enabled_video_stream(
|
||||
reinterpret_cast<OakEngineNode *>(candidate), &_vp) < 0 ||
|
||||
!oakengine_video_params_is_valid(&_vp) ||
|
||||
footage.contains(candidate)) {
|
||||
continue;
|
||||
}
|
||||
@@ -65,45 +71,6 @@ QVector<Footage *> get_selected_proxy_footage(const QVector<Node *> &items)
|
||||
return footage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Proxy generation driven by the liboakengine C ABI facade
|
||||
*
|
||||
* Replaces the direct ProxyManager::get_or_start_proxy() drive: the actual
|
||||
* transcode and its synchronous wait live behind
|
||||
* oakengine_footage_proxy_generate() (which also records the proxy state
|
||||
* on the footage and invalidates it), while the task stays on the
|
||||
* TaskManager queue like before.
|
||||
*/
|
||||
class FacadeProxyTask : public Task {
|
||||
public:
|
||||
FacadeProxyTask(Footage *footage)
|
||||
: footage_(footage)
|
||||
{
|
||||
set_title(tr("Generating proxy for \"%1\"")
|
||||
.arg(footage->get_label_or_name()));
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual bool run() override
|
||||
{
|
||||
OakEngineFootage *handle = oakengine_footage_borrow(
|
||||
reinterpret_cast<OakEngineNode *>(footage_));
|
||||
const int rc = oakengine_footage_proxy_generate(handle);
|
||||
oakengine_footage_free(handle);
|
||||
if (rc != OAKENGINE_OK) {
|
||||
char err[512];
|
||||
err[0] = '\0';
|
||||
oakengine_footage_last_error(err, sizeof(err));
|
||||
set_error(err[0] ? QString::fromUtf8(err) :
|
||||
tr("Proxy generation failed"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
Footage *footage_;
|
||||
};
|
||||
}
|
||||
|
||||
ProjectExplorer::ProjectExplorer(QWidget *parent)
|
||||
@@ -191,10 +158,10 @@ void ProjectExplorer::set_view_type(ProjectToolbar::ViewType type)
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectExplorer::edit(Node *item)
|
||||
void ProjectExplorer::edit(OakEngineNode *item)
|
||||
{
|
||||
current_view()->edit(
|
||||
sort_model_.mapFromSource(model_.create_index_from_item(item)));
|
||||
sort_model_.mapFromSource(model_.create_index_from_item(reinterpret_cast<Node *>(item))));
|
||||
}
|
||||
|
||||
void ProjectExplorer::add_view(QAbstractItemView *view)
|
||||
@@ -257,7 +224,7 @@ int ProjectExplorer::confirm_item_deletion(Node *item)
|
||||
|
||||
bool ProjectExplorer::delete_items_internal(const QVector<Node *> &selected,
|
||||
bool &check_if_item_is_in_use,
|
||||
MultiUndoCommand *command)
|
||||
void *command)
|
||||
{
|
||||
for (int i = 0; i < selected.size(); i++) {
|
||||
// Delete sequences first
|
||||
@@ -291,16 +258,29 @@ bool ProjectExplorer::delete_items_internal(const QVector<Node *> &selected,
|
||||
Sequence *sequence = dynamic_cast<Sequence *>(node);
|
||||
if (sequence &&
|
||||
Core::instance()->main_window()->is_sequence_open(sequence)) {
|
||||
command->add_child(new CloseSequenceCommand(sequence));
|
||||
oakengine_undo_command_multi_add_child(command, make_close_sequence_command(sequence));
|
||||
}
|
||||
|
||||
if (node->folder()) {
|
||||
command->add_child(
|
||||
new Folder::RemoveElementCommand(node->folder(), node));
|
||||
oakengine_undo_command_multi_add_child(
|
||||
command,
|
||||
oakengine_folder_remove_element_command(
|
||||
reinterpret_cast<OakEngineNode *>(node->folder()),
|
||||
reinterpret_cast<OakEngineNode *>(node)));
|
||||
}
|
||||
|
||||
command->add_child(
|
||||
new NodeRemoveWithExclusiveDependenciesAndDisconnect(node));
|
||||
void *remove_cmd = oakengine_undo_command_create_multi();
|
||||
oakengine_undo_command_multi_add_child(
|
||||
remove_cmd,
|
||||
oakengine_node_remove_and_disconnect_command(
|
||||
reinterpret_cast<void *>(node)));
|
||||
for (Node *dep : node->get_exclusive_dependencies()) {
|
||||
oakengine_undo_command_multi_add_child(
|
||||
remove_cmd,
|
||||
oakengine_node_remove_and_disconnect_command(
|
||||
reinterpret_cast<void *>(dep)));
|
||||
}
|
||||
oakengine_undo_command_multi_add_child(command, remove_cmd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,7 +336,7 @@ void ProjectExplorer::item_double_clicked_slot(const QModelIndex &index)
|
||||
}
|
||||
|
||||
// Emit a signal
|
||||
emit double_clicked_item(i);
|
||||
emit double_clicked_item(reinterpret_cast<OakEngineNode *>(i));
|
||||
}
|
||||
|
||||
void ProjectExplorer::size_changed_slot(int s)
|
||||
@@ -457,7 +437,9 @@ void ProjectExplorer::show_context_menu()
|
||||
Sequence *sequence_cast_test = dynamic_cast<Sequence *>(i);
|
||||
|
||||
if (footage_cast_test &&
|
||||
!footage_cast_test->has_enabled_video_streams()) {
|
||||
!oakengine_viewer_has_enabled_streams(
|
||||
reinterpret_cast<OakEngineNode *>(footage_cast_test),
|
||||
OAKENGINE_TRACK_TYPE_VIDEO)) {
|
||||
all_items_have_video_streams = false;
|
||||
}
|
||||
|
||||
@@ -659,8 +641,10 @@ void ProjectExplorer::generate_proxies_for_selected_footage()
|
||||
<< "GenerateProxiesForSelectedFootage: starting proxy generation for"
|
||||
<< footage.size() << "footage item(s)";
|
||||
for (Footage *item : footage) {
|
||||
const VideoParams video = item->get_first_enabled_video_stream();
|
||||
if (!video.is_valid()) {
|
||||
oak_video_params _vp;
|
||||
if (oakengine_viewer_get_first_enabled_video_stream(
|
||||
reinterpret_cast<OakEngineNode *>(item), &_vp) < 0 ||
|
||||
!oakengine_video_params_is_valid(&_vp)) {
|
||||
qWarning()
|
||||
<< "GenerateProxiesForSelectedFootage: skipping item with no valid video stream"
|
||||
<< item->filename();
|
||||
@@ -669,7 +653,9 @@ void ProjectExplorer::generate_proxies_for_selected_footage()
|
||||
|
||||
// Queue one facade-backed task per footage item (same queueing
|
||||
// semantics as the old per-footage proxy tasks).
|
||||
TaskManager::instance()->add_task(new FacadeProxyTask(item));
|
||||
OakEngineTask *proxy_task = oakengine_task_create_proxy(
|
||||
reinterpret_cast<OakEngineNode *>(item));
|
||||
oakengine_task_manager_add(proxy_task);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -689,10 +675,10 @@ void ProjectExplorer::set_selected_footage_proxy_enabled(bool enabled)
|
||||
OakEngineFootage *handle = oakengine_footage_borrow(
|
||||
reinterpret_cast<OakEngineNode *>(item));
|
||||
oakengine_footage_proxy_set_enabled(handle, enabled ? 1 : 0);
|
||||
oakengine_footage_free(handle);
|
||||
// The facade call toggles the flag; cache invalidation for the UI
|
||||
// stays here.
|
||||
item->invalidate_all(Footage::k_filename_input);
|
||||
oakengine_footage_invalidate(handle);
|
||||
oakengine_footage_free(handle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -765,18 +751,19 @@ void ProjectExplorer::view_selection_changed()
|
||||
|
||||
QModelIndexList selection = model->selectedIndexes();
|
||||
|
||||
QVector<Node *> nodes;
|
||||
QVector<OakEngineNode *> nodes;
|
||||
|
||||
foreach (const QModelIndex &index, selection) {
|
||||
Node *sel = static_cast<Node *>(
|
||||
sort_model_.mapToSource(index).internalPointer());
|
||||
if (!nodes.contains(sel)) {
|
||||
nodes.append(sel);
|
||||
auto handle = reinterpret_cast<OakEngineNode *>(sel);
|
||||
if (!nodes.contains(handle)) {
|
||||
nodes.append(handle);
|
||||
}
|
||||
}
|
||||
|
||||
if (nodes.isEmpty()) {
|
||||
nodes.append(get_root());
|
||||
nodes.append(reinterpret_cast<OakEngineNode *>(get_root()));
|
||||
}
|
||||
|
||||
emit selection_changed(nodes);
|
||||
@@ -900,15 +887,15 @@ void ProjectExplorer::delete_selected()
|
||||
return;
|
||||
}
|
||||
|
||||
MultiUndoCommand *command = new MultiUndoCommand();
|
||||
void *command = oakengine_undo_command_create_multi();
|
||||
|
||||
bool check_if_item_is_in_use = true;
|
||||
|
||||
if (delete_items_internal(selected, check_if_item_is_in_use, command)) {
|
||||
Core::instance()->undo_stack()->push(
|
||||
command, tr("Deleted %1 Item(s)").arg(selected.size()));
|
||||
oakengine_undo_push(
|
||||
command, tr("Deleted %1 Item(s)").arg(selected.size()).toUtf8().constData());
|
||||
} else {
|
||||
delete command;
|
||||
oakengine_undo_command_free(command);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include "widget/projectexplorer/projectexplorernavigation.h"
|
||||
#include "widget/projecttoolbar/projecttoolbar.h"
|
||||
|
||||
struct OakEngineNode;
|
||||
|
||||
namespace olive
|
||||
{
|
||||
|
||||
@@ -91,7 +93,7 @@ public:
|
||||
public slots:
|
||||
void set_view_type(ProjectToolbar::ViewType type);
|
||||
|
||||
void edit(Node *item);
|
||||
void edit(OakEngineNode *item);
|
||||
|
||||
void rename_selected_item();
|
||||
|
||||
@@ -105,9 +107,9 @@ signals:
|
||||
*
|
||||
* The Item that was double clicked, or nullptr if empty area was double clicked
|
||||
*/
|
||||
void double_clicked_item(Node *item);
|
||||
void double_clicked_item(OakEngineNode *item);
|
||||
|
||||
void selection_changed(const QVector<Node *> &selected);
|
||||
void selection_changed(const QVector<OakEngineNode *> &selected);
|
||||
|
||||
private:
|
||||
/**
|
||||
@@ -143,7 +145,7 @@ private:
|
||||
|
||||
bool delete_items_internal(const QVector<Node *> &selected,
|
||||
bool &check_if_item_is_in_use,
|
||||
MultiUndoCommand *command);
|
||||
void *command);
|
||||
|
||||
static QString get_human_readable_node_name(Node *node);
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#ifndef OAK_PROJECTEXPLORERUNDO_H
|
||||
#define OAK_PROJECTEXPLORERUNDO_H
|
||||
|
||||
#include "undo/undocommand.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
***/
|
||||
|
||||
#include "projectviewmodel.h"
|
||||
#include "ui/icons/icons.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMimeData>
|
||||
@@ -27,7 +28,9 @@
|
||||
|
||||
#include "common/qtutils.h"
|
||||
#include "core.h"
|
||||
#include "node/nodeundo.h"
|
||||
#include "oakengine/project.h"
|
||||
#include "oakengine/node.h"
|
||||
#include "oakengine/undo.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
@@ -35,7 +38,35 @@ namespace olive
|
||||
ProjectViewModel::ProjectViewModel(QObject *parent)
|
||||
: QAbstractItemModel(parent)
|
||||
, project_(nullptr)
|
||||
, bridge_(new EngineEventBridge(this))
|
||||
{
|
||||
connect_bridge_signals();
|
||||
}
|
||||
|
||||
void ProjectViewModel::connect_bridge_signals()
|
||||
{
|
||||
connect(bridge_, &EngineEventBridge::folder_begin_insert_item, this,
|
||||
[this](OakEngineNode *folder, OakEngineNode *child, int index) {
|
||||
this->folder_begin_insert_item(
|
||||
reinterpret_cast<Folder *>(folder),
|
||||
reinterpret_cast<Node *>(child), index);
|
||||
});
|
||||
connect(bridge_, &EngineEventBridge::folder_end_insert_item, this,
|
||||
[this](OakEngineNode *) {
|
||||
this->folder_end_insert_item();
|
||||
});
|
||||
connect(bridge_, &EngineEventBridge::folder_begin_remove_item, this,
|
||||
[this](OakEngineNode *folder, OakEngineNode *child, int index) {
|
||||
this->folder_begin_remove_item(
|
||||
reinterpret_cast<Folder *>(folder),
|
||||
reinterpret_cast<Node *>(child), index);
|
||||
});
|
||||
connect(bridge_, &EngineEventBridge::folder_end_remove_item, this,
|
||||
[this](OakEngineNode *) {
|
||||
this->folder_end_remove_item();
|
||||
});
|
||||
connect(bridge_, &EngineEventBridge::node_label_changed, this,
|
||||
&ProjectViewModel::item_renamed);
|
||||
}
|
||||
|
||||
Project *ProjectViewModel::project() const
|
||||
@@ -49,6 +80,10 @@ void ProjectViewModel::set_project(Project *p)
|
||||
|
||||
if (project_) {
|
||||
disconnect_item(project_->root());
|
||||
// Recreate bridge to clear all folder subscriptions
|
||||
delete bridge_;
|
||||
bridge_ = new EngineEventBridge(this);
|
||||
connect_bridge_signals();
|
||||
}
|
||||
|
||||
project_ = p;
|
||||
@@ -182,7 +217,7 @@ QVariant ProjectViewModel::data(const QModelIndex &index, int role) const
|
||||
case Qt::DecorationRole:
|
||||
// If this is the first column, return the Item's icon
|
||||
if (column_type == k_name) {
|
||||
return internal_item->data(Node::icon);
|
||||
return icon::from_name(internal_item->data(Node::icon).toString());
|
||||
}
|
||||
break;
|
||||
case Qt::ToolTipRole:
|
||||
@@ -239,13 +274,13 @@ bool ProjectViewModel::setData(const QModelIndex &index, const QVariant &value,
|
||||
QString new_name = value.toString();
|
||||
|
||||
if (!new_name.isEmpty()) {
|
||||
NodeRenameCommand *nrc = new NodeRenameCommand();
|
||||
void *nrc = oakengine_node_rename_command(
|
||||
reinterpret_cast<OakEngineNode *>(item),
|
||||
new_name.toUtf8().constData());
|
||||
|
||||
nrc->add_node(item, value.toString());
|
||||
|
||||
Core::instance()->undo_stack()->push(
|
||||
nrc, tr("Renamed Item \"%1\" to \"%2\"")
|
||||
.arg(item->get_label(), new_name));
|
||||
oakengine_undo_push(
|
||||
nrc,
|
||||
tr("Renamed Item \"%1\" to \"%2\"").arg(item->get_label(), new_name).toUtf8().constData());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -284,7 +319,7 @@ Qt::ItemFlags ProjectViewModel::flags(const QModelIndex &index) const
|
||||
QStringList ProjectViewModel::mimeTypes() const
|
||||
{
|
||||
// Allow data from this model and a file list from external sources
|
||||
return { Project::k_item_mime_type, QStringLiteral("text/uri-list") };
|
||||
return { QString::fromUtf8(oakengine_project_item_mime_type()), QStringLiteral("text/uri-list") };
|
||||
}
|
||||
|
||||
QMimeData *ProjectViewModel::mimeData(const QModelIndexList &indexes) const
|
||||
@@ -326,7 +361,7 @@ QMimeData *ProjectViewModel::mimeData(const QModelIndexList &indexes) const
|
||||
}
|
||||
|
||||
// Set byte array as the mime data and return the mime data
|
||||
data->setData(Project::k_item_mime_type, encoded_data);
|
||||
data->setData(QString::fromUtf8(oakengine_project_item_mime_type()), encoded_data);
|
||||
|
||||
return data;
|
||||
}
|
||||
@@ -347,9 +382,9 @@ bool ProjectViewModel::dropMimeData(const QMimeData *data,
|
||||
// Probe mime data for its format
|
||||
QStringList mime_formats = data->formats();
|
||||
|
||||
if (mime_formats.contains(Project::k_item_mime_type)) {
|
||||
if (mime_formats.contains(QString::fromUtf8(oakengine_project_item_mime_type()))) {
|
||||
// Data is drag/drop data from this model
|
||||
QByteArray model_data = data->data(Project::k_item_mime_type);
|
||||
QByteArray model_data = data->data(QString::fromUtf8(oakengine_project_item_mime_type()));
|
||||
|
||||
// Use QDataStream to deserialize the data
|
||||
QDataStream stream(&model_data, QIODevice::ReadOnly);
|
||||
@@ -367,10 +402,8 @@ bool ProjectViewModel::dropMimeData(const QMimeData *data,
|
||||
quintptr item_ptr;
|
||||
QList<Track::Reference> streams;
|
||||
|
||||
// Loop through all data
|
||||
MultiUndoCommand *move_command = new MultiUndoCommand();
|
||||
|
||||
int count = 0;
|
||||
// Loop through all data, collecting the items to move
|
||||
QVector<OakEngineNode *> items_to_move;
|
||||
|
||||
while (!stream.atEnd()) {
|
||||
stream >> streams >> item_ptr;
|
||||
@@ -384,18 +417,18 @@ bool ProjectViewModel::dropMimeData(const QMimeData *data,
|
||||
(!dynamic_cast<Folder *>(item) ||
|
||||
!item_is_parent_of_child(static_cast<Folder *>(item),
|
||||
drop_location))) {
|
||||
move_command->add_child(new NodeEdgeRemoveCommand(
|
||||
item,
|
||||
NodeInput(item->folder(), Folder::k_child_input,
|
||||
item->folder()->index_of_child_in_array(item))));
|
||||
move_command->add_child(
|
||||
new FolderAddChild(drop_location, item));
|
||||
count++;
|
||||
items_to_move.append(reinterpret_cast<OakEngineNode *>(item));
|
||||
}
|
||||
}
|
||||
|
||||
Core::instance()->undo_stack()->push(move_command,
|
||||
tr("Move %1 Item(s)").arg(count));
|
||||
if (!items_to_move.isEmpty()) {
|
||||
// ONE undoable command for the whole move (facade removes each
|
||||
// item from its old folder, then adds it to the drop location)
|
||||
oakengine_folder_move_children(
|
||||
items_to_move.constData(), items_to_move.size(),
|
||||
reinterpret_cast<OakEngineNode *>(drop_location),
|
||||
tr("Move %1 Item(s)").arg(items_to_move.size()).toUtf8().constData());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -475,18 +508,16 @@ bool ProjectViewModel::item_is_parent_of_child(Folder *parent, Node *child) cons
|
||||
|
||||
void ProjectViewModel::connect_item(Node *n)
|
||||
{
|
||||
connect(n, &Node::label_changed, this, &ProjectViewModel::item_renamed);
|
||||
label_changed_subs_[n] = bridge_->subscribe(
|
||||
reinterpret_cast<void *>(n), OAKENGINE_EVENT_NODE_LABEL_CHANGED);
|
||||
|
||||
Folder *f = dynamic_cast<Folder *>(n);
|
||||
if (f) {
|
||||
connect(f, &Folder::begin_insert_item, this,
|
||||
&ProjectViewModel::folder_begin_insert_item);
|
||||
connect(f, &Folder::end_insert_item, this,
|
||||
&ProjectViewModel::folder_end_insert_item);
|
||||
connect(f, &Folder::begin_remove_item, this,
|
||||
&ProjectViewModel::folder_begin_remove_item);
|
||||
connect(f, &Folder::end_remove_item, this,
|
||||
&ProjectViewModel::folder_end_remove_item);
|
||||
OakEngineNode *handle = reinterpret_cast<OakEngineNode *>(f);
|
||||
bridge_->subscribe(handle, OAKENGINE_EVENT_FOLDER_BEGIN_INSERT_ITEM);
|
||||
bridge_->subscribe(handle, OAKENGINE_EVENT_FOLDER_END_INSERT_ITEM);
|
||||
bridge_->subscribe(handle, OAKENGINE_EVENT_FOLDER_BEGIN_REMOVE_ITEM);
|
||||
bridge_->subscribe(handle, OAKENGINE_EVENT_FOLDER_END_REMOVE_ITEM);
|
||||
|
||||
foreach (Node *c, f->children()) {
|
||||
connect_item(c);
|
||||
@@ -496,29 +527,23 @@ void ProjectViewModel::connect_item(Node *n)
|
||||
|
||||
void ProjectViewModel::disconnect_item(Node *n)
|
||||
{
|
||||
disconnect(n, &Node::label_changed, this, &ProjectViewModel::item_renamed);
|
||||
int64_t sub = label_changed_subs_.take(n);
|
||||
if (sub > 0) {
|
||||
bridge_->unsubscribe(sub);
|
||||
}
|
||||
|
||||
Folder *f = dynamic_cast<Folder *>(n);
|
||||
if (f) {
|
||||
disconnect(f, &Folder::begin_insert_item, this,
|
||||
&ProjectViewModel::folder_begin_insert_item);
|
||||
disconnect(f, &Folder::end_insert_item, this,
|
||||
&ProjectViewModel::folder_end_insert_item);
|
||||
disconnect(f, &Folder::begin_remove_item, this,
|
||||
&ProjectViewModel::folder_begin_remove_item);
|
||||
disconnect(f, &Folder::end_remove_item, this,
|
||||
&ProjectViewModel::folder_end_remove_item);
|
||||
|
||||
// Bridge subscriptions are cleaned up by recreating the bridge in set_project
|
||||
foreach (Node *c, f->children()) {
|
||||
disconnect_item(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectViewModel::folder_begin_insert_item(Node *n, int insert_index)
|
||||
void ProjectViewModel::folder_begin_insert_item(Folder *folder, Node *n,
|
||||
int insert_index)
|
||||
{
|
||||
Folder *folder = static_cast<Folder *>(sender());
|
||||
|
||||
connect_item(n);
|
||||
|
||||
QModelIndex index;
|
||||
@@ -535,10 +560,9 @@ void ProjectViewModel::folder_end_insert_item()
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void ProjectViewModel::folder_begin_remove_item(Node *n, int child_index)
|
||||
void ProjectViewModel::folder_begin_remove_item(Folder *folder, Node *n,
|
||||
int child_index)
|
||||
{
|
||||
Folder *folder = static_cast<Folder *>(sender());
|
||||
|
||||
disconnect_item(n);
|
||||
|
||||
QModelIndex index;
|
||||
@@ -555,9 +579,9 @@ void ProjectViewModel::folder_end_remove_item()
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
void ProjectViewModel::item_renamed()
|
||||
void ProjectViewModel::item_renamed(OakEngineNode *source)
|
||||
{
|
||||
Node *item = static_cast<Node *>(sender());
|
||||
Node *item = reinterpret_cast<Node *>(source);
|
||||
|
||||
QModelIndex index = create_index_from_item(item);
|
||||
|
||||
|
||||
@@ -23,10 +23,11 @@
|
||||
#define OAK_VIEWMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QHash>
|
||||
|
||||
#include "engineeventbridge.h"
|
||||
#include "node/block/block.h"
|
||||
#include "node/project.h"
|
||||
#include "undo/undocommand.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
@@ -157,18 +158,30 @@ private:
|
||||
|
||||
void disconnect_item(Node *n);
|
||||
|
||||
Project *project_;
|
||||
/**
|
||||
* @brief Wire the bridge's folder signals to our handlers.
|
||||
*
|
||||
* Must be re-run every time bridge_ is recreated (set_project), since
|
||||
* Qt connections belong to the old bridge instance.
|
||||
*/
|
||||
void connect_bridge_signals();
|
||||
|
||||
private slots:
|
||||
void folder_begin_insert_item(Node *n, int insert_index);
|
||||
void folder_begin_insert_item(Folder *folder, Node *n, int insert_index);
|
||||
|
||||
void folder_end_insert_item();
|
||||
|
||||
void folder_begin_remove_item(Node *n, int child_index);
|
||||
void folder_begin_remove_item(Folder *folder, Node *n, int child_index);
|
||||
|
||||
void folder_end_remove_item();
|
||||
|
||||
void item_renamed();
|
||||
Project *project_;
|
||||
|
||||
EngineEventBridge *bridge_;
|
||||
|
||||
QHash<Node *, int64_t> label_changed_subs_;
|
||||
|
||||
private slots:
|
||||
void item_renamed(OakEngineNode *source);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user