File indexing completed on 2024-05-05 08:46:07
0001 /*************************************************************************** 0002 * Copyright 2007 Niko Sams <niko.sams@gmail.com> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify * 0005 * it under the terms of the GNU General Public License as published by * 0006 * the Free Software Foundation; either version 2 of the License, or * 0007 * (at your option) any later version. * 0008 * * 0009 ***************************************************************************/ 0010 #include "uploadjob.h" 0011 0012 #include <QPushButton> 0013 #include <QHeaderView> 0014 #include <QStandardItemModel> 0015 #include <QtWidgets/QProgressDialog> 0016 #include <QUrl> 0017 #include <QDir> 0018 #include "kdevuploaddebug.h" 0019 0020 #include <kconfiggroup.h> 0021 #include <kmessagebox.h> 0022 #include <kio/job.h> 0023 #include <kio/copyjob.h> 0024 #include <kio/jobuidelegate.h> 0025 #include <KLocalizedString> 0026 #include <kjob.h> 0027 #include <kjobwidgets.h> 0028 0029 #include <interfaces/iproject.h> 0030 #include <interfaces/iprojectcontroller.h> 0031 #include <project/projectmodel.h> 0032 #include <util/path.h> 0033 0034 #include "uploadprojectmodel.h" 0035 0036 UploadJob::UploadJob(KDevelop::IProject* project, UploadProjectModel* model, QWidget *parent) 0037 : QObject(parent), m_project(project), m_uploadProjectModel(model), 0038 m_onlyMarkUploaded(false), m_quickUpload(false), m_outputModel(nullptr) 0039 { 0040 m_progressDialog = new QProgressDialog(); 0041 m_progressDialog->setWindowTitle(i18n("Uploading files")); 0042 m_progressDialog->setLabelText(i18n("Preparing...")); 0043 m_progressDialog->setModal(true); 0044 } 0045 0046 UploadJob::~UploadJob() 0047 { 0048 delete m_progressDialog; 0049 } 0050 0051 void UploadJob::start() 0052 { 0053 m_progressBytesDone = 0; 0054 m_progressDialog->setLabelText(i18n("Calculating size...")); 0055 m_progressDialog->setValue(0); 0056 m_progressDialog->show(); 0057 0058 int sumSize = 0; 0059 QModelIndex i; 0060 while((i = m_uploadProjectModel->nextRecursionIndex(i)).isValid()) { 0061 KDevelop::ProjectBaseItem* item = m_uploadProjectModel->item(i); 0062 Qt::CheckState checked = static_cast<Qt::CheckState>(m_uploadProjectModel 0063 ->data(i, Qt::CheckStateRole).toInt()); 0064 if (item->file() && checked != Qt::Unchecked) { 0065 KIO::UDSEntry entry; 0066 KIO::StatJob *statjob = KIO::stat(item->path().toUrl()); 0067 KJobWidgets::setWindow(statjob, m_progressDialog); 0068 if (statjob->exec()) { 0069 entry = statjob->statResult(); 0070 sumSize += entry.numberValue(KIO::UDSEntry::UDS_SIZE); 0071 } 0072 } 0073 } 0074 m_progressDialog->setMaximum(sumSize); 0075 0076 m_uploadIndex = QModelIndex(); 0077 uploadNext(); 0078 } 0079 0080 void UploadJob::uploadNext() 0081 { 0082 if (m_progressDialog->wasCanceled()) return; 0083 0084 m_uploadIndex = m_uploadProjectModel->nextRecursionIndex(m_uploadIndex); 0085 0086 if (!m_uploadIndex.isValid()) { 0087 //last index reached - completed 0088 appendLog(i18n("Upload completed")); 0089 emit uploadFinished(); 0090 delete this; 0091 return; 0092 } 0093 0094 if (!m_uploadIndex.parent().isValid()) { 0095 //don't upload project root 0096 uploadNext(); 0097 return; 0098 } 0099 0100 KDevelop::ProjectBaseItem* item = m_uploadProjectModel->item(m_uploadIndex); 0101 0102 Qt::CheckState checked = static_cast<Qt::CheckState>(m_uploadProjectModel 0103 ->data(m_uploadIndex, Qt::CheckStateRole).toInt()); 0104 0105 KDevelop::Path url; 0106 QUrl localUrl = m_uploadProjectModel->currentProfileLocalUrl().adjusted(QUrl::StripTrailingSlash); 0107 0108 KDevelop::Path localPath = KDevelop::Path(localUrl.path()); 0109 0110 if (item->folder()) { 0111 url = item->folder()->path(); 0112 } else if (item->file()) { 0113 url = item->file()->path(); 0114 } 0115 0116 if(localPath.path().isEmpty()) { 0117 localPath = m_project->path(); 0118 } 0119 0120 QString relativeUrl(localPath.relativePath(url)); 0121 0122 if (isQuickUpload() && checked == Qt::Unchecked) { 0123 appendLog(i18n("File was not modified for %1: %2", 0124 m_uploadProjectModel->currentProfileName(), 0125 relativeUrl)); 0126 } 0127 0128 if (!(item->file() || item->folder()) || checked == Qt::Unchecked) { 0129 uploadNext(); 0130 return; 0131 } 0132 0133 QUrl dest = m_uploadProjectModel->currentProfileUrl().adjusted(QUrl::StripTrailingSlash); 0134 dest.setPath(dest.path() + "/" + relativeUrl); 0135 KIO::Job* job = nullptr; 0136 0137 if (m_onlyMarkUploaded) { 0138 appendLog(i18n("Marked as uploaded for %1: %2", 0139 m_uploadProjectModel->currentProfileName(), 0140 relativeUrl)); 0141 m_uploadProjectModel->profileConfigGroup() 0142 .writeEntry(relativeUrl, 0143 QDateTime::currentDateTime()); 0144 uploadNext(); 0145 return; 0146 } else if (item->file()) { 0147 appendLog(i18n("Uploading to %1: %2", 0148 m_uploadProjectModel->currentProfileName(), 0149 relativeUrl)); 0150 qCDebug(KDEVUPLOAD) << "file_copy" << url.pathOrUrl() << dest; 0151 job = KIO::file_copy(url.toUrl(), dest, -1, KIO::Overwrite | KIO::HideProgressInfo); 0152 m_progressDialog->setLabelText(i18n("Uploading %1...", relativeUrl)); 0153 } else if (item->folder()) { 0154 KIO::StatJob *statjob = KIO::stat(dest, KIO::StatJob::DestinationSide, 0); 0155 KJobWidgets::setWindow(statjob, m_progressDialog); 0156 if (statjob->exec()) { 0157 appendLog(i18n("Directory in %1 already exists: %2", 0158 m_uploadProjectModel->currentProfileName(), 0159 relativeUrl)); 0160 m_uploadProjectModel->profileConfigGroup() 0161 .writeEntry(relativeUrl, 0162 QDateTime::currentDateTime()); 0163 uploadNext(); 0164 return; 0165 } else { 0166 appendLog(i18n("Creating directory in %1: %2", 0167 m_uploadProjectModel->currentProfileName(), 0168 relativeUrl)); 0169 qCDebug(KDEVUPLOAD) << "mkdir" << dest; 0170 job = KIO::mkdir(dest); 0171 } 0172 } else { 0173 uploadNext(); 0174 return; 0175 } 0176 0177 KJobWidgets::setWindow(job, m_progressDialog); 0178 connect(job, SIGNAL(result(KJob*)), 0179 this, SLOT(uploadResult(KJob*))); 0180 connect(job, SIGNAL(processedSize(KJob*, qulonglong)), 0181 this, SLOT(processedSize(KJob*, qulonglong))); 0182 connect(job, SIGNAL(infoMessage(KJob*, QString)), 0183 this, SLOT(uploadInfoMessage(KJob*, QString))); 0184 0185 connect(m_progressDialog, SIGNAL(canceled()), 0186 this, SLOT(cancelClicked())); 0187 connect(m_progressDialog, SIGNAL(rejected()), 0188 job, SLOT(kill())); 0189 job->start(); 0190 } 0191 0192 void UploadJob::cancelClicked() 0193 { 0194 appendLog(i18n("Upload canceled")); 0195 deleteLater(); 0196 } 0197 0198 0199 void UploadJob::uploadResult(KJob* job) 0200 { 0201 if (job->error()) { 0202 if (job->error() == KIO::ERR_USER_CANCELED) { 0203 cancelClicked(); 0204 return; 0205 } 0206 appendLog(i18n("Upload error: %1", job->errorString())); 0207 job->uiDelegate()->showErrorMessage(); 0208 deleteLater(); 0209 return; 0210 } 0211 0212 KDevelop::ProjectBaseItem* item = m_uploadProjectModel->item(m_uploadIndex); 0213 QUrl url; 0214 if (item->file()) { 0215 url = item->file()->path().toUrl(); 0216 } else if (item->folder()) { 0217 url = item->folder()->path().toUrl(); 0218 } 0219 m_uploadProjectModel->profileConfigGroup() 0220 .writeEntry(m_project->path().relativePath(KDevelop::Path(url)), QDateTime::currentDateTime()); 0221 m_uploadProjectModel->profileConfigGroup().sync(); 0222 0223 KIO::UDSEntry entry; 0224 KIO::StatJob *statjob = KIO::stat(url, nullptr); 0225 KJobWidgets::setWindow(statjob, m_progressDialog); 0226 if (statjob->exec()) { 0227 entry = statjob->statResult(); 0228 m_progressBytesDone += entry.numberValue(KIO::UDSEntry::UDS_SIZE); 0229 } 0230 m_progressDialog->setValue(m_progressBytesDone); 0231 0232 uploadNext(); 0233 } 0234 0235 void UploadJob::processedSize(KJob*, qulonglong size) 0236 { 0237 m_progressDialog->setValue(m_progressBytesDone + size); 0238 } 0239 0240 void UploadJob::uploadInfoMessage(KJob*, const QString& plain) 0241 { 0242 m_progressDialog->setLabelText(plain); 0243 } 0244 0245 void UploadJob::setOutputModel(QStandardItemModel* model) 0246 { 0247 m_outputModel = model; 0248 } 0249 QStandardItemModel* UploadJob::outputModel() 0250 { 0251 return m_outputModel; 0252 } 0253 QStandardItem* UploadJob::appendLog(const QString& message) 0254 { 0255 if (m_outputModel) { 0256 QStandardItem* item = new QStandardItem(message); 0257 m_outputModel->appendRow(item); 0258 return item; 0259 } else { 0260 return nullptr; 0261 } 0262 } 0263 void UploadJob::setQuickUpload(bool v) 0264 { 0265 m_quickUpload = v; 0266 } 0267 0268 bool UploadJob::isQuickUpload() 0269 { 0270 return m_quickUpload; 0271 } 0272 0273 // kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on