File indexing completed on 2024-04-21 16:32:33

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