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 "abstractfilesystemconnectjob_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 AbstractFileSystemConnectJobPrivate::connectWithFile()
0025 {
0026     Q_Q(AbstractFileSystemConnectJob);
0027 
0028     bool isWorkFileOk;
0029     if (mOption == AbstractModelSynchronizer::ReplaceRemote) {
0030         if (mUrl.isLocalFile()) {
0031             mWorkFilePath = mUrl.toLocalFile();
0032             mFile = new QFile(mWorkFilePath);
0033             isWorkFileOk = mFile->open(QIODevice::WriteOnly);
0034         } else {
0035             auto* temporaryFile = new QTemporaryFile;
0036             isWorkFileOk = temporaryFile->open();
0037 
0038             mWorkFilePath = temporaryFile->fileName();
0039             mTempFilePath = mWorkFilePath;
0040             mFile = temporaryFile;
0041         }
0042         if (!isWorkFileOk) {
0043             q->setErrorText(mFile->errorString());
0044         }
0045     } else {
0046         if (mUrl.isLocalFile()) {
0047             // file protocol. We do not need the network
0048             mWorkFilePath = mUrl.toLocalFile();
0049             isWorkFileOk = true;
0050         } else {
0051             QTemporaryFile tmpFile;
0052             tmpFile.setAutoRemove(false);
0053             tmpFile.open();
0054 
0055             mWorkFilePath = tmpFile.fileName();
0056             mTempFilePath = mWorkFilePath;
0057 
0058             KIO::FileCopyJob* fileCopyJob =
0059                 KIO::file_copy(mUrl, QUrl::fromLocalFile(mWorkFilePath), -1, KIO::Overwrite);
0060             KJobWidgets::setWindow(fileCopyJob, /*mWidget*/ nullptr);
0061 
0062             isWorkFileOk = fileCopyJob->exec();
0063             if (!isWorkFileOk) {
0064                 q->setErrorText(fileCopyJob->errorString());
0065             }
0066         }
0067 
0068         if (isWorkFileOk) {
0069             mFile = new QFile(mWorkFilePath);
0070             isWorkFileOk = mFile->open(QIODevice::ReadOnly);
0071             if (!isWorkFileOk) {
0072                 q->setErrorText(mFile->errorString());
0073             }
0074         }
0075     }
0076 
0077     if (isWorkFileOk) {
0078         q->startConnectWithFile();
0079     } else {
0080         q->setError(KJob::KilledJobError);
0081         delete mFile;
0082         // TODO: should we rather skip setDocument in the API?
0083         q->emitResult();
0084     }
0085 }
0086 
0087 void AbstractFileSystemConnectJobPrivate::complete(bool success)
0088 {
0089     Q_Q(AbstractFileSystemConnectJob);
0090 
0091     if (success) {
0092         mFile->close(); // TODO: when is new time written, on close?
0093         QFileInfo fileInfo(*mFile);
0094         mSynchronizer->setFileDateTimeOnSync(fileInfo.lastModified());
0095 
0096         mSynchronizer->setUrl(mUrl);
0097 
0098         if (!mUrl.isLocalFile()) {
0099             KIO::FileCopyJob* fileCopyJob =
0100                 KIO::file_copy(QUrl::fromLocalFile(mWorkFilePath), mUrl, -1, KIO::Overwrite);
0101             KJobWidgets::setWindow(fileCopyJob, /*mWidget*/ nullptr);
0102 
0103             const bool uploaded = fileCopyJob->exec();
0104             if (!uploaded) {
0105                 q->setError(KJob::KilledJobError);
0106                 q->setErrorText(fileCopyJob->errorString());
0107             } else {
0108                 mSynchronizer->startNetworkWatching();
0109                 mSynchronizer->setRemoteState(RemoteUnknown);
0110             }
0111         } else {
0112             mSynchronizer->startFileWatching();
0113             mSynchronizer->setRemoteState(RemoteInSync);
0114         }
0115 
0116         // TODO; in path of both constructor by url and synchWithRemote
0117         // only needed for the first, so constructor writers can forget about this
0118         // for now we just check in setSynchronizer that new != old before deleting old
0119         mDocument->setSynchronizer(mSynchronizer);
0120     } else {
0121         delete mSynchronizer;
0122         // TODO: these reports should go to a notification system, for log or popup
0123         q->setError(KJob::KilledJobError);
0124         q->setErrorText(mFile->errorString());
0125     }
0126 
0127     delete mFile;
0128 
0129     if (!mTempFilePath.isEmpty()) {
0130         QFile::remove(mTempFilePath);
0131     }
0132 
0133     q->emitResult();
0134 }
0135 
0136 }