Newer
Older
// ************************************************************************************************
// BornAgain: simulate and fit reflection and scattering
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
// ************************************************************************************************
#include "GUI/Model/Group/FilterPropertyProxy.h"
#include "GUI/Model/Project/ProjectDocument.h"
#include "GUI/Model/Sample/MultiLayerItem.h"
Matthias Puchner
committed
#include "GUI/Model/Sample/SampleModel.h"
Matthias Puchner
committed
#include "GUI/View/Realspace/RealSpaceCanvas.h"
#include "GUI/View/SampleDesigner/DesignerScene.h"
#include "GUI/View/SampleDesigner/DesignerView.h"
#include "GUI/View/SampleDesigner/LayerOrientedSampleEditor.h"
#include "GUI/View/SampleDesigner/RealSpacePanel.h"
#include "GUI/View/SampleDesigner/SampleListView.h"
#include "GUI/View/SampleDesigner/SamplePropertyWidget.h"
#include "GUI/View/SampleDesigner/SampleToolBar.h"
#include "GUI/View/SampleDesigner/SampleToolBox.h"
#include "GUI/View/SampleDesigner/SampleTreeWidget.h"
#include "GUI/View/SampleDesigner/ScriptPanel.h"
#include <QBoxLayout>
#include <QToolButton>
SampleView::SampleView(QWidget* parent, ProjectDocument* document, bool initAsLayerOrientedEditor)
: QMainWindow(parent), m_document(document)
Matthias Puchner
committed
connect(m_document, &ProjectDocument::modified, this, &SampleView::updateFunctionalities);
if (initAsLayerOrientedEditor)
initLayerOrientedEditor();
else
initNetOrientedEditor();
}
void SampleView::initNetOrientedEditor()
{
const bool wasVisible = isVisible();
hide(); // important; otherwise the dockwidget layout is messed up
deleteEditor();
m_docks = new DocksController(this);
auto* designerScene = new DesignerScene(this, m_document);
auto* designerView = new DesignerView(designerScene, this);
Matthias Puchner
committed
auto* toolBox = new SampleToolBox(this);
auto* treeWidget = new SampleTreeWidget(this, m_document->sampleModel());
auto* propertyWidget = new SamplePropertyWidget(treeWidget->treeView()->selectionModel(), this);
auto* scriptPanel = new ScriptPanel(m_document->sampleModel(), this);
Matthias Puchner
committed
m_realSpacePanel = new RealSpacePanel(m_document->sampleModel(), this);
Matthias Puchner
committed
m_docks->addWidget(TOOLBOX, toolBox, Qt::LeftDockWidgetArea);
m_docks->addWidget(SAMPLE_TREE, treeWidget, Qt::RightDockWidgetArea);
m_docks->addWidget(PROPERTY_EDITOR, propertyWidget, Qt::RightDockWidgetArea);
m_docks->addWidget(INFO, scriptPanel, Qt::BottomDockWidgetArea);
Matthias Puchner
committed
m_docks->addWidget(REALSPACEPANEL, m_realSpacePanel, Qt::BottomDockWidgetArea);
Matthias Puchner
committed
connect(scriptPanel, &ScriptPanel::widgetHeightRequest, m_docks,
&DocksController::setDockHeightForWidget);
designerScene->setSelectionModel(
treeWidget->treeView()->selectionModel(),
dynamic_cast<FilterPropertyProxy*>(
const_cast<QAbstractItemModel*>(treeWidget->treeView()->model())));
setCentralWidget(designerView);
resetLayout();
// m_toolBar should be initialized after MaterialBrowser
m_toolBar = new SampleToolBar(this);
connect(m_toolBar, &SampleToolBar::deleteItems, designerView,
&DesignerView::deleteSelectedItems);
connect(m_toolBar, &SampleToolBar::selectionMode, designerView, &DesignerView::onSelectionMode);
connect(designerView, &DesignerView::selectionModeChanged, m_toolBar,
Matthias Puchner
committed
&SampleToolBar::onViewSelectionMode);
connect(m_toolBar, &SampleToolBar::centerView, designerView, &DesignerView::onCenterView);
connect(m_toolBar, &SampleToolBar::changeScale, designerView, &DesignerView::onChangeScale);
Matthias Puchner
committed
connect(designerScene, &DesignerScene::selectionModeChangeRequest, designerView,
&DesignerView::onSelectionMode);
Matthias Puchner
committed
connect(treeWidget->treeView()->selectionModel(), &QItemSelectionModel::selectionChanged, this,
&SampleView::onSampleTreeViewSelectionChanged);
Matthias Puchner
committed
addToolBar(m_toolBar);
m_useLayerOrientedEditor = false;
if (wasVisible)
show();
}
void SampleView::initLayerOrientedEditor()
{
const bool wasVisible = isVisible();
hide(); // important; otherwise the dockwidget layout is messed up
deleteEditor();
m_docks = new DocksController(this);

Wuttke, Joachim
committed
auto *editor = new LayerOrientedSampleEditor(this);
auto* sampleSelectionPane = new QWidget(this);
auto* sampleSelectionLayout = new QVBoxLayout(sampleSelectionPane);
sampleSelectionLayout->setContentsMargins(0, 0, 0, 0);
sampleSelectionLayout->setSpacing(0);

Wuttke, Joachim
committed
auto *sampleSelectionToolbar = new StyledToolBar(sampleSelectionPane);
auto* sampleSelectionView = new SampleListView(this, m_document->sampleModel());
sampleSelectionToolbar->addAction(sampleSelectionView->newSampleAction());
sampleSelectionToolbar->addAction(sampleSelectionView->chooseFromLibraryAction());
if (auto* btn = dynamic_cast<QToolButton*>(sampleSelectionToolbar->widgetForAction(
sampleSelectionView->chooseFromLibraryAction())))
btn->setPopupMode(QToolButton::InstantPopup);
sampleSelectionToolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
sampleSelectionLayout->addWidget(sampleSelectionToolbar);
sampleSelectionLayout->addWidget(sampleSelectionView);
sampleSelectionView->setSizePolicy(QSizePolicy::MinimumExpanding,
QSizePolicy::MinimumExpanding);
auto* scriptPanel = new ScriptPanel(m_document->sampleModel(), this);
Matthias Puchner
committed
m_realSpacePanel = new RealSpacePanel(m_document->sampleModel(), this);
m_realSpacePanel->setLockViewActionVisible(false); // lock not used in layer oriented editor
sampleSelectionPane->setWindowTitle("Samples");
m_docks->addWidget(SAMPLE_LIST, sampleSelectionPane, Qt::LeftDockWidgetArea);
Matthias Puchner
committed
m_docks->addWidget(REALSPACEPANEL, m_realSpacePanel, Qt::BottomDockWidgetArea);
m_docks->addWidget(INFO, scriptPanel, Qt::BottomDockWidgetArea);
connect(scriptPanel, &ScriptPanel::widgetHeightRequest, m_docks,
&DocksController::setDockHeightForWidget);
connect(sampleSelectionView, &SampleListView::currentSampleChanged, this,
&SampleView::onCurrentSampleChanged);
connect(sampleSelectionView, &SampleListView::currentSampleChanged, editor,
&LayerOrientedSampleEditor::setCurrentSample);
Matthias Puchner
committed
connect(editor, &LayerOrientedSampleEditor::requestViewInRealSpace, this,
&SampleView::onRequestViewInRealSpace);
setCentralWidget(editor);
resetLayout();
m_useLayerOrientedEditor = true;
if (wasVisible)
show();
}
void SampleView::deleteEditor()
{
delete m_toolBar;
m_toolBar = nullptr;
if (m_docks != nullptr) {
auto dockWidgets = m_docks->dockWidgets();
delete m_docks;
m_docks = nullptr;
qDeleteAll(dockWidgets);
}
Matthias Puchner
committed
if (auto* w = dynamic_cast<DesignerView*>(centralWidget()))
delete w->scene();
delete centralWidget();
}
void SampleView::updateFunctionalities()
{
if (auto* d = m_docks->findDock(SAMPLE_LIST)) {
if (m_document->singleSampleMode())
d->hide();
else
d->show();
}
Matthias Puchner
committed
void SampleView::onSampleTreeViewSelectionChanged(const QItemSelection& selected,
const QItemSelection&)
{
if (m_realSpacePanel->isViewLocked())
return;
if (selected.indexes().empty())
return;
const QModelIndex currentIndex = FilterPropertyProxy::toSourceIndex(selected.indexes().back());
auto* item = m_document->sampleModel()->itemForIndex(currentIndex);
if (item)
m_realSpacePanel->canvas()->setCurrentItem(item);
}
void SampleView::onCurrentSampleChanged(MultiLayerItem* current)
{
if (m_layerOrientedSampleEditor)
m_layerOrientedSampleEditor->setCurrentSample(current);
m_realSpacePanel->canvas()->setCurrentItem(current);
}
Matthias Puchner
committed
void SampleView::onRequestViewInRealSpace(SessionItem* itemToView)
{
if (!itemToView)
return;
m_docks->setDockVisible(REALSPACEPANEL);
m_realSpacePanel->canvas()->setCurrentItem(itemToView);
}
void SampleView::toggleRealSpaceView()
{
m_docks->toggleDock(REALSPACEPANEL);
}
void SampleView::fillViewMenu(QMenu* menu)
{
auto* editorSelectionActions = new QActionGroup(this);

Wuttke, Joachim
committed
auto *action = menu->addAction("Layer oriented sample editor");
action->setCheckable(true);
action->setChecked(m_useLayerOrientedEditor);
connect(action, &QAction::triggered, this, &SampleView::initLayerOrientedEditor,
Qt::QueuedConnection);
editorSelectionActions->addAction(action);
action = menu->addAction("Net oriented sample editor");
action->setCheckable(true);
action->setChecked(!m_useLayerOrientedEditor);
connect(action, &QAction::triggered, this, &SampleView::initNetOrientedEditor,
Qt::QueuedConnection);
editorSelectionActions->addAction(action);
menu->addSeparator();
m_docks->addDockActionsToMenu(menu);
menu->addSeparator();
action = new QAction(menu);
action->setText("Reset to default layout");
connect(action, &QAction::triggered, this, &SampleView::resetLayout);
menu->addAction(action);
void SampleView::resetLayout()
{
Matthias
committed
m_docks->resetLayout();
tabifyDockWidget(m_docks->findDock(REALSPACEPANEL), m_docks->findDock(INFO));
m_docks->findDock(REALSPACEPANEL)->raise(); // makes first tab active
m_docks->findDock(REALSPACEPANEL)->hide();
m_docks->findDock(INFO)->hide();
if (auto* d = m_docks->findDock(SAMPLE_LIST)) {
if (m_document->singleSampleMode())
d->hide();
else
d->show();
}