mainwindow: improved panel organization
This commit is contained in:
+22
-19
@@ -144,15 +144,15 @@ void Core::Start()
|
||||
// Initialize task manager
|
||||
TaskManager::CreateInstance();
|
||||
|
||||
// Initialize ConformManager
|
||||
ConformManager::CreateInstance();
|
||||
|
||||
// Initialize RenderManager
|
||||
RenderManager::CreateInstance();
|
||||
|
||||
// Initialize FrameManager
|
||||
FrameManager::CreateInstance();
|
||||
|
||||
// Initialize ConformManager
|
||||
ConformManager::CreateInstance();
|
||||
|
||||
// Initialize project serializers
|
||||
ProjectSerializer::Initialize();
|
||||
|
||||
@@ -468,8 +468,6 @@ void Core::AddOpenProject(Project* p, bool add_to_recents)
|
||||
{
|
||||
// Ensure project is not open at the moment
|
||||
if (open_project_ == p) {
|
||||
// Signal UI to switch to this project
|
||||
emit ProjectOpened(p);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -478,15 +476,11 @@ void Core::AddOpenProject(Project* p, bool add_to_recents)
|
||||
CloseProject(false);
|
||||
}
|
||||
|
||||
connect(p, &Project::ModifiedChanged, this, &Core::ProjectWasModified);
|
||||
open_project_ = p;
|
||||
RenderManager::instance()->SetProject(p);
|
||||
SetActiveProject(p);
|
||||
|
||||
if (!p->filename().isEmpty() && add_to_recents) {
|
||||
PushRecentlyOpenedProject(p->filename());
|
||||
}
|
||||
|
||||
emit ProjectOpened(p);
|
||||
}
|
||||
|
||||
bool Core::AddOpenProjectFromTask(Task *task, bool add_to_recents)
|
||||
@@ -510,6 +504,21 @@ bool Core::AddOpenProjectFromTask(Task *task, bool add_to_recents)
|
||||
return false;
|
||||
}
|
||||
|
||||
void Core::SetActiveProject(Project *p)
|
||||
{
|
||||
if (open_project_) {
|
||||
disconnect(open_project_, &Project::ModifiedChanged, this, &Core::ProjectWasModified);
|
||||
}
|
||||
|
||||
open_project_ = p;
|
||||
RenderManager::instance()->SetProject(p);
|
||||
main_window_->SetProject(p);
|
||||
|
||||
if (open_project_) {
|
||||
connect(open_project_, &Project::ModifiedChanged, this, &Core::ProjectWasModified);
|
||||
}
|
||||
}
|
||||
|
||||
void Core::ImportTaskComplete(Task* task)
|
||||
{
|
||||
ProjectImportTask* import_task = static_cast<ProjectImportTask*>(task);
|
||||
@@ -758,10 +767,6 @@ void Core::StartGUI(bool full_screen)
|
||||
QWindowsWindowFunctions::setHasBorderInFullScreen(main_window_->windowHandle(), true);
|
||||
#endif
|
||||
|
||||
// When a new project is opened, update the mainwindow
|
||||
connect(this, &Core::ProjectOpened, main_window_, &MainWindow::ProjectOpen, Qt::QueuedConnection);
|
||||
connect(this, &Core::ProjectClosed, main_window_, &MainWindow::ProjectClose);
|
||||
|
||||
// Start autorecovery timer using the config value as its interval
|
||||
SetAutorecoveryInterval(OLIVE_CONFIG("AutorecoveryInterval").toInt());
|
||||
connect(&autorecovery_timer_, &QTimer::timeout, this, &Core::SaveAutorecovery);
|
||||
@@ -1476,11 +1481,9 @@ bool Core::CloseProject(bool auto_open_new, bool ignore_modified)
|
||||
// For safety, the undo stack is cleared so no commands try to affect a freed project
|
||||
undo_stack_.clear();
|
||||
|
||||
disconnect(open_project_, &Project::ModifiedChanged, this, &Core::ProjectWasModified);
|
||||
RenderManager::instance()->SetProject(nullptr);
|
||||
emit ProjectClosed(open_project_);
|
||||
delete open_project_;
|
||||
open_project_ = nullptr;
|
||||
Project *tmp = open_project_;
|
||||
SetActiveProject(nullptr);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
// Ensure a project is always active
|
||||
|
||||
+2
-14
@@ -407,20 +407,6 @@ public slots:
|
||||
}
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when a project is opened
|
||||
*
|
||||
* Connects to main window so its UI can update based on the project
|
||||
*
|
||||
* @param p
|
||||
*/
|
||||
void ProjectOpened(Project* p);
|
||||
|
||||
/**
|
||||
* @brief Signal emitted when a project is closed
|
||||
*/
|
||||
void ProjectClosed(Project* p);
|
||||
|
||||
/**
|
||||
* @brief Signal emitted when the tool is changed from somewhere
|
||||
*/
|
||||
@@ -520,6 +506,8 @@ private:
|
||||
|
||||
bool AddOpenProjectFromTask(Task* task, bool add_to_recents);
|
||||
|
||||
void SetActiveProject(Project *p);
|
||||
|
||||
/**
|
||||
* @brief Internal main window object
|
||||
*/
|
||||
|
||||
@@ -33,6 +33,8 @@ add_subdirectory(viewer)
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
panel/panel.h
|
||||
panel/panel.cpp
|
||||
panel/panelmanager.h
|
||||
panel/panelmanager.cpp
|
||||
PARENT_SCOPE
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
#ifndef AUDIOMONITORPANEL_H
|
||||
#define AUDIOMONITORPANEL_H
|
||||
|
||||
#include "panel/panel.h"
|
||||
#include "widget/audiomonitor/audiomonitor.h"
|
||||
#include "widget/panel/panel.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
#ifndef NODEPANEL_H
|
||||
#define NODEPANEL_H
|
||||
|
||||
#include "panel/panel.h"
|
||||
#include "widget/nodeview/nodewidget.h"
|
||||
#include "widget/panel/panel.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
|
||||
@@ -32,8 +32,10 @@
|
||||
|
||||
namespace olive {
|
||||
|
||||
#define super QDockWidget
|
||||
|
||||
PanelWidget::PanelWidget(const QString &object_name, QWidget *parent) :
|
||||
QDockWidget(parent),
|
||||
super(parent),
|
||||
border_visible_(false),
|
||||
signal_instead_of_close_(false)
|
||||
{
|
||||
@@ -55,15 +57,9 @@ void PanelWidget::SetMovementLocked(bool locked)
|
||||
if (locked) {
|
||||
// Disable moving on QDockWidget
|
||||
setFeatures(features() & ~QDockWidget::DockWidgetMovable);
|
||||
|
||||
// Hide the title bar (only real way to do this is to replace it with an empty QWidget)
|
||||
setTitleBarWidget(new QWidget(this));
|
||||
} else {
|
||||
// Re-enable moving on QDockWidget
|
||||
setFeatures(features() | QDockWidget::DockWidgetMovable);
|
||||
|
||||
// Set the "custom" titlebar to null so the default gets restored
|
||||
setTitleBarWidget(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +85,7 @@ void PanelWidget::SetSubtitle(const QString &t)
|
||||
void PanelWidget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
// Perform default behavior
|
||||
QDockWidget::paintEvent(event);
|
||||
super::paintEvent(event);
|
||||
|
||||
// Check if this panel (or a child of it) has focus using PanelFocusManager
|
||||
if (border_visible_) {
|
||||
@@ -66,6 +66,11 @@ public:
|
||||
*/
|
||||
void SetSignalInsteadOfClose(bool e);
|
||||
|
||||
using Info = std::map<QString, QString>;
|
||||
|
||||
virtual void LoadData(const Info &info){}
|
||||
virtual Info SaveData() const {return Info();}
|
||||
|
||||
/**
|
||||
* @brief Called whenever this panel is focused and user uses "Zoom In" (either in menus or as a keyboard shortcut)
|
||||
*
|
||||
@@ -78,6 +78,17 @@ PanelWidget *PanelManager::CurrentlyHovered() const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PanelWidget *PanelManager::GetPanelWithName(const QString &name) const
|
||||
{
|
||||
foreach (PanelWidget* panel, focus_history_) {
|
||||
if (panel->objectName() == name) {
|
||||
return panel;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool PanelManager::ArePanelsLocked()
|
||||
{
|
||||
return locked_;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
|
||||
#include "widget/panel/panel.h"
|
||||
#include "panel/panel.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
@@ -74,6 +74,8 @@ public:
|
||||
*/
|
||||
PanelWidget* CurrentlyHovered() const;
|
||||
|
||||
PanelWidget *GetPanelWithName(const QString &name) const;
|
||||
|
||||
template<class T>
|
||||
/**
|
||||
* @brief Get most recently focused panel of a certain type
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#ifndef PIXELSAMPLERPANEL_H
|
||||
#define PIXELSAMPLERPANEL_H
|
||||
|
||||
#include "widget/panel/panel.h"
|
||||
#include "panel/panel.h"
|
||||
#include "widget/pixelsampler/pixelsampler.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "footagemanagementpanel.h"
|
||||
#include "node/project/project.h"
|
||||
#include "widget/panel/panel.h"
|
||||
#include "panel/panel.h"
|
||||
#include "widget/projectexplorer/projectexplorer.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
#include <QComboBox>
|
||||
#include <QStackedWidget>
|
||||
|
||||
#include "panel/panel.h"
|
||||
#include "panel/viewer/viewerbase.h"
|
||||
#include "widget/panel/panel.h"
|
||||
#include "widget/scope/histogram/histogram.h"
|
||||
#include "widget/scope/waveform/waveform.h"
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
#ifndef TASKMANAGER_PANEL_H
|
||||
#define TASKMANAGER_PANEL_H
|
||||
|
||||
#include "panel/panel.h"
|
||||
#include "widget/taskview/taskview.h"
|
||||
#include "widget/panel/panel.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#ifndef TIMEBASEDPANEL_H
|
||||
#define TIMEBASEDPANEL_H
|
||||
|
||||
#include "widget/panel/panel.h"
|
||||
#include "panel/panel.h"
|
||||
#include "widget/timebased/timebasedwidget.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
@@ -44,14 +44,18 @@ void TimelinePanel::SplitAtPlayhead()
|
||||
timeline_widget()->SplitAtPlayhead();
|
||||
}
|
||||
|
||||
QByteArray TimelinePanel::SaveSplitterState() const
|
||||
void TimelinePanel::LoadData(const Info &info)
|
||||
{
|
||||
return timeline_widget()->SaveSplitterState();
|
||||
timeline_widget()->RestoreSplitterState(QByteArray::fromBase64(info.at("splitter").toUtf8()));
|
||||
}
|
||||
|
||||
void TimelinePanel::RestoreSplitterState(const QByteArray &state)
|
||||
PanelWidget::Info TimelinePanel::SaveData() const
|
||||
{
|
||||
timeline_widget()->RestoreSplitterState(state);
|
||||
Info i;
|
||||
|
||||
i["splitter"] = timeline_widget()->SaveSplitterState().toBase64();
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void TimelinePanel::SelectAll()
|
||||
|
||||
@@ -42,9 +42,8 @@ public:
|
||||
|
||||
void SplitAtPlayhead();
|
||||
|
||||
QByteArray SaveSplitterState() const;
|
||||
|
||||
void RestoreSplitterState(const QByteArray& state);
|
||||
virtual void LoadData(const Info &info) override;
|
||||
virtual Info SaveData() const override;
|
||||
|
||||
virtual void SelectAll() override;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#ifndef TOOL_PANEL_H
|
||||
#define TOOL_PANEL_H
|
||||
|
||||
#include "widget/panel/panel.h"
|
||||
#include "panel/panel.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ add_subdirectory(nodetableview)
|
||||
add_subdirectory(nodetreeview)
|
||||
add_subdirectory(nodevaluetree)
|
||||
add_subdirectory(nodeview)
|
||||
add_subdirectory(panel)
|
||||
add_subdirectory(path)
|
||||
add_subdirectory(pixelsampler)
|
||||
add_subdirectory(playbackcontrols)
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2022 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/panel/panel.h
|
||||
widget/panel/panel.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
@@ -495,12 +495,12 @@ void ProjectExplorer::ReplaceSelectedFootage()
|
||||
|
||||
void ProjectExplorer::OpenContextMenuItemInNewTab()
|
||||
{
|
||||
Core::instance()->main_window()->FolderOpen(project(), static_cast<Folder*>(context_menu_items_.first()), false);
|
||||
Core::instance()->main_window()->OpenFolder(project(), static_cast<Folder*>(context_menu_items_.first()), false);
|
||||
}
|
||||
|
||||
void ProjectExplorer::OpenContextMenuItemInNewWindow()
|
||||
{
|
||||
Core::instance()->main_window()->FolderOpen(project(), static_cast<Folder*>(context_menu_items_.first()), true);
|
||||
Core::instance()->main_window()->OpenFolder(project(), static_cast<Folder*>(context_menu_items_.first()), true);
|
||||
}
|
||||
|
||||
void ProjectExplorer::ContextMenuStartProxy(QAction *a)
|
||||
|
||||
@@ -37,7 +37,8 @@
|
||||
namespace olive {
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent)
|
||||
QMainWindow(parent),
|
||||
project_(nullptr)
|
||||
{
|
||||
// Resizes main window to desktop geometry on startup. Fixes the following issues:
|
||||
// * Qt on Windows has a bug that "de-maximizes" the window when widgets are added, resizing the
|
||||
@@ -88,7 +89,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
sequence_viewer_panel_ = new SequenceViewerPanel(this);
|
||||
multicam_panel_ = new MulticamPanel(this);
|
||||
pixel_sampler_panel_ = new PixelSamplerPanel(this);
|
||||
AppendProjectPanel();
|
||||
project_panel_ = new ProjectPanel(this);
|
||||
tool_panel_ = new ToolPanel(this);
|
||||
task_man_panel_ = new TaskManagerPanel(this);
|
||||
AppendTimelinePanel();
|
||||
@@ -103,6 +104,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
connect(param_panel_, &ParamPanel::RequestViewerToStartEditingText, sequence_viewer_panel_, &ViewerPanel::RequestStartEditingText);
|
||||
connect(param_panel_, &ParamPanel::FocusedNodeChanged, curve_panel_, &CurvePanel::SetNode);
|
||||
connect(param_panel_, &ParamPanel::SelectedNodesChanged, node_panel_, &NodePanel::Select);
|
||||
connect(project_panel_, &ProjectPanel::ProjectNameChanged, this, &MainWindow::UpdateTitle);
|
||||
|
||||
connect(node_panel_, &NodePanel::NodeSelectionChanged, sequence_viewer_panel_, &ViewerPanel::SetNodeViewSelections);
|
||||
|
||||
@@ -135,12 +137,22 @@ MainWindow::~MainWindow()
|
||||
void MainWindow::LoadLayout(const MainWindowLayoutInfo &info)
|
||||
{
|
||||
foreach (Folder* folder, info.open_folders()) {
|
||||
FolderOpen(folder->project(), folder, true);
|
||||
OpenFolder(folder->project(), folder, true);
|
||||
}
|
||||
|
||||
foreach (const MainWindowLayoutInfo::OpenSequence& sequence, info.open_sequences()) {
|
||||
TimelinePanel* panel = OpenSequence(sequence.sequence, info.open_sequences().size() == 1);
|
||||
panel->RestoreSplitterState(sequence.panel_state);
|
||||
foreach (Sequence *sequence, info.open_sequences()) {
|
||||
OpenSequence(sequence, info.open_sequences().size() == 1);
|
||||
}
|
||||
|
||||
foreach (ViewerOutput *viewer, info.open_viewers()) {
|
||||
OpenNodeInViewer(viewer);
|
||||
}
|
||||
|
||||
for (auto it=info.panel_data().cbegin(); it!=info.panel_data().cend(); it++) {
|
||||
// Find panel with this ID
|
||||
if (PanelWidget *panel = PanelManager::instance()->GetPanelWithName(it->first)) {
|
||||
panel->LoadData(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
restoreState(info.state());
|
||||
@@ -158,12 +170,19 @@ MainWindowLayoutInfo MainWindow::SaveLayout() const
|
||||
|
||||
foreach (TimelinePanel* panel, timeline_panels_) {
|
||||
if (panel->GetConnectedViewer()) {
|
||||
info.add_sequence({static_cast<Sequence*>(panel->GetConnectedViewer()),
|
||||
panel->SaveSplitterState()});
|
||||
info.add_sequence(panel->GetSequence());
|
||||
}
|
||||
}
|
||||
|
||||
info.set_state(saveState());
|
||||
for (auto it=viewer_panels_.cbegin(); it!=viewer_panels_.cend(); it++) {
|
||||
info.add_viewer((*it)->GetConnectedViewer());
|
||||
}
|
||||
|
||||
foreach (PanelWidget *panel, PanelManager::instance()->panels()) {
|
||||
info.set_panel_data(panel->objectName(), panel->SaveData());
|
||||
}
|
||||
|
||||
info.set_state(this->saveState());
|
||||
|
||||
return info;
|
||||
}
|
||||
@@ -222,39 +241,38 @@ bool MainWindow::IsSequenceOpen(Sequence *sequence) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void MainWindow::FolderOpen(Project* p, Folder *i, bool floating)
|
||||
void MainWindow::OpenFolder(Project* p, Folder *i, bool floating)
|
||||
{
|
||||
ProjectPanel* panel = new ProjectPanel(this);
|
||||
ProjectPanel* panel = AppendPanelInternal(folder_panels_);
|
||||
|
||||
panel->set_project(p);
|
||||
panel->set_root(i);
|
||||
|
||||
// Tabify with source project panel
|
||||
foreach (ProjectPanel* proj_panel, project_panels_) {
|
||||
if (proj_panel->project() == p) {
|
||||
tabifyDockWidget(proj_panel, panel);
|
||||
break;
|
||||
}
|
||||
if (floating) {
|
||||
panel->setFloating(floating);
|
||||
} else {
|
||||
tabifyDockWidget(project_panel_, panel);
|
||||
}
|
||||
|
||||
panel->setFloating(floating);
|
||||
|
||||
panel->show();
|
||||
panel->raise();
|
||||
|
||||
// If the panel is closed, just destroy it
|
||||
panel->SetSignalInsteadOfClose(true);
|
||||
panel->setProperty("parent_list", reinterpret_cast<quintptr>(&folder_panels_));
|
||||
connect(panel, &ProjectPanel::CloseRequested, this, &MainWindow::FloatingPanelCloseRequested);
|
||||
|
||||
folder_panels_.append(panel);
|
||||
connect(panel, &ProjectPanel::CloseRequested, this, &MainWindow::FolderPanelCloseRequested);
|
||||
}
|
||||
|
||||
void MainWindow::OpenNodeInViewer(ViewerOutput *node)
|
||||
{
|
||||
if (viewer_panels_.contains(node)) {
|
||||
ViewerPanel *existing = nullptr;
|
||||
|
||||
for (auto it = viewer_panels_.cbegin(); it != viewer_panels_.cend(); it++) {
|
||||
ViewerPanel *it2 = (*it);
|
||||
if (it2->GetConnectedViewer() == node) {
|
||||
existing = it2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (existing) {
|
||||
// This node already has a viewer, raise it
|
||||
viewer_panels_.value(node)->raise();
|
||||
existing->raise();
|
||||
} else {
|
||||
// Create a viewer for this node
|
||||
ViewerPanel* viewer = new ViewerPanel(this);
|
||||
@@ -267,7 +285,7 @@ void MainWindow::OpenNodeInViewer(ViewerOutput *node)
|
||||
connect(viewer, &ViewerPanel::CloseRequested, this, &MainWindow::ViewerCloseRequested);
|
||||
connect(node, &ViewerOutput::RemovedFromGraph, this, &MainWindow::ViewerWithPanelRemovedFromGraph);
|
||||
|
||||
viewer_panels_.insert(node, viewer);
|
||||
viewer_panels_.append(viewer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,62 +346,47 @@ void MainWindow::ToggleMaximizedPanel()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::ProjectOpen(Project *p)
|
||||
void MainWindow::SetProject(Project *p)
|
||||
{
|
||||
// See if this project is already open, and switch to it if so
|
||||
foreach (ProjectPanel* pl, project_panels_) {
|
||||
if (pl->project() == p) {
|
||||
pl->raise();
|
||||
return;
|
||||
}
|
||||
if (project_ == p) {
|
||||
return;
|
||||
}
|
||||
|
||||
ProjectPanel* panel;
|
||||
if (project_) {
|
||||
// Clear all data
|
||||
param_panel_->SetContexts(QVector<Node*>());
|
||||
node_panel_->SetContexts(QVector<Node*>());
|
||||
|
||||
if (!project_panels_.first()->project()) {
|
||||
panel = project_panels_.first();
|
||||
} else {
|
||||
panel = AppendProjectPanel();
|
||||
}
|
||||
// Close any nodes open in TimeBasedWidgets
|
||||
foreach (PanelWidget* panel, PanelManager::instance()->panels()) {
|
||||
TimeBasedPanel* tbp = dynamic_cast<TimeBasedPanel*>(panel);
|
||||
|
||||
panel->set_project(p);
|
||||
panel->setFocus();
|
||||
}
|
||||
|
||||
void MainWindow::ProjectClose(Project *p)
|
||||
{
|
||||
// Close project from NodeParamView
|
||||
param_panel_->CloseContextsBelongingToProject(p);
|
||||
|
||||
// Close project from NodeView
|
||||
node_panel_->CloseContextsBelongingToProject(p);
|
||||
|
||||
// Close any nodes open in TimeBasedWidgets
|
||||
foreach (PanelWidget* panel, PanelManager::instance()->panels()) {
|
||||
TimeBasedPanel* tbp = dynamic_cast<TimeBasedPanel*>(panel);
|
||||
|
||||
if (tbp && tbp->GetConnectedViewer() && tbp->GetConnectedViewer()->project() == p) {
|
||||
if (dynamic_cast<TimelinePanel*>(tbp)) {
|
||||
// Prefer our CloseSequence function which will delete any unnecessary timeline panels
|
||||
CloseSequence(static_cast<Sequence*>(tbp->GetConnectedViewer()));
|
||||
} else {
|
||||
tbp->DisconnectViewerNode();
|
||||
if (tbp && tbp->GetConnectedViewer() && tbp->GetConnectedViewer()->project() == project_) {
|
||||
if (dynamic_cast<TimelinePanel*>(tbp)) {
|
||||
// Prefer our CloseSequence function which will delete any unnecessary timeline panels
|
||||
CloseSequence(static_cast<Sequence*>(tbp->GetConnectedViewer()));
|
||||
} else {
|
||||
tbp->DisconnectViewerNode();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close any extra folder panels
|
||||
foreach (ProjectPanel* panel, folder_panels_) {
|
||||
if (panel->project() == p) {
|
||||
// Close any extra folder panels
|
||||
foreach (ProjectPanel* panel, folder_panels_) {
|
||||
panel->close();
|
||||
}
|
||||
|
||||
// Close any extra viewer panels
|
||||
foreach (ViewerPanel *viewer, viewer_panels_) {
|
||||
viewer->close();
|
||||
}
|
||||
}
|
||||
|
||||
// Close project from project panel
|
||||
foreach (ProjectPanel* panel, project_panels_) {
|
||||
if (panel->project() == p) {
|
||||
RemoveProjectPanel(panel);
|
||||
}
|
||||
project_ = p;
|
||||
project_panel_->set_project(p);
|
||||
|
||||
if (project_) {
|
||||
project_panel_->setFocus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,9 +423,7 @@ void MainWindow::SetApplicationProgressValue(int value)
|
||||
|
||||
void MainWindow::SelectFootage(const QVector<Footage *> &e)
|
||||
{
|
||||
for (ProjectPanel *p : project_panels_) {
|
||||
SelectFootageForProjectPanel(e, p);
|
||||
}
|
||||
SelectFootageForProjectPanel(e, project_panel_);
|
||||
for (ProjectPanel *p : folder_panels_) {
|
||||
SelectFootageForProjectPanel(e, p);
|
||||
}
|
||||
@@ -502,8 +503,11 @@ void MainWindow::ShowWelcomeDialog()
|
||||
|
||||
void MainWindow::RevealViewerInProject(ViewerOutput *r)
|
||||
{
|
||||
foreach (ProjectPanel *p, project_panels_) {
|
||||
if (p->project() == r->project() && p->SelectItem(r)) {
|
||||
// Rather than just using the resident ProjectPanel, find the most recently focused one since
|
||||
// that's probably the one people will want
|
||||
auto panels = PanelManager::instance()->GetPanelsOfType<ProjectPanel>();
|
||||
foreach (ProjectPanel *p, panels) {
|
||||
if (p->SelectItem(r)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -553,11 +557,6 @@ void MainWindow::TimelineCloseRequested()
|
||||
RemoveTimelinePanel(t);
|
||||
}
|
||||
|
||||
void MainWindow::ProjectCloseRequested()
|
||||
{
|
||||
Core::instance()->CloseProject(true);
|
||||
}
|
||||
|
||||
void MainWindow::ViewerCloseRequested()
|
||||
{
|
||||
ViewerPanel* panel = static_cast<ViewerPanel*>(sender());
|
||||
@@ -566,7 +565,7 @@ void MainWindow::ViewerCloseRequested()
|
||||
scope_panel_->SetViewerPanel(sequence_viewer_panel_);
|
||||
}
|
||||
|
||||
viewer_panels_.remove(viewer_panels_.key(panel));
|
||||
RemovePanelInternal(viewer_panels_, panel);
|
||||
|
||||
panel->deleteLater();
|
||||
}
|
||||
@@ -574,24 +573,37 @@ void MainWindow::ViewerCloseRequested()
|
||||
void MainWindow::ViewerWithPanelRemovedFromGraph()
|
||||
{
|
||||
ViewerOutput* vo = static_cast<ViewerOutput*>(sender());
|
||||
viewer_panels_.take(vo)->deleteLater();
|
||||
disconnect(vo, &ViewerOutput::RemovedFromGraph, this, &MainWindow::ViewerWithPanelRemovedFromGraph);
|
||||
ViewerPanel *panel = nullptr;
|
||||
|
||||
foreach (ViewerPanel *p, viewer_panels_) {
|
||||
if (p->GetConnectedViewer() == vo) {
|
||||
panel = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (panel) {
|
||||
RemovePanelInternal(viewer_panels_, panel);
|
||||
panel->deleteLater();
|
||||
disconnect(vo, &ViewerOutput::RemovedFromGraph, this, &MainWindow::ViewerWithPanelRemovedFromGraph);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::FloatingPanelCloseRequested()
|
||||
void MainWindow::FolderPanelCloseRequested()
|
||||
{
|
||||
PanelWidget* panel = static_cast<PanelWidget*>(sender());
|
||||
|
||||
quintptr list_ptr = panel->property("parent_list").value<quintptr>();
|
||||
QList<PanelWidget*>* list = reinterpret_cast< QList<PanelWidget*>* >(list_ptr);
|
||||
|
||||
list->removeOne(panel);
|
||||
ProjectPanel* panel = static_cast<ProjectPanel*>(sender());
|
||||
RemovePanelInternal(folder_panels_, panel);
|
||||
removeDockWidget(panel);
|
||||
panel->deleteLater();
|
||||
}
|
||||
|
||||
TimelinePanel* MainWindow::AppendTimelinePanel()
|
||||
{
|
||||
TimelinePanel* panel = AppendPanelInternal<TimelinePanel>(timeline_panels_);
|
||||
TimelinePanel* panel = AppendPanelInternal(timeline_panels_);
|
||||
|
||||
if (!timeline_panels_.isEmpty()) {
|
||||
tabifyDockWidget(timeline_panels_.last(), panel);
|
||||
}
|
||||
|
||||
connect(panel, &PanelWidget::CloseRequested, this, &MainWindow::TimelineCloseRequested);
|
||||
connect(panel, &TimelinePanel::RequestCaptureStart, sequence_viewer_panel_, &SequenceViewerPanel::StartCapture);
|
||||
@@ -604,16 +616,6 @@ TimelinePanel* MainWindow::AppendTimelinePanel()
|
||||
return panel;
|
||||
}
|
||||
|
||||
ProjectPanel *MainWindow::AppendProjectPanel()
|
||||
{
|
||||
ProjectPanel* panel = AppendPanelInternal<ProjectPanel>(project_panels_);
|
||||
|
||||
connect(panel, &PanelWidget::CloseRequested, this, &MainWindow::ProjectCloseRequested);
|
||||
connect(panel, &ProjectPanel::ProjectNameChanged, this, &MainWindow::UpdateTitle);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
void MainWindow::RemoveTimelinePanel(TimelinePanel *panel)
|
||||
{
|
||||
// Stop showing this timeline in the viewer
|
||||
@@ -621,17 +623,7 @@ void MainWindow::RemoveTimelinePanel(TimelinePanel *panel)
|
||||
panel->ConnectViewerNode(nullptr);
|
||||
|
||||
if (timeline_panels_.size() != 1) {
|
||||
timeline_panels_.removeOne(panel);
|
||||
panel->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::RemoveProjectPanel(ProjectPanel *panel)
|
||||
{
|
||||
if (project_panels_.size() == 1) {
|
||||
panel->set_project(nullptr);
|
||||
} else {
|
||||
project_panels_.removeOne(panel);
|
||||
RemovePanelInternal(timeline_panels_, panel);
|
||||
panel->deleteLater();
|
||||
}
|
||||
}
|
||||
@@ -841,8 +833,8 @@ void MainWindow::SetDefaultLayout()
|
||||
pixel_sampler_panel_->setFloating(true);
|
||||
addDockWidget(Qt::TopDockWidgetArea, pixel_sampler_panel_);
|
||||
|
||||
project_panels_.first()->show();
|
||||
addDockWidget(Qt::BottomDockWidgetArea, project_panels_.first());
|
||||
project_panel_->show();
|
||||
addDockWidget(Qt::BottomDockWidgetArea, project_panel_);
|
||||
|
||||
tool_panel_->show();
|
||||
addDockWidget(Qt::BottomDockWidgetArea, tool_panel_);
|
||||
@@ -861,11 +853,11 @@ void MainWindow::SetDefaultLayout()
|
||||
{width()/2, width()/2},
|
||||
Qt::Horizontal);
|
||||
|
||||
resizeDocks({project_panels_.first(), tool_panel_, timeline_panels_.first(), audio_monitor_panel_},
|
||||
resizeDocks({project_panel_, tool_panel_, timeline_panels_.first(), audio_monitor_panel_},
|
||||
{width()/4, 1, width(), 1},
|
||||
Qt::Horizontal);
|
||||
|
||||
resizeDocks({node_panel_, project_panels_.first()},
|
||||
resizeDocks({node_panel_, project_panel_},
|
||||
{height()/2, height()/2},
|
||||
Qt::Vertical);
|
||||
}
|
||||
@@ -897,19 +889,24 @@ void MainWindow::showEvent(QShowEvent *e)
|
||||
}
|
||||
}
|
||||
|
||||
void UpdatePanelName(PanelWidget *panel, int index)
|
||||
{
|
||||
QString old_name = panel->objectName();
|
||||
QString new_name = QStringLiteral("%1:%2").arg(old_name.split(':').at(0), QString::number(index));
|
||||
qDebug() << "renaming" << old_name << "to" << new_name;
|
||||
panel->setObjectName(new_name);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *MainWindow::AppendPanelInternal(QList<T*>& list)
|
||||
{
|
||||
T* panel = new T(this);
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
tabifyDockWidget(list.last(), panel);
|
||||
}
|
||||
|
||||
// For some reason raise() on its own doesn't do anything, we need both
|
||||
panel->show();
|
||||
panel->raise();
|
||||
|
||||
UpdatePanelName(panel, list.size());
|
||||
list.append(panel);
|
||||
|
||||
// Let us handle the panel closing rather than the panel itself
|
||||
@@ -919,19 +916,16 @@ T *MainWindow::AppendPanelInternal(QList<T*>& list)
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *MainWindow::AppendFloatingPanelInternal(QList<T *> &list)
|
||||
void MainWindow::RemovePanelInternal(QList<T *> &list, T *panel)
|
||||
{
|
||||
T* panel = new T(this);
|
||||
int index = list.indexOf(panel);
|
||||
|
||||
panel->setFloating(true);
|
||||
panel->show();
|
||||
|
||||
panel->SetSignalInsteadOfClose(true);
|
||||
connect(panel, &PanelWidget::CloseRequested, this, &MainWindow::FloatingPanelCloseRequested);
|
||||
|
||||
panel->setProperty("parent_list", reinterpret_cast<quintptr>(&list));
|
||||
|
||||
return panel;
|
||||
if (index != -1) {
|
||||
list.removeAt(index);
|
||||
for (int i = index; i < list.size(); i++) {
|
||||
UpdatePanelName(list.at(i), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
|
||||
bool IsSequenceOpen(Sequence* sequence) const;
|
||||
|
||||
void FolderOpen(Project* p, Folder *i, bool floating);
|
||||
void OpenFolder(Project* p, Folder *i, bool floating);
|
||||
|
||||
void OpenNodeInViewer(ViewerOutput* node);
|
||||
|
||||
@@ -96,9 +96,7 @@ public:
|
||||
void SelectFootage(const QVector<Footage*> &e);
|
||||
|
||||
public slots:
|
||||
void ProjectOpen(Project *p);
|
||||
|
||||
void ProjectClose(Project* p);
|
||||
void SetProject(Project *p);
|
||||
|
||||
void SetFullscreen(bool fullscreen);
|
||||
|
||||
@@ -118,21 +116,14 @@ protected:
|
||||
private:
|
||||
TimelinePanel* AppendTimelinePanel();
|
||||
|
||||
ProjectPanel* AppendProjectPanel();
|
||||
|
||||
template <typename T>
|
||||
T* AppendPanelInternal(QList<T*>& list);
|
||||
|
||||
template <typename T>
|
||||
T* AppendFloatingPanelInternal(QList<T*>& list);
|
||||
|
||||
template<typename T>
|
||||
void SetUniquePanelID(T* panel, const QList<T*>& list);
|
||||
void RemovePanelInternal(QList<T*>& list, T *panel);
|
||||
|
||||
void RemoveTimelinePanel(TimelinePanel *panel);
|
||||
|
||||
void RemoveProjectPanel(ProjectPanel* panel);
|
||||
|
||||
void TimelineFocused(ViewerOutput *viewer);
|
||||
|
||||
static QString GetCustomShortcutsFile();
|
||||
@@ -150,12 +141,12 @@ private:
|
||||
QByteArray premaximized_state_;
|
||||
|
||||
// Standard panels
|
||||
ProjectPanel *project_panel_;
|
||||
NodePanel* node_panel_;
|
||||
ParamPanel* param_panel_;
|
||||
CurvePanel* curve_panel_;
|
||||
SequenceViewerPanel* sequence_viewer_panel_;
|
||||
FootageViewerPanel* footage_viewer_panel_;
|
||||
QList<ProjectPanel*> project_panels_;
|
||||
QList<ProjectPanel*> folder_panels_;
|
||||
ToolPanel* tool_panel_;
|
||||
QList<TimelinePanel*> timeline_panels_;
|
||||
@@ -163,7 +154,7 @@ private:
|
||||
TaskManagerPanel* task_man_panel_;
|
||||
PixelSamplerPanel* pixel_sampler_panel_;
|
||||
ScopePanel* scope_panel_;
|
||||
QMap<ViewerOutput*, ViewerPanel*> viewer_panels_;
|
||||
QList<ViewerPanel*> viewer_panels_;
|
||||
MulticamPanel *multicam_panel_;
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
@@ -174,6 +165,8 @@ private:
|
||||
|
||||
bool first_show_;
|
||||
|
||||
Project *project_;
|
||||
|
||||
private slots:
|
||||
void FocusedPanelChanged(PanelWidget* panel);
|
||||
|
||||
@@ -181,13 +174,11 @@ private slots:
|
||||
|
||||
void TimelineCloseRequested();
|
||||
|
||||
void ProjectCloseRequested();
|
||||
|
||||
void ViewerCloseRequested();
|
||||
|
||||
void ViewerWithPanelRemovedFromGraph();
|
||||
|
||||
void FloatingPanelCloseRequested();
|
||||
void FolderPanelCloseRequested();
|
||||
|
||||
void StatusBarDoubleClicked();
|
||||
|
||||
|
||||
@@ -6,27 +6,55 @@ void MainWindowLayoutInfo::toXml(QXmlStreamWriter *writer) const
|
||||
{
|
||||
writer->writeStartElement(QStringLiteral("layout"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("version"), QString::number(kVersion));
|
||||
|
||||
writer->writeStartElement(QStringLiteral("folders"));
|
||||
|
||||
foreach (Folder* folder, open_folders_) {
|
||||
writer->writeTextElement(QStringLiteral("folder"),
|
||||
QString::number(reinterpret_cast<quintptr>(folder)));
|
||||
writer->writeTextElement(QStringLiteral("folder"), QString::number(reinterpret_cast<quintptr>(folder)));
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // folders
|
||||
|
||||
writer->writeStartElement(QStringLiteral("timeline"));
|
||||
|
||||
foreach (const OpenSequence& sequence, open_sequences_) {
|
||||
writer->writeTextElement(QStringLiteral("sequence"),
|
||||
QString::number(reinterpret_cast<quintptr>(sequence.sequence)));
|
||||
|
||||
writer->writeTextElement(QStringLiteral("state"),
|
||||
QString(sequence.panel_state.toBase64()));
|
||||
foreach (Sequence *sequence, open_sequences_) {
|
||||
writer->writeTextElement(QStringLiteral("sequence"), QString::number(reinterpret_cast<quintptr>(sequence)));
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // timeline
|
||||
|
||||
writer->writeStartElement(QStringLiteral("viewers"));
|
||||
|
||||
foreach (Sequence *sequence, open_sequences_) {
|
||||
writer->writeTextElement(QStringLiteral("viewer"), QString::number(reinterpret_cast<quintptr>(sequence)));
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // viewers
|
||||
|
||||
writer->writeStartElement(QStringLiteral("data"));
|
||||
|
||||
for (auto it = panel_data_.cbegin(); it != panel_data_.cend(); it++) {
|
||||
writer->writeStartElement(QStringLiteral("panel"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("id"), it->first);
|
||||
|
||||
const PanelWidget::Info &info = it->second;
|
||||
for (auto jt = info.cbegin(); jt != info.cend(); jt++) {
|
||||
writer->writeStartElement(QStringLiteral("option"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("name"), jt->first);
|
||||
|
||||
writer->writeCharacters(jt->second);
|
||||
|
||||
writer->writeEndElement(); // option
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // panel
|
||||
}
|
||||
|
||||
writer->writeEndElement(); // data
|
||||
|
||||
writer->writeTextElement(QStringLiteral("state"), QString(state_.toBase64()));
|
||||
|
||||
writer->writeEndElement(); // layout
|
||||
@@ -36,6 +64,19 @@ MainWindowLayoutInfo MainWindowLayoutInfo::fromXml(QXmlStreamReader *reader, con
|
||||
{
|
||||
MainWindowLayoutInfo info;
|
||||
|
||||
unsigned int file_version = 0;
|
||||
|
||||
XMLAttributeLoop(reader, attr) {
|
||||
if (attr.name() == QStringLiteral("version")) {
|
||||
file_version = attr.value().toUInt();
|
||||
}
|
||||
}
|
||||
|
||||
// Really basic version checking, in the future we may use this to parse multiple versions
|
||||
if (file_version != kVersion) {
|
||||
return info;
|
||||
}
|
||||
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("folders")) {
|
||||
|
||||
@@ -44,7 +85,7 @@ MainWindowLayoutInfo MainWindowLayoutInfo::fromXml(QXmlStreamReader *reader, con
|
||||
quintptr item_id = reader->readElementText().toULongLong();
|
||||
|
||||
Folder* open_item = static_cast<Folder*>(node_ptrs.value(item_id));
|
||||
info.open_folders_.append(open_item);
|
||||
info.open_folders_.push_back(open_item);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
@@ -52,29 +93,61 @@ MainWindowLayoutInfo MainWindowLayoutInfo::fromXml(QXmlStreamReader *reader, con
|
||||
|
||||
} else if (reader->name() == QStringLiteral("timeline")) {
|
||||
|
||||
Sequence* open_seq = nullptr;
|
||||
QByteArray tl_state;
|
||||
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("sequence")) {
|
||||
quintptr item_id = reader->readElementText().toULongLong();
|
||||
|
||||
open_seq = static_cast<Sequence*>(node_ptrs.value(item_id));
|
||||
} else if (reader->name() == QStringLiteral("state")) {
|
||||
tl_state = QByteArray::fromBase64(reader->readElementText().toUtf8());
|
||||
Sequence *open_seq = static_cast<Sequence*>(node_ptrs.value(item_id));
|
||||
info.open_sequences_.push_back(open_seq);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
if (open_seq) {
|
||||
info.open_sequences_.append({open_seq, tl_state});
|
||||
}
|
||||
|
||||
} else if (reader->name() == QStringLiteral("state")) {
|
||||
|
||||
info.state_ = QByteArray::fromBase64(reader->readElementText().toLatin1());
|
||||
|
||||
} else if (reader->name() == QStringLiteral("data")) {
|
||||
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("panel")) {
|
||||
QString id;
|
||||
XMLAttributeLoop(reader, attr) {
|
||||
if (attr.name() == QStringLiteral("id")) {
|
||||
id = attr.value().toString();
|
||||
}
|
||||
}
|
||||
|
||||
if (!id.isEmpty()) {
|
||||
PanelWidget::Info i;
|
||||
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("option")) {
|
||||
QString name;
|
||||
|
||||
XMLAttributeLoop(reader, attr) {
|
||||
if (attr.name() == QStringLiteral("name")) {
|
||||
name = attr.value().toString();
|
||||
}
|
||||
}
|
||||
|
||||
if (!name.isEmpty()) {
|
||||
i[name] = reader->readElementText();
|
||||
}
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
info.panel_data_[id] = i;
|
||||
}
|
||||
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
@@ -85,12 +158,22 @@ MainWindowLayoutInfo MainWindowLayoutInfo::fromXml(QXmlStreamReader *reader, con
|
||||
|
||||
void MainWindowLayoutInfo::add_folder(olive::Folder *f)
|
||||
{
|
||||
open_folders_.append(f);
|
||||
open_folders_.push_back(f);
|
||||
}
|
||||
|
||||
void MainWindowLayoutInfo::add_sequence(const OpenSequence &seq)
|
||||
void MainWindowLayoutInfo::add_sequence(Sequence *seq)
|
||||
{
|
||||
open_sequences_.append(seq);
|
||||
open_sequences_.push_back(seq);
|
||||
}
|
||||
|
||||
void MainWindowLayoutInfo::add_viewer(ViewerOutput *viewer)
|
||||
{
|
||||
open_viewers_.push_back(viewer);
|
||||
}
|
||||
|
||||
void MainWindowLayoutInfo::set_panel_data(const QString &id, const PanelWidget::Info &data)
|
||||
{
|
||||
panel_data_[id] = data;
|
||||
}
|
||||
|
||||
void MainWindowLayoutInfo::set_state(const QByteArray &layout)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "node/project/folder/folder.h"
|
||||
#include "node/project/sequence/sequence.h"
|
||||
#include "panel/panel.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
@@ -17,25 +18,34 @@ public:
|
||||
|
||||
void add_folder(Folder* f);
|
||||
|
||||
struct OpenSequence {
|
||||
Sequence* sequence;
|
||||
QByteArray panel_state;
|
||||
};
|
||||
void add_sequence(Sequence *seq);
|
||||
|
||||
void add_sequence(const OpenSequence& seq);
|
||||
void add_viewer(ViewerOutput *viewer);
|
||||
|
||||
void set_panel_data(const QString &id, const PanelWidget::Info &data);
|
||||
|
||||
void set_state(const QByteArray& layout);
|
||||
|
||||
const QList<Folder*>& open_folders() const
|
||||
const std::vector<Folder*>& open_folders() const
|
||||
{
|
||||
return open_folders_;
|
||||
}
|
||||
|
||||
const QList<OpenSequence>& open_sequences() const
|
||||
const std::vector<Sequence*>& open_sequences() const
|
||||
{
|
||||
return open_sequences_;
|
||||
}
|
||||
|
||||
const std::vector<ViewerOutput*>& open_viewers() const
|
||||
{
|
||||
return open_viewers_;
|
||||
}
|
||||
|
||||
const std::map<QString, PanelWidget::Info> &panel_data() const
|
||||
{
|
||||
return panel_data_;
|
||||
}
|
||||
|
||||
const QByteArray& state() const
|
||||
{
|
||||
return state_;
|
||||
@@ -44,9 +54,15 @@ public:
|
||||
private:
|
||||
QByteArray state_;
|
||||
|
||||
QList<Folder*> open_folders_;
|
||||
std::vector<Folder*> open_folders_;
|
||||
|
||||
QList<OpenSequence> open_sequences_;
|
||||
std::vector<Sequence*> open_sequences_;
|
||||
|
||||
std::vector<ViewerOutput*> open_viewers_;
|
||||
|
||||
std::map<QString, PanelWidget::Info> panel_data_;
|
||||
|
||||
static const unsigned int kVersion = 1;
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user