diff --git a/plugins/appwizard/projectselectionpage.cpp b/plugins/appwizard/projectselectionpage.cpp index 10aa8723c0..aa96abf47f 100644 --- a/plugins/appwizard/projectselectionpage.cpp +++ b/plugins/appwizard/projectselectionpage.cpp @@ -1,365 +1,366 @@ /*************************************************************************** * Copyright 2007 Alexander Dymo * * Copyright 2011 Aleix Pol Gonzalez * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "projectselectionpage.h" #include "debug.h" #include #include #include #include #include #include #include #include "ui_projectselectionpage.h" #include "projecttemplatesmodel.h" #include #include #include #include #include -#include -#include +#include + +using namespace KDevelop; ProjectSelectionPage::ProjectSelectionPage(ProjectTemplatesModel *templatesModel, AppWizardDialog *wizardDialog) : AppWizardPageWidget(wizardDialog), m_templatesModel(templatesModel) { ui = new Ui::ProjectSelectionPage(); ui->setupUi(this); setContentsMargins(0,0,0,0); ui->descriptionContent->setBackgroundRole(QPalette::Base); ui->descriptionContent->setForegroundRole(QPalette::Text); ui->locationUrl->setMode(KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); ui->locationUrl->setUrl(KDevelop::ICore::self()->projectController()->projectsBaseDirectory()); ui->locationValidLabel->setText(QString(" ")); connect( ui->locationUrl->lineEdit(), &KLineEdit::textEdited, this, &ProjectSelectionPage::urlEdited); connect( ui->locationUrl, &KUrlRequester::urlSelected, this, &ProjectSelectionPage::urlEdited); connect( ui->appNameEdit, &QLineEdit::textEdited, this, &ProjectSelectionPage::nameChanged ); m_listView = new KDevelop::MultiLevelListView(this); m_listView->setLevels(2); m_listView->setHeaderLabels(QStringList() << i18n("Category") << i18n("Project Type")); m_listView->setModel(templatesModel); m_listView->setLastModelsFilterBehavior(KSelectionProxyModel::ChildrenOfExactSelection); m_listView->setContentsMargins(0, 0, 0, 0); - connect (m_listView, &KDevelop::MultiLevelListView::currentIndexChanged, this, &ProjectSelectionPage::typeChanged); + connect (m_listView, &MultiLevelListView::currentIndexChanged, this, &ProjectSelectionPage::typeChanged); ui->gridLayout->addWidget(m_listView, 0, 0, 1, 1); typeChanged(m_listView->currentIndex()); connect( ui->templateType, static_cast(&QComboBox::currentIndexChanged), this, &ProjectSelectionPage::templateChanged ); KNS3::Button* knsButton = new KNS3::Button(i18n("Get More Templates"), "kdevappwizard.knsrc", m_listView); connect (knsButton, &KNS3::Button::dialogFinished, this, &ProjectSelectionPage::templatesDownloaded); m_listView->addWidget(0, knsButton); QPushButton* loadButton = new QPushButton(m_listView); loadButton->setText(i18n("Load Template From File")); loadButton->setIcon(QIcon::fromTheme("application-x-archive")); connect (loadButton, &QPushButton::clicked, this, &ProjectSelectionPage::loadFileClicked); m_listView->addWidget(0, loadButton); m_wizardDialog = wizardDialog; } void ProjectSelectionPage::nameChanged() { validateData(); emit locationChanged( location() ); } ProjectSelectionPage::~ProjectSelectionPage() { delete ui; } void ProjectSelectionPage::typeChanged(const QModelIndex& idx) { if (!idx.model()) { qCDebug(PLUGIN_APPWIZARD) << "Index with no model"; return; } int children = idx.model()->rowCount(idx); ui->templateType->setVisible(children); ui->templateType->setEnabled(children > 1); if (children) { ui->templateType->setModel(m_templatesModel); ui->templateType->setRootModelIndex(idx); ui->templateType->setCurrentIndex(0); itemChanged(idx.child(0, 0)); } else { itemChanged(idx); } } void ProjectSelectionPage::templateChanged(int current) { QModelIndex idx=m_templatesModel->index(current, 0, ui->templateType->rootModelIndex()); itemChanged(idx); } void ProjectSelectionPage::itemChanged( const QModelIndex& current) { QString picPath = current.data( KDevelop::TemplatesModel::IconNameRole ).toString(); if( picPath.isEmpty() ) { QIcon icon("kdevelop"); ui->icon->setPixmap(icon.pixmap(128, 128)); ui->icon->setFixedHeight(128); } else { QPixmap pixmap( picPath ); ui->icon->setPixmap( pixmap ); ui->icon->setFixedHeight( pixmap.height() ); } // header name is either from this index directly or the parents if we show the combo box const QVariant headerData = ui->templateType->isVisible() ? current.parent().data() : current.data(); ui->header->setText(QString("

%1

").arg(headerData.toString().trimmed())); ui->description->setText(current.data(KDevelop::TemplatesModel::CommentRole).toString()); validateData(); ui->propertiesBox->setEnabled(true); } QString ProjectSelectionPage::selectedTemplate() { QStandardItem *item = getCurrentItem(); if (item) return item->data().toString(); else return ""; } QUrl ProjectSelectionPage::location() { QUrl url = ui->locationUrl->url().adjusted(QUrl::StripTrailingSlash); url.setPath(url.path() + '/' + encodedAppName()); return url; } QString ProjectSelectionPage::appName() { return ui->appNameEdit->text(); } void ProjectSelectionPage::urlEdited() { validateData(); emit locationChanged( location() ); } void setForeground(QLabel* label, KColorScheme::ForegroundRole role) { QPalette p = label->palette(); KColorScheme::adjustForeground(p, role, label->foregroundRole(), KColorScheme::Window); label->setPalette(p); } void ProjectSelectionPage::validateData() { QUrl url = ui->locationUrl->url(); if( !url.isLocalFile() || url.isEmpty() ) { ui->locationValidLabel->setText( i18n("Invalid location") ); setForeground(ui->locationValidLabel, KColorScheme::NegativeText); emit invalid(); return; } if( appName().isEmpty() ) { ui->locationValidLabel->setText( i18n("Empty project name") ); setForeground(ui->locationValidLabel, KColorScheme::NegativeText); emit invalid(); return; } if( !appName().isEmpty() ) { QString appname = appName(); QString templatefile = m_wizardDialog->appInfo().appTemplate; // Read template file KConfig config(templatefile); KConfigGroup configgroup(&config, "General"); QString pattern = configgroup.readEntry( "ValidProjectName" , "^[a-zA-Z][a-zA-Z0-9_]+$" ); // Validation int pos = 0; QRegExp regex( pattern ); QRegExpValidator validator( regex ); if( validator.validate(appname, pos) == QValidator::Invalid ) { ui->locationValidLabel->setText( i18n("Invalid project name") ); setForeground(ui->locationValidLabel, KColorScheme::NegativeText); emit invalid(); return; } } QDir tDir(url.toLocalFile()); while (!tDir.exists() && !tDir.isRoot()) { if (!tDir.cdUp()) { break; } } if (tDir.exists()) { QFileInfo tFileInfo(tDir.absolutePath()); if (!tFileInfo.isWritable() || !tFileInfo.isExecutable()) { ui->locationValidLabel->setText( i18n("Unable to create subdirectories, " "missing permissions on: %1", tDir.absolutePath()) ); setForeground(ui->locationValidLabel, KColorScheme::NegativeText); emit invalid(); return; } } QStandardItem* item = getCurrentItem(); if( item && !item->hasChildren() ) { ui->locationValidLabel->setText( QString(" ") ); setForeground(ui->locationValidLabel, KColorScheme::NormalText); emit valid(); } else { ui->locationValidLabel->setText( i18n("Invalid project template, please choose a leaf item") ); setForeground(ui->locationValidLabel, KColorScheme::NegativeText); emit invalid(); return; } // Check for non-empty target directory. Not an error, but need to display a warning. url.setPath( url.path() + '/' + encodedAppName() ); QFileInfo fi( url.toLocalFile() ); if( fi.exists() && fi.isDir() ) { if( !QDir( fi.absoluteFilePath()).entryList( QDir::NoDotAndDotDot | QDir::AllEntries ).isEmpty() ) { ui->locationValidLabel->setText( i18n("Path already exists and contains files") ); setForeground(ui->locationValidLabel, KColorScheme::NegativeText); } } } QByteArray ProjectSelectionPage::encodedAppName() { // : < > * ? / \ | " are invalid on windows QByteArray tEncodedName = appName().toUtf8(); for (int i = 0; i < tEncodedName.size(); ++i) { QChar tChar(tEncodedName.at( i )); if (tChar.isDigit() || tChar.isSpace() || tChar.isLetter() || tChar == '%') continue; QByteArray tReplace = QUrl::toPercentEncoding( tChar ); tEncodedName.replace( tEncodedName.at( i ) ,tReplace ); i = i + tReplace.size() - 1; } return tEncodedName; } QStandardItem* ProjectSelectionPage::getCurrentItem() const { QStandardItem* item = m_templatesModel->itemFromIndex( m_listView->currentIndex() ); if ( item && item->hasChildren() ) { const int currect = ui->templateType->currentIndex(); const QModelIndex idx = m_templatesModel->index( currect, 0, ui->templateType->rootModelIndex() ); item = m_templatesModel->itemFromIndex(idx); } return item; } bool ProjectSelectionPage::shouldContinue() { QFileInfo fi(location().toLocalFile()); if (fi.exists() && fi.isDir()) { if (!QDir(fi.absoluteFilePath()).entryList(QDir::NoDotAndDotDot | QDir::AllEntries).isEmpty()) { int res = KMessageBox::questionYesNo(this, i18n("The specified path already exists and contains files. " "Are you sure you want to proceed?")); return res == KMessageBox::Yes; } } return true; } void ProjectSelectionPage::loadFileClicked() { QString filter = "application/x-desktop application/x-bzip-compressed-tar application/zip"; QString fileName = KFileDialog::getOpenFileName(QUrl("kfiledialog:///kdevapptemplate"), filter, this); if (!fileName.isEmpty()) { QString destination = m_templatesModel->loadTemplateFile(fileName); QModelIndexList indexes = m_templatesModel->templateIndexes(destination); if (indexes.size() > 2) { m_listView->setCurrentIndex(indexes.at(1)); ui->templateType->setCurrentIndex(indexes.at(2).row()); } } } void ProjectSelectionPage::templatesDownloaded (const KNS3::Entry::List& entries) { if (entries.isEmpty()) { return; } m_templatesModel->refresh(); bool updated = false; foreach (const KNS3::Entry& entry, entries) { if (!entry.installedFiles().isEmpty()) { updated = true; setCurrentTemplate(entry.installedFiles().first()); break; } } if (!updated) { m_listView->setCurrentIndex(QModelIndex()); } } void ProjectSelectionPage::setCurrentTemplate (const QString& fileName) { QModelIndexList indexes = m_templatesModel->templateIndexes(fileName); if (indexes.size() > 1) { m_listView->setCurrentIndex(indexes.at(1)); } if (indexes.size() > 2) { ui->templateType->setCurrentIndex(indexes.at(2).row()); } } diff --git a/plugins/appwizard/projectvcspage.cpp b/plugins/appwizard/projectvcspage.cpp index 1bb517ba3f..2127caf769 100644 --- a/plugins/appwizard/projectvcspage.cpp +++ b/plugins/appwizard/projectvcspage.cpp @@ -1,152 +1,154 @@ /*************************************************************************** * This file is part of KDevelop * * Copyright 2007 Andreas Pakulat * * * * This program 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 program 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 General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "projectvcspage.h" #include "ui_projectvcspage.h" #include #include #include #include #include #include #include #include +using namespace KDevelop; + ProjectVcsPage::ProjectVcsPage( KDevelop::IPluginController* controller, QWidget * parent ) : AppWizardPageWidget( parent ), m_ui( new Ui::ProjectVcsPage ) { m_ui->setupUi( this ); QList vcsplugins = controller->allPluginsForExtension ( "org.kdevelop.IBasicVersionControl" ); int idx = 1; m_ui->vcsImportOptions->insertWidget( 0, new QWidget(this) ); m_ui->vcsTypes->insertItem( 0, i18nc("No Version Control Support chosen", "None") ); foreach( KDevelop::IPlugin* plugin, vcsplugins ) { KDevelop::IBasicVersionControl* iface = plugin->extension(); if( iface ) { KDevelop::VcsImportMetadataWidget* widget = iface->createImportMetadataWidget( m_ui->vcsImportOptions ); if( widget ) { widget->setSourceLocationEditable( false ); widget->setUseSourceDirForDestination( true ); m_ui->vcsTypes->insertItem( idx, iface->name() ); importWidgets.push_back( widget ); vcsPlugins.push_back( qMakePair( controller->pluginInfo( plugin ).pluginName(), iface->name() ) ); m_ui->vcsImportOptions->insertWidget( idx, widget ); idx++; } } } connect( m_ui->vcsTypes, static_cast(&KComboBox::activated), m_ui->vcsImportOptions, &QStackedWidget::setCurrentIndex ); connect( m_ui->vcsTypes, static_cast(&KComboBox::activated), this, &ProjectVcsPage::vcsTypeChanged ); validateData(); } void ProjectVcsPage::vcsTypeChanged( int idx ) { validateData(); int widgetidx = idx - 1; disconnect( this, static_cast(nullptr), this, &ProjectVcsPage::validateData ); if ( widgetidx < 0 || widgetidx >= importWidgets.size()) return; - connect( importWidgets[widgetidx], &KDevelop::VcsImportMetadataWidget::changed, this, &ProjectVcsPage::validateData ); + connect( importWidgets[widgetidx], &VcsImportMetadataWidget::changed, this, &ProjectVcsPage::validateData ); } void ProjectVcsPage::validateData() { if( shouldContinue() ) { emit valid(); } else { emit invalid(); } } ProjectVcsPage::~ProjectVcsPage( ) { delete m_ui; } void ProjectVcsPage::setSourceLocation( const QUrl& s ) { foreach(KDevelop::VcsImportMetadataWidget* widget, importWidgets) { widget->setSourceLocation( KDevelop::VcsLocation( s ) ); } } QString ProjectVcsPage::pluginName() const { int idx = m_ui->vcsTypes->currentIndex() - 1; if ( idx < 0 || idx >= vcsPlugins.size()) return ""; return vcsPlugins[idx].first; } QString ProjectVcsPage::commitMessage() const { int idx = m_ui->vcsTypes->currentIndex() - 1; if ( idx < 0 || idx >= importWidgets.size()) return QString(); return importWidgets[idx]->message(); } QUrl ProjectVcsPage::source() const { int idx = m_ui->vcsTypes->currentIndex() - 1; if ( idx < 0 || idx >= importWidgets.size()) return QUrl(); return importWidgets[idx]->source(); } KDevelop::VcsLocation ProjectVcsPage::destination() const { int idx = m_ui->vcsTypes->currentIndex() - 1; if ( idx < 0 || idx >= importWidgets.size()) return KDevelop::VcsLocation(); return importWidgets[idx]->destination(); } bool ProjectVcsPage::shouldContinue() { int idx = m_ui->vcsTypes->currentIndex() - 1; if ( idx < 0 || idx >= importWidgets.size()) return true; KDevelop::VcsImportMetadataWidget* widget = importWidgets[idx]; return widget->hasValidData(); } diff --git a/plugins/bazaar/bzrannotatejob.cpp b/plugins/bazaar/bzrannotatejob.cpp index c29c665a50..458977d312 100644 --- a/plugins/bazaar/bzrannotatejob.cpp +++ b/plugins/bazaar/bzrannotatejob.cpp @@ -1,195 +1,197 @@ /*************************************************************************** * Copyright 2013-2014 Maciej Poleski * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 2 of * * the License or (at your option) version 3 or any later version * * accepted by the membership of KDE e.V. (or its successor approved * * by the membership of KDE e.V.), which shall act as a proxy * * defined in Section 14 of version 3 of the license. * * * * This program 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ #include "bzrannotatejob.h" #include #include #include #include #include #include #include #include +using namespace KDevelop; + BzrAnnotateJob::BzrAnnotateJob(const QDir& workingDir, const QString& revisionSpec, const QUrl& localLocation, KDevelop::IPlugin* parent, KDevelop::OutputJob::OutputJobVerbosity verbosity) : VcsJob(parent, verbosity), m_workingDir(workingDir), m_revisionSpec(revisionSpec), m_localLocation(localLocation), m_vcsPlugin(parent), m_status(KDevelop::VcsJob::JobNotStarted) { setType(JobType::Annotate); setCapabilities(Killable); } bool BzrAnnotateJob::doKill() { m_status = KDevelop::VcsJob::JobCanceled; if (m_job) return m_job->kill(KJob::Quietly); else return true; } void BzrAnnotateJob::start() { if (m_status != KDevelop::VcsJob::JobNotStarted) return; - KDevelop::DVcsJob* job = new KDevelop::DVcsJob(m_workingDir, m_vcsPlugin, KDevelop::OutputJob::Silent); + DVcsJob* job = new KDevelop::DVcsJob(m_workingDir, m_vcsPlugin, KDevelop::OutputJob::Silent); *job << "bzr" << "annotate" << "--all" << m_revisionSpec << m_localLocation; - connect(job, &KDevelop::DVcsJob::readyForParsing, this, &BzrAnnotateJob::parseBzrAnnotateOutput); - m_status = KDevelop::VcsJob::JobRunning; + connect(job, &DVcsJob::readyForParsing, this, &BzrAnnotateJob::parseBzrAnnotateOutput); + m_status = VcsJob::JobRunning; m_job = job; job->start(); } void BzrAnnotateJob::parseBzrAnnotateOutput(KDevelop::DVcsJob* job) { m_outputLines = job->output().split('\n'); m_currentLine = 0; if (m_status == KDevelop::VcsJob::JobRunning) QTimer::singleShot(0, this, SLOT(parseNextLine())); } void BzrAnnotateJob::parseNextLine() { for(;;) { Q_ASSERT(m_currentLine<=m_outputLines.size()); if (m_currentLine == m_outputLines.size()) { m_status = KDevelop::VcsJob::JobSucceeded; emitResult(); emit resultsReady(this); break; } QString currentLine = m_outputLines[m_currentLine]; if (currentLine.isEmpty()) { ++m_currentLine; continue; } bool revOk; auto revision = currentLine.left(currentLine.indexOf(' ')).toULong(&revOk); if (!revOk) { // Future compatibility - not a revision yet ++m_currentLine; continue; } auto i = m_commits.find(revision); if (i != m_commits.end()) { KDevelop::VcsAnnotationLine line; line.setAuthor(i.value().author()); line.setCommitMessage(i.value().message()); line.setDate(i.value().date()); line.setLineNumber(m_currentLine); line.setRevision(i.value().revision()); m_results.append(QVariant::fromValue(line)); ++m_currentLine; continue; } else { prepareCommitInfo(revision); break; //Will reenter this function when commit info will be ready } } } void BzrAnnotateJob::prepareCommitInfo(std::size_t revision) { if (m_status != KDevelop::VcsJob::JobRunning) return; KDevelop::DVcsJob* job = new KDevelop::DVcsJob(m_workingDir, m_vcsPlugin, KDevelop::OutputJob::Silent); job->setType(KDevelop::VcsJob::Log); *job << "bzr" << "log" << "--long" << "-r" << QString::number(revision); - connect(job, &KDevelop::DVcsJob::readyForParsing, this, &BzrAnnotateJob::parseBzrLog); + connect(job, &DVcsJob::readyForParsing, this, &BzrAnnotateJob::parseBzrLog); m_job = job; job->start(); } /* * This is slightly different from BazaarUtils::parseBzrLogPart(...). * This function parses only commit general info. It does not parse signle * actions. In fact output parsed by this function is slightly different * from output parsed by BazaarUtils. As a result parsing this output using * BazaarUtils would yield different results. * NOTE: This is all about parsing 'message'. */ void BzrAnnotateJob::parseBzrLog(KDevelop::DVcsJob* job) { QStringList outputLines = job->output().split('\n'); KDevelop::VcsEvent commitInfo; int revision=-1; bool atMessage = false; QString message; for (const QString &line : outputLines) { if (!atMessage) { if (line.startsWith("revno")) { QString revno = line.mid(QString("revno: ").length()); // In future there is possibility that "revno: " will change to // "revno??". If that's all, then we recover matching only // "revno" prefix and assuming placeholder of length 2 (": " or // "??"). // The same below with exception of "commiter" which possibly // can have also some suffix which changes meaning like // "commiter-some_property: "... revno = revno.left(revno.indexOf(' ')); revision = revno.toInt(); KDevelop::VcsRevision revision; revision.setRevisionValue(revno.toLongLong(), KDevelop::VcsRevision::GlobalNumber); commitInfo.setRevision(revision); } else if (line.startsWith("committer: ")) { QString commiter = line.mid(QString("committer: ").length()); commitInfo.setAuthor(commiter); // Author goes after commiter, but only if is different } else if (line.startsWith("author")) { QString author = line.mid(QString("author: ").length()); commitInfo.setAuthor(author); // It may override commiter (In fact commiter is not supported by VcsEvent) } else if (line.startsWith("timestamp")) { const QString formatString = "yyyy-MM-dd hh:mm:ss"; QString timestamp = line.mid(QString("timestamp: ddd ").length(), formatString.length()); commitInfo.setDate(QDateTime::fromString(timestamp, formatString)); } else if (line.startsWith("message")) { atMessage = true; } } else { message += line.trimmed() + "\n"; } } if (atMessage) commitInfo.setMessage(message.trimmed()); Q_ASSERT(revision!=-1); m_commits[revision] = commitInfo; // Invoke from event loop to protect against stack overflow (it could happen // on very big files with very big history of changes if tail-recursion // optimization had failed here). QTimer::singleShot(0, this, SLOT(parseNextLine())); } QVariant BzrAnnotateJob::fetchResults() { return m_results; } KDevelop::VcsJob::JobStatus BzrAnnotateJob::status() const { return m_status; } KDevelop::IPlugin* BzrAnnotateJob::vcsPlugin() const { return m_vcsPlugin; } diff --git a/plugins/bazaar/copyjob.cpp b/plugins/bazaar/copyjob.cpp index 1cfde89393..4d426bd1cb 100644 --- a/plugins/bazaar/copyjob.cpp +++ b/plugins/bazaar/copyjob.cpp @@ -1,98 +1,100 @@ /*************************************************************************** * Copyright 2013-2014 Maciej Poleski * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 2 of * * the License or (at your option) version 3 or any later version * * accepted by the membership of KDE e.V. (or its successor approved * * by the membership of KDE e.V.), which shall act as a proxy * * defined in Section 14 of version 3 of the license. * * * * This program 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ #include "copyjob.h" #include #include #include #include #include "bazaarplugin.h" +using namespace KDevelop; + CopyJob::CopyJob(const QUrl& localLocationSrc, const QUrl& localLocationDstn, BazaarPlugin* parent, KDevelop::OutputJob::OutputJobVerbosity verbosity) : VcsJob(parent, verbosity), m_plugin(parent), m_source(localLocationSrc), m_destination(localLocationDstn), m_status(KDevelop::VcsJob::JobNotStarted) { setType(JobType::Copy); setCapabilities(Killable); } KDevelop::IPlugin* CopyJob::vcsPlugin() const { return m_plugin; } KDevelop::VcsJob::JobStatus CopyJob::status() const { return m_status; } QVariant CopyJob::fetchResults() { return QVariant(); } void CopyJob::start() { if (m_status != KDevelop::VcsJob::JobNotStarted) return; KIO::CopyJob* job = KIO::copy(m_source, m_destination, KIO::HideProgressInfo); connect(job, &KIO::CopyJob::copyingDone, this, &CopyJob::addToVcs); m_status = KDevelop::VcsJob::JobRunning; m_job = job; job->start(); } bool CopyJob::doKill() { m_status = KDevelop::VcsJob::JobCanceled; if (m_job) return m_job->kill(KJob::Quietly); else return true; } void CopyJob::addToVcs(KIO::Job* job, const QUrl& from, const QUrl& to, const QDateTime& mtime, bool directory, bool renamed) { Q_UNUSED(job); Q_UNUSED(from); Q_UNUSED(mtime); Q_UNUSED(directory); Q_UNUSED(renamed); if (m_status != KDevelop::VcsJob::JobRunning) return; KDevelop::VcsJob* job2 = m_plugin->add(QList() << to, KDevelop::IBasicVersionControl::Recursive); - connect(job2, &KDevelop::VcsJob::result, this, &CopyJob::finish); + connect(job2, &VcsJob::result, this, &CopyJob::finish); m_job = job2; job2->start(); } void CopyJob::finish(KJob*) { m_status = KDevelop::VcsJob::JobSucceeded; emitResult(); emit resultsReady(this); } diff --git a/plugins/bazaar/diffjob.cpp b/plugins/bazaar/diffjob.cpp index d0f8af5526..549dc0f6f6 100644 --- a/plugins/bazaar/diffjob.cpp +++ b/plugins/bazaar/diffjob.cpp @@ -1,94 +1,96 @@ /*************************************************************************** * Copyright 2013-2014 Maciej Poleski * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 2 of * * the License or (at your option) version 3 or any later version * * accepted by the membership of KDE e.V. (or its successor approved * * by the membership of KDE e.V.), which shall act as a proxy * * defined in Section 14 of version 3 of the license. * * * * This program 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ #include "diffjob.h" #include #include #include #include "bazaarplugin.h" +using namespace KDevelop; + DiffJob::DiffJob(const QDir& workingDir, const QString& revisionSpecRange, const QUrl& fileOrDirectory, BazaarPlugin* parent, KDevelop::OutputJob::OutputJobVerbosity verbosity) : VcsJob(parent, verbosity), m_plugin(parent), m_status(KDevelop::VcsJob::JobNotStarted) { setType(KDevelop::VcsJob::Diff); setCapabilities(Killable); m_job = new KDevelop::DVcsJob(workingDir, parent, verbosity); m_job->setType(VcsJob::Diff); *m_job << "bzr" << "diff" << "-p1" << revisionSpecRange << fileOrDirectory; } KDevelop::IPlugin* DiffJob::vcsPlugin() const { return m_plugin; } KDevelop::VcsJob::JobStatus DiffJob::status() const { return m_status; } QVariant DiffJob::fetchResults() { return m_result; } void DiffJob::start() { if (m_status != KDevelop::VcsJob::JobNotStarted) return; if (m_job) { - connect(m_job.data(), &KDevelop::DVcsJob::finished, this, &DiffJob::prepareResult); + connect(m_job.data(), &DVcsJob::finished, this, &DiffJob::prepareResult); m_status = KDevelop::VcsJob::JobRunning; m_job->start(); } } bool DiffJob::doKill() { m_status = KDevelop::VcsJob::JobCanceled; if (m_job) return m_job->kill(KJob::Quietly); else return true; } void DiffJob::prepareResult(KJob*) { if (m_job->process()->exitStatus() <= 2) { KDevelop::VcsDiff diff; diff.setDiff(m_job->output()); diff.setBaseDiff(QUrl::fromLocalFile(m_job->directory().absolutePath())); m_result.setValue(diff); m_status = KDevelop::VcsJob::JobSucceeded; } else { setError(m_job->process()->exitStatus()); m_status = KDevelop::VcsJob::JobFailed; } emitResult(); emit resultsReady(this); } diff --git a/plugins/documentview/kdevdocumentview.cpp b/plugins/documentview/kdevdocumentview.cpp index 39899b12cb..a8daf36f5d 100644 --- a/plugins/documentview/kdevdocumentview.cpp +++ b/plugins/documentview/kdevdocumentview.cpp @@ -1,348 +1,350 @@ /* This file is part of KDevelop Copyright 2005 Adam Treat Copyright 2013 Sebastian Kügler 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 "kdevdocumentview.h" #include "kdevdocumentviewplugin.h" #include "kdevdocumentmodel.h" #include #include #include #include #include #include #include #include #include #include #include #include "kdevdocumentselection.h" #include "kdevdocumentviewdelegate.h" #include #include #include #include #include #include #include #include +using namespace KDevelop; + KDevDocumentView::KDevDocumentView( KDevDocumentViewPlugin *plugin, QWidget *parent ) : QTreeView( parent ), m_plugin( plugin ) { - connect(KDevelop::ICore::self()->projectController(), &KDevelop::IProjectController::projectOpened, + connect(ICore::self()->projectController(), &IProjectController::projectOpened, this, &KDevDocumentView::updateProjectPaths); - connect(KDevelop::ICore::self()->projectController(), &KDevelop::IProjectController::projectClosed, + connect(ICore::self()->projectController(), &IProjectController::projectClosed, this, &KDevDocumentView::updateProjectPaths); m_documentModel = new KDevDocumentModel(this); m_delegate = new KDevDocumentViewDelegate( this ); m_proxy = new QSortFilterProxyModel( this ); m_proxy->setSourceModel( m_documentModel ); m_proxy->setDynamicSortFilter( true ); m_proxy->setSortCaseSensitivity( Qt::CaseInsensitive ); m_proxy->sort(0); m_selectionModel = new KDevDocumentSelection( m_proxy ); setModel( m_proxy ); setSelectionModel( m_selectionModel ); setItemDelegate( m_delegate ); setObjectName( i18n( "Documents" ) ); setWindowIcon( QIcon::fromTheme( "document-multiple" ) ); setWindowTitle( i18n( "Documents" ) ); setFocusPolicy( Qt::NoFocus ); header()->hide(); setSelectionBehavior( QAbstractItemView::SelectRows ); setSelectionMode( QAbstractItemView::ExtendedSelection ); } KDevDocumentView::~KDevDocumentView() {} KDevDocumentViewPlugin *KDevDocumentView::plugin() const { return m_plugin; } void KDevDocumentView::mousePressEvent( QMouseEvent * event ) { QModelIndex proxyIndex = indexAt( event->pos() ); QModelIndex index = m_proxy->mapToSource( proxyIndex ); if (event->button() == Qt::LeftButton && event->modifiers() == Qt::NoModifier) { if (proxyIndex.parent().isValid()) { // this is a document item KDevelop::IDocumentController* dc = m_plugin->core()->documentController(); QUrl documentUrl = static_cast(m_documentModel->itemFromIndex(index))->fileItem()->url(); if (dc->documentForUrl(documentUrl) != dc->activeDocument()) { dc->openDocument(documentUrl); return; } } else { // this is a folder item setExpanded(proxyIndex, !isExpanded(proxyIndex)); return; } } QTreeView::mousePressEvent( event ); } template void KDevDocumentView::visitItems(F f, bool selectedItems) { KDevelop::IDocumentController* dc = m_plugin->core()->documentController(); QList docs = selectedItems ? m_selectedDocs : m_unselectedDocs; foreach(const QUrl& url, docs) { KDevelop::IDocument* doc = dc->documentForUrl(url); if (doc) f(doc); } } namespace { class DocSaver { public: void operator()(KDevelop::IDocument* doc) { doc->save(); } }; class DocCloser { public: void operator()(KDevelop::IDocument* doc) { doc->close(); } }; class DocReloader { public: void operator()(KDevelop::IDocument* doc) { doc->reload(); } }; } void KDevDocumentView::saveSelected() { visitItems(DocSaver(), true); } void KDevDocumentView::closeSelected() { visitItems(DocCloser(), true); } void KDevDocumentView::closeUnselected() { visitItems(DocCloser(), false); } void KDevDocumentView::reloadSelected() { visitItems(DocReloader(), true); } void KDevDocumentView::contextMenuEvent( QContextMenuEvent * event ) { QModelIndex proxyIndex = indexAt( event->pos() ); // for now, ignore clicks on empty space or folder items if (!proxyIndex.isValid() || !proxyIndex.parent().isValid()) { return; } updateSelectedDocs(); if (!m_selectedDocs.isEmpty()) { QMenu* ctxMenu = new QMenu(this); KDevelop::FileContext context(m_selectedDocs); QList extensions = m_plugin->core()->pluginController()->queryPluginsForContextMenuExtensions( &context ); QList vcsActions; QList fileActions; QList editActions; QList extensionActions; foreach( const KDevelop::ContextMenuExtension& ext, extensions ) { fileActions += ext.actions(KDevelop::ContextMenuExtension::FileGroup); vcsActions += ext.actions(KDevelop::ContextMenuExtension::VcsGroup); editActions += ext.actions(KDevelop::ContextMenuExtension::EditGroup); extensionActions += ext.actions(KDevelop::ContextMenuExtension::ExtensionGroup); } appendActions(ctxMenu, fileActions); QAction* save = KStandardAction::save(this, SLOT(saveSelected()), ctxMenu); save->setEnabled(selectedDocHasChanges()); ctxMenu->addAction(save); ctxMenu->addAction(QIcon::fromTheme("view-refresh"), i18n( "Reload" ), this, SLOT(reloadSelected())); appendActions(ctxMenu, editActions); ctxMenu->addAction(KStandardAction::close(this, SLOT(closeSelected()), ctxMenu)); QAction* closeUnselected = ctxMenu->addAction(QIcon::fromTheme("document-close"), i18n( "Close Other Files" ), this, SLOT(closeUnselected())); closeUnselected->setEnabled(!m_unselectedDocs.isEmpty()); appendActions(ctxMenu, vcsActions); appendActions(ctxMenu, extensionActions); connect(ctxMenu, &QMenu::aboutToHide, ctxMenu, &QMenu::deleteLater); ctxMenu->popup( event->globalPos() ); } } void KDevDocumentView::appendActions(QMenu* menu, const QList& actions) { foreach( QAction* act, actions ) { menu->addAction(act); } menu->addSeparator(); } bool KDevDocumentView::selectedDocHasChanges() { KDevelop::IDocumentController* dc = m_plugin->core()->documentController(); foreach(const QUrl& url, m_selectedDocs) { KDevelop::IDocument* doc = dc->documentForUrl(url); if (!doc) continue; if (doc->state() != KDevelop::IDocument::Clean) { return true; } } return false; } void KDevDocumentView::updateSelectedDocs() { m_selectedDocs.clear(); m_unselectedDocs.clear(); QList allItems = m_documentModel->findItems("*", Qt::MatchWildcard | Qt::MatchRecursive); foreach (QStandardItem* item, allItems) { if (KDevFileItem * fileItem = dynamic_cast(item)->fileItem()) { if (m_selectionModel->isSelected(m_proxy->mapFromSource(m_documentModel->indexFromItem(fileItem)))) m_selectedDocs << fileItem->url(); else m_unselectedDocs << fileItem->url(); } } } void KDevDocumentView::activated( KDevelop::IDocument* document ) { setCurrentIndex( m_proxy->mapFromSource( m_documentModel->indexFromItem( m_doc2index[ document ] ) ) ); } void KDevDocumentView::saved( KDevelop::IDocument* ) { } void KDevDocumentView::opened( KDevelop::IDocument* document ) { const QString path = QFileInfo( document->url().path() ).path(); KDevCategoryItem *categoryItem = m_documentModel->category( path ); if ( !categoryItem ) { categoryItem = new KDevCategoryItem( path ); categoryItem->setUrl( document->url() ); m_documentModel->insertRow( m_documentModel->rowCount(), categoryItem ); setExpanded( m_proxy->mapFromSource( m_documentModel->indexFromItem( categoryItem ) ), false); updateCategoryItem( categoryItem ); } if ( !categoryItem->file( document->url() ) ) { KDevFileItem * fileItem = new KDevFileItem( document->url() ); categoryItem->setChild( categoryItem->rowCount(), fileItem ); setCurrentIndex( m_proxy->mapFromSource( m_documentModel->indexFromItem( fileItem ) ) ); m_doc2index[ document ] = fileItem; } } void KDevDocumentView::closed( KDevelop::IDocument* document ) { KDevFileItem* file = m_doc2index[ document ]; if ( !file ) return; QStandardItem* categoryItem = file->parent(); qDeleteAll(categoryItem->takeRow(m_documentModel->indexFromItem(file).row())); m_doc2index.remove(document); if ( categoryItem->hasChildren() ) return; qDeleteAll(m_documentModel->takeRow(m_documentModel->indexFromItem(categoryItem).row())); doItemsLayout(); } void KDevDocumentView::updateCategoryItem( KDevCategoryItem *item ) { QString text = KDevelop::ICore::self()->projectController()->prettyFilePath(item->url(), KDevelop::IProjectController::FormatPlain); // remove trailing slash if (text.length() > 1) { text.chop(1); } item->setText(text); } void KDevDocumentView::updateProjectPaths() { foreach ( KDevCategoryItem *it, m_documentModel->categoryList() ) updateCategoryItem( it ); } void KDevDocumentView::contentChanged( KDevelop::IDocument* ) { } void KDevDocumentView::stateChanged( KDevelop::IDocument* document ) { KDevDocumentItem * documentItem = m_doc2index[ document ]; if ( documentItem && documentItem->documentState() != document->state() ) documentItem->setDocumentState( document->state() ); doItemsLayout(); } void KDevDocumentView::documentUrlChanged( KDevelop::IDocument* document ) { closed(document); opened(document); } diff --git a/plugins/documentview/kdevdocumentviewplugin.cpp b/plugins/documentview/kdevdocumentviewplugin.cpp index fd83ef1e5c..6d65e17657 100644 --- a/plugins/documentview/kdevdocumentviewplugin.cpp +++ b/plugins/documentview/kdevdocumentviewplugin.cpp @@ -1,107 +1,109 @@ /* * This file is part of KDevelop * * Copyright 2006 Adam Treat * * This program 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 program 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 General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kdevdocumentviewplugin.h" #include "kdevdocumentview.h" #include "kdevdocumentmodel.h" #include "kdevdocumentselection.h" #include #include #include #include #include #include #include +using namespace KDevelop; + K_PLUGIN_FACTORY_WITH_JSON(KDevDocumentViewFactory, "kdevdocumentview.json", registerPlugin();) class KDevDocumentViewPluginFactory: public KDevelop::IToolViewFactory { public: KDevDocumentViewPluginFactory( KDevDocumentViewPlugin *plugin ): m_plugin( plugin ) {} virtual QWidget* create( QWidget *parent = 0 ) { KDevDocumentView* view = new KDevDocumentView( m_plugin, parent ); KDevelop::IDocumentController* docController = m_plugin->core()->documentController(); foreach(KDevelop::IDocument* doc, docController->openDocuments()) { view->opened( doc ); } - QObject::connect( docController, &KDevelop::IDocumentController::documentActivated, + QObject::connect( docController, &IDocumentController::documentActivated, view, &KDevDocumentView::activated ); - QObject::connect( docController, &KDevelop::IDocumentController::documentSaved, + QObject::connect( docController, &IDocumentController::documentSaved, view, &KDevDocumentView::saved ); - QObject::connect( docController, &KDevelop::IDocumentController::documentOpened, + QObject::connect( docController, &IDocumentController::documentOpened, view, &KDevDocumentView::opened ); - QObject::connect( docController, &KDevelop::IDocumentController::documentClosed, + QObject::connect( docController, &IDocumentController::documentClosed, view, &KDevDocumentView::closed ); QObject::connect( docController, - &KDevelop::IDocumentController::documentContentChanged, + &IDocumentController::documentContentChanged, view, &KDevDocumentView::contentChanged ); QObject::connect( docController, - &KDevelop::IDocumentController::documentStateChanged, + &IDocumentController::documentStateChanged, view, &KDevDocumentView::stateChanged ); QObject::connect( docController, - &KDevelop::IDocumentController::documentUrlChanged, + &IDocumentController::documentUrlChanged, view, &KDevDocumentView::documentUrlChanged ); return view; } virtual Qt::DockWidgetArea defaultPosition() { return Qt::LeftDockWidgetArea; } virtual QString id() const { return "org.kdevelop.DocumentsView"; } private: KDevDocumentViewPlugin* m_plugin; }; KDevDocumentViewPlugin::KDevDocumentViewPlugin( QObject *parent, const QVariantList& args ) : KDevelop::IPlugin( "kdevdocumentview", parent ) { Q_UNUSED( args ); factory = new KDevDocumentViewPluginFactory( this ); core()->uiController()->addToolView( i18n("Documents"), factory ); setXMLFile( "kdevdocumentview.rc" ); } KDevDocumentViewPlugin::~KDevDocumentViewPlugin() { } void KDevDocumentViewPlugin::unload() { core()->uiController()->removeToolView( factory ); } #include "kdevdocumentviewplugin.moc" diff --git a/plugins/execute/nativeappconfig.cpp b/plugins/execute/nativeappconfig.cpp index 77beb0ddbd..a1070715cc 100644 --- a/plugins/execute/nativeappconfig.cpp +++ b/plugins/execute/nativeappconfig.cpp @@ -1,522 +1,524 @@ /* This file is part of KDevelop Copyright 2009 Andreas Pakulat Copyright 2010 Aleix Pol Gonzalez 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 "nativeappconfig.h" #include #include #include #include #include #include #include "nativeappjob.h" #include #include #include #include #include #include #include #include #include #include #include "executeplugin.h" #include "debug.h" #include #include #include #include "projecttargetscombobox.h" #include #include #include #include #include #include #include +using namespace KDevelop; + QIcon NativeAppConfigPage::icon() const { return QIcon::fromTheme("system-run"); } static KDevelop::ProjectBaseItem* itemForPath(const QStringList& path, KDevelop::ProjectModel* model) { return model->itemFromIndex(model->pathToIndex(path)); } //TODO: Make sure to auto-add the executable target to the dependencies when its used. void NativeAppConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject* project ) { bool b = blockSignals( true ); projectTarget->setBaseItem( project ? project->projectItem() : 0, true); projectTarget->setCurrentItemPath( cfg.readEntry( ExecutePlugin::projectTargetEntry, QStringList() ) ); QUrl exe = cfg.readEntry( ExecutePlugin::executableEntry, QUrl()); if( !exe.isEmpty() || project ){ executablePath->setUrl( !exe.isEmpty() ? exe : project->folder() ); }else{ KDevelop::IProjectController* pc = KDevelop::ICore::self()->projectController(); if( pc ){ executablePath->setUrl( pc->projects().count() ? pc->projects().first()->folder() : QUrl() ); } } //executablePath->setFilter("application/x-executable"); executableRadio->setChecked( true ); if ( !cfg.readEntry( ExecutePlugin::isExecutableEntry, false ) && projectTarget->count() ){ projectTargetRadio->setChecked( true ); } arguments->setClearButtonEnabled( true ); arguments->setText( cfg.readEntry( ExecutePlugin::argumentsEntry, "" ) ); workingDirectory->setUrl( cfg.readEntry( ExecutePlugin::workingDirEntry, QUrl() ) ); environment->setCurrentProfile( cfg.readEntry( ExecutePlugin::environmentGroupEntry, QString() ) ); runInTerminal->setChecked( cfg.readEntry( ExecutePlugin::useTerminalEntry, false ) ); terminal->setEditText( cfg.readEntry( ExecutePlugin::terminalEntry, terminal->itemText(0) ) ); QVariantList deps = KDevelop::stringToQVariant( cfg.readEntry( ExecutePlugin::dependencyEntry, QString() ) ).toList(); QStringList strDeps; foreach( const QVariant& dep, deps ) { QStringList deplist = dep.toStringList(); KDevelop::ProjectModel* model = KDevelop::ICore::self()->projectController()->projectModel(); KDevelop::ProjectBaseItem* pitem=itemForPath(deplist, model); QIcon icon; if(pitem) icon=QIcon::fromTheme(pitem->iconName()); QListWidgetItem* item = new QListWidgetItem(icon, KDevelop::joinWithEscaping( deplist, '/', '\\' ), dependencies ); item->setData( Qt::UserRole, dep ); } dependencyAction->setCurrentIndex( dependencyAction->findData( cfg.readEntry( ExecutePlugin::dependencyActionEntry, "Nothing" ) ) ); blockSignals( b ); } NativeAppConfigPage::NativeAppConfigPage( QWidget* parent ) : LaunchConfigurationPage( parent ) { setupUi(this); //Setup data info for combobox dependencyAction->setItemData(0, "Nothing" ); dependencyAction->setItemData(1, "Build" ); dependencyAction->setItemData(2, "Install" ); dependencyAction->setItemData(3, "SudoInstall" ); addDependency->setIcon( QIcon::fromTheme("list-add") ); removeDependency->setIcon( QIcon::fromTheme("list-remove") ); moveDepUp->setIcon( QIcon::fromTheme("go-up") ); moveDepDown->setIcon( QIcon::fromTheme("go-down") ); browseProject->setIcon(QIcon::fromTheme("folder-document")); //Set workingdirectory widget to ask for directories rather than files workingDirectory->setMode(KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly); configureEnvironment->setSelectionWidget(environment); //connect signals to changed signal connect( projectTarget, static_cast(&ProjectTargetsComboBox::currentIndexChanged), this, &NativeAppConfigPage::changed ); connect( projectTargetRadio, &QRadioButton::toggled, this, &NativeAppConfigPage::changed ); connect( executableRadio, &QRadioButton::toggled, this, &NativeAppConfigPage::changed ); connect( executablePath->lineEdit(), &KLineEdit::textEdited, this, &NativeAppConfigPage::changed ); connect( executablePath, &KUrlRequester::urlSelected, this, &NativeAppConfigPage::changed ); connect( arguments, &QLineEdit::textEdited, this, &NativeAppConfigPage::changed ); connect( workingDirectory, &KUrlRequester::urlSelected, this, &NativeAppConfigPage::changed ); connect( workingDirectory->lineEdit(), &KLineEdit::textEdited, this, &NativeAppConfigPage::changed ); - connect( environment, &KDevelop::EnvironmentSelectionWidget::currentProfileChanged, this, &NativeAppConfigPage::changed ); + connect( environment, &EnvironmentSelectionWidget::currentProfileChanged, this, &NativeAppConfigPage::changed ); connect( addDependency, &QPushButton::clicked, this, &NativeAppConfigPage::addDep ); connect( addDependency, &QPushButton::clicked, this, &NativeAppConfigPage::changed ); connect( removeDependency, &QPushButton::clicked, this, &NativeAppConfigPage::changed ); connect( removeDependency, &QPushButton::clicked, this, &NativeAppConfigPage::removeDep ); connect( moveDepDown, &QPushButton::clicked, this, &NativeAppConfigPage::changed ); connect( moveDepUp, &QPushButton::clicked, this, &NativeAppConfigPage::changed ); connect( moveDepDown, &QPushButton::clicked, this, &NativeAppConfigPage::moveDependencyDown ); connect( moveDepUp, &QPushButton::clicked, this, &NativeAppConfigPage::moveDependencyUp ); connect( dependencies->selectionModel(), &QItemSelectionModel::selectionChanged, this, &NativeAppConfigPage::checkActions ); connect( dependencyAction, static_cast(&KComboBox::currentIndexChanged), this, &NativeAppConfigPage::changed ); connect( runInTerminal, &QCheckBox::toggled, this, &NativeAppConfigPage::changed ); connect( terminal, &KComboBox::editTextChanged, this, &NativeAppConfigPage::changed ); connect( terminal, static_cast(&KComboBox::currentIndexChanged), this, &NativeAppConfigPage::changed ); connect( dependencyAction, static_cast(&KComboBox::currentIndexChanged), this, &NativeAppConfigPage::activateDeps ); connect( targetDependency, &ProjectItemLineEdit::textChanged, this, &NativeAppConfigPage::depEdited); connect( browseProject, &QPushButton::clicked, this, &NativeAppConfigPage::selectItemDialog); } void NativeAppConfigPage::depEdited( const QString& str ) { int pos; QString tmp = str; addDependency->setEnabled( !str.isEmpty() && ( !targetDependency->validator() || targetDependency->validator()->validate( tmp, pos ) == QValidator::Acceptable ) ); } void NativeAppConfigPage::activateDeps( int idx ) { browseProject->setEnabled( dependencyAction->itemData( idx ).toString() != "Nothing" ); dependencies->setEnabled( dependencyAction->itemData( idx ).toString() != "Nothing" ); targetDependency->setEnabled( dependencyAction->itemData( idx ).toString() != "Nothing" ); } void NativeAppConfigPage::checkActions( const QItemSelection& selected, const QItemSelection& unselected ) { Q_UNUSED( unselected ); qCDebug(PLUGIN_EXECUTE) << "checkActions"; if( !selected.indexes().isEmpty() ) { qCDebug(PLUGIN_EXECUTE) << "have selection"; Q_ASSERT( selected.indexes().count() == 1 ); QModelIndex idx = selected.indexes().at( 0 ); qCDebug(PLUGIN_EXECUTE) << "index" << idx; moveDepUp->setEnabled( idx.row() > 0 ); moveDepDown->setEnabled( idx.row() < dependencies->count() - 1 ); removeDependency->setEnabled( true ); } else { removeDependency->setEnabled( false ); moveDepUp->setEnabled( false ); moveDepDown->setEnabled( false ); } } void NativeAppConfigPage::moveDependencyDown() { QList list = dependencies->selectedItems(); if( !list.isEmpty() ) { Q_ASSERT( list.count() == 1 ); QListWidgetItem* item = list.at( 0 ); int row = dependencies->row( item ); dependencies->takeItem( row ); dependencies->insertItem( row+1, item ); dependencies->selectionModel()->select( dependencies->model()->index( row+1, 0, QModelIndex() ), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::SelectCurrent ); } } void NativeAppConfigPage::moveDependencyUp() { QList list = dependencies->selectedItems(); if( !list.isEmpty() ) { Q_ASSERT( list.count() == 1 ); QListWidgetItem* item = list.at( 0 ); int row = dependencies->row( item ); dependencies->takeItem( row ); dependencies->insertItem( row-1, item ); dependencies->selectionModel()->select( dependencies->model()->index( row-1, 0, QModelIndex() ), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::SelectCurrent ); } } void NativeAppConfigPage::addDep() { QIcon icon; KDevelop::ProjectBaseItem* pitem = targetDependency->currentItem(); if(pitem) icon = QIcon::fromTheme(pitem->iconName()); QListWidgetItem* item = new QListWidgetItem(icon, targetDependency->text(), dependencies); item->setData( Qt::UserRole, targetDependency->itemPath() ); targetDependency->setText(""); addDependency->setEnabled( false ); dependencies->selectionModel()->clearSelection(); item->setSelected(true); // dependencies->selectionModel()->select( dependencies->model()->index( dependencies->model()->rowCount() - 1, 0, QModelIndex() ), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::SelectCurrent ); } void NativeAppConfigPage::selectItemDialog() { if(targetDependency->selectItemDialog()) { addDep(); } } void NativeAppConfigPage::removeDep() { QList list = dependencies->selectedItems(); if( !list.isEmpty() ) { Q_ASSERT( list.count() == 1 ); int row = dependencies->row( list.at(0) ); delete dependencies->takeItem( row ); dependencies->selectionModel()->select( dependencies->model()->index( row - 1, 0, QModelIndex() ), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::SelectCurrent ); } } void NativeAppConfigPage::saveToConfiguration( KConfigGroup cfg, KDevelop::IProject* project ) const { Q_UNUSED( project ); cfg.writeEntry( ExecutePlugin::isExecutableEntry, executableRadio->isChecked() ); cfg.writeEntry( ExecutePlugin::executableEntry, executablePath->url() ); cfg.writeEntry( ExecutePlugin::projectTargetEntry, projectTarget->currentItemPath() ); cfg.writeEntry( ExecutePlugin::argumentsEntry, arguments->text() ); cfg.writeEntry( ExecutePlugin::workingDirEntry, workingDirectory->url() ); cfg.writeEntry( ExecutePlugin::environmentGroupEntry, environment->currentProfile() ); cfg.writeEntry( ExecutePlugin::useTerminalEntry, runInTerminal->isChecked() ); cfg.writeEntry( ExecutePlugin::terminalEntry, terminal->currentText() ); cfg.writeEntry( ExecutePlugin::dependencyActionEntry, dependencyAction->itemData( dependencyAction->currentIndex() ).toString() ); QVariantList deps; for( int i = 0; i < dependencies->count(); i++ ) { deps << dependencies->item( i )->data( Qt::UserRole ); } cfg.writeEntry( ExecutePlugin::dependencyEntry, KDevelop::qvariantToString( QVariant( deps ) ) ); } QString NativeAppConfigPage::title() const { return i18n("Configure Native Application"); } QList< KDevelop::LaunchConfigurationPageFactory* > NativeAppLauncher::configPages() const { return QList(); } QString NativeAppLauncher::description() const { return "Executes Native Applications"; } QString NativeAppLauncher::id() { return "nativeAppLauncher"; } QString NativeAppLauncher::name() const { return i18n("Native Application"); } NativeAppLauncher::NativeAppLauncher() { } KJob* NativeAppLauncher::start(const QString& launchMode, KDevelop::ILaunchConfiguration* cfg) { Q_ASSERT(cfg); if( !cfg ) { return 0; } if( launchMode == "execute" ) { IExecutePlugin* iface = KDevelop::ICore::self()->pluginController()->pluginForExtension("org.kdevelop.IExecutePlugin", "kdevexecute")->extension(); Q_ASSERT(iface); KJob* depjob = iface->dependecyJob( cfg ); QList l; if( depjob ) { l << depjob; } l << new NativeAppJob( KDevelop::ICore::self()->runController(), cfg ); return new KDevelop::ExecuteCompositeJob( KDevelop::ICore::self()->runController(), l ); } qWarning() << "Unknown launch mode " << launchMode << "for config:" << cfg->name(); return 0; } QStringList NativeAppLauncher::supportedModes() const { return QStringList() << "execute"; } KDevelop::LaunchConfigurationPage* NativeAppPageFactory::createWidget(QWidget* parent) { return new NativeAppConfigPage( parent ); } NativeAppPageFactory::NativeAppPageFactory() { } NativeAppConfigType::NativeAppConfigType() { factoryList.append( new NativeAppPageFactory() ); } NativeAppConfigType::~NativeAppConfigType() { qDeleteAll(factoryList); factoryList.clear(); } QString NativeAppConfigType::name() const { return i18n("Compiled Binary"); } QList NativeAppConfigType::configPages() const { return factoryList; } QString NativeAppConfigType::id() const { return ExecutePlugin::_nativeAppConfigTypeId; } QIcon NativeAppConfigType::icon() const { return QIcon::fromTheme("application-x-executable"); } bool NativeAppConfigType::canLaunch ( KDevelop::ProjectBaseItem* item ) const { if( item->target() && item->target()->executable() ) { return canLaunch( item->target()->executable()->builtUrl() ); } return false; } bool NativeAppConfigType::canLaunch ( const QUrl& file ) const { return ( file.isLocalFile() && QFileInfo( file.toLocalFile() ).isExecutable() ); } void NativeAppConfigType::configureLaunchFromItem ( KConfigGroup cfg, KDevelop::ProjectBaseItem* item ) const { cfg.writeEntry( ExecutePlugin::isExecutableEntry, false ); KDevelop::ProjectModel* model = KDevelop::ICore::self()->projectController()->projectModel(); cfg.writeEntry( ExecutePlugin::projectTargetEntry, model->pathFromIndex( model->indexFromItem( item ) ) ); cfg.writeEntry( ExecutePlugin::workingDirEntry, item->executable()->builtUrl().adjusted(QUrl::RemoveFilename) ); cfg.sync(); } void NativeAppConfigType::configureLaunchFromCmdLineArguments ( KConfigGroup cfg, const QStringList& args ) const { cfg.writeEntry( ExecutePlugin::isExecutableEntry, true ); Q_ASSERT(QFile::exists(args.first())); // TODO: we probably want to flexibilize, but at least we won't be accepting wrong values anymore cfg.writeEntry( ExecutePlugin::executableEntry, QUrl::fromLocalFile(args.first()) ); QStringList a(args); a.removeFirst(); cfg.writeEntry( ExecutePlugin::argumentsEntry, KShell::joinArgs(a) ); cfg.sync(); } QList targetsInFolder(KDevelop::ProjectFolderItem* folder) { QList ret; foreach(KDevelop::ProjectFolderItem* f, folder->folderList()) ret += targetsInFolder(f); ret += folder->targetList(); return ret; } bool actionLess(QAction* a, QAction* b) { return a->text() < b->text(); } bool menuLess(QMenu* a, QMenu* b) { return a->title() < b->title(); } QMenu* NativeAppConfigType::launcherSuggestions() { QMenu* ret = new QMenu(i18n("Project Executables")); KDevelop::ProjectModel* model = KDevelop::ICore::self()->projectController()->projectModel(); QList projects = KDevelop::ICore::self()->projectController()->projects(); foreach(KDevelop::IProject* project, projects) { if(project->projectFileManager()->features() & KDevelop::IProjectFileManager::Targets) { QList targets=targetsInFolder(project->projectItem()); QHash > targetsContainer; QMenu* projectMenu = ret->addMenu(QIcon::fromTheme("project-development"), project->name()); foreach(KDevelop::ProjectTargetItem* target, targets) { if(target->executable()) { QStringList path = model->pathFromIndex(target->index()); if(!path.isEmpty()){ QAction* act = new QAction(projectMenu); act->setData(KDevelop::joinWithEscaping(path, '/','\\')); act->setProperty("name", target->text()); path.removeFirst(); act->setText(path.join("/")); act->setIcon(QIcon::fromTheme("system-run")); connect(act, &QAction::triggered, this, &NativeAppConfigType::suggestionTriggered); targetsContainer[target->parent()].append(act); } } } QList separateActions; QList submenus; foreach(KDevelop::ProjectBaseItem* folder, targetsContainer.keys()) { QList actions = targetsContainer.value(folder); if(actions.size()==1 || !folder->parent()) { separateActions += actions.first(); } else { foreach(QAction* a, actions) { a->setText(a->property("name").toString()); } QStringList path = model->pathFromIndex(folder->index()); path.removeFirst(); QMenu* submenu = new QMenu(path.join("/")); submenu->addActions(actions); submenus += submenu; } } std::sort(separateActions.begin(), separateActions.end(), actionLess); std::sort(submenus.begin(), submenus.end(), menuLess); foreach(QMenu* m, submenus) projectMenu->addMenu(m); projectMenu->addActions(separateActions); projectMenu->setEnabled(!projectMenu->isEmpty()); } } return ret; } void NativeAppConfigType::suggestionTriggered() { QAction* action = qobject_cast(sender()); KDevelop::ProjectModel* model = KDevelop::ICore::self()->projectController()->projectModel(); KDevelop::ProjectTargetItem* pitem = dynamic_cast(itemForPath(KDevelop::splitWithEscaping(action->data().toString(),'/', '\\'), model)); if(pitem) { QPair launcher = qMakePair( launchers().at( 0 )->supportedModes().at(0), launchers().at( 0 )->id() ); KDevelop::IProject* p = pitem->project(); KDevelop::ILaunchConfiguration* config = KDevelop::ICore::self()->runController()->createLaunchConfiguration(this, launcher, p, pitem->text()); KConfigGroup cfg = config->config(); QStringList splitPath = model->pathFromIndex(pitem->index()); // QString path = KDevelop::joinWithEscaping(splitPath,'/','\\'); cfg.writeEntry( ExecutePlugin::projectTargetEntry, splitPath ); cfg.writeEntry( ExecutePlugin::dependencyEntry, KDevelop::qvariantToString( QVariantList() << splitPath ) ); cfg.writeEntry( ExecutePlugin::dependencyActionEntry, "Build" ); cfg.sync(); emit signalAddLaunchConfiguration(config); } } diff --git a/plugins/executescript/scriptappconfig.cpp b/plugins/executescript/scriptappconfig.cpp index e4375ea6a9..947cc464a4 100644 --- a/plugins/executescript/scriptappconfig.cpp +++ b/plugins/executescript/scriptappconfig.cpp @@ -1,255 +1,257 @@ /* This file is part of KDevelop Copyright 2009 Andreas Pakulat Copyright 2009 Niko Sams 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 "scriptappconfig.h" #include #include #include #include #include #include #include #include #include #include "scriptappjob.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "executescriptplugin.h" #include #include #include +using namespace KDevelop; + static const QString interpreterForUrl(const QUrl& url) { auto mimetype = QMimeDatabase().mimeTypeForUrl(url); static QHash knownMimetypes; if ( knownMimetypes.isEmpty() ) { knownMimetypes["text/x-python"] = "python"; knownMimetypes["application/x-php"] = "php"; knownMimetypes["application/x-ruby"] = "ruby"; knownMimetypes["application/x-shellscript"] = "bash"; knownMimetypes["application/x-perl"] = "perl -e"; } const QString& interp = knownMimetypes.value(mimetype.name()); return interp; } QIcon ScriptAppConfigPage::icon() const { return QIcon::fromTheme("system-run"); } void ScriptAppConfigPage::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject* project ) { bool b = blockSignals( true ); if( project ) { executablePath->setStartDir( project->folder() ); } auto doc = KDevelop::ICore::self()->documentController()->activeDocument(); interpreter->lineEdit()->setText( cfg.readEntry( ExecuteScriptPlugin::interpreterEntry, doc ? interpreterForUrl(doc->url()) : "" ) ); executablePath->setUrl( QUrl::fromLocalFile(cfg.readEntry( ExecuteScriptPlugin::executableEntry, QString() )) ); remoteHostCheckbox->setChecked( cfg.readEntry( ExecuteScriptPlugin::executeOnRemoteHostEntry, false ) ); remoteHost->setText( cfg.readEntry( ExecuteScriptPlugin::remoteHostEntry, "" ) ); bool runCurrent = cfg.readEntry( ExecuteScriptPlugin::runCurrentFileEntry, true ); if ( runCurrent ) { runCurrentFile->setChecked( true ); } else { runFixedFile->setChecked( true ); } arguments->setText( cfg.readEntry( ExecuteScriptPlugin::argumentsEntry, "" ) ); workingDirectory->setUrl( cfg.readEntry( ExecuteScriptPlugin::workingDirEntry, QUrl() ) ); environment->setCurrentProfile( cfg.readEntry( ExecuteScriptPlugin::environmentGroupEntry, QString() ) ); outputFilteringMode->setCurrentIndex( cfg.readEntry( ExecuteScriptPlugin::outputFilteringEntry, 2u )); //runInTerminal->setChecked( cfg.readEntry( ExecuteScriptPlugin::useTerminalEntry, false ) ); blockSignals( b ); } ScriptAppConfigPage::ScriptAppConfigPage( QWidget* parent ) : LaunchConfigurationPage( parent ) { setupUi(this); interpreter->lineEdit()->setPlaceholderText(i18n("Type or select an interpreter")); //Set workingdirectory widget to ask for directories rather than files workingDirectory->setMode(KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly); //connect signals to changed signal connect( interpreter->lineEdit(), &QLineEdit::textEdited, this, &ScriptAppConfigPage::changed ); connect( executablePath->lineEdit(), &KLineEdit::textEdited, this, &ScriptAppConfigPage::changed ); connect( executablePath, &KUrlRequester::urlSelected, this, &ScriptAppConfigPage::changed ); connect( arguments, &QLineEdit::textEdited, this, &ScriptAppConfigPage::changed ); connect( workingDirectory, &KUrlRequester::urlSelected, this, &ScriptAppConfigPage::changed ); connect( workingDirectory->lineEdit(), &KLineEdit::textEdited, this, &ScriptAppConfigPage::changed ); - connect( environment, &KDevelop::EnvironmentSelectionWidget::currentProfileChanged, this, &ScriptAppConfigPage::changed ); + connect( environment, &EnvironmentSelectionWidget::currentProfileChanged, this, &ScriptAppConfigPage::changed ); //connect( runInTerminal, SIGNAL(toggled(bool)), SIGNAL(changed()) ); } void ScriptAppConfigPage::saveToConfiguration( KConfigGroup cfg, KDevelop::IProject* project ) const { Q_UNUSED( project ); cfg.writeEntry( ExecuteScriptPlugin::interpreterEntry, interpreter->lineEdit()->text() ); cfg.writeEntry( ExecuteScriptPlugin::executableEntry, executablePath->url() ); cfg.writeEntry( ExecuteScriptPlugin::executeOnRemoteHostEntry, remoteHostCheckbox->isChecked() ); cfg.writeEntry( ExecuteScriptPlugin::remoteHostEntry, remoteHost->text() ); cfg.writeEntry( ExecuteScriptPlugin::runCurrentFileEntry, runCurrentFile->isChecked() ); cfg.writeEntry( ExecuteScriptPlugin::argumentsEntry, arguments->text() ); cfg.writeEntry( ExecuteScriptPlugin::workingDirEntry, workingDirectory->url() ); cfg.writeEntry( ExecuteScriptPlugin::environmentGroupEntry, environment->currentProfile() ); cfg.writeEntry( ExecuteScriptPlugin::outputFilteringEntry, outputFilteringMode->currentIndex() ); //cfg.writeEntry( ExecuteScriptPlugin::useTerminalEntry, runInTerminal->isChecked() ); } QString ScriptAppConfigPage::title() const { return i18n("Configure Script Application"); } QList< KDevelop::LaunchConfigurationPageFactory* > ScriptAppLauncher::configPages() const { return QList(); } QString ScriptAppLauncher::description() const { return i18n("Executes Script Applications"); } QString ScriptAppLauncher::id() { return "scriptAppLauncher"; } QString ScriptAppLauncher::name() const { return i18n("Script Application"); } ScriptAppLauncher::ScriptAppLauncher(ExecuteScriptPlugin* plugin) : m_plugin( plugin ) { } KJob* ScriptAppLauncher::start(const QString& launchMode, KDevelop::ILaunchConfiguration* cfg) { Q_ASSERT(cfg); if( !cfg ) { return 0; } if( launchMode == "execute" ) { return new ScriptAppJob( m_plugin, cfg); } qWarning() << "Unknown launch mode " << launchMode << "for config:" << cfg->name(); return 0; } QStringList ScriptAppLauncher::supportedModes() const { return QStringList() << "execute"; } KDevelop::LaunchConfigurationPage* ScriptAppPageFactory::createWidget(QWidget* parent) { return new ScriptAppConfigPage( parent ); } ScriptAppPageFactory::ScriptAppPageFactory() { } ScriptAppConfigType::ScriptAppConfigType() { factoryList.append( new ScriptAppPageFactory() ); } ScriptAppConfigType::~ScriptAppConfigType() { qDeleteAll(factoryList); factoryList.clear(); } QString ScriptAppConfigType::name() const { return i18n("Script Application"); } QList ScriptAppConfigType::configPages() const { return factoryList; } QString ScriptAppConfigType::id() const { return ExecuteScriptPlugin::_scriptAppConfigTypeId; } QIcon ScriptAppConfigType::icon() const { return QIcon::fromTheme("preferences-plugin-script"); } bool ScriptAppConfigType::canLaunch(const QUrl& file) const { return ! interpreterForUrl(file).isEmpty(); } bool ScriptAppConfigType::canLaunch(KDevelop::ProjectBaseItem* item) const { return ! interpreterForUrl(item->path().toUrl()).isEmpty(); } void ScriptAppConfigType::configureLaunchFromItem(KConfigGroup config, KDevelop::ProjectBaseItem* item) const { config.writeEntry(ExecuteScriptPlugin::executableEntry, item->path().toUrl()); config.writeEntry(ExecuteScriptPlugin::interpreterEntry, interpreterForUrl(item->path().toUrl())); config.writeEntry(ExecuteScriptPlugin::outputFilteringEntry, 2u); config.writeEntry(ExecuteScriptPlugin::runCurrentFileEntry, false); config.sync(); } void ScriptAppConfigType::configureLaunchFromCmdLineArguments(KConfigGroup cfg, const QStringList &args) const { QStringList a(args); cfg.writeEntry( ExecuteScriptPlugin::interpreterEntry, a.takeFirst() ); cfg.writeEntry( ExecuteScriptPlugin::executableEntry, a.takeFirst() ); cfg.writeEntry( ExecuteScriptPlugin::argumentsEntry, KShell::joinArgs(a) ); cfg.writeEntry( ExecuteScriptPlugin::runCurrentFileEntry, false ); cfg.sync(); } diff --git a/plugins/executescript/scriptappjob.cpp b/plugins/executescript/scriptappjob.cpp index 6ac2a82c9d..cbf9d75482 100644 --- a/plugins/executescript/scriptappjob.cpp +++ b/plugins/executescript/scriptappjob.cpp @@ -1,257 +1,259 @@ /* This file is part of KDevelop Copyright 2009 Andreas Pakulat Copyright 2009 Niko Sams 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 "scriptappjob.h" #include "executescriptplugin.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "iexecutescriptplugin.h" #include "debug.h" +using namespace KDevelop; + ScriptAppJob::ScriptAppJob(ExecuteScriptPlugin* parent, KDevelop::ILaunchConfiguration* cfg) : KDevelop::OutputJob( parent ), proc(0) { qCDebug(PLUGIN_EXECUTESCRIPT) << "creating script app job"; setCapabilities(Killable); IExecuteScriptPlugin* iface = KDevelop::ICore::self()->pluginController()->pluginForExtension("org.kdevelop.IExecuteScriptPlugin")->extension(); Q_ASSERT(iface); KDevelop::EnvironmentGroupList l(KSharedConfig::openConfig()); QString envgrp = iface->environmentGroup(cfg); QString err; QString interpreterString = iface->interpreter( cfg, err ); // check for errors happens in the executescript plugin already KShell::Errors err_; QStringList interpreter = KShell::splitArgs( interpreterString, KShell::TildeExpand | KShell::AbortOnMeta, &err_ ); if ( interpreter.isEmpty() ) { // This should not happen, because of the checks done in the executescript plugin qWarning() << "no interpreter specified"; return; } if( !err.isEmpty() ) { setError( -1 ); setErrorText( err ); return; } QUrl script; if( !iface->runCurrentFile( cfg ) ) { script = iface->script( cfg, err ); } else { KDevelop::IDocument* document = KDevelop::ICore::self()->documentController()->activeDocument(); if( !document ) { setError( -1 ); setErrorText( i18n( "There is no active document to launch." ) ); return; } script = document->url(); } if( !err.isEmpty() ) { setError( -3 ); setErrorText( err ); return; } QString remoteHost = iface->remoteHost( cfg, err ); if( !err.isEmpty() ) { setError( -4 ); setErrorText( err ); return; } if( envgrp.isEmpty() ) { qWarning() << "Launch Configuration:" << cfg->name() << i18n("No environment group specified, looks like a broken " "configuration, please check run configuration '%1'. " "Using default environment group.", cfg->name() ); envgrp = l.defaultGroup(); } QStringList arguments = iface->arguments( cfg, err ); if( !err.isEmpty() ) { setError( -2 ); setErrorText( err ); } if( error() != 0 ) { qWarning() << "Launch Configuration:" << cfg->name() << "oops, problem" << errorText(); return; } KDevelop::OutputModel::OutputFilterStrategy currentFilterMode = static_cast( iface->outputFilterModeId( cfg ) ); proc = new KProcess( this ); lineMaker = new KDevelop::ProcessLineMaker( proc, this ); setStandardToolView(KDevelop::IOutputView::RunView); setBehaviours(KDevelop::IOutputView::AllowUserClose | KDevelop::IOutputView::AutoScroll); KDevelop::OutputModel* m = new KDevelop::OutputModel; m->setFilteringStrategy(currentFilterMode); setModel( m ); setDelegate( new KDevelop::OutputDelegate ); - connect( lineMaker, &KDevelop::ProcessLineMaker::receivedStdoutLines, model(), &KDevelop::OutputModel::appendLines ); + connect( lineMaker, &ProcessLineMaker::receivedStdoutLines, model(), &OutputModel::appendLines ); connect( proc, static_cast(&KProcess::error), this, &ScriptAppJob::processError ); connect( proc, static_cast(&KProcess::finished), this, &ScriptAppJob::processFinished ); // Now setup the process parameters proc->setEnvironment( l.createEnvironment( envgrp, proc->systemEnvironment()) ); QUrl wc = iface->workingDirectory( cfg ); if( !wc.isValid() || wc.isEmpty() ) { wc = QUrl::fromLocalFile( QFileInfo( script.toLocalFile() ).absolutePath() ); } proc->setWorkingDirectory( wc.toLocalFile() ); proc->setProperty( "executable", interpreter.first() ); QStringList program; if (!remoteHost.isEmpty()) { program << "ssh"; QStringList parts = remoteHost.split(":"); program << parts.first(); if (parts.length() > 1) { program << "-p "+parts.at(1); } } program << interpreter; program << script.toLocalFile(); program << arguments; qCDebug(PLUGIN_EXECUTESCRIPT) << "setting app:" << program; proc->setOutputChannelMode(KProcess::MergedChannels); proc->setProgram( program ); setTitle(cfg->name()); } void ScriptAppJob::start() { qCDebug(PLUGIN_EXECUTESCRIPT) << "launching?" << proc; if( proc ) { startOutput(); appendLine( i18n("Starting: %1", proc->program().join(" ") ) ); proc->start(); } else { qWarning() << "No process, something went wrong when creating the job"; // No process means we've returned early on from the constructor, some bad error happened emitResult(); } } bool ScriptAppJob::doKill() { if( proc ) { proc->kill(); appendLine( i18n( "*** Killed Application ***" ) ); } return true; } void ScriptAppJob::processFinished( int exitCode , QProcess::ExitStatus status ) { lineMaker->flushBuffers(); if (exitCode == 0 && status == QProcess::NormalExit) { appendLine( i18n("*** Exited normally ***") ); } else if (status == QProcess::NormalExit) { appendLine( i18n("*** Exited with return code: %1 ***", QString::number(exitCode)) ); setError(OutputJob::FailedShownError); } else if (error() == KJob::KilledJobError) { appendLine( i18n("*** Process aborted ***") ); setError(KJob::KilledJobError); } else { appendLine( i18n("*** Crashed with return code: %1 ***", QString::number(exitCode)) ); setError(OutputJob::FailedShownError); } qCDebug(PLUGIN_EXECUTESCRIPT) << "Process done"; emitResult(); } void ScriptAppJob::processError( QProcess::ProcessError error ) { qCDebug(PLUGIN_EXECUTESCRIPT) << proc->readAllStandardError(); qCDebug(PLUGIN_EXECUTESCRIPT) << proc->readAllStandardOutput(); qCDebug(PLUGIN_EXECUTESCRIPT) << proc->errorString(); if( error == QProcess::FailedToStart ) { setError( FailedShownError ); QString errmsg = i18n("*** Could not start program '%1'. Make sure that the " "path is specified correctly ***", proc->program().join(" ") ); appendLine( errmsg ); setErrorText( errmsg ); emitResult(); } qCDebug(PLUGIN_EXECUTESCRIPT) << "Process error"; } void ScriptAppJob::appendLine(const QString& l) { if (KDevelop::OutputModel* m = model()) { m->appendLine(l); } } KDevelop::OutputModel* ScriptAppJob::model() { return dynamic_cast( OutputJob::model() ); } diff --git a/plugins/externalscript/externalscriptjob.cpp b/plugins/externalscript/externalscriptjob.cpp index 0d0db3c6f3..e65516d65e 100644 --- a/plugins/externalscript/externalscriptjob.cpp +++ b/plugins/externalscript/externalscriptjob.cpp @@ -1,396 +1,398 @@ /* This file is part of KDevelop Copyright 2009 Andreas Pakulat Copyright 2010 Milian Wolff 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 "externalscriptjob.h" #include "externalscriptitem.h" #include "externalscriptdebug.h" #include "externalscriptplugin.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +using namespace KDevelop; + ExternalScriptJob::ExternalScriptJob( ExternalScriptItem* item, const QUrl& url, ExternalScriptPlugin* parent ) : KDevelop::OutputJob( parent ), m_proc( 0 ), m_lineMaker( 0 ), m_outputMode( item->outputMode() ), m_inputMode( item->inputMode() ), m_errorMode( item->errorMode() ), m_filterMode( item->filterMode() ), m_document( 0 ), m_url( url ), m_selectionRange( KTextEditor::Range::invalid() ), m_showOutput( item->showOutput() ) { qCDebug(PLUGIN_EXTERNALSCRIPT) << "creating external script job"; setCapabilities( Killable ); setStandardToolView( KDevelop::IOutputView::RunView ); setBehaviours( KDevelop::IOutputView::AllowUserClose | KDevelop::IOutputView::AutoScroll ); KDevelop::OutputModel* model = new KDevelop::OutputModel; model->setFilteringStrategy(static_cast(m_filterMode)); setModel( model ); setDelegate( new KDevelop::OutputDelegate ); // also merge when error mode "equals" output mode if ( (m_outputMode == ExternalScriptItem::OutputInsertAtCursor && m_errorMode == ExternalScriptItem::ErrorInsertAtCursor) || (m_outputMode == ExternalScriptItem::OutputReplaceDocument && m_errorMode == ExternalScriptItem::ErrorReplaceDocument) || (m_outputMode == ExternalScriptItem::OutputReplaceSelectionOrDocument && m_errorMode == ExternalScriptItem::ErrorReplaceSelectionOrDocument) || (m_outputMode == ExternalScriptItem::OutputReplaceSelectionOrInsertAtCursor && m_errorMode == ExternalScriptItem::ErrorReplaceSelectionOrInsertAtCursor) || // also these two otherwise they clash... (m_outputMode == ExternalScriptItem::OutputReplaceSelectionOrInsertAtCursor && m_errorMode == ExternalScriptItem::ErrorReplaceSelectionOrDocument) || (m_outputMode == ExternalScriptItem::OutputReplaceSelectionOrDocument && m_errorMode == ExternalScriptItem::ErrorReplaceSelectionOrInsertAtCursor) ) { m_errorMode = ExternalScriptItem::ErrorMergeOutput; } KTextEditor::View* view = KDevelop::ICore::self()->documentController()->activeTextDocumentView(); if ( m_outputMode != ExternalScriptItem::OutputNone || m_inputMode != ExternalScriptItem::InputNone || m_errorMode != ExternalScriptItem::ErrorNone ) { if ( !view ) { KMessageBox::error( QApplication::activeWindow(), i18n( "Cannot run script '%1' since it tries to access " "the editor contents but no document is open.", item->text() ), i18n( "No Document Open" ) ); return; } m_document = view->document(); connect(m_document, &KTextEditor::Document::aboutToClose, this, [&] { kill(); }); m_selectionRange = view->selectionRange(); m_cursorPosition = view->cursorPosition(); } if ( item->saveMode() == ExternalScriptItem::SaveCurrentDocument && view ) { view->document()->save(); } else if ( item->saveMode() == ExternalScriptItem::SaveAllDocuments ) { foreach ( KDevelop::IDocument* doc, KDevelop::ICore::self()->documentController()->openDocuments() ) { doc->save(); } } QString command = item->command(); QString workingDir = item->workingDirectory(); if(item->performParameterReplacement()) command.replace( "%i", QString::number( QCoreApplication::applicationPid() ) ); if ( !m_url.isEmpty() ) { const QUrl url = m_url; KDevelop::ProjectFolderItem* folder = 0; if ( KDevelop::ICore::self()->projectController()->findProjectForUrl( url ) ) { QList folders = KDevelop::ICore::self()->projectController()->findProjectForUrl(url)->foldersForUrl(url); if ( !folders.isEmpty() ) { folder = folders.first(); } } if ( folder ) { if ( folder->path().isLocalFile() && workingDir.isEmpty() ) { ///TODO: make configurable, use fallback to project dir workingDir = folder->path().toLocalFile(); } ///TODO: make those placeholders escapeable if(item->performParameterReplacement()) { command.replace( "%d", KShell::quoteArg( m_url.toString(QUrl::PreferLocalFile) ) ); if ( KDevelop::IProject* project = KDevelop::ICore::self()->projectController()->findProjectForUrl( m_url ) ) { command.replace( "%p", project->path().pathOrUrl() ); } } } else { if ( m_url.isLocalFile() && workingDir.isEmpty() ) { ///TODO: make configurable, use fallback to project dir workingDir = view->document()->url().adjusted(QUrl::RemoveFilename).toLocalFile(); } ///TODO: make those placeholders escapeable if(item->performParameterReplacement()) { command.replace( "%u", KShell::quoteArg( m_url.toString() ) ); ///TODO: does that work with remote files? QFileInfo info( m_url.toString(QUrl::PreferLocalFile) ); command.replace( "%f", KShell::quoteArg( info.filePath() ) ); command.replace( "%b", KShell::quoteArg( info.baseName() ) ); command.replace( "%n", KShell::quoteArg( info.fileName() ) ); command.replace( "%d", KShell::quoteArg( info.path() ) ); if ( view->document() && view->selection() ) { command.replace( "%s", KShell::quoteArg( view->selectionText() ) ); } if ( KDevelop::IProject* project = KDevelop::ICore::self()->projectController()->findProjectForUrl( m_url ) ) { command.replace( "%p", project->path().pathOrUrl() ); } } } } m_proc = new KProcess( this ); if ( !workingDir.isEmpty() ) { m_proc->setWorkingDirectory( workingDir ); } - m_lineMaker = new KDevelop::ProcessLineMaker( m_proc, this ); - connect( m_lineMaker, &KDevelop::ProcessLineMaker::receivedStdoutLines, - model, &KDevelop::OutputModel::appendLines ); - connect( m_lineMaker, &KDevelop::ProcessLineMaker::receivedStdoutLines, + m_lineMaker = new ProcessLineMaker( m_proc, this ); + connect( m_lineMaker, &ProcessLineMaker::receivedStdoutLines, + model, &OutputModel::appendLines ); + connect( m_lineMaker, &ProcessLineMaker::receivedStdoutLines, this, &ExternalScriptJob::receivedStdoutLines ); - connect( m_lineMaker, &KDevelop::ProcessLineMaker::receivedStderrLines, - model, &KDevelop::OutputModel::appendLines ); - connect( m_lineMaker, &KDevelop::ProcessLineMaker::receivedStderrLines, + connect( m_lineMaker, &ProcessLineMaker::receivedStderrLines, + model, &OutputModel::appendLines ); + connect( m_lineMaker, &ProcessLineMaker::receivedStderrLines, this, &ExternalScriptJob::receivedStderrLines ); connect( m_proc, static_cast(&KProcess::error), this, &ExternalScriptJob::processError ); connect( m_proc, static_cast(&KProcess::finished), this, &ExternalScriptJob::processFinished ); // Now setup the process parameters qCDebug(PLUGIN_EXTERNALSCRIPT) << "setting command:" << command; if ( m_errorMode == ExternalScriptItem::ErrorMergeOutput ) { m_proc->setOutputChannelMode( KProcess::MergedChannels ); } else { m_proc->setOutputChannelMode( KProcess::SeparateChannels ); } m_proc->setShellCommand( command ); setObjectName( command ); } void ExternalScriptJob::start() { qCDebug(PLUGIN_EXTERNALSCRIPT) << "launching?" << m_proc; if ( m_proc ) { if ( m_showOutput ) { startOutput(); } appendLine( i18n( "Running external script: %1", m_proc->program().join( " " ) ) ); m_proc->start(); if ( m_inputMode != ExternalScriptItem::InputNone ) { QString inputText; switch ( m_inputMode ) { case ExternalScriptItem::InputNone: // do nothing; break; case ExternalScriptItem::InputSelectionOrNone: if ( m_selectionRange.isValid() ) { inputText = m_document->text(m_selectionRange); } // else nothing break; case ExternalScriptItem::InputSelectionOrDocument: if ( m_selectionRange.isValid() ) { inputText = m_document->text(m_selectionRange); } else { inputText = m_document->text(); } break; case ExternalScriptItem::InputDocument: inputText = m_document->text(); break; } ///TODO: what to do with the encoding here? /// maybe ask Christoph for what kate returns... m_proc->write( inputText.toUtf8() ); m_proc->closeWriteChannel(); } } else { qWarning() << "No process, something went wrong when creating the job"; // No process means we've returned early on from the constructor, some bad error happened emitResult(); } } bool ExternalScriptJob::doKill() { if ( m_proc ) { m_proc->kill(); appendLine( i18n( "*** Killed Application ***" ) ); } return true; } void ExternalScriptJob::processFinished( int exitCode , QProcess::ExitStatus status ) { m_lineMaker->flushBuffers(); if ( exitCode == 0 && status == QProcess::NormalExit ) { if ( m_outputMode != ExternalScriptItem::OutputNone ) { if ( !m_stdout.isEmpty() ) { QString output = m_stdout.join( "\n" ); switch ( m_outputMode ) { case ExternalScriptItem::OutputNone: // do nothing; break; case ExternalScriptItem::OutputCreateNewFile: KDevelop::ICore::self()->documentController()->openDocumentFromText( output ); break; case ExternalScriptItem::OutputInsertAtCursor: m_document->insertText( m_cursorPosition, output ); break; case ExternalScriptItem::OutputReplaceSelectionOrInsertAtCursor: if ( m_selectionRange.isValid() ) { m_document->replaceText( m_selectionRange, output ); } else { m_document->insertText( m_cursorPosition, output ); } break; case ExternalScriptItem::OutputReplaceSelectionOrDocument: if ( m_selectionRange.isValid() ) { m_document->replaceText( m_selectionRange, output ); } else { m_document->setText( output ); } break; case ExternalScriptItem::OutputReplaceDocument: m_document->setText( output ); break; } } } if ( m_errorMode != ExternalScriptItem::ErrorNone && m_errorMode != ExternalScriptItem::ErrorMergeOutput ) { QString output = m_stderr.join( "\n" ); if ( !output.isEmpty() ) { switch ( m_errorMode ) { case ExternalScriptItem::ErrorNone: case ExternalScriptItem::ErrorMergeOutput: // do nothing; break; case ExternalScriptItem::ErrorCreateNewFile: KDevelop::ICore::self()->documentController()->openDocumentFromText( output ); break; case ExternalScriptItem::ErrorInsertAtCursor: m_document->insertText( m_cursorPosition, output ); break; case ExternalScriptItem::ErrorReplaceSelectionOrInsertAtCursor: if ( m_selectionRange.isValid() ) { m_document->replaceText( m_selectionRange, output ); } else { m_document->insertText( m_cursorPosition, output ); } break; case ExternalScriptItem::ErrorReplaceSelectionOrDocument: if ( m_selectionRange.isValid() ) { m_document->replaceText( m_selectionRange, output ); } else { m_document->setText( output ); } break; case ExternalScriptItem::ErrorReplaceDocument: m_document->setText( output ); break; } } } appendLine( i18n( "*** Exited normally ***" ) ); } else { if ( status == QProcess::NormalExit ) appendLine( i18n( "*** Exited with return code: %1 ***", QString::number( exitCode ) ) ); else if ( error() == KJob::KilledJobError ) appendLine( i18n( "*** Process aborted ***" ) ); else appendLine( i18n( "*** Crashed with return code: %1 ***", QString::number( exitCode ) ) ); } qCDebug(PLUGIN_EXTERNALSCRIPT) << "Process done"; emitResult(); } void ExternalScriptJob::processError( QProcess::ProcessError error ) { if ( error == QProcess::FailedToStart ) { setError( -1 ); QString errmsg = i18n("*** Could not start program '%1'. Make sure that the " "path is specified correctly ***", m_proc->program().join(" ") ); appendLine( errmsg ); setErrorText( errmsg ); emitResult(); } qCDebug(PLUGIN_EXTERNALSCRIPT) << "Process error"; } void ExternalScriptJob::appendLine( const QString& l ) { if ( KDevelop::OutputModel* m = model() ) { m->appendLine( l ); } } KDevelop::OutputModel* ExternalScriptJob::model() { return dynamic_cast( OutputJob::model() ); } void ExternalScriptJob::receivedStderrLines(const QStringList& lines) { m_stderr += lines; } void ExternalScriptJob::receivedStdoutLines(const QStringList& lines) { m_stdout += lines; } // kate: indent-mode cstyle; space-indent on; indent-width 2; replace-tabs on; diff --git a/plugins/git/stashmanagerdialog.cpp b/plugins/git/stashmanagerdialog.cpp index 7ec0cdd995..16a09c1b80 100644 --- a/plugins/git/stashmanagerdialog.cpp +++ b/plugins/git/stashmanagerdialog.cpp @@ -1,147 +1,149 @@ /* * This file is part of KDevelop * Copyright 2010 Aleix Pol Gonzalez * * This program 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 program 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 General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "stashmanagerdialog.h" #include "ui_stashmanagerdialog.h" #include "gitplugin.h" #include "stashpatchsource.h" #include #include #include #include #include #include #include +using namespace KDevelop; + StashManagerDialog::StashManagerDialog(const QDir& stashed, GitPlugin* plugin, QWidget* parent) : KDialog(parent), m_plugin(plugin), m_dir(stashed) { setWindowTitle(KDialog::makeStandardCaption(i18n("Stash Manager"))); setButtons(KDialog::Close); QWidget* w = new QWidget(this); m_ui = new Ui::StashManager; m_ui->setupUi(w); StashModel* m = new StashModel(stashed, plugin, this); m_ui->stashView->setModel(m); connect(m_ui->show, &QPushButton::clicked, this, &StashManagerDialog::showStash); connect(m_ui->apply, &QPushButton::clicked, this, &StashManagerDialog::applyClicked); connect(m_ui->branch, &QPushButton::clicked, this, &StashManagerDialog::branchClicked); connect(m_ui->pop, &QPushButton::clicked, this, &StashManagerDialog::popClicked); connect(m_ui->drop, &QPushButton::clicked, this, &StashManagerDialog::dropClicked); connect(m, &StashModel::rowsInserted, this, &StashManagerDialog::stashesFound); setMainWidget(w); w->setEnabled(false); //we won't enable it until we have the model with data and selection } StashManagerDialog::~StashManagerDialog() { delete m_ui; } void StashManagerDialog::stashesFound() { QModelIndex firstIdx=m_ui->stashView->model()->index(0, 0); m_ui->stashView->setCurrentIndex(firstIdx); mainWidget()->setEnabled(true); } QString StashManagerDialog::selection() const { QModelIndex idx = m_ui->stashView->currentIndex(); Q_ASSERT(idx.isValid()); return idx.data().toString(); } void StashManagerDialog::runStash(const QStringList& arguments) { - KDevelop::VcsJob* job = m_plugin->gitStash(m_dir, arguments, KDevelop::OutputJob::Verbose); - connect(job, &KDevelop::VcsJob::result, this, &StashManagerDialog::accept); + VcsJob* job = m_plugin->gitStash(m_dir, arguments, OutputJob::Verbose); + connect(job, &VcsJob::result, this, &StashManagerDialog::accept); mainWidget()->setEnabled(false); - KDevelop::ICore::self()->runController()->registerJob(job); + ICore::self()->runController()->registerJob(job); } void StashManagerDialog::showStash() { - KDevelop::IPatchReview * review = KDevelop::ICore::self()->pluginController()->extensionForPlugin(); - KDevelop::IPatchSource::Ptr stashPatch(new StashPatchSource(selection(), m_plugin, m_dir)); + IPatchReview * review = ICore::self()->pluginController()->extensionForPlugin(); + IPatchSource::Ptr stashPatch(new StashPatchSource(selection(), m_plugin, m_dir)); review->startReview(stashPatch); accept(); } void StashManagerDialog::applyClicked() { runStash(QStringList("apply") << selection()); } void StashManagerDialog::popClicked() { runStash(QStringList("pop") << selection()); } void StashManagerDialog::dropClicked() { QString sel = selection(); int ret = KMessageBox::questionYesNo(this, i18n("Are you sure you want to drop the stash '%1'?", sel)); if(ret == KMessageBox::Yes) runStash(QStringList("drop") << sel); } void StashManagerDialog::branchClicked() { QString branchName = QInputDialog::getText(this, i18n("KDevelop - Git Stash"), i18n("Select a name for the new branch:")); if(!branchName.isEmpty()) runStash(QStringList("branch") << branchName << selection()); } //////////////////StashModel StashModel::StashModel(const QDir& dir, GitPlugin* git, QObject* parent) : QStandardItemModel(parent) { - KDevelop::VcsJob* job=git->gitStash(dir, QStringList("list"), KDevelop::OutputJob::Silent); - connect(job, &KDevelop::VcsJob::finished, this, &StashModel::stashListReady); + VcsJob* job=git->gitStash(dir, QStringList("list"), OutputJob::Silent); + connect(job, &VcsJob::finished, this, &StashModel::stashListReady); - KDevelop::ICore::self()->runController()->registerJob(job); + ICore::self()->runController()->registerJob(job); } void StashModel::stashListReady(KJob* _job) { - KDevelop::DVcsJob* job = qobject_cast(_job); + DVcsJob* job = qobject_cast(_job); QList< QByteArray > output = job->rawOutput().split('\n'); foreach(const QByteArray& line, output) { QList< QByteArray > fields = line.split(':'); QList elements; foreach(const QByteArray& field, fields) elements += new QStandardItem(QString(field.trimmed())); appendRow(elements); } } diff --git a/plugins/git/stashpatchsource.cpp b/plugins/git/stashpatchsource.cpp index 513411cfa5..5b02c3399c 100644 --- a/plugins/git/stashpatchsource.cpp +++ b/plugins/git/stashpatchsource.cpp @@ -1,86 +1,88 @@ /* * * Copyright (C) 2013 David E. Narvaez * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include "stashpatchsource.h" #include "gitplugin.h" #include "vcs/dvcs/dvcsjob.h" #include "interfaces/icore.h" #include "interfaces/iruncontroller.h" #include #include +using namespace KDevelop; + StashPatchSource::StashPatchSource(const QString& stashName, GitPlugin* plugin, const QDir & baseDir) : m_stashName(stashName), m_plugin(plugin), m_baseDir(baseDir) { QTemporaryFile tempFile; tempFile.setAutoRemove(false); tempFile.open(); m_patchFile = QUrl::fromLocalFile(tempFile.fileName()); KDevelop::DVcsJob * job = m_plugin->gitStash(m_baseDir, QStringList() << "show" << "-u" << m_stashName, KDevelop::OutputJob::Silent); - connect(job, &KDevelop::DVcsJob::resultsReady, this, &StashPatchSource::updatePatchFile); + connect(job, &DVcsJob::resultsReady, this, &StashPatchSource::updatePatchFile); KDevelop::ICore::self()->runController()->registerJob(job); } StashPatchSource::~StashPatchSource() { QFile::remove(m_patchFile.toLocalFile()); } QUrl StashPatchSource::baseDir() const { return QUrl::fromLocalFile(m_baseDir.absolutePath()); } QUrl StashPatchSource::file() const { return m_patchFile; } void StashPatchSource::update() { } bool StashPatchSource::isAlreadyApplied() const { return false; } QString StashPatchSource::name() const { return m_stashName; } void StashPatchSource::updatePatchFile(KDevelop::VcsJob* job) { KDevelop::DVcsJob* dvcsJob = qobject_cast(job); QFile f(m_patchFile.toLocalFile()); QTextStream txtStream(&f); f.open(QIODevice::WriteOnly); txtStream << dvcsJob->rawOutput(); f.close(); emit patchChanged(); } diff --git a/plugins/welcomepage/sessionsmodel.cpp b/plugins/welcomepage/sessionsmodel.cpp index 1b077075b7..15d68fae4c 100644 --- a/plugins/welcomepage/sessionsmodel.cpp +++ b/plugins/welcomepage/sessionsmodel.cpp @@ -1,90 +1,92 @@ /* This file is part of KDevelop Copyright 2010 Aleix Pol Gonzalez 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. */ #include "sessionsmodel.h" #include #include +using namespace KDevelop; + SessionsModel::SessionsModel(QObject* parent) : QAbstractListModel(parent) , m_sessions(KDevelop::SessionController::availableSessionInfo()) { - connect(KDevelop::Core::self()->sessionController(), &KDevelop::SessionController::sessionDeleted, this, &SessionsModel::sessionDeleted); + connect(Core::self()->sessionController(), &SessionController::sessionDeleted, this, &SessionsModel::sessionDeleted); } QHash< int, QByteArray > SessionsModel::roleNames() const { QHash< int, QByteArray > roles = QAbstractListModel::roleNames(); roles.insert(Uuid, "uuid"); roles.insert(Projects, "projects"); roles.insert(ProjectNames, "projectNames"); roles.insert(VisibleIdentifier, "identifier"); return roles; } QVariant SessionsModel::data(const QModelIndex& index, int role) const { if(!index.isValid() || index.row()>m_sessions.count()) { return QVariant(); } switch(role) { case Qt::DisplayRole: return m_sessions[index.row()].name; case Qt::ToolTip: return m_sessions[index.row()].description; case Uuid: return m_sessions[index.row()].uuid.toString(); case Projects: return QVariant::fromValue(m_sessions[index.row()].projects); case VisibleIdentifier: { const KDevelop::SessionInfo& s = m_sessions[index.row()]; return s.name.isEmpty() && !s.projects.isEmpty() ? s.projects.first().fileName() : s.name; } case ProjectNames: { QVariantList ret; foreach(const QUrl& project, m_sessions[index.row()].projects) { ret += project.fileName(); } return ret; } } return QVariant(); } int SessionsModel::rowCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : m_sessions.size(); } void SessionsModel::loadSession(const QString& nameOrId) const { KDevelop::Core::self()->sessionController()->loadSession(nameOrId); } void SessionsModel::sessionDeleted(const QString& id) { for(int i=0; i * * * * This program 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 program 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 General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "main.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool verbose=false, warnings=false; using namespace KDevelop; void messageOutput(QtMsgType type, const QMessageLogContext& context, const QString& msg) { Q_UNUSED(context); switch (type) { case QtDebugMsg: if(verbose) std::cerr << qPrintable(msg) << std::endl; break; case QtWarningMsg: if(warnings) std::cerr << qPrintable(msg) << std::endl; break; case QtCriticalMsg: std::cerr << qPrintable(msg) << std::endl; break; case QtFatalMsg: std::cerr << qPrintable(msg) << std::endl; abort(); } } Manager::Manager(QCommandLineParser* args) : m_total(0), m_args(args), m_allFilesAdded(0) { } void Manager::init() { QList includes; if(m_args->positionalArguments().isEmpty()) { std::cerr << "Need file or directory to duchainify" << std::endl; QCoreApplication::exit(1); } uint features = TopDUContext::VisibleDeclarationsAndContexts; if(m_args->isSet("features")) { QString featuresStr = m_args->value("features"); if(featuresStr == "visible-declarations") { features = TopDUContext::VisibleDeclarationsAndContexts; } else if(featuresStr == "all-declarations") { features = TopDUContext::AllDeclarationsAndContexts; } else if(featuresStr == "all-declarations-and-uses") { features = TopDUContext::AllDeclarationsContextsAndUses; } else if(featuresStr == "all-declarations-and-uses-and-AST") { features = TopDUContext::AllDeclarationsContextsAndUses | TopDUContext::AST; } else if(featuresStr == "empty") { features = TopDUContext::Empty; } else if(featuresStr == "simplified-visible-declarations") { features = TopDUContext::SimplifiedVisibleDeclarationsAndContexts; } else{ std::cerr << "Wrong feature-string given\n"; QCoreApplication::exit(2); return; } } if(m_args->isSet("force-update")) features |= TopDUContext::ForceUpdate; if(m_args->isSet("force-update-recursive")) features |= TopDUContext::ForceUpdateRecursive; if(m_args->isSet("threads")) { bool ok = false; int count = m_args->value("threads").toInt(&ok); ICore::self()->languageController()->backgroundParser()->setThreadCount(count); if(!ok) { std::cerr << "bad thread count\n"; QCoreApplication::exit(3); return; } } // quit when everything is done // background parser emits hideProgress() signal in two situations: // when everything is done and when bgparser is suspended // later doesn't happen in duchain, so just rely on hideProgress() // and quit when it's emitted - connect(ICore::self()->languageController()->backgroundParser(), &KDevelop::BackgroundParser::hideProgress, this, &Manager::finish); + connect(ICore::self()->languageController()->backgroundParser(), &BackgroundParser::hideProgress, this, &Manager::finish); foreach (const auto& file, m_args->positionalArguments()) { addToBackgroundParser(file, (TopDUContext::Features)features); } m_allFilesAdded = 1; if ( m_total ) { std::cerr << "Added " << m_total << " files to the background parser" << std::endl; const int threads = ICore::self()->languageController()->backgroundParser()->threadCount(); std::cerr << "parsing with " << threads << " threads" << std::endl; ICore::self()->languageController()->backgroundParser()->parseDocuments(); } else { std::cerr << "no files added to the background parser" << std::endl; QCoreApplication::exit(0); return; } } void Manager::updateReady(IndexedString url, ReferencedTopDUContext topContext) { qDebug() << "finished" << url.toUrl().toLocalFile() << "success: " << (bool)topContext; m_waiting.remove(url.toUrl()); std::cerr << "processed " << (m_total - m_waiting.size()) << " out of " << m_total << std::endl; if (!topContext) return; std::cerr << std::endl; QTextStream stream(stdout); if (m_args->isSet("dump-definitions")) { DUChainReadLocker lock; std::cerr << "Definitions:" << std::endl; DUChain::definitions()->dump(stream); std::cerr << std::endl; } if (m_args->isSet("dump-symboltable")) { DUChainReadLocker lock; std::cerr << "PersistentSymbolTable:" << std::endl; PersistentSymbolTable::self().dump(stream); std::cerr << std::endl; } DUChainDumper::Features features; if (m_args->isSet("dump-context")) { features |= DUChainDumper::DumpContext; } if (m_args->isSet("dump-errors")) { features |= DUChainDumper::DumpProblems; } if (auto depth = m_args->value("dump-depth").toInt()) { DUChainReadLocker lock; std::cerr << "Context:" << std::endl; DUChainDumper dumpChain(features); dumpChain.dump(topContext, depth); } if (m_args->isSet("dump-graph")) { DUChainReadLocker lock; DumpDotGraph dumpGraph; const QString dotOutput = dumpGraph.dotGraph(topContext); std::cout << qPrintable(dotOutput) << std::endl; } } void Manager::addToBackgroundParser(QString path, TopDUContext::Features features) { QFileInfo info(path); if(info.isFile()) { qDebug() << "adding file" << path; QUrl pathUrl = QUrl::fromLocalFile(info.canonicalFilePath()); m_waiting << pathUrl; ++m_total; KDevelop::DUChain::self()->updateContextForUrl(KDevelop::IndexedString(pathUrl), features, this); }else if(info.isDir()) { QDirIterator contents(path); while(contents.hasNext()) { QString newPath = contents.next(); if(!newPath.endsWith('.')) addToBackgroundParser(newPath, features); } } } QSet< QUrl > Manager::waiting() { return m_waiting; } void Manager::finish() { std::cerr << "ready" << std::endl; QApplication::quit(); } using namespace KDevelop; int main(int argc, char** argv) { KAboutData aboutData( "duchainify", i18n( "duchainify" ), "1", i18n("DUChain builder application"), KAboutLicense::GPL, i18n( "(c) 2009 David Nolden" ), QString(), "http://www.kdevelop.org" ); QApplication app(argc, argv); KAboutData::setApplicationData(aboutData); QCommandLineParser parser; aboutData.setupCommandLine(&parser); parser.addVersionOption(); parser.addHelpOption(); parser.addPositionalArgument("paths", i18n("file or directory"), "[PATH...]"); parser.addOption(QCommandLineOption{QStringList{"w", "warnings"}, i18n("Show warnings")}); parser.addOption(QCommandLineOption{QStringList{"V", "verbose"}, i18n("Show warnings and debug output")}); parser.addOption(QCommandLineOption{QStringList{"u", "force-update"}, i18n("Enforce an update of the top-contexts corresponding to the given files")}); parser.addOption(QCommandLineOption{QStringList{"r", "force-update-recursive"}, i18n("Enforce an update of the top-contexts corresponding to the given files and all included files")}); parser.addOption(QCommandLineOption{QStringList{"t", "threads"}, i18n("Number of threads to use"), "count"}); parser.addOption(QCommandLineOption{QStringList{"f", "features"}, i18n("Features to build. Options: empty, simplified-visible-declarations, visible-declarations (default), all-declarations, all-declarations-and-uses, all-declarations-and-uses-and-AST"), "features"}); parser.addOption(QCommandLineOption{QStringList{"dump-context"}, i18n("Print complete Definition-Use Chain on successful parse")}); parser.addOption(QCommandLineOption{QStringList{"dump-definitions"}, i18n("Print complete DUChain Definitions repository on successful parse")}); parser.addOption(QCommandLineOption{QStringList{"dump-symboltable"}, i18n("Print complete DUChain PersistentSymbolTable repository on successful parse")}); parser.addOption(QCommandLineOption{QStringList{"depth"}, i18n("Number defining the maximum depth where declaration details are printed"), "depth"}); parser.addOption(QCommandLineOption{QStringList{"dump-graph"}, i18n("Dump DUChain graph (in .dot format)")}); parser.addOption(QCommandLineOption{QStringList{"d", "dump-errors"}, i18n("Print problems encountered during parsing")}); parser.process(app); aboutData.processCommandLine(&parser); verbose = parser.isSet("verbose"); warnings = parser.isSet("warnings"); qInstallMessageHandler(messageOutput); AutoTestShell::init(); TestCore::initialize(Core::NoUi, "duchainify"); Manager manager(&parser); QTimer::singleShot(0, &manager, SLOT(init())); int ret = app.exec(); TestCore::shutdown(); return ret; }