| 147 | } |
| 148 | |
| 149 | PlotWidget::CurveInfo* PlotWidget::addCurve(const QString& name, QColor color) { |
| 150 | if (session_ == nullptr || catalog_ == nullptr) { |
| 151 | return nullptr; |
| 152 | } |
| 153 | |
| 154 | const auto descriptor = catalog_->curveDescriptor(name); |
| 155 | if (!descriptor.has_value()) { |
| 156 | return nullptr; |
| 157 | } |
| 158 | |
| 159 | // Auto-assignment (issue #68): reuse the curve's remembered color so it stays |
| 160 | // consistent across plots; otherwise take the next color from the shared, |
| 161 | // session-wide palette counter and remember it. An explicit (non-transparent) |
| 162 | // color — e.g. from a layout file — is honored as-is. session_ is non-null here |
| 163 | // (guarded above), so the session registry is always available. |
| 164 | if (color == Qt::transparent) { |
| 165 | CurveColorRegistry& registry = session_->curveColorRegistry(); |
| 166 | if (const auto remembered = registry.color(name); remembered.has_value()) { |
| 167 | color = QColor(*remembered); |
| 168 | } else { |
| 169 | // New curve: choose the colour index from the configured sequence. |
| 170 | // "global" advances the session-wide registry counter (one continuous |
| 171 | // sequence across every plot); "per plot" uses this curve's positional |
| 172 | // index within the plot, so each plot restarts at colour 0. Either way the |
| 173 | // colour is then remembered by name (always-on), so the curve keeps it on |
| 174 | // re-add and across plots. |
| 175 | QSettings settings; |
| 176 | const bool global = settings.value(QStringLiteral("Preferences::curve_color_global"), true).toBool(); |
| 177 | const int index = global ? registry.nextPaletteIndex() : static_cast<int>(curveList().size()); |
| 178 | color = PlotWidgetBase::paletteColor(index); |
| 179 | registry.setColor(name, color.name()); |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | auto* adapter = new DatastoreCurveAdapter(session_, *descriptor); |
| 184 | auto* info = PlotWidgetBase::addCurve(name, adapter, color, curveDisplayName(*descriptor)); |
| 185 | if (info == nullptr) { |
| 186 | return nullptr; |
| 187 | } |
| 188 | if (tracker_ != nullptr) { |
| 189 | tracker_->setEnabled(tracker_enabled_); |
| 190 | } |
| 191 | updateMaximumZoomArea(); |
| 192 | replot(); |
| 193 | return info; |
| 194 | } |
| 195 | |
| 196 | void PlotWidget::autoZoomPlotVertically() { |
| 197 | // Skip during layout restore (the saved range wins), when there is nothing to |