void DrawPathTool::undoLastPoint() { Q_ASSERT(editingInProgress()); if (preview_path->getCoordinateCount() <= (preview_path->parts().front().isClosed() ? 3 : (path_has_preview_point ? 2 : 1))) { abortDrawing(); return; } auto& part = preview_path->parts().back(); auto last_index = part.last_index; auto prev_coord_index = part.prevCoordIndex(part.last_index); auto prev_coord = preview_path->getCoordinate(prev_coord_index); // Pre-undo preparation if (path_has_preview_point) { if (prev_coord.isCurveStart()) { // Undo just the preview point path_has_preview_point = false; } else { // Remove the preview point from a straight edge, preparing for re-adding. Q_ASSERT(!previous_point_is_curve_point); preview_path->deleteCoordinate(last_index, false); last_index = prev_coord_index; prev_coord_index = part.prevCoordIndex(part.last_index); prev_coord = preview_path->getCoordinate(prev_coord_index); path_has_preview_point = !prev_coord.isCurveStart(); } } if (prev_coord.isCurveStart()) { // Removing last point of a curve, no re-adding of preview point. MapCoord prev_drag = preview_path->getCoordinate(prev_coord_index+1); previous_point_direction = -atan2(prev_drag.x() - prev_coord.x(), prev_coord.y() - prev_drag.y()); previous_pos_map = MapCoordF(prev_coord); previous_drag_map = MapCoordF((prev_coord.x() + prev_drag.x()) / 2, (prev_coord.y() + prev_drag.y()) / 2); previous_point_is_curve_point = true; path_has_preview_point = false; } else if (!path_has_preview_point) { // Removing last point from a straight edge, no re-adding of preview point. previous_point_is_curve_point = false; } // Actually delete the last point of the edge. preview_path->deleteCoordinate(last_index, false); if (preview_path->getRawCoordinateVector().empty()) { // Re-add first point. prev_coord.setCurveStart(false); preview_path->addCoordinate(prev_coord); } // Post-undo if (path_has_preview_point) { // Re-add preview point. preview_path->addCoordinate(MapCoord(cur_pos_map)); } else if (previous_point_is_curve_point && dragging) { cur_pos = click_pos; cur_pos_map = click_pos_map; } dragging = false; updateHover(); updatePreviewPath(); updateAngleHelper(); updateDirtyRect(); }
bool TemplateTrack::import(QWidget* dialog_parent) { if (track.getNumWaypoints() == 0 && track.getNumSegments() == 0) { QMessageBox::critical(dialog_parent, tr("Error"), tr("The path is empty, there is nothing to import!")); return false; } const Track::ElementTags& tags = track.tags(); DeleteObjectsUndoStep* undo_step = new DeleteObjectsUndoStep(map); MapPart* part = map->getCurrentPart(); std::vector< Object* > result; map->clearObjectSelection(false); if (track.getNumWaypoints() > 0) { int res = QMessageBox::question(dialog_parent, tr("Question"), tr("Should the waypoints be imported as a line going through all points?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (res == QMessageBox::No) { for (int i = 0; i < track.getNumWaypoints(); i++) result.push_back(importWaypoint(templateToMap(track.getWaypoint(i).map_coord), track.getWaypointName(i))); } else { PathObject* path = importPathStart(); for (int i = 0; i < track.getNumWaypoints(); i++) path->addCoordinate(MapCoord(templateToMap(track.getWaypoint(i).map_coord))); importPathEnd(path); path->setTag(QStringLiteral("name"), QString{}); result.push_back(path); } } int skipped_paths = 0; for (int i = 0; i < track.getNumSegments(); i++) { const int segment_size = track.getSegmentPointCount(i); if (segment_size == 0) { ++skipped_paths; continue; // Don't create path without objects. } PathObject* path = importPathStart(); QString name = track.getSegmentName(i); if (!tags[name].isEmpty()) { path->setTags(tags[name]); } else { path->setTag(QStringLiteral("name"), name); } for (int j = 0; j < segment_size; j++) { const TrackPoint& track_point = track.getSegmentPoint(i, j); auto coord = MapCoord { templateToMap(track_point.map_coord) }; if (track_point.is_curve_start && j < segment_size - 3) coord.setCurveStart(true); path->addCoordinate(coord); } if (track.getSegmentPoint(i, 0).gps_coord == track.getSegmentPoint(i, segment_size-1).gps_coord) { path->closeAllParts(); } importPathEnd(path); result.push_back(path); } for (int i = 0; i < (int)result.size(); ++i) // keep as separate loop to get the correct (final) indices undo_step->addObject(part->findObjectIndex(result[i])); map->setObjectsDirty(); map->push(undo_step); map->emitSelectionChanged(); map->emitSelectionEdited(); // TODO: is this necessary here? if (skipped_paths) { QMessageBox::information( dialog_parent, tr("Import problems"), tr("%n path object(s) could not be imported (reason: missing coordinates).", "", skipped_paths) ); } return true; }