File indexing completed on 2024-04-21 04:35:57
0001 /*************************************************************************** 0002 * Copyright 2007 Niko Sams <niko.sams@gmail.com> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify * 0005 * it under the terms of the GNU General Public License as published by * 0006 * the Free Software Foundation; either version 2 of the License, or * 0007 * (at your option) any later version. * 0008 * * 0009 ***************************************************************************/ 0010 0011 #include "kdevuploadplugin.h" 0012 0013 #include <QAction> 0014 #include <QVBoxLayout> 0015 #include <QSignalMapper> 0016 #include <QStandardItemModel> 0017 #include <QItemDelegate> 0018 #include "kdevuploaddebug.h" 0019 0020 #include <KPluginFactory> 0021 #include <KLocalizedString> 0022 #include <kparts/mainwindow.h> 0023 #include <kactioncollection.h> 0024 #include <kactionmenu.h> 0025 0026 #include <interfaces/icore.h> 0027 #include <interfaces/iproject.h> 0028 #include <interfaces/iprojectcontroller.h> 0029 #include <interfaces/iuicontroller.h> 0030 #include <interfaces/iplugincontroller.h> 0031 #include <interfaces/context.h> 0032 #include <interfaces/contextmenuextension.h> 0033 #include <project/projectconfigpage.h> 0034 #include <project/projectmodel.h> 0035 #include <outputview/ioutputview.h> 0036 #include <serialization/indexedstring.h> 0037 0038 #include "uploaddialog.h" 0039 #include "profilesfiletree.h" 0040 #include "uploadjob.h" 0041 #include "uploadprojectmodel.h" 0042 #include "uploadprofilemodel.h" 0043 #include "uploadprofileitem.h" 0044 #include "uploadpreferences.h" 0045 #include "allprofilesmodel.h" 0046 #include <interfaces/idocumentcontroller.h> 0047 0048 #include "version.h" 0049 0050 K_PLUGIN_FACTORY_WITH_JSON(UploadFactory, "kdevupload.json", registerPlugin<UploadPlugin>(); ) 0051 0052 class FilesTreeViewFactory: public KDevelop::IToolViewFactory{ 0053 public: 0054 FilesTreeViewFactory(UploadPlugin* plugin, AllProfilesModel* model) 0055 : m_plugin(plugin), m_allProfilesModel(model) {} 0056 0057 QWidget* create(QWidget *parent = nullptr) override 0058 { 0059 ProfilesFileTree* w = new ProfilesFileTree(m_plugin, parent); 0060 w->setModel(m_allProfilesModel); 0061 return w; 0062 } 0063 0064 QString id() const override 0065 { 0066 return "org.quanta.UploadFactory"; 0067 } 0068 0069 Qt::DockWidgetArea defaultPosition() const override 0070 { 0071 return Qt::RightDockWidgetArea; 0072 } 0073 0074 private: 0075 UploadPlugin* m_plugin; 0076 AllProfilesModel* m_allProfilesModel; 0077 }; 0078 0079 UploadPlugin::UploadPlugin(QObject *parent, const QVariantList &) 0080 : KDevelop::IPlugin(QStringLiteral("kdevupload"), parent), m_outputModel(nullptr), m_filesTreeViewFactory(nullptr) 0081 { 0082 connect(core()->projectController(), SIGNAL(projectOpened(KDevelop::IProject*)), 0083 this, SLOT(projectOpened(KDevelop::IProject*))); 0084 connect(core()->projectController(), SIGNAL(projectClosed(KDevelop::IProject*)), 0085 this, SLOT(projectClosed(KDevelop::IProject*))); 0086 connect(core()->documentController(), SIGNAL(documentActivated(KDevelop::IDocument*)), 0087 SLOT(documentActivated(KDevelop::IDocument*))); 0088 connect(core()->documentController(), SIGNAL(documentClosed(KDevelop::IDocument*)), 0089 SLOT(documentClosed(KDevelop::IDocument*))); 0090 0091 setXMLFile( QStringLiteral( "kdevupload.rc" ) ); 0092 0093 m_allProfilesModel = new AllProfilesModel(this); 0094 connect(m_allProfilesModel, SIGNAL(rowsInserted(QModelIndex, int, int)), 0095 this, SLOT(profilesRowChanged())); 0096 connect(m_allProfilesModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), 0097 this, SLOT(profilesRowChanged())); 0098 connect(m_allProfilesModel, SIGNAL(modelReset()), 0099 this, SLOT(profilesRowChanged())); 0100 0101 setupActions(); 0102 } 0103 0104 UploadPlugin::~UploadPlugin() 0105 { 0106 } 0107 0108 void UploadPlugin::setupActions() 0109 { 0110 m_signalMapper = new QSignalMapper(this); 0111 connect(m_signalMapper, SIGNAL(mapped(QObject*)), 0112 this, SLOT(projectUpload(QObject*))); 0113 m_projectUploadActionMenu = new KActionMenu(i18n("&Upload Project"), this); 0114 m_projectUploadActionMenu->setIcon(QIcon::fromTheme("go-up")); 0115 m_projectUploadActionMenu->setToolTip(i18n("Upload project")); 0116 m_projectUploadActionMenu->setVisible(false); //make it visible when there are upload profiles 0117 actionCollection()->addAction("project_upload", m_projectUploadActionMenu); 0118 0119 m_quickUploadCurrentFile = actionCollection()->addAction("quick_upload_current_file"); 0120 m_quickUploadCurrentFile->setText( i18n("&Quick Upload Current File") ); 0121 m_quickUploadCurrentFile->setIcon(QIcon::fromTheme("go-up")); 0122 m_projectUploadActionMenu->setEnabled(false); 0123 connect(m_quickUploadCurrentFile, SIGNAL(triggered(bool)), SLOT(quickUploadCurrentFile())); 0124 } 0125 0126 void UploadPlugin::projectOpened(KDevelop::IProject* project) 0127 { 0128 UploadProfileModel* model = new UploadProfileModel(); 0129 model->setProject(project); 0130 m_projectProfileModels.insert(project, model); 0131 m_allProfilesModel->addModel(model); 0132 0133 documentActivated(core()->documentController()->activeDocument()); 0134 } 0135 0136 void UploadPlugin::projectClosed(KDevelop::IProject* project) 0137 { 0138 QAction* action = m_projectUploadActions.value(project); 0139 if (action) { 0140 m_projectUploadActions.remove(project); 0141 m_projectUploadActionMenu->removeAction(action); 0142 delete action; 0143 } 0144 UploadProfileModel* model = m_projectProfileModels.value(project); 0145 if (model) { 0146 m_projectProfileModels.remove(project); 0147 m_allProfilesModel->removeModel(model); 0148 delete model; 0149 } 0150 } 0151 0152 0153 void UploadPlugin::documentActivated(KDevelop::IDocument* doc) 0154 { 0155 if (!doc) { 0156 m_quickUploadCurrentFile->setEnabled(false); 0157 return; 0158 } 0159 KDevelop::IProject* project = core()->projectController()->findProjectForUrl(doc->url()); 0160 if (!project) { 0161 m_quickUploadCurrentFile->setEnabled(false); 0162 return; 0163 } 0164 QList<KDevelop::ProjectFileItem*> files = project->filesForPath(KDevelop::IndexedString(doc->url())); 0165 if (files.isEmpty()) { 0166 m_quickUploadCurrentFile->setEnabled(false); 0167 return; 0168 } 0169 UploadProfileModel* profileModel = m_projectProfileModels.value(project); 0170 if (!profileModel || !profileModel->rowCount()) { 0171 m_quickUploadCurrentFile->setEnabled(false); 0172 return; 0173 } 0174 0175 m_quickUploadCurrentFile->setEnabled(true); 0176 } 0177 0178 0179 void UploadPlugin::documentClosed(KDevelop::IDocument* ) 0180 { 0181 m_quickUploadCurrentFile->setEnabled(false); 0182 } 0183 0184 0185 void UploadPlugin::projectUpload(QObject* p) 0186 { 0187 KDevelop::IProject* project = qobject_cast<KDevelop::IProject*>(p); 0188 if (project) { 0189 UploadDialog dialog(project, this, core()->uiController()->activeMainWindow()); 0190 UploadProfileModel* model = m_projectProfileModels.value(project); 0191 dialog.setProfileModel(model); 0192 dialog.exec(); 0193 } 0194 } 0195 0196 KDevelop::ContextMenuExtension UploadPlugin::contextMenuExtension(KDevelop::Context* context, QWidget* parent) 0197 { 0198 if (context->type() == KDevelop::Context::ProjectItemContext) { 0199 KDevelop::ContextMenuExtension cmExtension; 0200 KDevelop::ProjectItemContext *itemCtx = dynamic_cast<KDevelop::ProjectItemContext*>(context); 0201 if (itemCtx) { 0202 m_ctxUrlList.clear(); 0203 Q_FOREACH (KDevelop::ProjectBaseItem* _item, itemCtx->items()) { 0204 if (_item->folder() || _item->file()) { 0205 m_ctxUrlList << _item; 0206 } 0207 } 0208 if (!m_ctxUrlList.isEmpty()) { 0209 KDevelop::IProject* project = m_ctxUrlList.at(0)->project(); 0210 UploadProfileModel* model = m_projectProfileModels.value(project); 0211 if (model && model->rowCount()) { 0212 QAction *action; 0213 action = new QAction(i18n("Upload..."), parent); 0214 action->setIcon(QIcon::fromTheme("go-up")); 0215 connect(action, SIGNAL(triggered()), this, SLOT(upload())); 0216 cmExtension.addAction(KDevelop::ContextMenuExtension::FileGroup, action); 0217 0218 action = new QAction(i18n("Quick Upload"), parent); 0219 action->setIcon(QIcon::fromTheme("go-up")); 0220 connect(action, SIGNAL(triggered()), this, SLOT(quickUpload())); 0221 cmExtension.addAction(KDevelop::ContextMenuExtension::FileGroup, action); 0222 0223 return cmExtension; 0224 } 0225 } 0226 } 0227 } 0228 return KDevelop::IPlugin::contextMenuExtension(context, parent); 0229 } 0230 0231 int UploadPlugin::perProjectConfigPages() const 0232 { 0233 return 1; 0234 } 0235 0236 0237 KDevelop::ConfigPage* UploadPlugin::perProjectConfigPage(int number, const KDevelop::ProjectConfigOptions& options, QWidget* parent) 0238 { 0239 return number == 0 ? new UploadPreferences(this, options, parent) : nullptr; 0240 } 0241 0242 void UploadPlugin::upload() 0243 { 0244 if (m_ctxUrlList.isEmpty()) return; 0245 KDevelop::IProject* project = m_ctxUrlList.at(0)->project(); 0246 0247 UploadDialog dialog(project, this, core()->uiController()->activeMainWindow()); 0248 UploadProfileModel* model = m_projectProfileModels.value(project); 0249 dialog.setProfileModel(model); 0250 dialog.setRootItem(m_ctxUrlList.at(0)); 0251 dialog.exec(); 0252 } 0253 void UploadPlugin::quickUpload() 0254 { 0255 if (m_ctxUrlList.isEmpty()) return; 0256 KDevelop::IProject* project = m_ctxUrlList.at(0)->project(); 0257 0258 UploadProjectModel* model = new UploadProjectModel(project); 0259 model->setSourceModel(project->projectItem()->model()); 0260 model->setRootItem(m_ctxUrlList.at(0)); 0261 0262 UploadProfileModel* profileModel = m_projectProfileModels.value(project); 0263 for (int i = 0; i < profileModel->rowCount(); i++) { 0264 UploadProfileItem* item = profileModel->uploadItem(i); 0265 if (item->isDefault()) { 0266 KConfigGroup c = item->profileConfigGroup(); 0267 if (c.isValid()) { 0268 model->setProfileConfigGroup(c); 0269 } 0270 break; 0271 } 0272 } 0273 0274 UploadJob* job = new UploadJob(project, model, core()->uiController()->activeMainWindow()); 0275 job->setQuickUpload(true); 0276 job->setOutputModel(outputModel()); 0277 job->start(); 0278 } 0279 0280 0281 void UploadPlugin::quickUploadCurrentFile() 0282 { 0283 KDevelop::IDocument* doc = core()->documentController()->activeDocument(); 0284 if (!doc) return; 0285 KDevelop::IProject* project = KDevelop::ICore::self()->projectController()->findProjectForUrl(doc->url()); 0286 if (!project) return; 0287 QList<KDevelop::ProjectFileItem*> files = project->filesForPath(KDevelop::IndexedString(doc->url())); 0288 if (files.isEmpty()) return; 0289 0290 UploadProjectModel* model = new UploadProjectModel(project); 0291 model->setSourceModel(project->projectItem()->model()); 0292 model->setRootItem(files.first()); 0293 0294 UploadProfileModel* profileModel = m_projectProfileModels.value(project); 0295 for (int i = 0; i < profileModel->rowCount(); i++) { 0296 UploadProfileItem* item = profileModel->uploadItem(i); 0297 if (item->isDefault()) { 0298 KConfigGroup c = item->profileConfigGroup(); 0299 if (c.isValid()) { 0300 model->setProfileConfigGroup(c); 0301 } 0302 break; 0303 } 0304 } 0305 0306 UploadJob* job = new UploadJob(project, model, core()->uiController()->activeMainWindow()); 0307 job->setQuickUpload(true); 0308 job->setOutputModel(outputModel()); 0309 job->start(); 0310 0311 } 0312 0313 0314 QStandardItemModel* UploadPlugin::outputModel() 0315 { 0316 if (m_outputModel) return m_outputModel; 0317 IPlugin* plugin = core()->pluginController()->pluginForExtension( "org.kdevelop.IOutputView" ); 0318 Q_ASSERT(plugin); 0319 if (plugin) { 0320 KDevelop::IOutputView* view = plugin->extension<KDevelop::IOutputView>(); 0321 int tvid = view->registerToolView(i18n("Upload")); 0322 int id = view->registerOutputInToolView(tvid, i18n("Output"), KDevelop::IOutputView::AllowUserClose | KDevelop::IOutputView::AutoScroll); 0323 m_outputModel = new QStandardItemModel(this); 0324 0325 view->setModel(id, m_outputModel); 0326 view->setDelegate(id, new QItemDelegate(m_outputModel)); 0327 0328 return m_outputModel; 0329 } 0330 return nullptr; 0331 } 0332 0333 void UploadPlugin::profilesRowChanged() 0334 { 0335 if (m_allProfilesModel->rowCount()) { 0336 if (!m_filesTreeViewFactory) { 0337 m_filesTreeViewFactory = new FilesTreeViewFactory(this, m_allProfilesModel); 0338 core()->uiController()->addToolView(i18n("Upload Profiles"), m_filesTreeViewFactory); 0339 } 0340 } else { 0341 if (m_filesTreeViewFactory) { 0342 core()->uiController()->removeToolView(m_filesTreeViewFactory); 0343 m_filesTreeViewFactory = nullptr; 0344 } 0345 } 0346 Q_FOREACH(UploadProfileModel* model, m_projectProfileModels) { 0347 KDevelop::IProject* project = model->project(); 0348 0349 if (model->rowCount()) { 0350 if (!m_projectUploadActions.contains(project)) { 0351 QAction* action = new QAction(project->name(), m_projectUploadActionMenu); 0352 connect(action, SIGNAL(triggered()), m_signalMapper, SLOT(map())); 0353 m_signalMapper->setMapping(action, project); 0354 m_projectUploadActions.insert(project, action); 0355 m_projectUploadActionMenu->addAction(action); 0356 m_projectUploadActionMenu->setVisible(true); 0357 } 0358 } else { 0359 if (m_projectUploadActions.contains(project)) { 0360 QAction* action = m_projectUploadActions.value(project); 0361 m_projectUploadActions.remove(project); 0362 m_projectUploadActionMenu->removeAction(action); 0363 m_signalMapper->removeMappings(action); 0364 delete action; 0365 } 0366 } 0367 } 0368 0369 if (m_projectUploadActions.isEmpty()) { 0370 m_projectUploadActionMenu->setVisible(false); 0371 } 0372 } 0373 0374 #include "kdevuploadplugin.moc" 0375 // kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on