// vim: set tabstop=4 shiftwidth=4 expandtab: /* Gwenview: an image viewer Copyright 2009 Aurélien Gâteau This program 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 2 of the License, or (at your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA. */ // Self #include "fileutils.h" // Qt #include #include // KDE #include #include #include #include #include #include #include #include // libc #include #include #include namespace Gwenview { namespace FileUtils { bool contentsAreIdentical(const KUrl& url1, const KUrl& url2, QWidget* authWindow) { // FIXME: Support remote urls QFile file1(url1.toLocalFile()); if (!file1.open(QIODevice::ReadOnly)) { // Can't read url1, assume it's different from url2 kWarning() << "Can't read" << url1; return false; } QFile file2(url2.toLocalFile()); if (!file2.open(QIODevice::ReadOnly)) { // Can't read url2, assume it's different from url1 kWarning() << "Can't read" << url2; return false; } const int CHUNK_SIZE = 4096; while (!file1.atEnd() && !file2.atEnd()) { QByteArray url1Array = file1.read(CHUNK_SIZE); QByteArray url2Array = file2.read(CHUNK_SIZE); if (url1Array != url2Array) { return false; } } if (file1.atEnd() && file2.atEnd()) { return true; } else { kWarning() << "One file ended before the other"; return false; } } RenameResult rename(const KUrl& src, const KUrl& dst_, QWidget* authWindow) { KUrl dst = dst_; RenameResult result = RenamedOK; int count = 1; QFileInfo fileInfo(dst.fileName()); QString prefix = fileInfo.completeBaseName() + '_'; QString suffix = '.' + fileInfo.suffix(); // Get src size KIO::UDSEntry udsEntry; KIO::NetAccess::stat(src, udsEntry, authWindow); KFileItem item(udsEntry, src); KIO::filesize_t srcSize = item.size(); // Find unique name while (KIO::NetAccess::stat(dst, udsEntry, authWindow)) { // File exists. If it's not the same, try to create a new name item = KFileItem(udsEntry, dst); KIO::filesize_t dstSize = item.size(); if (srcSize == dstSize && contentsAreIdentical(src, dst, authWindow)) { // Already imported, skip it KIO::Job* job = KIO::file_delete(src, KIO::HideProgressInfo); if (job->ui()) { job->ui()->setWindow(authWindow); } return Skipped; } result = RenamedUnderNewName; dst.setFileName(prefix + QString::number(count) + suffix); ++count; } // Rename KIO::Job* job = KIO::rename(src, dst, KIO::HideProgressInfo); if (!KIO::NetAccess::synchronousRun(job, authWindow)) { result = RenameFailed; } return result; } QString createTempDir(const QString& baseDir, const QString& prefix, QString* errorMessage) { Q_ASSERT(errorMessage); QByteArray name = QFile::encodeName(baseDir + '/' + prefix + "XXXXXX"); if (!mkdtemp(name.data())) { // Failure *errorMessage = QString::fromLocal8Bit(::strerror(errno)); return QString(); } return QFile::decodeName(name + '/'); } } // namespace } // namespace