Warning, file /sdk/cervisia/repositorydialog.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * Copyright (C) 1999-2002 Bernd Gehrmann 0003 * bernd@mail.berlios.de 0004 * Copyright (c) 2002-2004 Christian Loose <christian.loose@kdemail.net> 0005 * 0006 * This program is free software; you can redistribute it and/or modify 0007 * it under the terms of the GNU General Public License as published by 0008 * the Free Software Foundation; either version 2 of the License, or 0009 * (at your option) any later version. 0010 * 0011 * This program is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 * GNU General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU General Public License 0017 * along with this program; if not, write to the Free Software 0018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include "repositorydialog.h" 0022 #include "debug.h" 0023 0024 #include <QDialogButtonBox> 0025 #include <QHBoxLayout> 0026 #include <QHeaderView> 0027 #include <QPushButton> 0028 #include <QTreeWidget> 0029 #include <QVBoxLayout> 0030 0031 #include <KConfigGroup> 0032 #include <KHelpClient> 0033 #include <KLocalizedString> 0034 #include <kconfig.h> 0035 #include <kconfiggroup.h> 0036 #include <kmessagebox.h> 0037 0038 #include "addrepositorydialog.h" 0039 #include "cvsloginjobinterface.h" 0040 #include "cvsserviceinterface.h" 0041 #include "misc.h" 0042 #include "progressdialog.h" 0043 #include "repositories.h" 0044 0045 class RepositoryListItem : public QTreeWidgetItem 0046 { 0047 public: 0048 RepositoryListItem(QTreeWidget *parent, const QString &repo, bool loggedin); 0049 0050 void setRsh(const QString &rsh); 0051 void setServer(const QString &server) 0052 { 0053 m_server = server; 0054 } 0055 void setCompression(int compression); 0056 void setIsLoggedIn(bool isLoggedIn); 0057 void setRetrieveCvsignore(bool retrieve) 0058 { 0059 m_retrieveCvsignore = retrieve; 0060 } 0061 0062 QString repository() const 0063 { 0064 return text(0); 0065 } 0066 QString rsh() const 0067 { 0068 QString str = text(1); 0069 return (str.startsWith(QLatin1String("ext (")) ? str.mid(5, str.length() - 6) : QString()); 0070 } 0071 QString server() const 0072 { 0073 return m_server; 0074 } 0075 int compression() const 0076 { 0077 bool ok; 0078 int n = text(2).toInt(&ok); 0079 return ok ? n : -1; 0080 } 0081 bool isLoggedIn() const 0082 { 0083 return m_isLoggedIn; 0084 } 0085 bool retrieveCvsignore() const 0086 { 0087 return m_retrieveCvsignore; 0088 } 0089 0090 private: 0091 void changeLoginStatusColumn(); 0092 0093 private: 0094 QString m_server; 0095 bool m_isLoggedIn; 0096 bool m_retrieveCvsignore; 0097 }; 0098 0099 static bool LoginNeeded(const QString &repository) 0100 { 0101 return repository.startsWith(QLatin1String(":pserver:")) || repository.startsWith(QLatin1String(":sspi:")); 0102 } 0103 0104 RepositoryListItem::RepositoryListItem(QTreeWidget *parent, const QString &repo, bool loggedin) 0105 : QTreeWidgetItem(parent) 0106 , m_isLoggedIn(loggedin) 0107 { 0108 qCDebug(log_cervisia) << "repo=" << repo; 0109 setText(0, repo); 0110 0111 changeLoginStatusColumn(); 0112 } 0113 0114 void RepositoryListItem::setRsh(const QString &rsh) 0115 { 0116 QString repo = repository(); 0117 QString method; 0118 0119 if (repo.startsWith(QLatin1String(":pserver:"))) 0120 method = "pserver"; 0121 else if (repo.startsWith(QLatin1String(":sspi:"))) 0122 method = "sspi"; 0123 else if (repo.contains(':')) { 0124 method = "ext"; 0125 if (!rsh.isEmpty()) { 0126 method += " ("; 0127 method += rsh; 0128 method += ')'; 0129 } 0130 } else 0131 method = "local"; 0132 0133 setText(1, method); 0134 } 0135 0136 void RepositoryListItem::setCompression(int compression) 0137 { 0138 QString compressionStr = (compression >= 0) ? QString::number(compression) : i18n("Default"); 0139 0140 setText(2, compressionStr); 0141 } 0142 0143 void RepositoryListItem::setIsLoggedIn(bool isLoggedIn) 0144 { 0145 m_isLoggedIn = isLoggedIn; 0146 0147 changeLoginStatusColumn(); 0148 } 0149 0150 void RepositoryListItem::changeLoginStatusColumn() 0151 { 0152 QString loginStatus; 0153 0154 if (LoginNeeded(repository())) 0155 loginStatus = m_isLoggedIn ? i18n("Logged in") : i18n("Not logged in"); 0156 else 0157 loginStatus = i18n("No login required"); 0158 0159 setText(3, loginStatus); 0160 } 0161 0162 RepositoryDialog::RepositoryDialog(KConfig &cfg, 0163 OrgKdeCervisia5CvsserviceCvsserviceInterface *cvsService, 0164 const QString &cvsServiceInterfaceName, 0165 QWidget *parent) 0166 : QDialog(parent) 0167 , m_partConfig(cfg) 0168 , m_cvsService(cvsService) 0169 , m_cvsServiceInterfaceName(cvsServiceInterfaceName) 0170 { 0171 setWindowTitle(i18n("Configure Access to Repositories")); 0172 setModal(true); 0173 0174 auto mainLayout = new QVBoxLayout; 0175 setLayout(mainLayout); 0176 0177 auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help); 0178 QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); 0179 okButton->setShortcut(Qt::CTRL | Qt::Key_Return); 0180 connect(okButton, SIGNAL(clicked()), this, SLOT(slotOk())); 0181 connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); 0182 0183 QBoxLayout *hbox = new QHBoxLayout; 0184 hbox->setContentsMargins(0, 0, 0, 0); 0185 mainLayout->addLayout(hbox); 0186 0187 m_repoList = new QTreeWidget; 0188 hbox->addWidget(m_repoList, 10); 0189 m_repoList->setMinimumWidth(fontMetrics().width('0') * 60); 0190 m_repoList->setAllColumnsShowFocus(true); 0191 m_repoList->setRootIsDecorated(false); 0192 m_repoList->setHeaderLabels(QStringList() << i18n("Repository") << i18n("Method") << i18n("Compression") << i18n("Status")); 0193 m_repoList->setFocus(); 0194 0195 connect(m_repoList, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(slotDoubleClicked(QTreeWidgetItem *, int))); 0196 connect(m_repoList, SIGNAL(itemSelectionChanged()), this, SLOT(slotSelectionChanged())); 0197 0198 auto actionbox = new QDialogButtonBox(Qt::Vertical); 0199 QPushButton *addbutton = actionbox->addButton(i18n("Add..."), QDialogButtonBox::ActionRole); 0200 m_modifyButton = actionbox->addButton(i18n("Modify..."), QDialogButtonBox::ActionRole); 0201 m_removeButton = actionbox->addButton(i18n("Remove"), QDialogButtonBox::ActionRole); 0202 m_loginButton = actionbox->addButton(i18n("Login..."), QDialogButtonBox::ActionRole); 0203 m_logoutButton = actionbox->addButton(i18n("Logout"), QDialogButtonBox::ActionRole); 0204 hbox->addWidget(actionbox, 0); 0205 0206 m_loginButton->setEnabled(false); 0207 m_logoutButton->setEnabled(false); 0208 0209 connect(addbutton, SIGNAL(clicked()), this, SLOT(slotAddClicked())); 0210 connect(m_modifyButton, SIGNAL(clicked()), this, SLOT(slotModifyClicked())); 0211 connect(m_removeButton, SIGNAL(clicked()), this, SLOT(slotRemoveClicked())); 0212 connect(m_loginButton, SIGNAL(clicked()), this, SLOT(slotLoginClicked())); 0213 connect(m_logoutButton, SIGNAL(clicked()), this, SLOT(slotLogoutClicked())); 0214 0215 // open cvs DBUS service configuration file 0216 m_serviceConfig = new KConfig("cvsservicerc"); 0217 0218 readCvsPassFile(); 0219 readConfigFile(); 0220 0221 if (QTreeWidgetItem *item = m_repoList->topLevelItem(0)) { 0222 m_repoList->setCurrentItem(item); 0223 item->setSelected(true); 0224 } else { 0225 // we have no item so disable modify and remove button 0226 slotSelectionChanged(); 0227 } 0228 0229 connect(buttonBox, &QDialogButtonBox::helpRequested, this, &RepositoryDialog::slotHelp); 0230 0231 setAttribute(Qt::WA_DeleteOnClose, true); 0232 0233 KConfigGroup cg(&m_partConfig, "RepositoryDialog"); 0234 restoreGeometry(cg.readEntry<QByteArray>("geometry", QByteArray())); 0235 0236 QByteArray state = cg.readEntry<QByteArray>("RepositoryListView", QByteArray()); 0237 m_repoList->header()->restoreState(state); 0238 0239 mainLayout->addWidget(buttonBox); 0240 } 0241 0242 RepositoryDialog::~RepositoryDialog() 0243 { 0244 KConfigGroup cg(&m_partConfig, "RepositoryDialog"); 0245 cg.writeEntry("geometry", saveGeometry()); 0246 0247 cg.writeEntry("RepositoryListView", m_repoList->header()->saveState()); 0248 0249 delete m_serviceConfig; 0250 } 0251 0252 void RepositoryDialog::readCvsPassFile() 0253 { 0254 QStringList list = Repositories::readCvsPassFile(); 0255 Q_FOREACH (const QString &it, list) 0256 (void)new RepositoryListItem(m_repoList, it, true); 0257 } 0258 0259 void RepositoryDialog::readConfigFile() 0260 { 0261 QStringList list = Repositories::readConfigFile(); 0262 0263 // Sort out all list elements which are already in the list view 0264 for (int i = 0; i < m_repoList->topLevelItemCount(); i++) 0265 list.removeAll(m_repoList->topLevelItem(i)->text(0)); 0266 0267 Q_FOREACH (const QString &it, list) 0268 new RepositoryListItem(m_repoList, it, false); 0269 0270 // Now look for the used methods 0271 for (int i = 0; i < m_repoList->topLevelItemCount(); i++) { 0272 auto ritem = static_cast<RepositoryListItem *>(m_repoList->topLevelItem(i)); 0273 0274 // read entries from cvs DBUS service configuration 0275 const KConfigGroup repoGroup = m_serviceConfig->group(QLatin1String("Repository-") + ritem->repository()); 0276 0277 qCDebug(log_cervisia) << "repository=" << ritem->repository(); 0278 0279 QString rsh = repoGroup.readEntry("rsh", QString()); 0280 QString server = repoGroup.readEntry("cvs_server", QString()); 0281 int compression = repoGroup.readEntry("Compression", -1); 0282 bool retrieveFile = repoGroup.readEntry("RetrieveCvsignore", false); 0283 0284 ritem->setRsh(rsh); 0285 ritem->setServer(server); 0286 ritem->setCompression(compression); 0287 ritem->setRetrieveCvsignore(retrieveFile); 0288 } 0289 0290 m_repoList->header()->resizeSections(QHeaderView::ResizeToContents); 0291 } 0292 0293 void RepositoryDialog::slotHelp() 0294 { 0295 KHelpClient::invokeHelp(QLatin1String("accessing-repository")); 0296 } 0297 0298 void RepositoryDialog::slotOk() 0299 { 0300 // Make list of repositories 0301 QStringList list; 0302 for (int i = 0; i < m_repoList->topLevelItemCount(); i++) 0303 list.append(m_repoList->topLevelItem(i)->text(0)); 0304 0305 KConfigGroup reposGroup = m_partConfig.group("Repositories"); 0306 reposGroup.writeEntry("Repos", list); 0307 0308 for (int i = 0; i < m_repoList->topLevelItemCount(); i++) { 0309 auto ritem = static_cast<RepositoryListItem *>(m_repoList->topLevelItem(i)); 0310 0311 // write entries to cvs DBUS service configuration 0312 writeRepositoryData(ritem); 0313 } 0314 0315 // write to disk so other services can reparse the configuration 0316 m_serviceConfig->sync(); 0317 0318 QDialog::accept(); 0319 } 0320 0321 void RepositoryDialog::slotAddClicked() 0322 { 0323 AddRepositoryDialog dlg(m_partConfig, QString(), this); 0324 // default compression level 0325 dlg.setCompression(-1); 0326 if (dlg.exec()) { 0327 QString repo = Cervisia::NormalizeRepository(dlg.repository()); 0328 QString rsh = dlg.rsh(); 0329 QString server = dlg.server(); 0330 int compression = dlg.compression(); 0331 bool retrieveFile = dlg.retrieveCvsignoreFile(); 0332 0333 for (int i = 0; i < m_repoList->topLevelItemCount(); i++) 0334 if (m_repoList->topLevelItem(i)->text(0) == repo) { 0335 KMessageBox::information(this, i18n("This repository is already known.")); 0336 return; 0337 } 0338 0339 auto ritem = new RepositoryListItem(m_repoList, repo, false); 0340 ritem->setRsh(rsh); 0341 ritem->setCompression(compression); 0342 ritem->setRetrieveCvsignore(retrieveFile); 0343 0344 // write entries to cvs DBUS service configuration 0345 writeRepositoryData(ritem); 0346 0347 // write to disk so other services can reparse the configuration 0348 m_serviceConfig->sync(); 0349 } 0350 } 0351 0352 void RepositoryDialog::slotModifyClicked() 0353 { 0354 slotDoubleClicked(m_repoList->currentItem(), 0); 0355 } 0356 0357 void RepositoryDialog::slotRemoveClicked() 0358 { 0359 // logout from pserver accounts so that they don't 0360 // get re-added because of the .cvspass file. (BR #51129) 0361 if (m_logoutButton->isEnabled()) 0362 slotLogoutClicked(); 0363 0364 delete m_repoList->currentItem(); 0365 } 0366 0367 void RepositoryDialog::slotDoubleClicked(QTreeWidgetItem *item, int column) 0368 { 0369 Q_UNUSED(column) 0370 0371 if (!item) 0372 return; 0373 0374 auto ritem = static_cast<RepositoryListItem *>(item); 0375 QString repo = ritem->repository(); 0376 QString rsh = ritem->rsh(); 0377 QString server = ritem->server(); 0378 int compression = ritem->compression(); 0379 bool retrieveFile = ritem->retrieveCvsignore(); 0380 0381 AddRepositoryDialog dlg(m_partConfig, repo, this); 0382 dlg.setRepository(repo); 0383 dlg.setRsh(rsh); 0384 dlg.setServer(server); 0385 dlg.setCompression(compression); 0386 dlg.setRetrieveCvsignoreFile(retrieveFile); 0387 if (dlg.exec()) { 0388 ritem->setRsh(dlg.rsh()); 0389 ritem->setServer(dlg.server()); 0390 ritem->setCompression(dlg.compression()); 0391 ritem->setRetrieveCvsignore(dlg.retrieveCvsignoreFile()); 0392 0393 // write entries to cvs DBUS service configuration 0394 writeRepositoryData(ritem); 0395 0396 // write to disk so other services can reparse the configuration 0397 m_serviceConfig->sync(); 0398 } 0399 } 0400 0401 void RepositoryDialog::slotLoginClicked() 0402 { 0403 auto item = (RepositoryListItem *)m_repoList->currentItem(); 0404 if (!item) 0405 return; 0406 0407 qCDebug(log_cervisia) << "repo=" << item->repository(); 0408 0409 QDBusReply<QDBusObjectPath> job = m_cvsService->login(item->repository()); 0410 if (!job.isValid()) 0411 // TODO: error handling 0412 return; 0413 QDBusObjectPath jobPath = job; 0414 OrgKdeCervisia5CvsserviceCvsloginjobInterface cvsloginjobinterface(m_cvsServiceInterfaceName, jobPath.path(), QDBusConnection::sessionBus(), this); 0415 QDBusReply<bool> reply = cvsloginjobinterface.execute(); 0416 bool success = false; 0417 if (reply.isValid()) 0418 success = reply; 0419 if (!success) { 0420 QDBusReply<QStringList> ret = cvsloginjobinterface.output(); 0421 0422 QStringList output = ret; 0423 KMessageBox::detailedError(this, i18n("Login failed."), output.join("\n")); 0424 return; 0425 } 0426 0427 item->setIsLoggedIn(true); 0428 slotSelectionChanged(); 0429 } 0430 0431 void RepositoryDialog::slotLogoutClicked() 0432 { 0433 auto item = (RepositoryListItem *)m_repoList->currentItem(); 0434 if (!item) 0435 return; 0436 0437 QDBusReply<QDBusObjectPath> job = m_cvsService->logout(item->repository()); 0438 if (!job.isValid()) 0439 // TODO: error handling 0440 return; 0441 0442 ProgressDialog dlg(this, "Logout", m_cvsService->service(), job, "logout", i18n("CVS Logout")); 0443 if (!dlg.execute()) 0444 return; 0445 0446 item->setIsLoggedIn(false); 0447 slotSelectionChanged(); 0448 } 0449 0450 void RepositoryDialog::slotSelectionChanged() 0451 { 0452 // retrieve the selected item 0453 auto item = (RepositoryListItem *)m_repoList->currentItem(); 0454 0455 // is an item in the list view selected? 0456 bool isItemSelected = (item != 0); 0457 m_modifyButton->setEnabled(isItemSelected); 0458 m_removeButton->setEnabled(isItemSelected); 0459 m_loginButton->setEnabled(isItemSelected); 0460 m_logoutButton->setEnabled(isItemSelected); 0461 0462 if (!isItemSelected) 0463 return; 0464 0465 // is this a pserver repository? 0466 if (!LoginNeeded(item->repository())) { 0467 m_loginButton->setEnabled(false); 0468 m_logoutButton->setEnabled(false); 0469 return; 0470 } 0471 0472 // are we logged in? 0473 bool isLoggedIn = item->isLoggedIn(); 0474 m_loginButton->setEnabled(!isLoggedIn); 0475 m_logoutButton->setEnabled(isLoggedIn); 0476 } 0477 0478 void RepositoryDialog::writeRepositoryData(RepositoryListItem *item) 0479 { 0480 // write entries to cvs DBUS service configuration 0481 KConfigGroup repoGroup = m_serviceConfig->group(QLatin1String("Repository-") + item->repository()); 0482 0483 qCDebug(log_cervisia) << "repository=" << item->repository(); 0484 0485 repoGroup.writeEntry("rsh", item->rsh()); 0486 repoGroup.writeEntry("cvs_server", item->server()); 0487 repoGroup.writeEntry("Compression", item->compression()); 0488 repoGroup.writeEntry("RetrieveCvsignore", item->retrieveCvsignore()); 0489 } 0490 0491 // kate: space-indent on; indent-width 4; replace-tabs on;