File indexing completed on 2024-04-28 04:38:39
0001 /* 0002 SPDX-FileCopyrightText: 2009 Andreas Pakulat <apaku@gmx.de> 0003 SPDX-FileCopyrightText: 2009 Niko Sams <niko.sams@gmail.com> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "plasmoidexecutionconfig.h" 0009 #include "plasmoidexecutionjob.h" 0010 #include "debug.h" 0011 0012 #include <KLocalizedString> 0013 #include <interfaces/ilaunchconfiguration.h> 0014 #include <interfaces/icore.h> 0015 #include <interfaces/iprojectcontroller.h> 0016 #include <interfaces/iproject.h> 0017 #include <interfaces/iruncontroller.h> 0018 #include <interfaces/iuicontroller.h> 0019 #include <project/projectmodel.h> 0020 #include <project/builderjob.h> 0021 #include <serialization/indexedstring.h> 0022 #include <util/kdevstringhandler.h> 0023 #include <util/executecompositejob.h> 0024 #include <util/path.h> 0025 0026 #include <KMessageBox> 0027 #include <KParts/MainWindow> 0028 #include <KConfigGroup> 0029 #include <QMenu> 0030 #include <QLineEdit> 0031 class la; 0032 0033 QIcon PlasmoidExecutionConfig::icon() const 0034 { 0035 return QIcon::fromTheme(QStringLiteral("system-run")); 0036 } 0037 0038 QStringList readProcess(QProcess* p) 0039 { 0040 QStringList ret; 0041 while(!p->atEnd()) { 0042 QByteArray line = p->readLine(); 0043 int nameEnd=line.indexOf(' '); 0044 if(nameEnd>0) { 0045 ret += QString::fromUtf8(line.left(nameEnd)); 0046 } 0047 } 0048 return ret; 0049 } 0050 0051 PlasmoidExecutionConfig::PlasmoidExecutionConfig( QWidget* parent ) 0052 : LaunchConfigurationPage( parent ) 0053 { 0054 setupUi(this); 0055 connect( identifier->lineEdit(), &QLineEdit::textEdited, this, &PlasmoidExecutionConfig::changed ); 0056 0057 QProcess pPlasmoids; 0058 pPlasmoids.start(QStringLiteral("plasmoidviewer"), QStringList(QStringLiteral("--list")), QIODevice::ReadOnly); 0059 0060 QProcess pThemes; 0061 pThemes.start(QStringLiteral("plasmoidviewer"), QStringList(QStringLiteral("--list-themes")), QIODevice::ReadOnly); 0062 pThemes.waitForFinished(); 0063 pPlasmoids.waitForFinished(); 0064 0065 const auto plasmoidListing = readProcess(&pPlasmoids); 0066 for (const QString& plasmoid : plasmoidListing) { 0067 identifier->addItem(plasmoid); 0068 } 0069 0070 themes->addItem(QString()); 0071 const auto themeListing = readProcess(&pThemes); 0072 for (const QString& theme : themeListing) { 0073 themes->addItem(theme); 0074 } 0075 0076 connect( dependencies, &KDevelop::DependenciesWidget::changed, this, &PlasmoidExecutionConfig::changed ); 0077 } 0078 0079 void PlasmoidExecutionConfig::saveToConfiguration( KConfigGroup cfg, KDevelop::IProject* project ) const 0080 { 0081 Q_UNUSED( project ); 0082 cfg.writeEntry("PlasmoidIdentifier", identifier->lineEdit()->text()); 0083 QStringList args{ 0084 QStringLiteral("--formfactor"), 0085 formFactor->currentText(), 0086 }; 0087 if(!themes->currentText().isEmpty()) { 0088 args += QStringLiteral("--theme"); 0089 args += themes->currentText(); 0090 } 0091 cfg.writeEntry("Arguments", args); 0092 0093 QVariantList deps = dependencies->dependencies(); 0094 cfg.writeEntry( "Dependencies", KDevelop::qvariantToString( QVariant( deps ) ) ); 0095 } 0096 0097 void PlasmoidExecutionConfig::loadFromConfiguration(const KConfigGroup& cfg, KDevelop::IProject* ) 0098 { 0099 bool b = blockSignals( true ); 0100 identifier->lineEdit()->setText(cfg.readEntry("PlasmoidIdentifier", "")); 0101 blockSignals( b ); 0102 0103 QStringList arguments = cfg.readEntry("Arguments", QStringList()); 0104 int idxFormFactor = arguments.indexOf(QStringLiteral("--formfactor"))+1; 0105 if(idxFormFactor>0) 0106 formFactor->setCurrentIndex(formFactor->findText(arguments[idxFormFactor])); 0107 0108 int idxTheme = arguments.indexOf(QStringLiteral("--theme"))+1; 0109 if(idxTheme>0) 0110 themes->setCurrentIndex(themes->findText(arguments[idxTheme])); 0111 0112 dependencies->setDependencies( KDevelop::stringToQVariant( cfg.readEntry( "Dependencies", QString() ) ).toList()); 0113 } 0114 0115 QString PlasmoidExecutionConfig::title() const 0116 { 0117 return i18nc("@title:tab", "Configure Plasmoid Execution"); 0118 } 0119 0120 QList< KDevelop::LaunchConfigurationPageFactory* > PlasmoidLauncher::configPages() const 0121 { 0122 return QList<KDevelop::LaunchConfigurationPageFactory*>(); 0123 } 0124 0125 QString PlasmoidLauncher::description() const 0126 { 0127 return i18n("Display a plasmoid"); 0128 } 0129 0130 QString PlasmoidLauncher::id() 0131 { 0132 return QStringLiteral("PlasmoidLauncher"); 0133 } 0134 0135 QString PlasmoidLauncher::name() const 0136 { 0137 return i18n("Plasmoid Launcher"); 0138 } 0139 0140 PlasmoidLauncher::PlasmoidLauncher(ExecutePlasmoidPlugin* plugin) 0141 : m_plugin(plugin) 0142 { 0143 } 0144 0145 KJob* PlasmoidLauncher::start(const QString& launchMode, KDevelop::ILaunchConfiguration* cfg) 0146 { 0147 Q_ASSERT(cfg); 0148 if( !cfg ) 0149 { 0150 return nullptr; 0151 } 0152 0153 if( launchMode == QLatin1String("execute") ) 0154 { 0155 KJob* depsJob = dependencies(cfg); 0156 QList<KJob*> jobs; 0157 if(depsJob) 0158 jobs << depsJob; 0159 jobs << new PlasmoidExecutionJob(m_plugin, cfg); 0160 0161 return new KDevelop::ExecuteCompositeJob( KDevelop::ICore::self()->runController(), jobs ); 0162 } 0163 qCWarning(EXECUTEPLASMOID) << "Unknown launch mode " << launchMode << "for config:" << cfg->name(); 0164 return nullptr; 0165 } 0166 0167 KJob* PlasmoidLauncher::calculateDependencies(KDevelop::ILaunchConfiguration* cfg) 0168 { 0169 const QVariantList deps = KDevelop::stringToQVariant(cfg->config().readEntry("Dependencies", QString())).toList(); 0170 if( !deps.isEmpty() ) 0171 { 0172 KDevelop::ProjectModel* model = KDevelop::ICore::self()->projectController()->projectModel(); 0173 QList<KDevelop::ProjectBaseItem*> items; 0174 for (const QVariant& dep : deps) { 0175 KDevelop::ProjectBaseItem* item = model->itemFromIndex( model->pathToIndex( dep.toStringList() ) ); 0176 if( item ) 0177 { 0178 items << item; 0179 } 0180 else 0181 { 0182 KMessageBox::error(KDevelop::ICore::self()->uiController()->activeMainWindow(), 0183 i18n("Could not resolve the dependency: %1", dep.toString())); 0184 } 0185 } 0186 auto* job = new KDevelop::BuilderJob; 0187 job->addItems( KDevelop::BuilderJob::Install, items ); 0188 job->updateJobName(); 0189 return job; 0190 } 0191 return nullptr; 0192 } 0193 0194 KJob* PlasmoidLauncher::dependencies(KDevelop::ILaunchConfiguration* cfg) 0195 { 0196 return calculateDependencies(cfg); 0197 } 0198 0199 0200 QStringList PlasmoidLauncher::supportedModes() const 0201 { 0202 return QStringList() << QStringLiteral("execute"); 0203 } 0204 0205 KDevelop::LaunchConfigurationPage* PlasmoidPageFactory::createWidget(QWidget* parent) 0206 { 0207 return new PlasmoidExecutionConfig( parent ); 0208 } 0209 0210 PlasmoidPageFactory::PlasmoidPageFactory() 0211 {} 0212 0213 PlasmoidExecutionConfigType::PlasmoidExecutionConfigType() 0214 { 0215 factoryList.append( new PlasmoidPageFactory ); 0216 } 0217 0218 PlasmoidExecutionConfigType::~PlasmoidExecutionConfigType() 0219 { 0220 qDeleteAll(factoryList); 0221 factoryList.clear(); 0222 } 0223 0224 QString PlasmoidExecutionConfigType::name() const 0225 { 0226 return i18n("Plasmoid Launcher"); 0227 } 0228 0229 QList<KDevelop::LaunchConfigurationPageFactory*> PlasmoidExecutionConfigType::configPages() const 0230 { 0231 return factoryList; 0232 } 0233 0234 QString PlasmoidExecutionConfigType::typeId() 0235 { 0236 return QStringLiteral("PlasmoidLauncherType"); 0237 } 0238 0239 QIcon PlasmoidExecutionConfigType::icon() const 0240 { 0241 return QIcon::fromTheme(QStringLiteral("plasma")); 0242 } 0243 0244 static bool canLaunchMetadataFile(const KDevelop::Path &path) 0245 { 0246 KConfig cfg(path.toLocalFile(), KConfig::SimpleConfig); 0247 KConfigGroup group(&cfg, "Desktop Entry"); 0248 QStringList services = group.readEntry("ServiceTypes", group.readEntry("X-KDE-ServiceTypes", QStringList())); 0249 return services.contains(QStringLiteral("Plasma/Applet")); 0250 } 0251 0252 //don't bother, nobody uses this interface 0253 bool PlasmoidExecutionConfigType::canLaunch(const QUrl& ) const 0254 { 0255 return false; 0256 } 0257 0258 bool PlasmoidExecutionConfigType::canLaunch(KDevelop::ProjectBaseItem* item) const 0259 { 0260 KDevelop::ProjectFolderItem* folder = item->folder(); 0261 if(folder && folder->hasFileOrFolder(QStringLiteral("metadata.desktop"))) { 0262 return canLaunchMetadataFile(KDevelop::Path(folder->path(), QStringLiteral("metadata.desktop"))); 0263 } 0264 return false; 0265 } 0266 0267 void PlasmoidExecutionConfigType::configureLaunchFromItem(KConfigGroup config, KDevelop::ProjectBaseItem* item) const 0268 { 0269 config.writeEntry("PlasmoidIdentifier", item->path().toUrl().toLocalFile()); 0270 } 0271 0272 void PlasmoidExecutionConfigType::configureLaunchFromCmdLineArguments(KConfigGroup /*config*/, const QStringList &/*args*/) const 0273 {} 0274 0275 QMenu* PlasmoidExecutionConfigType::launcherSuggestions() 0276 { 0277 QList<QAction*> found; 0278 const QList<KDevelop::IProject*> projects = KDevelop::ICore::self()->projectController()->projects(); 0279 for (KDevelop::IProject* p : projects) { 0280 const QSet<KDevelop::IndexedString> files = p->fileSet(); 0281 for (const KDevelop::IndexedString& file : files) { 0282 KDevelop::Path path(file.str()); 0283 if (path.lastPathSegment() == QLatin1String("metadata.desktop") && canLaunchMetadataFile(path)) { 0284 path = path.parent(); 0285 QString relUrl = p->path().relativePath(path); 0286 auto* action = new QAction(relUrl, this); 0287 action->setProperty("url", relUrl); 0288 action->setProperty("project", QVariant::fromValue<KDevelop::IProject*>(p)); 0289 connect(action, &QAction::triggered, this, &PlasmoidExecutionConfigType::suggestionTriggered); 0290 found.append(action); 0291 } 0292 } 0293 } 0294 0295 QMenu *m = nullptr; 0296 if(!found.isEmpty()) { 0297 m = new QMenu(i18nc("@title:menu", "Plasmoids")); 0298 m->addActions(found); 0299 } 0300 return m; 0301 } 0302 0303 void PlasmoidExecutionConfigType::suggestionTriggered() 0304 { 0305 auto* action = qobject_cast<QAction*>(sender()); 0306 auto* p = action->property("project").value<KDevelop::IProject*>(); 0307 QString relUrl = action->property("url").toString(); 0308 0309 KDevelop::ILauncher* launcherInstance = launchers().at( 0 ); 0310 QPair<QString,QString> launcher = qMakePair( launcherInstance->supportedModes().at(0), launcherInstance->id() ); 0311 0312 QString name = relUrl.mid(relUrl.lastIndexOf(QLatin1Char('/'))+1); 0313 KDevelop::ILaunchConfiguration* config = KDevelop::ICore::self()->runController()->createLaunchConfiguration(this, launcher, p, name); 0314 KConfigGroup cfg = config->config(); 0315 cfg.writeEntry("PlasmoidIdentifier", relUrl); 0316 emit signalAddLaunchConfiguration(config); 0317 } 0318 0319 #include "moc_plasmoidexecutionconfig.cpp"