MCPcopy Create free account
hub / github.com/PlotJuggler/PlotJuggler / restoreDataProcessors

Method restoreDataProcessors

pj_app/src/MainWindow.cpp:3164–3262  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3162}
3163
3164void MainWindow::restoreDataProcessors(const QDomElement& root) {
3165 // Reconcile the live filter set to this snapshot: drop ALL current filters first,
3166 // then recreate the snapshot's set. This makes restore idempotent for undo/redo (no
3167 // duplicate or output-name-colliding filters) and correct for a layout load onto an
3168 // existing session. A snapshot with NO <data_processors> still falls through to clear
3169 // every filter; the rebuild at the end MUST run on both branches so the now-retired
3170 // outputs leave the catalog.
3171 auto& service = session_->sessionManager().dataProcessorService();
3172 service.clearAllFilters();
3173
3174 const QDomElement element = root.firstChildElement(QStringLiteral("data_processors"));
3175 const auto datasets = session_->catalogModel().datasets();
3176 // A null <data_processors> yields a null firstChildElement, so this loop runs zero
3177 // times — the clear above is then the whole effect.
3178 for (QDomElement processor = element.firstChildElement(QStringLiteral("processor")); !processor.isNull();
3179 processor = processor.nextSiblingElement(QStringLiteral("processor"))) {
3180 const QString input_topic = processor.attribute(QStringLiteral("input_topic"));
3181 const QString input_field = processor.attribute(QStringLiteral("input_field"));
3182 // Resolve the input against whichever loaded dataset holds it (first match in
3183 // load order), so a multi-file layout restores each filter against its source.
3184 std::optional<CurveDescriptor> input_desc;
3185 for (const auto& [dataset_id, dataset_name] : datasets) {
3186 (void)dataset_name;
3187 if (auto descriptor = session_->catalogModel().descriptorForPath(dataset_id, input_topic, input_field)) {
3188 input_desc = std::move(descriptor);
3189 break;
3190 }
3191 }
3192 if (!input_desc.has_value()) {
3193 // The filter's source signal isn't in any loaded dataset -> the filter is
3194 // dropped. Tell the user which one, mirroring the unknown/apply-failed cases
3195 // below (otherwise a derived series silently vanishes on layout load).
3196 emitDiagnostic(
3197 DiagnosticLevel::kWarning, "Layout", "processor-input-missing",
3198 tr("Layout filter on '%1/%2' has no matching data; skipping.").arg(input_topic, input_field));
3199 continue;
3200 }
3201 const std::string id = processor.attribute(QStringLiteral("processor_id")).toStdString();
3202 // Params are the <processor>'s OWN direct CDATA — directCdataText ignores the
3203 // <source_fallback> child (QDomElement::text() would recurse and merge them).
3204 const QString params = layout_xml::directCdataText(processor);
3205 const QString source_fallback = processor.firstChildElement(QStringLiteral("source_fallback")).text();
3206 // Resolve order: live catalogue → embedded source → transitional C++ builtin.
3207 std::unique_ptr<proc::DataProcessor> built = service.makeRestoredProcessor(
3208 id, params.isEmpty() ? std::string("{}") : params.toStdString(), source_fallback.toStdString());
3209 if (!built) {
3210 emitDiagnostic(
3211 DiagnosticLevel::kWarning, "Layout", "processor-unknown",
3212 tr("Layout filter '%1' is unknown to this PlotJuggler; skipping.").arg(QString::fromStdString(id)));
3213 continue;
3214 }
3215 const auto applied = service.applyFilter(
3216 input_desc->topic_id, input_desc->dataset_id, std::move(built),
3217 processor.attribute(QStringLiteral("output_name")).toStdString(), input_desc->column_index);
3218 if (!applied.has_value()) {
3219 emitDiagnostic(
3220 DiagnosticLevel::kWarning, "Layout", "processor-apply-failed",
3221 tr("Could not restore filter: %1").arg(QString::fromStdString(applied.error())));

Callers

nothing calls this directly

Calls 15

trFunction · 0.85
directCdataTextFunction · 0.85
clearAllFiltersMethod · 0.80
datasetsMethod · 0.80
descriptorForPathMethod · 0.80
makeRestoredProcessorMethod · 0.80
clearAllTransformsMethod · 0.80
restoreTransformMethod · 0.80
rebuildFromDatastoreMethod · 0.80
sessionManagerMethod · 0.45
isNullMethod · 0.45
textMethod · 0.45

Tested by

no test coverage detected