| 632 | } |
| 633 | |
| 634 | QString ChangesManager::findBestMatchWithNormalization( |
| 635 | const QString &fileContent, |
| 636 | const QString &searchContent, |
| 637 | double *outSimilarity, |
| 638 | QString *outMatchType) const |
| 639 | { |
| 640 | if (searchContent.isEmpty() || fileContent.isEmpty()) { |
| 641 | if (outSimilarity) *outSimilarity = 0.0; |
| 642 | if (outMatchType) *outMatchType = "none"; |
| 643 | return QString(); |
| 644 | } |
| 645 | |
| 646 | if (fileContent.contains(searchContent)) { |
| 647 | LOG_MESSAGE("Match found: Exact match"); |
| 648 | if (outSimilarity) *outSimilarity = 1.0; |
| 649 | if (outMatchType) *outMatchType = "exact"; |
| 650 | return searchContent; |
| 651 | } |
| 652 | |
| 653 | double bestSim = 0.0; |
| 654 | QString bestMatch = findBestMatch(fileContent, searchContent, 0.0, &bestSim); |
| 655 | |
| 656 | if (!bestMatch.isEmpty() && bestSim >= 0.70) { |
| 657 | LOG_MESSAGE(QString("Match found: Fuzzy match (%1%% similarity)") |
| 658 | .arg(qRound(bestSim * 100))); |
| 659 | if (outSimilarity) *outSimilarity = bestSim; |
| 660 | if (outMatchType) { |
| 661 | if (bestSim >= 0.85) { |
| 662 | *outMatchType = "fuzzy_high"; |
| 663 | } else { |
| 664 | *outMatchType = "fuzzy_medium"; |
| 665 | } |
| 666 | } |
| 667 | return bestMatch; |
| 668 | } |
| 669 | |
| 670 | LOG_MESSAGE(QString("Cannot proceed: similarity too low (%1%%). " |
| 671 | "File may have been auto-formatted or manually edited.") |
| 672 | .arg(qRound(bestSim * 100))); |
| 673 | |
| 674 | if (outSimilarity) *outSimilarity = bestSim; |
| 675 | if (outMatchType) *outMatchType = "none"; |
| 676 | |
| 677 | return QString(); |
| 678 | } |
| 679 | |
| 680 | bool ChangesManager::performFragmentReplacement( |
| 681 | const QString &filePath, |