added ability to open viewers on any viewer node or derivative
Fixes #1362 Also fixes some other bugs that impeded this from working.
This commit is contained in:
+5
-3
@@ -396,9 +396,6 @@ void Core::CreateNewSequence()
|
||||
// Create new sequence
|
||||
Sequence* new_sequence = CreateNewSequenceForProject(active_project);
|
||||
|
||||
// Set all defaults for the sequence
|
||||
new_sequence->set_default_parameters();
|
||||
|
||||
SequenceDialog sd(new_sequence, SequenceDialog::kNew, main_window_);
|
||||
|
||||
// Make sure SequenceDialog doesn't make an undo command for editing the sequence, since we make an undo command for
|
||||
@@ -1091,6 +1088,11 @@ void Core::OpenRecoveryProject(const QString &filename)
|
||||
OpenProjectInternal(filename, true);
|
||||
}
|
||||
|
||||
void Core::OpenNodeInViewer(ViewerOutput *viewer)
|
||||
{
|
||||
main_window_->OpenNodeInViewer(viewer);
|
||||
}
|
||||
|
||||
void Core::CheckForAutoRecoveries()
|
||||
{
|
||||
QFile autorecovery_index(GetAutoRecoveryIndexFilename());
|
||||
|
||||
@@ -300,6 +300,8 @@ public:
|
||||
|
||||
void OpenRecoveryProject(const QString& filename);
|
||||
|
||||
void OpenNodeInViewer(ViewerOutput* viewer);
|
||||
|
||||
static const uint kProjectVersion;
|
||||
|
||||
public slots:
|
||||
|
||||
@@ -61,6 +61,7 @@ void NodeGraph::childEvent(QChildEvent *event)
|
||||
connect(node, &Node::ValueChanged, this, &NodeGraph::ValueChanged);
|
||||
|
||||
emit NodeAdded(node);
|
||||
emit node->AddedToGraph(this);
|
||||
|
||||
} else if (event->type() == QEvent::ChildRemoved) {
|
||||
|
||||
@@ -72,6 +73,7 @@ void NodeGraph::childEvent(QChildEvent *event)
|
||||
disconnect(node, &Node::ValueChanged, this, &NodeGraph::ValueChanged);
|
||||
|
||||
emit NodeRemoved(node);
|
||||
emit node->RemovedFromGraph(this);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -926,6 +926,10 @@ signals:
|
||||
|
||||
void InputDataTypeChanged(const QString& id, NodeValue::Type type);
|
||||
|
||||
void AddedToGraph(NodeGraph* graph);
|
||||
|
||||
void RemovedFromGraph(NodeGraph* graph);
|
||||
|
||||
private:
|
||||
class ArrayInsertCommand : public UndoCommand
|
||||
{
|
||||
|
||||
@@ -160,6 +160,7 @@ public:
|
||||
|
||||
static Type TypeFromString(const QString& s)
|
||||
{
|
||||
if (s.size() >= 3) {
|
||||
if (s.at(1) == ':') {
|
||||
if (s.at(0) == 'v') {
|
||||
// Video stream
|
||||
@@ -169,6 +170,7 @@ public:
|
||||
return Track::kAudio;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Track::kNone;
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ ViewerOutput::ViewerOutput(bool create_default_streams) :
|
||||
if (create_default_streams) {
|
||||
AddStream(Track::kVideo, QVariant());
|
||||
AddStream(Track::kAudio, QVariant());
|
||||
set_default_parameters();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,39 +303,19 @@ void ViewerOutput::Retranslate()
|
||||
|
||||
void ViewerOutput::VerifyLength()
|
||||
{
|
||||
NodeTraverser traverser;
|
||||
|
||||
rational video_length, audio_length, subtitle_length;
|
||||
|
||||
{
|
||||
video_length = GetCustomLength(Track::kVideo);
|
||||
|
||||
if (video_length.isNull() && IsInputConnected(kTextureInput)) {
|
||||
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kTextureInput), TimeRange(0, 0));
|
||||
video_length = t.Get(NodeValue::kRational, QStringLiteral("length")).value<rational>();
|
||||
}
|
||||
|
||||
video_length = VerifyLengthInternal(Track::kVideo);
|
||||
if (cache_enabled_) {
|
||||
video_frame_cache_.SetLength(video_length);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
audio_length = GetCustomLength(Track::kAudio);
|
||||
|
||||
if (audio_length.isNull() && IsInputConnected(kSamplesInput)) {
|
||||
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kSamplesInput), TimeRange(0, 0));
|
||||
audio_length = t.Get(NodeValue::kRational, QStringLiteral("length")).value<rational>();
|
||||
}
|
||||
|
||||
audio_length = VerifyLengthInternal(Track::kAudio);
|
||||
if (cache_enabled_) {
|
||||
audio_playback_cache_.SetLength(audio_length);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
subtitle_length = GetCustomLength(Track::kSubtitle);
|
||||
}
|
||||
subtitle_length = VerifyLengthInternal(Track::kSubtitle);
|
||||
|
||||
rational real_length = qMax(subtitle_length, qMax(video_length, audio_length));
|
||||
|
||||
@@ -362,9 +343,30 @@ void ViewerOutput::InputDisconnectedEvent(const QString &input, int element, con
|
||||
super::InputDisconnectedEvent(input, element, output);
|
||||
}
|
||||
|
||||
rational ViewerOutput::GetCustomLength(Track::Type type) const
|
||||
rational ViewerOutput::VerifyLengthInternal(Track::Type type) const
|
||||
{
|
||||
Q_UNUSED(type)
|
||||
NodeTraverser traverser;
|
||||
|
||||
switch (type) {
|
||||
case Track::kVideo:
|
||||
if (IsInputConnected(kTextureInput)) {
|
||||
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kTextureInput), TimeRange(0, 0));
|
||||
qDebug() << "Got video length:" << t.Get(NodeValue::kRational, QStringLiteral("length")).value<rational>();
|
||||
return t.Get(NodeValue::kRational, QStringLiteral("length")).value<rational>();
|
||||
}
|
||||
break;
|
||||
case Track::kAudio:
|
||||
if (IsInputConnected(kSamplesInput)) {
|
||||
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kSamplesInput), TimeRange(0, 0));
|
||||
return t.Get(NodeValue::kRational, QStringLiteral("length")).value<rational>();
|
||||
}
|
||||
break;
|
||||
case Track::kNone:
|
||||
case Track::kSubtitle:
|
||||
case Track::kCount:
|
||||
break;
|
||||
}
|
||||
|
||||
return rational();
|
||||
}
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ protected:
|
||||
|
||||
virtual void InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output) override;
|
||||
|
||||
virtual rational GetCustomLength(Track::Type type) const;
|
||||
virtual rational VerifyLengthInternal(Track::Type type) const;
|
||||
|
||||
virtual void ShiftVideoEvent(const rational &from, const rational &to);
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ void Footage::InputValueChangedEvent(const QString &input, int element)
|
||||
}
|
||||
}
|
||||
|
||||
rational Footage::GetCustomLength(Track::Type type) const
|
||||
rational Footage::VerifyLengthInternal(Track::Type type) const
|
||||
{
|
||||
if (type == Track::kVideo) {
|
||||
VideoParams first_stream = GetFirstEnabledVideoStream();
|
||||
@@ -196,7 +196,7 @@ rational Footage::GetCustomLength(Track::Type type) const
|
||||
}
|
||||
}
|
||||
|
||||
return super::GetCustomLength(type);
|
||||
return super::VerifyLengthInternal(type);
|
||||
}
|
||||
|
||||
QString Footage::GetColorspaceToUse(const VideoParams ¶ms) const
|
||||
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
|
||||
virtual QString Name() const override
|
||||
{
|
||||
return tr("Footage");
|
||||
return tr("Media");
|
||||
}
|
||||
|
||||
virtual QString id() const override
|
||||
@@ -195,7 +195,7 @@ protected:
|
||||
|
||||
virtual void InputValueChangedEvent(const QString &input, int element) override;
|
||||
|
||||
virtual rational GetCustomLength(Track::Type type) const override;
|
||||
virtual rational VerifyLengthInternal(Track::Type type) const override;
|
||||
|
||||
private:
|
||||
QString GetColorspaceToUse(const VideoParams& params) const;
|
||||
|
||||
@@ -430,9 +430,6 @@ void ProjectViewModel::ConnectItem(Node *n)
|
||||
connect(f, &Folder::BeginRemoveItem, this, &ProjectViewModel::FolderBeginRemoveItem);
|
||||
connect(f, &Folder::EndRemoveItem, this, &ProjectViewModel::FolderEndRemoveItem);
|
||||
|
||||
connect(f, &Folder::BeginInsertItem, this, &ProjectViewModel::ItemAdded);
|
||||
connect(f, &Folder::BeginRemoveItem, this, &ProjectViewModel::ItemRemoved);
|
||||
|
||||
foreach (Node* c, f->children()) {
|
||||
ConnectItem(c);
|
||||
}
|
||||
@@ -450,9 +447,6 @@ void ProjectViewModel::DisconnectItem(Node *n)
|
||||
disconnect(f, &Folder::BeginRemoveItem, this, &ProjectViewModel::FolderBeginRemoveItem);
|
||||
disconnect(f, &Folder::EndRemoveItem, this, &ProjectViewModel::FolderEndRemoveItem);
|
||||
|
||||
disconnect(f, &Folder::BeginInsertItem, this, &ProjectViewModel::ItemAdded);
|
||||
disconnect(f, &Folder::BeginRemoveItem, this, &ProjectViewModel::ItemRemoved);
|
||||
|
||||
foreach (Node* c, f->children()) {
|
||||
DisconnectItem(c);
|
||||
}
|
||||
|
||||
@@ -104,11 +104,6 @@ public:
|
||||
*/
|
||||
QModelIndex CreateIndexFromItem(Node *item, int column = 0);
|
||||
|
||||
signals:
|
||||
void ItemAdded(Node* node);
|
||||
|
||||
void ItemRemoved(Node* node);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Retrieve the index of `item` in its parent
|
||||
|
||||
@@ -107,7 +107,7 @@ void Sequence::Retranslate()
|
||||
}
|
||||
}
|
||||
|
||||
rational Sequence::GetCustomLength(Track::Type type) const
|
||||
rational Sequence::VerifyLengthInternal(Track::Type type) const
|
||||
{
|
||||
if (!track_lists_.isEmpty()) {
|
||||
switch (type) {
|
||||
|
||||
@@ -103,7 +103,7 @@ protected:
|
||||
|
||||
virtual void InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output) override;
|
||||
|
||||
virtual rational GetCustomLength(Track::Type type) const override;
|
||||
virtual rational VerifyLengthInternal(Track::Type type) const override;
|
||||
|
||||
signals:
|
||||
void TrackAdded(Track* track);
|
||||
|
||||
+13
-1
@@ -382,8 +382,13 @@ NodeValueTable NodeValueTable::Merge(QList<NodeValueTable> tables)
|
||||
NodeValueTable merged_table;
|
||||
|
||||
// Slipstreams all tables together
|
||||
while (true) {
|
||||
bool all_merged = true;
|
||||
|
||||
foreach (const NodeValueTable& t, tables) {
|
||||
if (row >= t.Count()) {
|
||||
if (row < t.Count()) {
|
||||
all_merged = false;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -392,6 +397,13 @@ NodeValueTable NodeValueTable::Merge(QList<NodeValueTable> tables)
|
||||
merged_table.Prepend(t.at(row_index));
|
||||
}
|
||||
|
||||
row++;
|
||||
|
||||
if (all_merged) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return merged_table;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ ProjectPanel::ProjectPanel(QWidget *parent) :
|
||||
explorer_ = new ProjectExplorer(this);
|
||||
layout->addWidget(explorer_);
|
||||
connect(explorer_, &ProjectExplorer::DoubleClickedItem, this, &ProjectPanel::ItemDoubleClickSlot);
|
||||
connect(explorer_, &ProjectExplorer::ItemRemoved, this, &ProjectPanel::ItemRemoved);
|
||||
|
||||
// Set toolbar's view to the explorer's view
|
||||
toolbar->SetView(explorer_->view_type());
|
||||
@@ -233,16 +232,6 @@ void ProjectPanel::SaveConnectedProject()
|
||||
Core::instance()->SaveProject(this->project());
|
||||
}
|
||||
|
||||
void ProjectPanel::ItemRemoved(Node *item)
|
||||
{
|
||||
// Open this footage in a FootageViewer
|
||||
FootageViewerPanel* panel = PanelManager::instance()->MostRecentlyFocused<FootageViewerPanel>();
|
||||
|
||||
if (panel->GetConnectedViewer() == item) {
|
||||
panel->DisconnectViewerNode();
|
||||
}
|
||||
}
|
||||
|
||||
QVector<ViewerOutput *> ProjectPanel::GetSelectedFootage() const
|
||||
{
|
||||
QVector<Node*> items = SelectedItems();
|
||||
|
||||
@@ -80,8 +80,6 @@ private slots:
|
||||
|
||||
void SaveConnectedProject();
|
||||
|
||||
void ItemRemoved(Node* item);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -25,13 +25,13 @@ namespace olive {
|
||||
ViewerPanel::ViewerPanel(const QString &object_name, QWidget *parent) :
|
||||
ViewerPanelBase(object_name, parent)
|
||||
{
|
||||
// Set ViewerWidget as the central widget
|
||||
ViewerWidget* vw = new ViewerWidget();
|
||||
connect(vw, &ViewerWidget::RequestScopePanel, this, &ViewerPanel::CreateScopePanel);
|
||||
SetTimeBasedWidget(vw);
|
||||
Init();
|
||||
}
|
||||
|
||||
// Set strings
|
||||
Retranslate();
|
||||
ViewerPanel::ViewerPanel(QWidget *parent) :
|
||||
ViewerPanelBase(QStringLiteral("ViewerPanel"), parent)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
void ViewerPanel::Retranslate()
|
||||
@@ -41,4 +41,15 @@ void ViewerPanel::Retranslate()
|
||||
SetTitle(tr("Viewer"));
|
||||
}
|
||||
|
||||
void ViewerPanel::Init()
|
||||
{
|
||||
// Set ViewerWidget as the central widget
|
||||
ViewerWidget* vw = new ViewerWidget();
|
||||
connect(vw, &ViewerWidget::RequestScopePanel, this, &ViewerPanel::CreateScopePanel);
|
||||
SetTimeBasedWidget(vw);
|
||||
|
||||
// Set strings
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,10 +34,14 @@ class ViewerPanel : public ViewerPanelBase {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ViewerPanel(const QString& object_name, QWidget* parent);
|
||||
ViewerPanel(QWidget* parent);
|
||||
|
||||
protected:
|
||||
virtual void Retranslate() override;
|
||||
|
||||
private:
|
||||
void Init();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -668,6 +668,13 @@ void NodeView::ShowContextMenu(const QPoint &pos)
|
||||
QAction* autopos = m.addAction(tr("Auto-Position"));
|
||||
connect(autopos, &QAction::triggered, this, &NodeView::AutoPositionDescendents);
|
||||
|
||||
ViewerOutput* viewer = dynamic_cast<ViewerOutput*>(selected.first()->GetNode());
|
||||
if (viewer) {
|
||||
m.addSeparator();
|
||||
QAction* open_in_viewer_action = m.addAction(tr("Open in Viewer"));
|
||||
connect(open_in_viewer_action, &QAction::triggered, this, &NodeView::OpenSelectedNodeInViewer);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
QAction* curved_action = m.addAction(tr("Smooth Edges"));
|
||||
@@ -756,6 +763,16 @@ void NodeView::ContextMenuFilterChanged(QAction *action)
|
||||
Q_UNUSED(action)
|
||||
}
|
||||
|
||||
void NodeView::OpenSelectedNodeInViewer()
|
||||
{
|
||||
QVector<Node*> selected = scene_.GetSelectedNodes();
|
||||
ViewerOutput* viewer = selected.isEmpty() ? nullptr : dynamic_cast<ViewerOutput*>(selected.first());
|
||||
|
||||
if (viewer) {
|
||||
Core::instance()->OpenNodeInViewer(viewer);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeView::AttachNodesToCursor(const QVector<Node *> &nodes)
|
||||
{
|
||||
QVector<NodeViewItem*> items(nodes.size());
|
||||
|
||||
@@ -194,6 +194,11 @@ private slots:
|
||||
*/
|
||||
void ContextMenuFilterChanged(QAction* action);
|
||||
|
||||
/**
|
||||
* @brief Opens the selected node in a Viewer
|
||||
*/
|
||||
void OpenSelectedNodeInViewer();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -95,8 +95,6 @@ ProjectExplorer::ProjectExplorer(QWidget *parent) :
|
||||
connect(tree_view_, &ProjectExplorerTreeView::customContextMenuRequested, this, &ProjectExplorer::ShowContextMenu);
|
||||
connect(list_view_, &ProjectExplorerListView::customContextMenuRequested, this, &ProjectExplorer::ShowContextMenu);
|
||||
connect(icon_view_, &ProjectExplorerIconView::customContextMenuRequested, this, &ProjectExplorer::ShowContextMenu);
|
||||
|
||||
connect(&model_, &ProjectViewModel::ItemRemoved, this, &ProjectExplorer::ItemRemoved);
|
||||
}
|
||||
|
||||
const ProjectToolbar::ViewType &ProjectExplorer::view_type() const
|
||||
|
||||
@@ -100,8 +100,6 @@ signals:
|
||||
*/
|
||||
void DoubleClickedItem(Node* item);
|
||||
|
||||
void ItemRemoved(Node* node);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Get all the blocks that solely rely on an input node
|
||||
|
||||
@@ -85,6 +85,7 @@ void TimeBasedWidget::ConnectViewerNode(ViewerOutput *node)
|
||||
|
||||
// Disconnect length changed signal
|
||||
disconnect(viewer_node_, &ViewerOutput::LengthChanged, this, &TimeBasedWidget::UpdateMaximumScroll);
|
||||
disconnect(viewer_node_, &ViewerOutput::RemovedFromGraph, this, &TimeBasedWidget::ConnectedNodeRemovedFromGraph);
|
||||
|
||||
// Disconnect rate change signals if they were connected
|
||||
disconnect(viewer_node_, &ViewerOutput::FrameRateChanged, this, &TimeBasedWidget::AutoUpdateTimebase);
|
||||
@@ -109,6 +110,7 @@ void TimeBasedWidget::ConnectViewerNode(ViewerOutput *node)
|
||||
if (viewer_node_) {
|
||||
// Connect length changed signal
|
||||
connect(viewer_node_, &ViewerOutput::LengthChanged, this, &TimeBasedWidget::UpdateMaximumScroll);
|
||||
connect(viewer_node_, &ViewerOutput::RemovedFromGraph, this, &TimeBasedWidget::ConnectedNodeRemovedFromGraph);
|
||||
|
||||
// Connect ruler and scrollbar to timeline points
|
||||
ruler()->ConnectTimelinePoints(viewer_node_->GetTimelinePoints());
|
||||
@@ -216,6 +218,11 @@ void TimeBasedWidget::AutoUpdateTimebase()
|
||||
}
|
||||
}
|
||||
|
||||
void TimeBasedWidget::ConnectedNodeRemovedFromGraph()
|
||||
{
|
||||
ConnectViewerNode(nullptr);
|
||||
}
|
||||
|
||||
TimeRuler *TimeBasedWidget::ruler() const
|
||||
{
|
||||
return ruler_;
|
||||
|
||||
@@ -230,6 +230,8 @@ private slots:
|
||||
|
||||
void AutoUpdateTimebase();
|
||||
|
||||
void ConnectedNodeRemovedFromGraph();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -261,6 +261,27 @@ ScopePanel *MainWindow::AppendScopePanel()
|
||||
return AppendFloatingPanelInternal<ScopePanel>(scope_panels_);
|
||||
}
|
||||
|
||||
void MainWindow::OpenNodeInViewer(ViewerOutput *node)
|
||||
{
|
||||
if (viewer_panels_.contains(node)) {
|
||||
// This node already has a viewer, raise it
|
||||
viewer_panels_.value(node)->raise();
|
||||
} else {
|
||||
// Create a viewer for this node
|
||||
ViewerPanel* viewer = PanelManager::instance()->CreatePanel<ViewerPanel>(this);
|
||||
|
||||
viewer->SetSignalInsteadOfClose(true);
|
||||
viewer->setFloating(true);
|
||||
viewer->setVisible(true);
|
||||
viewer->ConnectViewerNode(node);
|
||||
|
||||
connect(viewer, &ViewerPanel::CloseRequested, this, &MainWindow::ViewerCloseRequested);
|
||||
connect(node, &ViewerOutput::RemovedFromGraph, this, &MainWindow::ViewerWithPanelRemovedFromGraph);
|
||||
|
||||
viewer_panels_.insert(node, viewer);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::SetFullscreen(bool fullscreen)
|
||||
{
|
||||
if (fullscreen) {
|
||||
@@ -481,6 +502,22 @@ void MainWindow::ProjectCloseRequested()
|
||||
Core::instance()->CloseProject(p, true);
|
||||
}
|
||||
|
||||
void MainWindow::ViewerCloseRequested()
|
||||
{
|
||||
ViewerPanel* panel = static_cast<ViewerPanel*>(sender());
|
||||
|
||||
viewer_panels_.remove(viewer_panels_.key(panel));
|
||||
|
||||
panel->deleteLater();
|
||||
}
|
||||
|
||||
void MainWindow::ViewerWithPanelRemovedFromGraph()
|
||||
{
|
||||
ViewerOutput* vo = static_cast<ViewerOutput*>(sender());
|
||||
viewer_panels_.take(vo)->deleteLater();
|
||||
disconnect(vo, &ViewerOutput::RemovedFromGraph, this, &MainWindow::ViewerWithPanelRemovedFromGraph);
|
||||
}
|
||||
|
||||
void MainWindow::FloatingPanelCloseRequested()
|
||||
{
|
||||
PanelWidget* panel = static_cast<PanelWidget*>(sender());
|
||||
|
||||
@@ -71,6 +71,8 @@ public:
|
||||
|
||||
ScopePanel* AppendScopePanel();
|
||||
|
||||
void OpenNodeInViewer(ViewerOutput* node);
|
||||
|
||||
enum ProgressStatus {
|
||||
kProgressNone,
|
||||
kProgressShow,
|
||||
@@ -155,6 +157,7 @@ private:
|
||||
PixelSamplerPanel* pixel_sampler_panel_;
|
||||
QList<ScopePanel*> scope_panels_;
|
||||
NodeTablePanel* table_panel_;
|
||||
QMap<ViewerOutput*, ViewerPanel*> viewer_panels_;
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
unsigned int taskbar_btn_id_;
|
||||
@@ -173,6 +176,10 @@ private slots:
|
||||
|
||||
void ProjectCloseRequested();
|
||||
|
||||
void ViewerCloseRequested();
|
||||
|
||||
void ViewerWithPanelRemovedFromGraph();
|
||||
|
||||
void FloatingPanelCloseRequested();
|
||||
|
||||
void StatusBarDoubleClicked();
|
||||
|
||||
Reference in New Issue
Block a user