mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Dive pictures: implement FindMovedImagesDialog
Move the find-moved-images functions into a new translation unit and present the user with the identified matches before applying them. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
f3ef38ca0d
commit
09fd5c40d1
9 changed files with 535 additions and 125 deletions
|
@ -1217,97 +1217,6 @@ QStringList imageExtensionFilters() {
|
|||
return filters;
|
||||
}
|
||||
|
||||
// Compare two full paths and return the number of matching levels, starting from the filename.
|
||||
// String comparison is case-insensitive.
|
||||
static int matchFilename(const QString &path1, const QString &path2)
|
||||
{
|
||||
QFileInfo f1(path1);
|
||||
QFileInfo f2(path2);
|
||||
|
||||
int score = 0;
|
||||
for (;;) {
|
||||
QString fn1 = f1.fileName();
|
||||
QString fn2 = f2.fileName();
|
||||
if (fn1.isEmpty() || fn2.isEmpty())
|
||||
break;
|
||||
if (fn1 == ".") {
|
||||
f1 = QFileInfo(f1.path());
|
||||
continue;
|
||||
}
|
||||
if (fn2 == ".") {
|
||||
f2 = QFileInfo(f2.path());
|
||||
continue;
|
||||
}
|
||||
if (QString::compare(fn1, fn2, Qt::CaseInsensitive) != 0)
|
||||
break;
|
||||
f1 = QFileInfo(f1.path());
|
||||
f2 = QFileInfo(f2.path());
|
||||
++score;
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
||||
struct ImageMatch {
|
||||
QString localFilename;
|
||||
int score;
|
||||
};
|
||||
|
||||
static void learnImage(const QString &filename, QMap<QString, ImageMatch> &matches, const QVector<QString> &imageFilenames)
|
||||
{
|
||||
// Find the original filenames with the highest match-score
|
||||
QStringList newMatches;
|
||||
int bestScore = 1;
|
||||
|
||||
for (const QString &originalFilename: imageFilenames) {
|
||||
int score = matchFilename(filename, originalFilename);
|
||||
if (score < bestScore)
|
||||
continue;
|
||||
if (score > bestScore)
|
||||
newMatches.clear();
|
||||
newMatches.append(originalFilename);
|
||||
bestScore = score;
|
||||
}
|
||||
|
||||
// Add the new original filenames to the list of matches, if the score is higher than previously
|
||||
for (const QString &originalFilename: newMatches) {
|
||||
auto it = matches.find(originalFilename);
|
||||
if (it == matches.end())
|
||||
matches.insert(originalFilename, { filename, bestScore });
|
||||
else if (it->score < bestScore)
|
||||
*it = { filename, bestScore };
|
||||
}
|
||||
}
|
||||
|
||||
void learnImages(const QStringList &dirNames, int max_recursions, const QVector<QString> &imageFilenames)
|
||||
{
|
||||
QStringList filters = imageExtensionFilters();
|
||||
QMap<QString, ImageMatch> matches;
|
||||
|
||||
QVector<QStringList> stack; // Use a stack to recurse into directories
|
||||
stack.reserve(max_recursions + 1);
|
||||
stack.append(dirNames);
|
||||
while (!stack.isEmpty()) {
|
||||
if (stack.last().isEmpty()) {
|
||||
stack.removeLast();
|
||||
continue;
|
||||
}
|
||||
QDir dir(stack.last().takeLast());
|
||||
|
||||
for (const QString &file: dir.entryList(filters, QDir::Files))
|
||||
learnImage(dir.absoluteFilePath(file), matches, imageFilenames);
|
||||
if (stack.size() <= max_recursions) {
|
||||
stack.append(QStringList());
|
||||
for (const QString &dirname: dir.entryList(QStringList(), QDir::NoDotAndDotDot | QDir::Dirs))
|
||||
stack.last().append(dir.filePath(dirname));
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = matches.begin(); it != matches.end(); ++it)
|
||||
learnPictureFilename(it.key(), it->localFilename);
|
||||
|
||||
write_hashes();
|
||||
}
|
||||
|
||||
extern "C" const char *local_file_path(struct picture *picture)
|
||||
{
|
||||
return copy_qstring(localFilePath(picture->filename));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue