File indexing completed on 2024-04-28 04:37:26
0001 /* 0002 SPDX-FileCopyrightText: 2008 Cédric Pasteur <cedric.pasteur@free.fr> 0003 SPDX-FileCopyrightText: 2009 Andreas Pakulat <apaku@gmx.de> 0004 SPDX-FileCopyrightText: 2017 Friedrich W. H. Kossebau <kossebau@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "sourceformatterjob.h" 0010 0011 #include "sourceformattercontroller.h" 0012 0013 #include <debug.h> 0014 0015 #include <QTextStream> 0016 0017 #include <KIO/StoredTransferJob> 0018 #include <KLocalizedString> 0019 0020 #include <interfaces/icore.h> 0021 #include <interfaces/iuicontroller.h> 0022 #include <interfaces/idocumentcontroller.h> 0023 #include <sublime/message.h> 0024 0025 using namespace KDevelop; 0026 0027 0028 SourceFormatterJob::SourceFormatterJob(SourceFormatterController* sourceFormatterController) 0029 : KJob(sourceFormatterController) 0030 , m_sourceFormatterController(sourceFormatterController) 0031 , m_workState(WorkIdle) 0032 , m_fileIndex(0) 0033 { 0034 setCapabilities(Killable); 0035 // set name for job listing 0036 setObjectName(i18n("Reformatting")); 0037 0038 KDevelop::ICore::self()->uiController()->registerStatus(this); 0039 0040 connect(this, &SourceFormatterJob::finished, this, [this]() { 0041 emit hideProgress(this); 0042 }); 0043 } 0044 0045 QString SourceFormatterJob::statusName() const 0046 { 0047 return i18n("Reformat Files"); 0048 } 0049 0050 void SourceFormatterJob::doWork() 0051 { 0052 // TODO: consider to use ExecuteCompositeJob, with every file a separate subjob 0053 switch (m_workState) { 0054 case WorkIdle: 0055 m_workState = WorkFormat; 0056 m_fileIndex = 0; 0057 emit showProgress(this, 0, 0, 0); 0058 emit showMessage(this, i18np("Reformatting one file", 0059 "Reformatting %1 files", 0060 m_fileList.length())); 0061 0062 QMetaObject::invokeMethod(this, "doWork", Qt::QueuedConnection); 0063 break; 0064 case WorkFormat: 0065 if (m_fileIndex < m_fileList.length()) { 0066 emit showProgress(this, 0, m_fileList.length(), m_fileIndex); 0067 formatFile(m_fileList[m_fileIndex]); 0068 0069 // trigger formatting of next file 0070 ++m_fileIndex; 0071 QMetaObject::invokeMethod(this, "doWork", Qt::QueuedConnection); 0072 } else { 0073 m_workState = WorkIdle; 0074 emitResult(); 0075 } 0076 break; 0077 case WorkCancelled: 0078 break; 0079 } 0080 } 0081 0082 void SourceFormatterJob::start() 0083 { 0084 if (m_workState != WorkIdle) 0085 return; 0086 0087 m_workState = WorkIdle; 0088 0089 QMetaObject::invokeMethod(this, "doWork", Qt::QueuedConnection); 0090 } 0091 0092 bool SourceFormatterJob::doKill() 0093 { 0094 m_workState = WorkCancelled; 0095 return true; 0096 } 0097 0098 void SourceFormatterJob::setFiles(const QList<QUrl>& fileList) 0099 { 0100 m_fileList = fileList; 0101 } 0102 0103 void SourceFormatterJob::formatFile(const QUrl& url) 0104 { 0105 qCDebug(SHELL) << "Checking whether to format file" << url; 0106 SourceFormatterController::FileFormatter ff(url); 0107 if (!ff.readFormatterAndStyle(m_sourceFormatterController->formatters())) { 0108 return; // unsupported MIME type or no configured formatter for it 0109 } 0110 0111 // if the file is opened in the editor, format the text in the editor without saving it 0112 auto doc = ICore::self()->documentController()->documentForUrl(url); 0113 if (doc) { 0114 qCDebug(SHELL) << "Processing file " << url << "opened in editor"; 0115 ff.formatDocument(*doc); 0116 return; 0117 } 0118 0119 qCDebug(SHELL) << "Processing file " << url; 0120 auto getJob = KIO::storedGet(url); 0121 // TODO: make also async and use start() and integrate using setError and setErrorString. 0122 if (getJob->exec()) { 0123 // TODO: really fromLocal8Bit/toLocal8Bit? no encoding detection? added in b8062f736a2bf2eec098af531a7fda6ebcdc7cde 0124 QString text = QString::fromLocal8Bit(getJob->data()); 0125 text = ff.format(text); 0126 text = ff.addModeline(text); 0127 0128 auto putJob = KIO::storedPut(text.toLocal8Bit(), url, -1, KIO::Overwrite); 0129 // see getJob 0130 if (!putJob->exec()) { 0131 auto* message = new Sublime::Message(putJob->errorString(), Sublime::Message::Error); 0132 ICore::self()->uiController()->postMessage(message); 0133 } 0134 } else { 0135 auto* message = new Sublime::Message(getJob->errorString(), Sublime::Message::Error); 0136 ICore::self()->uiController()->postMessage(message); 0137 } 0138 } 0139 0140 #include "moc_sourceformatterjob.cpp"