diff --git a/addons/replicode/replicodeview.cpp b/addons/replicode/replicodeview.cpp index 3a9eca57a..dc1298d9c 100644 --- a/addons/replicode/replicodeview.cpp +++ b/addons/replicode/replicodeview.cpp @@ -1,251 +1,251 @@ /* This file is part of the KDE project Copyright (C) 2014 Martin Sandsmark 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 "replicodeview.h" #include #include #include #include #include "replicodesettings.h" #include "replicodeconfig.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include ReplicodeView::ReplicodeView(KTextEditor::Plugin *plugin, KTextEditor::MainWindow *mainWindow) : QObject(mainWindow) , m_mainWindow(mainWindow) , m_executor(nullptr) { m_runAction = new QAction(QIcon(QStringLiteral("code-block")), i18n("Run replicode"), this); connect(m_runAction, &QAction::triggered, this, &ReplicodeView::runReplicode); actionCollection()->addAction(QStringLiteral("katereplicode_run"), m_runAction); m_stopAction = new QAction(QIcon(QStringLiteral("process-stop")), i18n("Stop replicode"), this); connect(m_stopAction, &QAction::triggered, this, &ReplicodeView::stopReplicode); actionCollection()->addAction(QStringLiteral("katereplicode_stop"), m_stopAction); m_stopAction->setEnabled(false); - m_toolview = m_mainWindow->createToolView(plugin, QStringLiteral("kate_private_plugin_katereplicodeplugin_run"), KTextEditor::MainWindow::Bottom, SmallIcon(QStringLiteral("code-block")), i18n("Replicode Output")); + m_toolview = m_mainWindow->createToolView(plugin, QStringLiteral("kate_private_plugin_katereplicodeplugin_run"), KTextEditor::MainWindow::Bottom, QIcon::fromTheme(QStringLiteral("code-block")), i18n("Replicode Output")); m_replicodeOutput = new QListWidget(m_toolview); m_replicodeOutput->setSelectionMode(QAbstractItemView::ContiguousSelection); connect(m_replicodeOutput, &QListWidget::itemActivated, this, &ReplicodeView::outputClicked); m_mainWindow->hideToolView(m_toolview); - m_configSidebar = m_mainWindow->createToolView(plugin, QStringLiteral("kate_private_plugin_katereplicodeplugin_config"), KTextEditor::MainWindow::Right, SmallIcon(QStringLiteral("code-block")), i18n("Replicode Config")); + m_configSidebar = m_mainWindow->createToolView(plugin, QStringLiteral("kate_private_plugin_katereplicodeplugin_config"), KTextEditor::MainWindow::Right, QIcon::fromTheme(QStringLiteral("code-block")), i18n("Replicode Config")); m_configView = new ReplicodeConfig(m_configSidebar); m_runButton = new QPushButton(i18nc("shortcut for action", "Run (%1)", m_runAction->shortcut().toString())); m_stopButton = new QPushButton(i18nc("shortcut for action", "Stop (%1)", m_stopAction->shortcut().toString())); m_stopButton->setEnabled(false); QFormLayout *l = qobject_cast(m_configView->widget(0)->layout()); Q_ASSERT(l); l->addRow(m_runButton, m_stopButton); connect(m_runButton, &QPushButton::clicked, m_runAction, &QAction::trigger); connect(m_stopButton, &QPushButton::clicked, m_stopAction, &QAction::trigger); m_mainWindow->guiFactory()->addClient(this); connect(m_mainWindow, &KTextEditor::MainWindow::viewChanged, this, &ReplicodeView::viewChanged); } ReplicodeView::~ReplicodeView() { m_mainWindow->guiFactory()->removeClient(this); delete m_executor; } void ReplicodeView::viewChanged() { if (m_mainWindow->activeView() && m_mainWindow->activeView()->document() && m_mainWindow->activeView()->document()->url().fileName().endsWith(QLatin1String(".replicode"))) { m_mainWindow->showToolView(m_configSidebar); } else { m_mainWindow->hideToolView(m_configSidebar); m_mainWindow->hideToolView(m_toolview); } } void ReplicodeView::runReplicode() { m_mainWindow->showToolView(m_toolview); KTextEditor::View *editor = m_mainWindow->activeView(); if (!editor || !editor->document()) { QMessageBox::warning(m_mainWindow->window(), i18nc("@title:window", "Active Document Not Found"), i18n("Could not find an active document to run.")); return; } if (editor->document()->isEmpty()) { QMessageBox::warning(m_mainWindow->window(), i18nc("@title:window", "Empty Document"), i18n("Cannot execute an empty document.")); return; } QFileInfo sourceFile = QFileInfo(editor->document()->url().toLocalFile()); if (!sourceFile.isReadable()) { QMessageBox::warning(m_mainWindow->window(), i18nc("@title:window", "File Not Found"), i18n("Unable to open source file for reading.")); return; } KConfigGroup config(KSharedConfig::openConfig(), QStringLiteral("Replicode")); QString executorPath = config.readEntry("replicodePath", QString()); if (executorPath.isEmpty()) { QMessageBox::warning(m_mainWindow->window(), i18nc("@title:window", "Replicode Executable Not Found"), i18n("Unable to find replicode executor.\n" "Please go to settings and set the path to the Replicode executable.")); return; } if (m_configView->settingsObject()->userOperatorPath.isEmpty()) { QMessageBox::warning(m_mainWindow->window(), i18nc("@title:window", "User Operator Library Not Found"), i18n("Unable to find user operator library.\n" "Please go to settings and set the path to the library.")); } m_configView->settingsObject()->sourcePath = editor->document()->url().toLocalFile(); m_configView->load(); m_configView->settingsObject()->save(); m_replicodeOutput->clear(); if (m_executor) delete m_executor; m_executor = new QProcess(this); m_executor->setWorkingDirectory(sourceFile.canonicalPath()); connect(m_executor, &QProcess::readyReadStandardError, this, &ReplicodeView::gotStderr); connect(m_executor, &QProcess::readyReadStandardOutput, this, &ReplicodeView::gotStdout); connect(m_executor, static_cast(&QProcess::finished), this, &ReplicodeView::replicodeFinished); connect(m_executor, static_cast(&QProcess::error), this, &ReplicodeView::runErrored); qDebug() << executorPath << sourceFile.canonicalPath(); m_completed = false; m_executor->start(executorPath, QStringList(), QProcess::ReadOnly); m_runAction->setEnabled(false); m_runButton->setEnabled(false); m_stopAction->setEnabled(true); m_stopButton->setEnabled(true); } void ReplicodeView::stopReplicode() { if (m_executor) { m_executor->kill(); } } void ReplicodeView::outputClicked(QListWidgetItem *item) { QString output = item->text(); QStringList pieces = output.split(QLatin1Char(':')); if (pieces.length() < 2) return; QFileInfo file(pieces[0]); if (!file.isReadable()) return; bool ok = false; int lineNumber = pieces[1].toInt(&ok); qDebug() << lineNumber; if (!ok) return; KTextEditor::View *doc = m_mainWindow->openUrl(QUrl::fromLocalFile(pieces[0])); doc->setCursorPosition(KTextEditor::Cursor(lineNumber, 0)); qDebug() << doc->cursorPosition().line(); } void ReplicodeView::runErrored(QProcess::ProcessError error) { Q_UNUSED(error); QListWidgetItem *item = new QListWidgetItem(i18n("Replicode execution failed: %1", m_executor->errorString())); item->setForeground(Qt::red); m_replicodeOutput->addItem(item); m_replicodeOutput->scrollToBottom(); m_completed = true; } void ReplicodeView::replicodeFinished() { if (!m_completed) { QListWidgetItem *item = new QListWidgetItem(i18n("Replicode execution finished.")); item->setForeground(Qt::blue); m_replicodeOutput->addItem(item); m_replicodeOutput->scrollToBottom(); } m_runAction->setEnabled(true); m_runButton->setEnabled(true); m_stopAction->setEnabled(false); m_stopButton->setEnabled(false); // delete m_executor; // delete m_settingsFile; // m_executor = 0; // m_settingsFile = 0; } void ReplicodeView::gotStderr() { QByteArray output = m_executor->readAllStandardError(); foreach (QByteArray line, output.split('\n')) { line = line.simplified(); if (line.isEmpty()) continue; QListWidgetItem *item = new QListWidgetItem(QString::fromLocal8Bit(line)); item->setForeground(Qt::red); m_replicodeOutput->addItem(item); } m_replicodeOutput->scrollToBottom(); } void ReplicodeView::gotStdout() { QByteArray output = m_executor->readAllStandardOutput(); foreach (QByteArray line, output.split('\n')) { line = line.simplified(); if (line.isEmpty()) continue; QListWidgetItem *item = new QListWidgetItem(QString::fromLocal8Bit(' ' + line)); if (line[0] == '>') item->setForeground(Qt::gray); m_replicodeOutput->addItem(item); } m_replicodeOutput->scrollToBottom(); } diff --git a/kate/katemwmodonhddialog.cpp b/kate/katemwmodonhddialog.cpp index 6e6b0ba9b..a1a019845 100644 --- a/kate/katemwmodonhddialog.cpp +++ b/kate/katemwmodonhddialog.cpp @@ -1,372 +1,372 @@ /* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. 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. --- Copyright (C) 2004, Anders Lund */ #include "katemwmodonhddialog.h" #include "kateapp.h" #include "katedocmanager.h" #include "katemainwindow.h" #include #include #include #include #include #include #include #include #include #include #include #include class KateDocItem : public QTreeWidgetItem { public: KateDocItem(KTextEditor::Document *doc, const QString &status, QTreeWidget *tw) : QTreeWidgetItem(tw) , document(doc) { setText(0, doc->url().toString()); setText(1, status); if (!doc->isModified()) { setCheckState(0, Qt::Checked); } else { setCheckState(0, Qt::Unchecked); } } ~KateDocItem() override { } KTextEditor::Document *document; }; KateMwModOnHdDialog::KateMwModOnHdDialog(DocVector docs, QWidget *parent, const char *name) : QDialog(parent) , m_proc(nullptr) , m_diffFile(nullptr) , m_blockAddDocument(false) { setWindowTitle(i18n("Documents Modified on Disk")); setObjectName(QString::fromLatin1(name)); setModal(true); QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); // Message QHBoxLayout *hb = new QHBoxLayout; mainLayout->addLayout(hb); // dialog text QLabel *icon = new QLabel(this); hb->addWidget(icon); - icon->setPixmap(DesktopIcon(QStringLiteral("dialog-warning"))); + icon->setPixmap(QIcon::fromTheme(QStringLiteral("dialog-warning")).pixmap(KIconLoader::SizeLarge)); QLabel *t = new QLabel(i18n("The documents listed below have changed on disk.

Select one " "or more at once, and press an action button until the list is empty.

"), this); hb->addWidget(t); hb->setStretchFactor(t, 1000); // Document list twDocuments = new QTreeWidget(this); mainLayout->addWidget(twDocuments); QStringList header; header << i18n("Filename") << i18n("Status on Disk"); twDocuments->setHeaderLabels(header); twDocuments->setSelectionMode(QAbstractItemView::SingleSelection); twDocuments->setRootIsDecorated(false); m_stateTexts << QString() << i18n("Modified") << i18n("Created") << i18n("Deleted"); for (auto &doc : qAsConst(docs)) { new KateDocItem(doc, m_stateTexts[(uint)KateApp::self()->documentManager()->documentInfo(doc)->modifiedOnDiscReason], twDocuments); } twDocuments->header()->setStretchLastSection(false); twDocuments->header()->setSectionResizeMode(0, QHeaderView::Stretch); twDocuments->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); connect(twDocuments, &QTreeWidget::currentItemChanged, this, &KateMwModOnHdDialog::slotSelectionChanged); // Diff line hb = new QHBoxLayout; mainLayout->addLayout(hb); btnDiff = new QPushButton(QIcon::fromTheme(QStringLiteral("document-preview")), i18n("&View Difference"), this); btnDiff->setWhatsThis( i18n("Calculates the difference between the editor contents and the disk " "file for the selected document, and shows the difference with the " "default application. Requires diff(1).")); hb->addWidget(btnDiff); connect(btnDiff, &QPushButton::clicked, this, &KateMwModOnHdDialog::slotDiff); // Dialog buttons QDialogButtonBox *buttons = new QDialogButtonBox(this); mainLayout->addWidget(buttons); QPushButton *ignoreButton = new QPushButton(QIcon::fromTheme(QStringLiteral("dialog-warning")), i18n("&Ignore Changes")); ignoreButton->setToolTip(i18n("Remove modified flag from selected documents")); buttons->addButton(ignoreButton, QDialogButtonBox::RejectRole); connect(ignoreButton, &QPushButton::clicked, this, &KateMwModOnHdDialog::slotIgnore); QPushButton *overwriteButton = new QPushButton; KGuiItem::assign(overwriteButton, KStandardGuiItem::overwrite()); overwriteButton->setToolTip(i18n("Overwrite selected documents, discarding disk changes")); buttons->addButton(overwriteButton, QDialogButtonBox::DestructiveRole); connect(overwriteButton, &QPushButton::clicked, this, &KateMwModOnHdDialog::slotOverwrite); QPushButton *reloadButton = new QPushButton(QIcon::fromTheme(QStringLiteral("view-refresh")), i18n("&Reload")); reloadButton->setDefault(true); reloadButton->setToolTip(i18n("Reload selected documents from disk")); buttons->addButton(reloadButton, QDialogButtonBox::DestructiveRole); connect(reloadButton, &QPushButton::clicked, this, &KateMwModOnHdDialog::slotReload); slotSelectionChanged(nullptr, nullptr); } KateMwModOnHdDialog::~KateMwModOnHdDialog() { KateMainWindow::unsetModifiedOnDiscDialogIfIf(this); if (m_proc) { m_proc->kill(); m_proc->waitForFinished(); delete m_proc; m_proc = Q_NULLPTR; } if (m_diffFile) { m_diffFile->setAutoRemove(true); delete m_diffFile; m_diffFile = Q_NULLPTR; } } void KateMwModOnHdDialog::slotIgnore() { handleSelected(Ignore); } void KateMwModOnHdDialog::slotOverwrite() { handleSelected(Overwrite); } void KateMwModOnHdDialog::slotReload() { handleSelected(Reload); } void KateMwModOnHdDialog::handleSelected(int action) { // don't alter the treewidget via addDocument, we modify it here! m_blockAddDocument = true; // collect all items we can remove QList itemsToDelete; for (QTreeWidgetItemIterator it(twDocuments); *it; ++it) { KateDocItem *item = (KateDocItem *)*it; if (item->checkState(0) == Qt::Checked) { KTextEditor::ModificationInterface::ModifiedOnDiskReason reason = KateApp::self()->documentManager()->documentInfo(item->document)->modifiedOnDiscReason; bool success = true; if (KTextEditor::ModificationInterface *iface = qobject_cast(item->document)) { iface->setModifiedOnDisk(KTextEditor::ModificationInterface::OnDiskUnmodified); } switch (action) { case Overwrite: success = item->document->save(); if (!success) { KMessageBox::sorry(this, i18n("Could not save the document \n'%1'", item->document->url().toString())); } break; case Reload: item->document->documentReload(); break; default: break; } if (success) { itemsToDelete.append(item); } else { if (KTextEditor::ModificationInterface *iface = qobject_cast(item->document)) { iface->setModifiedOnDisk(reason); } } } } // remove the marked items, addDocument is blocked, this is save! for (int i = 0; i < itemsToDelete.count(); ++i) { delete itemsToDelete[i]; } // any documents left unhandled? if (!twDocuments->topLevelItemCount()) { accept(); } // allow addDocument again m_blockAddDocument = false; } void KateMwModOnHdDialog::slotSelectionChanged(QTreeWidgetItem *current, QTreeWidgetItem *) { KateDocItem *currentDocItem = static_cast(current); // set the diff button enabled btnDiff->setEnabled(currentDocItem && KateApp::self()->documentManager()->documentInfo(currentDocItem->document)->modifiedOnDiscReason != KTextEditor::ModificationInterface::OnDiskDeleted); } // ### the code below is slightly modified from kdelibs/kate/part/katedialogs, // class KateModOnHdPrompt. void KateMwModOnHdDialog::slotDiff() { if (!btnDiff->isEnabled()) { // diff button already pressed, proc not finished yet return; } if (!twDocuments->currentItem()) { return; } KTextEditor::Document *doc = (static_cast(twDocuments->currentItem()))->document; // don't try to diff a deleted file if (KateApp::self()->documentManager()->documentInfo(doc)->modifiedOnDiscReason == KTextEditor::ModificationInterface::OnDiskDeleted) { return; } if (m_diffFile) { return; } m_diffFile = new QTemporaryFile(); m_diffFile->open(); // Start a KProcess that creates a diff m_proc = new KProcess(this); m_proc->setOutputChannelMode(KProcess::MergedChannels); *m_proc << QStringLiteral("diff") << QStringLiteral("-ub") << QStringLiteral("-") << doc->url().toLocalFile(); connect(m_proc, &KProcess::readyRead, this, &KateMwModOnHdDialog::slotDataAvailable); connect(m_proc, static_cast(&KProcess::finished), this, &KateMwModOnHdDialog::slotPDone); setCursor(Qt::WaitCursor); btnDiff->setEnabled(false); m_proc->start(); QTextStream ts(m_proc); int lastln = doc->lines() - 1; for (int l = 0; l < lastln; ++l) { ts << doc->line(l) << QLatin1Char('\n'); } ts << doc->line(lastln); ts.flush(); m_proc->closeWriteChannel(); } void KateMwModOnHdDialog::slotDataAvailable() { m_diffFile->write(m_proc->readAll()); } void KateMwModOnHdDialog::slotPDone() { setCursor(Qt::ArrowCursor); slotSelectionChanged(twDocuments->currentItem(), nullptr); const QProcess::ExitStatus es = m_proc->exitStatus(); delete m_proc; m_proc = nullptr; if (es != QProcess::NormalExit) { KMessageBox::sorry(this, i18n("The diff command failed. Please make sure that " "diff(1) is installed and in your PATH."), i18n("Error Creating Diff")); delete m_diffFile; m_diffFile = nullptr; return; } if (m_diffFile->size() == 0) { KMessageBox::information(this, i18n("Ignoring amount of white space changed, the files are identical."), i18n("Diff Output")); delete m_diffFile; m_diffFile = nullptr; return; } m_diffFile->setAutoRemove(false); QUrl url = QUrl::fromLocalFile(m_diffFile->fileName()); delete m_diffFile; m_diffFile = nullptr; // KRun::runUrl should delete the file, once the client exits KRun::runUrl(url, QStringLiteral("text/x-patch"), this, KRun::RunFlags(KRun::DeleteTemporaryFiles)); } void KateMwModOnHdDialog::addDocument(KTextEditor::Document *doc) { // guard this e.g. during handleSelected if (m_blockAddDocument) return; for (QTreeWidgetItemIterator it(twDocuments); *it; ++it) { KateDocItem *item = (KateDocItem *)*it; if (item->document == doc) { delete item; break; } } uint reason = (uint)KateApp::self()->documentManager()->documentInfo(doc)->modifiedOnDiscReason; if (reason) { new KateDocItem(doc, m_stateTexts[reason], twDocuments); } if (!twDocuments->topLevelItemCount()) { accept(); } } void KateMwModOnHdDialog::keyPressEvent(QKeyEvent *event) { if (event->modifiers() == 0) { if (event->key() == Qt::Key_Escape) { event->accept(); return; } } QDialog::keyPressEvent(event); } void KateMwModOnHdDialog::closeEvent(QCloseEvent *e) { if (!twDocuments->topLevelItemCount()) { QDialog::closeEvent(e); } else { e->ignore(); } }