KDECore
kautosavefile.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (c) 2006 Jacob R Rideout <kde@jacobrideout.net> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "kautosavefile.h" 00021 00022 #include <stdio.h> // for FILENAME_MAX 00023 00024 #include <QtCore/QLatin1Char> 00025 #include <QtCore/QCoreApplication> 00026 #include "klockfile.h" 00027 #include "krandom.h" 00028 #include "kglobal.h" 00029 #include "kstandarddirs.h" 00030 00031 class KAutoSaveFilePrivate 00032 { 00033 public: 00034 KAutoSaveFilePrivate() 00035 : lock(0), 00036 managedFileNameChanged(false) 00037 {} 00038 00039 QString tempFileName(); 00040 KUrl managedFile; 00041 KLockFile::Ptr lock; 00042 static const int padding; 00043 bool managedFileNameChanged; 00044 }; 00045 00046 const int KAutoSaveFilePrivate::padding = 8; 00047 00048 QString KAutoSaveFilePrivate::tempFileName() 00049 { 00050 static const int maxNameLength = FILENAME_MAX; 00051 00052 // Note: we drop any query string and user/pass info 00053 QString protocol(managedFile.protocol()); 00054 QString path(managedFile.directory()); 00055 QString name(managedFile.fileName()); 00056 00057 // Remove any part of the path to the right if it is longer than the max file size and 00058 // ensure that the max filesize takes into account the other parts of the tempFileName 00059 // Subtract 1 for the _ char, 3 for the padding sepperator, 5 is for the .lock 00060 path = path.left(maxNameLength - padding - name.size() - protocol.size() - 9); 00061 00062 QString junk = KRandom::randomString(padding); 00063 // tempName = fileName + junk.trunicated + protocol + _ + path.trunicated + junk 00064 // This is done so that the separation between the filename and path can be determined 00065 name += junk.right(3) + protocol + QLatin1Char('_'); 00066 name += path + junk; 00067 00068 return QString::fromLatin1(KUrl::toPercentEncoding(name)); 00069 } 00070 00071 KAutoSaveFile::KAutoSaveFile(const KUrl &filename, QObject *parent) 00072 : QFile(parent), 00073 d(new KAutoSaveFilePrivate) 00074 { 00075 setManagedFile(filename); 00076 KGlobal::dirs()->addResourceType("stale", 0, QString::fromLatin1("data/stalefiles")); 00077 } 00078 00079 KAutoSaveFile::KAutoSaveFile(QObject *parent) 00080 : QFile(parent), 00081 d(new KAutoSaveFilePrivate) 00082 { 00083 KGlobal::dirs()->addResourceType("stale", 0, QString::fromLatin1("data/stalefiles")); 00084 } 00085 00086 KAutoSaveFile::~KAutoSaveFile() 00087 { 00088 releaseLock(); 00089 delete d; 00090 } 00091 00092 KUrl KAutoSaveFile::managedFile() const 00093 { 00094 return d->managedFile; 00095 } 00096 00097 void KAutoSaveFile::setManagedFile(const KUrl &filename) 00098 { 00099 releaseLock(); 00100 00101 d->managedFile = filename; 00102 d->managedFileNameChanged = true; 00103 } 00104 00105 void KAutoSaveFile::releaseLock() 00106 { 00107 if (d->lock && d->lock->isLocked()) { 00108 d->lock.clear(); 00109 if (!fileName().isEmpty()) { 00110 remove(); 00111 } 00112 } 00113 } 00114 00115 bool KAutoSaveFile::open(OpenMode openmode) 00116 { 00117 if (d->managedFile == KUrl()) { 00118 return false; 00119 } 00120 00121 QString tempFile; 00122 if (d->managedFileNameChanged) { 00123 tempFile = KStandardDirs::locateLocal("stale", 00124 QCoreApplication::instance()->applicationName() 00125 + QChar::fromLatin1('/') 00126 + d->tempFileName() 00127 ); 00128 } else { 00129 tempFile = fileName(); 00130 } 00131 00132 d->managedFileNameChanged = false; 00133 00134 setFileName(tempFile); 00135 00136 if (QFile::open(openmode)) { 00137 00138 d->lock = new KLockFile(tempFile + QString::fromLatin1(".lock")); 00139 if (d->lock->isLocked()) { 00140 close(); 00141 return false; 00142 } 00143 00144 d->lock->setStaleTime(60); // HARDCODE, 1 minute 00145 00146 if (d->lock->lock(KLockFile::ForceFlag|KLockFile::NoBlockFlag) == KLockFile::LockOK) { 00147 return true; 00148 } else { 00149 close(); 00150 } 00151 } 00152 00153 return false; 00154 } 00155 00156 QList<KAutoSaveFile *> KAutoSaveFile::staleFiles(const KUrl &filename, const QString &applicationName) 00157 { 00158 KGlobal::dirs()->addResourceType("stale", 0, QString::fromLatin1("data/stalefiles")); 00159 00160 QString appName(applicationName); 00161 if (appName.isEmpty()) { 00162 appName = QCoreApplication::instance()->applicationName(); 00163 } 00164 00165 QString url = filename.fileName(); 00166 00167 if (url.isEmpty()) { 00168 return QList<KAutoSaveFile *>(); 00169 } 00170 00171 // get stale files 00172 const QStringList files = KGlobal::dirs()->findAllResources("stale", 00173 appName + QChar::fromLatin1('/') + 00174 url + QChar::fromLatin1('*'), 00175 KStandardDirs::Recursive); 00176 00177 QList<KAutoSaveFile *> list; 00178 KAutoSaveFile * asFile; 00179 00180 // contruct a KAutoSaveFile for each stale file 00181 foreach(const QString &file, files) { 00182 if (file.endsWith(QLatin1String(".lock"))) 00183 continue; 00184 // sets managedFile 00185 asFile = new KAutoSaveFile(filename); 00186 asFile->setFileName(file); 00187 // flags the name, so it isn't regenerated 00188 asFile->d->managedFileNameChanged = false; 00189 list.append(asFile); 00190 } 00191 00192 return list; 00193 } 00194 00195 QList<KAutoSaveFile *> KAutoSaveFile::allStaleFiles(const QString &applicationName) 00196 { 00197 KGlobal::dirs()->addResourceType("stale", 0, QString::fromLatin1("data/stalefiles")); 00198 00199 QString appName(applicationName); 00200 if (appName.isEmpty()) { 00201 appName = QCoreApplication::instance()->applicationName(); 00202 } 00203 00204 // get stale files 00205 const QStringList files = KGlobal::dirs()->findAllResources("stale", appName + QLatin1String("/*")); 00206 00207 QList<KAutoSaveFile *> list; 00208 00209 // contruct a KAutoSaveFile for each stale file 00210 foreach(QString file, files) { // krazy:exclude=foreach (no const& because modified below) 00211 if (file.endsWith(QLatin1String(".lock"))) 00212 continue; 00213 const QString sep = file.right(3); 00214 file.chop(KAutoSaveFilePrivate::padding); 00215 00216 int sepPos = file.indexOf(sep); 00217 int pathPos = file.indexOf(QChar::fromLatin1('_'), sepPos); 00218 KUrl name; 00219 name.setProtocol(file.mid(sepPos + 3, pathPos - sep.size() - 3)); 00220 name.setPath(KUrl::fromPercentEncoding(file.right(pathPos - 1).toLatin1())); 00221 name.addPath(KUrl::fromPercentEncoding(file.left(sepPos).toLatin1())); 00222 00223 // sets managedFile 00224 KAutoSaveFile* asFile = new KAutoSaveFile(name); 00225 asFile->setFileName(file); 00226 // flags the name, so it isn't regenerated 00227 asFile->d->managedFileNameChanged = false; 00228 list.append(asFile); 00229 } 00230 00231 return list; 00232 } 00233 00234 #include "kautosavefile.moc"
KDE 4.6 API Reference