/*********************************************************************** * This file is part of module_misc. * * module_misc is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * module_misc is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with module_misc. If not, see * * * Copyright (C) 2015, Dominik Rueß; info@dominik-ruess.de **********************************************************************/ #include #include #include #include #include #include "filenamenumbering_pre.h" namespace MiscTools { /** * a separator to build up a filenamestring */ #ifdef _WIN32 #define SEPARATOR QString("<") #else #define SEPARATOR QString('/') #endif FilenameNumbering_PRE::FilenameNumbering_PRE() { } InfoList FilenameNumbering_PRE::splitFileToStringParts(const QString& filenameOrig, const bool caseInsensitive, const bool withoutExtension, InfoList *stringValues) { InfoList out; if (stringValues != NULL) { stringValues->clear(); } const QFileInfo f = filenameOrig; QString filename; if (withoutExtension) { filename = caseInsensitive ? f.completeBaseName().toLower() : f.completeBaseName(); } else { filename = caseInsensitive ? f.fileName().toLower() : f.fileName(); } for (int i=0; i FilenameNumbering_PRE::getDifferentFile_Patterns(QStringList filenames, const bool caseInsensitive, const bool withoutExtension) { QVector patterns; for (int i=0; i > &fileNumberValues, QVector &numbersUnique, QVector &numberingPositions, bool & onePatternFound, const bool caseInsensitive, const bool withoutExtension) { const int nF = filenames.size(); fileNumberValues.clear(); numbersUnique.clear(); numberingPositions.clear(); const QVector diffPatterns = getDifferentFile_Patterns(filenames, caseInsensitive, withoutExtension); if (diffPatterns.size() != 1) { onePatternFound = false; qWarning() << "different file patterns found, please revise"; return; } onePatternFound = true; const InfoList patterns = diffPatterns.first(); numberingPositions.clear(); for (int i=0; i tmp; for (int i=0; i sortedInd = tmp.values(); for (int j=0; j >& tagsAndDateMap, const QString& tag, QVector& runningFileNumbers, QVector > >& startAndLengthOfRunnNumbers) { startAndLengthOfRunnNumbers.clear(); runningFileNumbers.clear(); QMultiMap tagPositions; QVector > filenameNumericValues; QVector tmp1; QString tmp2; QVector > > startAndLengthOfAllTags; _getTagMap(filenames, taggedFileName, tagsAndDateMap, tagPositions, tmp1, tmp2, filenameNumericValues, startAndLengthOfAllTags); if (filenameNumericValues.size() != filenames.size()) { qWarning() << "number of filenames mismatch"; return false; } // create tag number map to numerical value // position in filename, QVector numberingPos; QMapIterator i(tagPositions); int k=0; while (i.hasNext()) { i.next(); const int tagNo = i.value(); if (tagsAndDateMap[tagNo].first == tag) { numberingPos.push_back(k); } k++; } if (numberingPos.size() == 0) { qWarning() << "could not determine running number"; return false; } const int n = filenames.size(); runningFileNumbers.resize(n); startAndLengthOfRunnNumbers.resize(n); for (int j=0; j >& tagsAndDateMap, QMultiMap& tagPositions, // first = tagNo, second = tagOrderPos; QVector& datePatternsUsed, QString& datePattern, QVector >& filenameNumericValues, QVector > >& tagSourceFNPositionsAndLengths) { // find positions and order of given tags datePattern=""; tagPositions.clear(); datePatternsUsed.clear(); filenameNumericValues.clear(); tagSourceFNPositionsAndLengths.clear(); for (int i=0;i=0) { tagPositions.insertMulti(pos, i); pos = taggedFileName.indexOf(tagsAndDateMap[i].first, pos+1); } } // now extract fixed text between tags // also create datePatterns/parse format for comparison QStringList textInBetween; datePattern = ""; datePatternsUsed.clear(); QMapIterator i(tagPositions); int pos = 0; int k=0; while (i.hasNext()) { i.next(); const int tagPos = i.key(); const int tagNo = i.value(); if (tagsAndDateMap[tagNo].second.length() > 0) { datePatternsUsed.push_back(k); datePattern += QString("%1%2").arg(SEPARATOR).arg(tagsAndDateMap[tagNo].second); } if (tagPos != pos) { textInBetween.push_back(taggedFileName.mid(pos, tagPos-pos)); } pos = tagPos + tagsAndDateMap[tagNo].first.length(); k++; if (!i.hasNext()) { if (pos != taggedFileName.length()) { textInBetween.push_back(taggedFileName.right(taggedFileName.length()-pos)); } } } // strip all known text to obtain numerical values const int n = filenames.size(); const int d = tagPositions.size(); filenameNumericValues.resize(n); tagSourceFNPositionsAndLengths.resize(n); for (int i=0; i0) { currLength = pos - currLength; tagSourceFNPositionsAndLengths[i][ind] = QPair(currPosValue, currLength); currPosValue += textInBetween[j].length() + currLength; ind++; } // make sure, just inserted space is not considered again: pos++; } if (ind == d-1) { // last part of basename was a number tagSourceFNPositionsAndLengths[i][ind] = QPair(currPosValue, originalFilenameLength - currPosValue); ind++; } else if (ind != d) { qWarning() << "error, problems with determining the positions and lengths of the " " tag values for " << filenames[i] << " " << ind << " " << n-1; return false; } QStringList values = fn.split(SEPARATOR, QString::SkipEmptyParts); if (values.length() != d) { qWarning() << "mismatching number of tags and found values"; filenameNumericValues[i].clear(); continue; } for (int j=0; j < d; j++) { bool ok; const int val = values[j].toInt(&ok); filenameNumericValues[i][j] = ok ? val : QVariant(values[j]); } } datePattern = datePattern.replace(SEPARATOR, " "); return true; } QVector FilenameNumbering_PRE::findMoveOrdering( const QList >& moveExisting ) { QVector currentExisting(moveExisting.size()); QList > notHandled = moveExisting; QVector backMap(notHandled.size()); for (int i=0; i order; int lastSize = order.size() - 1; while (notHandled.size() > 0) { if (lastSize == order.size()) { qCritical() << "could not resolve movement, circular dependencies ?!"; return QVector(); } lastSize = order.size(); for (int i=notHandled.size()-1; i>=0; i--) { const QString src = notHandled[i].first; const QString target = notHandled[i].second; // either the file does not exist or it exists but will be removed before // current file gets moved if (!currentExisting.contains(target) ) { order.push_back(backMap[i]); //added.push_back(notHandled[i].second); //deleted.push_back(notHandled[i].first); currentExisting.append(target); if (currentExisting.contains(src)) { currentExisting.remove(currentExisting.indexOf(src)); } notHandled.removeAt(i); backMap.remove(i); } } } return order; } template <> template <> Q_OUTOFLINE_TEMPLATE bool MyFilePartsList::operator==(const MyFilePartsList &b) const { if (size() != b.size()) { return false; } bool same = true; for (int i=0; i < (int)size(); i++) { if (this->at(i).typeName() == b.at(i).typeName()) { if (this->at(i).typeName() == QString("QString")) { same &= this->at(i).toString() == b[i].toString(); } } else { same = false; break; } } return same; } } // end namespace MiscTools