| 7697 | } |
| 7698 | |
| 7699 | void MainWindow::applyPanLayout(const QString& layoutId) |
| 7700 | { |
| 7701 | if (!m_radioModel.isConnected()) return; |
| 7702 | |
| 7703 | const int needed = panCountForLayoutId(layoutId); |
| 7704 | const int existing = m_panStack->count(); |
| 7705 | |
| 7706 | if (needed < existing) { |
| 7707 | qDebug() << "applyPanLayout: reducing from" << existing << "to" << needed << "pans"; |
| 7708 | |
| 7709 | // Close extra pans from the end (keep the first N) |
| 7710 | auto allApplets = m_panStack->allApplets(); |
| 7711 | int toRemove = existing - needed; |
| 7712 | for (int i = allApplets.size() - 1; i >= 0 && toRemove > 0; --i) { |
| 7713 | auto* applet = allApplets[i]; |
| 7714 | QString panId = applet->panId(); |
| 7715 | if (panId == "default") continue; |
| 7716 | qDebug() << "applyPanLayout: closing pan" << panId; |
| 7717 | // Route through removePanadapter so a layout-shrink tears down the |
| 7718 | // waterfall too ("display pan remove" + "display panafall remove"), |
| 7719 | // not just the panadapter stream. (#3843) |
| 7720 | m_radioModel.removePanadapter(panId); |
| 7721 | // Radio will send "removed" status → panadapterRemoved signal |
| 7722 | // → PanadapterStack::removePanadapter() |
| 7723 | --toRemove; |
| 7724 | } |
| 7725 | |
| 7726 | // Rearrange remaining pans after a short delay for radio to process |
| 7727 | QTimer::singleShot(500, this, [this, layoutId]() { |
| 7728 | m_panStack->rearrangeLayout(layoutId); |
| 7729 | }); |
| 7730 | return; |
| 7731 | } |
| 7732 | if (needed == existing) { |
| 7733 | // Same count, just rearrange |
| 7734 | m_panStack->rearrangeLayout(layoutId); |
| 7735 | return; |
| 7736 | } |
| 7737 | |
| 7738 | // Create additional pans to reach the needed count. |
| 7739 | // Keep existing pan(s) alive — no tear-down, no dangling signals. |
| 7740 | const int currentSliceCount = static_cast<int>(m_radioModel.slices().size()); |
| 7741 | if (currentSliceCount >= m_radioModel.maxSlices()) { |
| 7742 | showPanadapterSliceCapacityMessage(); |
| 7743 | return; |
| 7744 | } |
| 7745 | |
| 7746 | const int toCreate = needed - existing; |
| 7747 | auto panIds = std::make_shared<QStringList>(); |
| 7748 | |
| 7749 | // Collect existing pan IDs first (they'll be part of the layout) |
| 7750 | for (auto* applet : m_panStack->allApplets()) |
| 7751 | panIds->append(applet->panId()); |
| 7752 | |
| 7753 | qDebug() << "applyPanLayout: have" << existing << "pans, creating" |
| 7754 | << toCreate << "more for layout" << layoutId; |
| 7755 | |
| 7756 | createPansSequentially(layoutId, toCreate, panIds, 0); |
nothing calls this directly
no test coverage detected