2014-11-13 01:04:59 +02:00
|
|
|
/* This file is part of the KDE libraries
|
|
|
|
Copyright (c) 2006 Jacob R Rideout <kde@jacobrideout.net>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library 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
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "kautosavefile.h"
|
|
|
|
|
|
|
|
#include <stdio.h> // for FILENAME_MAX
|
|
|
|
|
2015-09-04 13:06:11 +00:00
|
|
|
#include <QtCore/qstringlist.h>
|
|
|
|
#include <QtCore/qcoreapplication.h>
|
2014-11-13 01:04:59 +02:00
|
|
|
#include "klockfile.h"
|
|
|
|
#include "krandom.h"
|
|
|
|
#include "kglobal.h"
|
|
|
|
#include "kstandarddirs.h"
|
|
|
|
|
|
|
|
class KAutoSaveFilePrivate
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
KAutoSaveFilePrivate()
|
|
|
|
: lock(0),
|
|
|
|
managedFileNameChanged(false)
|
|
|
|
{}
|
|
|
|
|
|
|
|
QString tempFileName();
|
|
|
|
KUrl managedFile;
|
|
|
|
KLockFile::Ptr lock;
|
|
|
|
static const int padding;
|
|
|
|
bool managedFileNameChanged;
|
|
|
|
};
|
|
|
|
|
|
|
|
const int KAutoSaveFilePrivate::padding = 8;
|
|
|
|
|
|
|
|
QString KAutoSaveFilePrivate::tempFileName()
|
|
|
|
{
|
|
|
|
static const int maxNameLength = FILENAME_MAX;
|
|
|
|
|
|
|
|
// Note: we drop any query string and user/pass info
|
|
|
|
QString protocol(managedFile.protocol());
|
|
|
|
QString path(managedFile.directory());
|
|
|
|
QString name(managedFile.fileName());
|
|
|
|
|
|
|
|
// Remove any part of the path to the right if it is longer than the max file size and
|
|
|
|
// ensure that the max filesize takes into account the other parts of the tempFileName
|
|
|
|
// Subtract 1 for the _ char, 3 for the padding sepperator, 5 is for the .lock
|
|
|
|
path = path.left(maxNameLength - padding - name.size() - protocol.size() - 9);
|
|
|
|
|
|
|
|
QString junk = KRandom::randomString(padding);
|
|
|
|
// tempName = fileName + junk.trunicated + protocol + _ + path.trunicated + junk
|
|
|
|
// This is done so that the separation between the filename and path can be determined
|
|
|
|
name += junk.right(3) + protocol + QLatin1Char('_');
|
|
|
|
name += path + junk;
|
|
|
|
|
|
|
|
return QString::fromLatin1(KUrl::toPercentEncoding(name));
|
|
|
|
}
|
|
|
|
|
|
|
|
KAutoSaveFile::KAutoSaveFile(const KUrl &filename, QObject *parent)
|
|
|
|
: QFile(parent),
|
|
|
|
d(new KAutoSaveFilePrivate)
|
|
|
|
{
|
|
|
|
setManagedFile(filename);
|
|
|
|
KGlobal::dirs()->addResourceType("stale", 0, QString::fromLatin1("data/stalefiles"));
|
|
|
|
}
|
|
|
|
|
|
|
|
KAutoSaveFile::KAutoSaveFile(QObject *parent)
|
|
|
|
: QFile(parent),
|
|
|
|
d(new KAutoSaveFilePrivate)
|
|
|
|
{
|
|
|
|
KGlobal::dirs()->addResourceType("stale", 0, QString::fromLatin1("data/stalefiles"));
|
|
|
|
}
|
|
|
|
|
|
|
|
KAutoSaveFile::~KAutoSaveFile()
|
|
|
|
{
|
|
|
|
releaseLock();
|
|
|
|
delete d;
|
|
|
|
}
|
|
|
|
|
|
|
|
KUrl KAutoSaveFile::managedFile() const
|
|
|
|
{
|
|
|
|
return d->managedFile;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KAutoSaveFile::setManagedFile(const KUrl &filename)
|
|
|
|
{
|
|
|
|
releaseLock();
|
|
|
|
|
|
|
|
d->managedFile = filename;
|
|
|
|
d->managedFileNameChanged = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KAutoSaveFile::releaseLock()
|
|
|
|
{
|
|
|
|
if (d->lock && d->lock->isLocked()) {
|
|
|
|
d->lock.clear();
|
|
|
|
if (!fileName().isEmpty()) {
|
|
|
|
remove();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KAutoSaveFile::open(OpenMode openmode)
|
|
|
|
{
|
|
|
|
if (d->managedFile == KUrl()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString tempFile;
|
|
|
|
if (d->managedFileNameChanged) {
|
|
|
|
tempFile = KStandardDirs::locateLocal("stale",
|
|
|
|
QCoreApplication::instance()->applicationName()
|
|
|
|
+ QChar::fromLatin1('/')
|
|
|
|
+ d->tempFileName()
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
tempFile = fileName();
|
|
|
|
}
|
|
|
|
|
|
|
|
d->managedFileNameChanged = false;
|
|
|
|
|
|
|
|
setFileName(tempFile);
|
|
|
|
|
|
|
|
if (QFile::open(openmode)) {
|
|
|
|
|
|
|
|
d->lock = new KLockFile(tempFile + QString::fromLatin1(".lock"));
|
|
|
|
d->lock->setStaleTime(60); // HARDCODE, 1 minute
|
|
|
|
|
|
|
|
if (d->lock->lock(KLockFile::ForceFlag|KLockFile::NoBlockFlag) == KLockFile::LockOK) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
QList<KAutoSaveFile *> KAutoSaveFile::staleFiles(const KUrl &filename, const QString &applicationName)
|
|
|
|
{
|
|
|
|
KGlobal::dirs()->addResourceType("stale", 0, QString::fromLatin1("data/stalefiles"));
|
|
|
|
|
|
|
|
QString appName(applicationName);
|
|
|
|
if (appName.isEmpty()) {
|
|
|
|
appName = QCoreApplication::instance()->applicationName();
|
|
|
|
}
|
|
|
|
|
|
|
|
QString url = filename.fileName();
|
|
|
|
|
|
|
|
if (url.isEmpty()) {
|
|
|
|
return QList<KAutoSaveFile *>();
|
|
|
|
}
|
|
|
|
|
|
|
|
// get stale files
|
|
|
|
const QStringList files = KGlobal::dirs()->findAllResources("stale",
|
|
|
|
appName + QChar::fromLatin1('/') +
|
|
|
|
url + QChar::fromLatin1('*'),
|
|
|
|
KStandardDirs::Recursive);
|
|
|
|
|
|
|
|
QList<KAutoSaveFile *> list;
|
|
|
|
KAutoSaveFile * asFile;
|
|
|
|
|
|
|
|
// contruct a KAutoSaveFile for each stale file
|
|
|
|
foreach(const QString &file, files) {
|
|
|
|
if (file.endsWith(QLatin1String(".lock")))
|
|
|
|
continue;
|
|
|
|
// sets managedFile
|
|
|
|
asFile = new KAutoSaveFile(filename);
|
|
|
|
asFile->setFileName(file);
|
|
|
|
// flags the name, so it isn't regenerated
|
|
|
|
asFile->d->managedFileNameChanged = false;
|
|
|
|
list.append(asFile);
|
|
|
|
}
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
QList<KAutoSaveFile *> KAutoSaveFile::allStaleFiles(const QString &applicationName)
|
|
|
|
{
|
|
|
|
KGlobal::dirs()->addResourceType("stale", 0, QString::fromLatin1("data/stalefiles"));
|
|
|
|
|
|
|
|
QString appName(applicationName);
|
|
|
|
if (appName.isEmpty()) {
|
|
|
|
appName = QCoreApplication::instance()->applicationName();
|
|
|
|
}
|
|
|
|
|
|
|
|
// get stale files
|
|
|
|
const QStringList files = KGlobal::dirs()->findAllResources("stale", appName + QLatin1String("/*"));
|
|
|
|
|
|
|
|
QList<KAutoSaveFile *> list;
|
|
|
|
|
|
|
|
// contruct a KAutoSaveFile for each stale file
|
|
|
|
foreach(QString file, files) { // krazy:exclude=foreach (no const& because modified below)
|
|
|
|
if (file.endsWith(QLatin1String(".lock")))
|
|
|
|
continue;
|
|
|
|
const QString sep = file.right(3);
|
|
|
|
file.chop(KAutoSaveFilePrivate::padding);
|
|
|
|
|
|
|
|
int sepPos = file.indexOf(sep);
|
|
|
|
int pathPos = file.indexOf(QChar::fromLatin1('_'), sepPos);
|
|
|
|
KUrl name;
|
|
|
|
name.setProtocol(file.mid(sepPos + 3, pathPos - sep.size() - 3));
|
|
|
|
name.setPath(KUrl::fromPercentEncoding(file.right(pathPos - 1).toLatin1()));
|
|
|
|
name.addPath(KUrl::fromPercentEncoding(file.left(sepPos).toLatin1()));
|
|
|
|
|
|
|
|
// sets managedFile
|
|
|
|
KAutoSaveFile* asFile = new KAutoSaveFile(name);
|
|
|
|
asFile->setFileName(file);
|
|
|
|
// flags the name, so it isn't regenerated
|
|
|
|
asFile->d->managedFileNameChanged = false;
|
|
|
|
list.append(asFile);
|
|
|
|
}
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2015-02-27 07:40:26 +00:00
|
|
|
#include "moc_kautosavefile.cpp"
|