diff --git a/src/swapfile/kateswapdiffcreator.cpp b/src/swapfile/kateswapdiffcreator.cpp index 165e8224..cd9f76ea 100644 --- a/src/swapfile/kateswapdiffcreator.cpp +++ b/src/swapfile/kateswapdiffcreator.cpp @@ -1,164 +1,166 @@ /* This file is part of the Kate project. * * Copyright (C) 2010-2018 Dominik Haumann * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kateswapdiffcreator.h" #include "kateswapfile.h" #include "katedocument.h" #include "katepartdebug.h" -#include #include #include #include #include //BEGIN SwapDiffCreator SwapDiffCreator::SwapDiffCreator(Kate::SwapFile *swapFile) : QObject(swapFile) , m_swapFile(swapFile) - , m_proc(nullptr) { } SwapDiffCreator::~SwapDiffCreator() { } void SwapDiffCreator::viewDiff() { QString path = m_swapFile->fileName(); if (path.isNull()) { return; } QFile swp(path); if (!swp.open(QIODevice::ReadOnly)) { qCWarning(LOG_KTE) << "Can't open swap file"; return; } // create all needed tempfiles m_originalFile.setFileTemplate(QDir::tempPath() + QLatin1String("/katepart_XXXXXX.original")); m_recoveredFile.setFileTemplate(QDir::tempPath() + QLatin1String("/katepart_XXXXXX.recovered")); m_diffFile.setFileTemplate(QDir::tempPath() + QLatin1String("/katepart_XXXXXX.diff")); if (!m_originalFile.open() || !m_recoveredFile.open() || !m_diffFile.open()) { qCWarning(LOG_KTE) << "Can't open temporary files needed for diffing"; return; } // truncate files, just in case m_originalFile.resize(0); m_recoveredFile.resize(0); m_diffFile.resize(0); // create a document with the recovered data KTextEditor::DocumentPrivate recoverDoc; recoverDoc.setText(m_swapFile->document()->text()); // store original text in a file as utf-8 and close it { QTextStream stream(&m_originalFile); stream.setCodec(QTextCodec::codecForName("UTF-8")); stream << recoverDoc.text(); } m_originalFile.close(); // recover data QDataStream stream(&swp); recoverDoc.swapFile()->recover(stream, false); // store recovered text in a file as utf-8 and close it { QTextStream stream(&m_recoveredFile); stream.setCodec(QTextCodec::codecForName("UTF-8")); stream << recoverDoc.text(); } m_recoveredFile.close(); - // create a KProcess proc for diff - m_proc = new KProcess(this); - m_proc->setOutputChannelMode(KProcess::MergedChannels); - *m_proc << QStringLiteral("diff") << QStringLiteral("-u") << m_originalFile.fileName() << m_recoveredFile.fileName(); + // create a process for diff + m_proc.setProcessChannelMode(QProcess::MergedChannels); - connect(m_proc, SIGNAL(readyRead()), this, SLOT(slotDataAvailable())); - connect(m_proc, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(slotDiffFinished())); + connect(&m_proc, SIGNAL(readyRead()), this, SLOT(slotDataAvailable()), Qt::UniqueConnection); + connect(&m_proc, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(slotDiffFinished()), Qt::UniqueConnection); -// setCursor(Qt::WaitCursor); - - m_proc->start(); + // try to start diff process, if we can't be started be done with error + m_proc.start(QStringLiteral("diff"), QStringList() << QStringLiteral("-u") << m_originalFile.fileName() << m_recoveredFile.fileName()); + if (!m_proc.waitForStarted()) { + KMessageBox::sorry(nullptr, + i18n("The diff command could not be started. Please make sure that " + "diff(1) is installed and in your PATH."), + i18n("Error Creating Diff")); + deleteLater(); + return; + } - QTextStream ts(m_proc); + // process is up and running, we can write data to it + QTextStream ts(&m_proc); int lineCount = recoverDoc.lines(); for (int line = 0; line < lineCount; ++line) { ts << recoverDoc.line(line) << '\n'; } ts.flush(); - m_proc->closeWriteChannel(); + m_proc.closeWriteChannel(); } void SwapDiffCreator::slotDataAvailable() { // collect diff output - m_diffFile.write(m_proc->readAll()); + m_diffFile.write(m_proc.readAll()); } void SwapDiffCreator::slotDiffFinished() { // collect last diff output, if any - m_diffFile.write(m_proc->readAll()); + m_diffFile.write(m_proc.readAll()); // get the exit status to check whether diff command run successfully - const QProcess::ExitStatus es = m_proc->exitStatus(); - delete m_proc; - m_proc = nullptr; + const QProcess::ExitStatus es = m_proc.exitStatus(); // check exit status if (es != QProcess::NormalExit) { KMessageBox::sorry(nullptr, i18n("The diff command failed. Please make sure that " "diff(1) is installed and in your PATH."), i18n("Error Creating Diff")); deleteLater(); return; } // sanity check: is there any diff content? if (m_diffFile.size() == 0) { KMessageBox::information(nullptr, i18n("The files are identical."), i18n("Diff Output")); deleteLater(); return; } // close diffFile and avoid removal, KRun will do that later! m_diffFile.close(); m_diffFile.setAutoRemove(false); // KRun::runUrl should delete the file, once the client exits KRun::runUrl(QUrl::fromLocalFile(m_diffFile.fileName()), QStringLiteral("text/x-patch"), m_swapFile->document()->activeView(), KRun::RunFlags(KRun::DeleteTemporaryFiles)); deleteLater(); } //END SwapDiffCreator diff --git a/src/swapfile/kateswapdiffcreator.h b/src/swapfile/kateswapdiffcreator.h index 0f50b5ad..92b200a2 100644 --- a/src/swapfile/kateswapdiffcreator.h +++ b/src/swapfile/kateswapdiffcreator.h @@ -1,61 +1,60 @@ /* This file is part of the Kate project. * * Copyright (C) 2010-2018 Dominik Haumann * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KATE_SWAP_DIFF_CREATOR_H #define KATE_SWAP_DIFF_CREATOR_H #include #include +#include #include -class KProcess; - namespace Kate { class SwapFile; } class SwapDiffCreator : public QObject { Q_OBJECT public: explicit SwapDiffCreator(Kate::SwapFile *swapFile); ~SwapDiffCreator(); public Q_SLOTS: void viewDiff(); private: - Kate::SwapFile *m_swapFile; + Kate::SwapFile * const m_swapFile; protected Q_SLOTS: void slotDataAvailable(); void slotDiffFinished(); private: - KProcess *m_proc; + QProcess m_proc; QTemporaryFile m_originalFile; QTemporaryFile m_recoveredFile; QTemporaryFile m_diffFile; }; #endif //KATE_SWAP_DIFF_CREATOR_H