File indexing completed on 2024-04-21 05:51:44

0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 // SPDX-FileCopyrightText: 2010 Dominik Seichter <domseichter@web.de>
0003 
0004 #include "krenametokensorter.h"
0005 
0006 #include "plugin.h"
0007 #include "pluginloader.h"
0008 
0009 #include <krandom.h>
0010 
0011 // Helper functions for sorting
0012 static const QString findNumInString(unsigned int pos, const QString &s)
0013 {
0014     QString num;
0015 
0016     for (int i = static_cast<int>(pos); i >= 0; i--)
0017         if (s[i].isDigit()) {
0018             num.prepend(s[i]);
0019         } else {
0020             break;
0021         }
0022 
0023     for (int i = pos + 1; i < s.length(); i++)
0024         if (s[i].isDigit()) {
0025             num.append(s[i]);
0026         } else {
0027             break;
0028         }
0029 
0030     return num;
0031 }
0032 
0033 static int compareNummeric(const QString &s1, const QString &s2)
0034 {
0035     int z = 0;
0036     int max = (s1.length() > s2.length() ? s1.length() : s2.length());
0037 
0038     QString num1;
0039     QString num2;
0040     for (z = 0; z < max; z++) {
0041         //if( z >= s1.length() || z >= s2.length() )
0042         //    break;
0043 
0044         if ((z < s1.length() && z < s2.length() && s1[z] != s2[z])) {
0045             if (z < s1.length() && s1[z].isDigit()) {
0046                 num1 = findNumInString(z, s1);
0047             }
0048 
0049             if (z < s2.length() && s2[z].isDigit()) {
0050                 num2 = findNumInString(z, s2);
0051             }
0052 
0053             if (num1.isNull() && num2.isNull()) {
0054                 break;
0055             }
0056 
0057             int a = num1.toInt();
0058             int b = num2.toInt();
0059             if (a == b) {
0060                 return s1.compare(s2);
0061             } else {
0062                 return (a > b) ? 1 : -1;
0063             }
0064         }
0065     }
0066 
0067     return s1.compare(s2);
0068 }
0069 
0070 // Less than functions for sorting
0071 bool ascendingKRenameFileLessThan(const KRenameFile &file1, const KRenameFile &file2)
0072 {
0073     return file1.srcUrl() < file2.srcUrl();
0074 }
0075 
0076 bool descendingKRenameFileLessThan(const KRenameFile &file1, const KRenameFile &file2)
0077 {
0078     return !(file1.srcUrl() < file2.srcUrl());
0079 }
0080 
0081 bool numericKRenameFileLessThan(const KRenameFile &file1, const KRenameFile &file2)
0082 {
0083     QUrl url1 = file1.srcUrl();
0084     QUrl url2 = file2.srcUrl();
0085     QString directory1 = url1.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash).path();
0086     QString directory2 = url2.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash).path();
0087     if (directory1 != directory2) {
0088         // not in the same directory so do lexical comparison
0089         return url1 < url2;
0090     } else {
0091         return (compareNummeric(file1.srcFilename(), file2.srcFilename()) < 0);
0092     }
0093 
0094     return false;
0095 }
0096 
0097 KRenameTokenSorter::KRenameTokenSorter(BatchRenamer *renamer, const QString &token,
0098                                        const KRenameFile::List &list, ESimpleSortMode eSortMode)
0099     : m_renamer(renamer), m_token(token), m_list(list), m_eSortMode(eSortMode)
0100 {
0101     m_plugin = PluginLoader::Instance()->findPlugin(token);
0102 
0103     KRenameFile::List::ConstIterator it = list.begin();
0104     int index = 0;
0105     while (it != list.end()) {
0106         QString value = processString(index++);
0107         m_values.insert((*it).srcUrl(), value);
0108 
0109         ++it;
0110     }
0111 }
0112 
0113 bool KRenameTokenSorter::operator()(const KRenameFile &file1, const KRenameFile &file2)
0114 {
0115     QString str1, str2;
0116 
0117     str1 = m_values.value(file1.srcUrl());
0118     str2 = m_values.value(file2.srcUrl());
0119 
0120     if (m_eSortMode == eSimpleSortMode_Ascending) {
0121         return str1 < str2;
0122     } else if (m_eSortMode == eSimpleSortMode_Descending) {
0123         return !(str1 < str2);
0124     } else if (m_eSortMode == eSimpleSortMode_Numeric) {
0125         return compareNummeric(str1, str2) < 0;
0126     }
0127 
0128     // Default, should never be reached
0129     return (str1 < str2);
0130 }
0131 
0132 QString KRenameTokenSorter::processString(int index) const
0133 {
0134     QString ret = m_token;
0135     if (m_plugin != nullptr) {
0136         ret = m_plugin->processFile(m_renamer, index, ret, ePluginType_Token);
0137     }
0138     return ret;
0139 }
0140