File indexing completed on 2025-02-09 07:11:24

0001 /*
0002     This file is part of the Kasten Framework, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2008-2009, 2011, 2014 Friedrich W. H. Kossebau <kossebau@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007 */
0008 
0009 #include "abstractfilesystemloadjob_p.hpp"
0010 
0011 // library
0012 #include "abstractmodelfilesystemsynchronizer.hpp"
0013 #include <abstractdocument.hpp>
0014 // KF
0015 #include <KIO/FileCopyJob>
0016 #include <KJobWidgets>
0017 // Qt
0018 #include <QFileInfo>
0019 #include <QDateTime>
0020 #include <QTemporaryFile>
0021 
0022 namespace Kasten {
0023 
0024 void AbstractFileSystemLoadJobPrivate::load()
0025 {
0026     Q_Q(AbstractFileSystemLoadJob);
0027 
0028     bool isWorkFileOk;
0029 
0030     if (mUrl.isLocalFile()) {
0031         // file protocol. We do not need the network
0032         mWorkFilePath = mUrl.toLocalFile();
0033         isWorkFileOk = true;
0034     } else {
0035         QTemporaryFile tmpFile;
0036         tmpFile.setAutoRemove(false);
0037         tmpFile.open();
0038 
0039         mWorkFilePath = tmpFile.fileName();
0040         mTempFilePath = mWorkFilePath;
0041 
0042         KIO::FileCopyJob* fileCopyJob =
0043             KIO::file_copy(mUrl, QUrl::fromLocalFile(mWorkFilePath), -1, KIO::Overwrite);
0044         KJobWidgets::setWindow(fileCopyJob, /*mWidget*/ nullptr);
0045 
0046         isWorkFileOk = fileCopyJob->exec();
0047         if (!isWorkFileOk) {
0048             q->setErrorText(fileCopyJob->errorString());
0049         }
0050     }
0051 
0052     if (isWorkFileOk) {
0053         mFile = new QFile(mWorkFilePath);
0054         isWorkFileOk = mFile->open(QIODevice::ReadOnly);
0055         if (!isWorkFileOk) {
0056             q->setErrorText(mFile->errorString());
0057         }
0058     }
0059 
0060     if (isWorkFileOk) {
0061         q->startLoadFromFile();
0062     } else {
0063         q->setError(KJob::KilledJobError);
0064         // TODO: should we rather skip setDocument in the API?
0065         q->AbstractLoadJob::setDocument(nullptr);
0066     }
0067 }
0068 
0069 void AbstractFileSystemLoadJobPrivate::setDocument(AbstractDocument* document)
0070 {
0071     Q_Q(AbstractFileSystemLoadJob);
0072 
0073     if (document) {
0074         const bool isLocalFile = mUrl.isLocalFile();
0075         mFile->close(); // TODO: when is new time written, on close?
0076 
0077         // TODO: reading the fileinfo here separated from the content reading without a lock
0078         // asks for a race-condition to happen where the file is modified in between
0079         // TODO: how to handle remote+temp?
0080         QFileInfo fileInfo(*mFile);
0081         mSynchronizer->setFileDateTimeOnSync(fileInfo.lastModified());
0082         mSynchronizer->setUrl(mUrl);
0083         if (isLocalFile) {
0084             mSynchronizer->startFileWatching();
0085         } else {
0086             mSynchronizer->startNetworkWatching();
0087         }
0088         mSynchronizer->setRemoteState(isLocalFile ? RemoteInSync : RemoteUnknown);
0089 
0090         document->setSynchronizer(mSynchronizer);
0091     } else {
0092         delete mSynchronizer;
0093     }
0094 
0095     delete mFile;
0096 
0097     if (!mTempFilePath.isEmpty()) {
0098         QFile::remove(mTempFilePath);
0099     }
0100 
0101     q->AbstractLoadJob::setDocument(document);
0102 }
0103 
0104 }