File indexing completed on 2024-05-12 15:56:59

0001 /*
0002     This file is part of the KDE libraries
0003 
0004     SPDX-FileCopyrightText: 1999 Waldo Bastian <bastian@kde.org>
0005     SPDX-FileCopyrightText: 2006 Allen Winter <winter@kde.org>
0006     SPDX-FileCopyrightText: 2006 Gregory S. Hayes <syncomm@kde.org>
0007     SPDX-FileCopyrightText: 2006 Jaison Lee <lee.jaison@gmail.com>
0008     SPDX-FileCopyrightText: 2011 Romain Perier <bambi@ubuntu.com>
0009 
0010     SPDX-License-Identifier: LGPL-2.0-only
0011 */
0012 
0013 #include "KisBackup.h"
0014 
0015 #include <QDebug>
0016 #include <QDir>
0017 #include <QFileInfo>
0018 
0019 bool KisBackup::backupFile(const QString &qFilename, const QString &backupDir)
0020 {
0021     return (simpleBackupFile(qFilename, backupDir, QStringLiteral("~")));
0022 }
0023 
0024 bool KisBackup::simpleBackupFile(const QString &qFilename, const QString &backupDir, const QString &backupExtension)
0025 {
0026     QString backupFileName = qFilename + backupExtension;
0027 
0028     if (!backupDir.isEmpty()) {
0029         QFileInfo fileInfo(qFilename);
0030         backupFileName = backupDir + QLatin1Char('/') + fileInfo.fileName() + backupExtension;
0031     }
0032 
0033     //    qCDebug(KCOREADDONS_DEBUG) << "KisBackup copying " << qFilename << " to " << backupFileName;
0034     QFile::remove(backupFileName);
0035     return QFile::copy(qFilename, backupFileName);
0036 }
0037 
0038 bool KisBackup::numberedBackupFile(const QString &qFilename, const QString &backupDir, const QString &backupExtension, const uint maxBackups)
0039 {
0040     QFileInfo fileInfo(qFilename);
0041 
0042     // The backup file name template.
0043     QString sTemplate;
0044 
0045     if (backupDir.isEmpty()) {
0046         sTemplate = qFilename + QLatin1String(".%1") + backupExtension;
0047     } else {
0048         sTemplate = backupDir + QLatin1Char('/') + fileInfo.fileName() + QLatin1String(".%1") + backupExtension;
0049     }
0050     // First, search backupDir for numbered backup files to remove.
0051     // Remove all with number 'maxBackups' and greater.
0052     QDir d = backupDir.isEmpty() ? fileInfo.dir() : backupDir;
0053     d.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
0054 
0055     QString nameFilter = fileInfo.fileName() + QLatin1String(".*") + backupExtension;
0056     nameFilter.replace('[', '*');
0057     nameFilter.replace(']', '*');
0058 
0059     const QStringList nameFilters = QStringList(nameFilter);
0060     d.setNameFilters(nameFilters);
0061     d.setSorting(QDir::Name);
0062 
0063     uint maxBackupFound = 0;
0064     const QFileInfoList infoList = d.entryInfoList();
0065     for (const QFileInfo &fi : infoList) {
0066         if (fi.fileName().endsWith(backupExtension)) {
0067             // sTemp holds the file name, without the ending backupExtension
0068             QString sTemp = fi.fileName();
0069 
0070             sTemp.truncate(fi.fileName().length() - backupExtension.length());
0071 
0072             // compute the backup number
0073             int idex = sTemp.lastIndexOf(QLatin1Char('.'));
0074             if (idex > 0) {
0075                 bool ok;
0076 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
0077                 const uint num = QStringView(sTemp).mid(idex + 1).toUInt(&ok);
0078 #else
0079                 const uint num = sTemp.midRef(idex + 1).toUInt(&ok);
0080 #endif
0081                 if (ok) {
0082                     if (num >= maxBackups) {
0083                         QFile::remove(fi.filePath());
0084                     } else {
0085                         maxBackupFound = qMax(maxBackupFound, num);
0086                     }
0087                 }
0088             }
0089         }
0090     }
0091 
0092     // Next, rename max-1 to max, max-2 to max-1, etc.
0093     QString to = sTemplate.arg(maxBackupFound + 1);
0094 
0095     for (int i = maxBackupFound; i > 0; i--) {
0096         QString from = sTemplate.arg(i);
0097         //        qCDebug(KCOREADDONS_DEBUG) << "KisBackup renaming " << from << " to " << to;
0098         QFile::rename(from, to);
0099         to = from;
0100     }
0101 
0102     // Finally create most recent backup by copying the file to backup number 1.
0103     //    qCDebug(KCOREADDONS_DEBUG) << "KisBackup copying " << qFilename << " to " << sTemplate.arg(1);
0104     bool r = QFile::copy(qFilename, sTemplate.arg(1));
0105     return r;
0106 }