| 1511 | } |
| 1512 | |
| 1513 | void QmitkMxNMultiWidget::SetDataBasedLayout(const QmitkAbstractNodeSelectionWidget::NodeList& nodes) |
| 1514 | { |
| 1515 | // Tear the existing cell tree down first. The previous implementation |
| 1516 | // tried to recycle existing 'widget<i>' cells by positional index, which |
| 1517 | // misses entirely after a v2 layout with custom names is loaded |
| 1518 | // (lookups return null, new cells are appended while the old custom-named |
| 1519 | // ones stay in the map and are then double-deleted by 'delete this->layout()'). |
| 1520 | // Mirroring 'ApplyLayout's structure (tear down, allocate groups, build |
| 1521 | // fresh) avoids that hazard regardless of the prior naming scheme. |
| 1522 | this->ResetGridState(); |
| 1523 | this->TearDownAllCells(); |
| 1524 | |
| 1525 | auto vSplit = new QSplitter(Qt::Vertical); |
| 1526 | |
| 1527 | unsigned int rowCounter = 0; |
| 1528 | unsigned int cellCounter = 0; |
| 1529 | for (auto node : nodes) |
| 1530 | { |
| 1531 | rowCounter++; |
| 1532 | // Pre-create the row's synchronization group via the canonical API so that |
| 1533 | // every utility widget's combobox has the entry before SetSyncGroup() runs. |
| 1534 | this->AddSynchronizationGroup(rowCounter); |
| 1535 | |
| 1536 | auto hSplit = new QSplitter(Qt::Horizontal); |
| 1537 | for (auto viewPlane : { mitk::AnatomicalPlane::Axial, mitk::AnatomicalPlane::Coronal, mitk::AnatomicalPlane::Sagittal }) |
| 1538 | { |
| 1539 | // Use the explicit-id overload (which leaves cells unattached) and |
| 1540 | // place each cell directly into its row group via the canonical API, |
| 1541 | // mirroring ApplyLayout. Avoids the churn of the positional overload's |
| 1542 | // initial seeding into group 1 followed by an immediate move. |
| 1543 | const auto id = this->GetMultiWidgetName() + NAMESPACE_DELIMITER |
| 1544 | + QStringLiteral("widget") + QString::number(cellCounter++); |
| 1545 | auto window = this->CreateRenderWindowWidget(id); |
| 1546 | this->SetSynchronizationGroup(window->GetUtilityWidget()->GetNodeSelectionWidget(), rowCounter); |
| 1547 | |
| 1548 | window->GetSliceNavigationController()->SetDefaultViewDirection(viewPlane); |
| 1549 | window->GetSliceNavigationController()->Update(); |
| 1550 | auto baseRenderer = mitk::BaseRenderer::GetInstance(window->GetRenderWindow()->GetVtkRenderWindow()); |
| 1551 | node->SetVisibility(true, baseRenderer); |
| 1552 | mitk::RenderingManager::GetInstance()->InitializeView(baseRenderer->GetRenderWindow(), node->GetData()->GetTimeGeometry()); |
| 1553 | hSplit->addWidget(window.get()); |
| 1554 | window->show(); |
| 1555 | } |
| 1556 | |
| 1557 | auto* const rowConnector = this->GetSyncGroupConnector(rowCounter); |
| 1558 | rowConnector->ChangeSelectionMode(false); |
| 1559 | rowConnector->ChangeSelection(QList({ node })); |
| 1560 | |
| 1561 | auto sizes = QList<int>({1, 1, 1}); |
| 1562 | hSplit->setSizes(sizes); |
| 1563 | vSplit->addWidget(hSplit); |
| 1564 | } |
| 1565 | |
| 1566 | auto hBoxLayout = new QHBoxLayout(this); |
| 1567 | this->setLayout(hBoxLayout); |
| 1568 | hBoxLayout->addWidget(vSplit); |
| 1569 | |
| 1570 | // Deterministic active-cell assignment after rebuild. ResetGridState() |