| 148 | } |
| 149 | |
| 150 | int matchPathFilter(const Path& toFilter, const QStringList& text, const Path& prefixPath) |
| 151 | { |
| 152 | enum PathFilterMatchQuality { |
| 153 | NoMatch = -1, |
| 154 | ExactMatch = 0, |
| 155 | StartMatch = 1, |
| 156 | OtherMatch = 2 // and anything higher than that |
| 157 | }; |
| 158 | const QVector<QString>& segments = toFilter.segments(); |
| 159 | |
| 160 | if (text.count() > segments.count()) { |
| 161 | // number of segments mismatches, thus item cannot match |
| 162 | return NoMatch; |
| 163 | } |
| 164 | |
| 165 | bool allMatched = true; |
| 166 | int searchIndex = text.size() - 1; |
| 167 | int pathIndex = segments.size() - 1; |
| 168 | int lastMatchIndex = -1; |
| 169 | // stop early if more search fragments remain than available after path index |
| 170 | while (pathIndex >= 0 && searchIndex >= 0 |
| 171 | && (pathIndex + text.size() - searchIndex - 1) < segments.size()) { |
| 172 | const QString& segment = segments.at(pathIndex); |
| 173 | const QString& typedSegment = text.at(searchIndex); |
| 174 | const int matchIndex = segment.indexOf(typedSegment, 0, Qt::CaseInsensitive); |
| 175 | const bool isLastPathSegment = pathIndex == segments.size() - 1; |
| 176 | const bool isLastSearchSegment = searchIndex == text.size() - 1; |
| 177 | |
| 178 | // check for exact matches |
| 179 | allMatched &= matchIndex == 0 && segment.size() == typedSegment.size(); |
| 180 | |
| 181 | // check for fuzzy matches |
| 182 | bool isMatch = matchIndex != -1; |
| 183 | // do fuzzy path matching on the last segment |
| 184 | if (!isMatch && isLastPathSegment && isLastSearchSegment) { |
| 185 | isMatch = matchesPath(segment, typedSegment); |
| 186 | } else if (!isMatch) { // check other segments for abbreviations |
| 187 | isMatch = matchesAbbreviation(segment, typedSegment); |
| 188 | } |
| 189 | |
| 190 | if (!isMatch) { |
| 191 | // no match, try with next path segment |
| 192 | --pathIndex; |
| 193 | continue; |
| 194 | } |
| 195 | // else we matched |
| 196 | if (isLastPathSegment) { |
| 197 | lastMatchIndex = matchIndex; |
| 198 | } |
| 199 | --searchIndex; |
| 200 | --pathIndex; |
| 201 | } |
| 202 | |
| 203 | if (searchIndex != -1) { |
| 204 | return NoMatch; |
| 205 | } |
| 206 | |
| 207 | const int segmentMatchDistance = segments.size() - (pathIndex + 1); |
no test coverage detected