      double max_sec = std::min(std::floor(display_range.first + max_chart_range), can->lastEventSecond());
      display_range.first = std::max(0.0, max_sec - max_chart_range);
      display_range.second = display_range.first + max_chart_range;
    } else if (cur_sec < zoomed_range.first || cur_sec >= zoomed_range.second) {
      // loop in zoommed range
      can->seekTo(zoomed_range.first);
    }
  
    const auto &range = is_zoomed ? zoomed_range : display_range;
    for (auto c : charts) {
 
</s> remove void ChartsWidget::zoomIn(double min, double max) {
 </s> add void ChartsWidget::setZoom(double min, double max) { </s> remove   zoomIn(display_range.first, display_range.second);
 </s> add   setZoom(display_range.first, display_range.second);
}

void ChartsWidget::zoomUndo() {
  if (!zoom_stack.isEmpty()) {
    auto r = zoom_stack.pop();
    setZoom(r.first, r.second);
  } else {
    zoomReset();
  } </s> remove     emit zoomReset();
 </s> add     emit zoomUndo();
    // loop in zoomed range
      double max_sec = std::min(std::floor(display_range.first + max_chart_range), can->lastEventSecond());
      display_range.first = std::max(0.0, max_sec - max_chart_range);
      display_range.second = display_range.first + max_chart_range;
    } else if (cur_sec < zoomed_range.first || cur_sec >= zoomed_range.second) {
    // loop in zoomed range
      can->seekTo(zoomed_range.first);
    }
  
    const auto &range = is_zoomed ? zoomed_range : display_range;
    for (auto c : charts) {
keep keep keep keep replace keep keep keep keep keep
 cabana: go to previous zoom window (#27702)

* cabana: go to previous zoom level

* zoom undo on right click

* catch mousepress event on linux 
tools/cabana/chartswidget.cc