File indexing completed on 2024-04-14 05:35:35
0001 /*************************************************************************** 0002 * Copyright (C) 2005-2009 by Rajko Albrecht * 0003 * ral@alwins-world.de * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 0019 ***************************************************************************/ 0020 0021 #include "kdesvnview.h" 0022 #include "settings/kdesvnsettings.h" 0023 #include "svnfrontend/createrepodlg.h" 0024 #include "svnfrontend/dumprepo_impl.h" 0025 #include "svnfrontend/fronthelpers/propertylist.h" 0026 #include "svnfrontend/hotcopydlg_impl.h" 0027 #include "svnfrontend/loaddmpdlg_impl.h" 0028 #include "svnfrontend/maintreewidget.h" 0029 #include "svnfrontend/stopdlg.h" 0030 #include "svnqt/repository.h" 0031 #include "svnqt/svnqttypes.h" 0032 #include "svnqt/url.h" 0033 #include "svnqt/version_check.h" 0034 0035 #include <QFileInfo> 0036 #include <QMenu> 0037 #include <QProgressBar> 0038 #include <QSplitter> 0039 #include <QTemporaryFile> 0040 #include <QTextBrowser> 0041 0042 #include <KActionCollection> 0043 #include <KIO/FileCopyJob> 0044 #include <KJobWidgets> 0045 #include <KLocalizedString> 0046 #include <KMessageBox> 0047 0048 kdesvnView::kdesvnView(KActionCollection *aCollection, QWidget *parent, bool full) 0049 : QWidget(parent) 0050 , svn::repository::RepositoryListener() 0051 , m_Collection(aCollection) 0052 , m_currentUrl() 0053 , m_CacheProgressBar(nullptr) 0054 , m_ReposCancel(false) 0055 { 0056 Q_UNUSED(full); 0057 setFocusPolicy(Qt::StrongFocus); 0058 setupActions(); 0059 0060 m_topLayout = new QVBoxLayout(this); 0061 0062 m_Splitter = new QSplitter(this); 0063 m_Splitter->setOrientation(Qt::Vertical); 0064 0065 // m_TreeWidget=new kdesvnfilelist(m_Collection,m_Splitter); 0066 m_TreeWidget = new MainTreeWidget(m_Collection, m_Splitter); 0067 0068 m_infoSplitter = new QSplitter(m_Splitter); 0069 m_infoSplitter->setOrientation(Qt::Horizontal); 0070 m_infoSplitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 0071 m_LogWindow = new QTextBrowser(m_infoSplitter); 0072 m_LogWindow->setContextMenuPolicy(Qt::CustomContextMenu); 0073 connect(m_LogWindow, &QWidget::customContextMenuRequested, this, &kdesvnView::onCustomLogWindowContextMenuRequested); 0074 Propertylist *pl = new Propertylist(m_infoSplitter); 0075 pl->setCommitchanges(true); 0076 connect(pl, &Propertylist::sigSetProperty, m_TreeWidget, &MainTreeWidget::slotChangeProperties); 0077 connect(m_TreeWidget, &MainTreeWidget::sigProplist, pl, &Propertylist::displayList); 0078 connect(m_TreeWidget, &MainTreeWidget::sigProplist, pl, &Propertylist::displayList); 0079 0080 m_TreeWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 0081 0082 m_topLayout->addWidget(m_Splitter); 0083 connect(m_TreeWidget, &MainTreeWidget::sigLogMessage, this, &kdesvnView::slotAppendLog); 0084 connect(m_TreeWidget, &MainTreeWidget::changeCaption, this, &kdesvnView::slotSetTitle); 0085 connect(m_TreeWidget, &MainTreeWidget::sigShowPopup, this, &kdesvnView::slotDispPopup); 0086 connect(m_TreeWidget, &MainTreeWidget::sigUrlOpened, this, &kdesvnView::sigUrlOpened); 0087 connect(m_TreeWidget, &MainTreeWidget::sigSwitchUrl, this, &kdesvnView::sigSwitchUrl); 0088 connect(m_TreeWidget, &MainTreeWidget::sigUrlChanged, this, &kdesvnView::slotUrlChanged); 0089 connect(m_TreeWidget, &MainTreeWidget::sigCacheStatus, this, &kdesvnView::fillCacheStatus); 0090 connect(m_TreeWidget, &MainTreeWidget::sigExtraStatusMessage, this, &kdesvnView::sigExtraStatusMessage); 0091 0092 connect(this, &kdesvnView::sigMakeBaseDirs, m_TreeWidget, &MainTreeWidget::slotMkBaseDirs); 0093 0094 KConfigGroup cs(Kdesvnsettings::self()->config(), "kdesvn-mainlayout"); 0095 QByteArray t1 = cs.readEntry("split1", QByteArray()); 0096 if (!t1.isEmpty()) { 0097 m_Splitter->restoreState(t1); 0098 } 0099 if (m_infoSplitter) { 0100 t1 = cs.readEntry("infosplit", QByteArray()); 0101 if (!t1.isEmpty()) { 0102 m_infoSplitter->restoreState(t1); 0103 } 0104 } 0105 } 0106 0107 void kdesvnView::slotAppendLog(const QString &text) 0108 { 0109 m_LogWindow->append(text); 0110 } 0111 0112 kdesvnView::~kdesvnView() 0113 { 0114 } 0115 0116 void kdesvnView::slotSavestate() 0117 { 0118 KConfigGroup cs(Kdesvnsettings::self()->config(), "kdesvn-mainlayout"); 0119 cs.writeEntry("split1", m_Splitter->saveState()); 0120 if (m_infoSplitter) { 0121 cs.writeEntry("infosplit", m_infoSplitter->saveState()); 0122 } 0123 } 0124 0125 void kdesvnView::slotUrlChanged(const QUrl &url) 0126 { 0127 m_currentUrl = url; 0128 slotSetTitle(url.toString()); 0129 emit sigUrlChanged(url); 0130 slotOnURL(i18n("Repository opened")); 0131 } 0132 0133 QUrl kdesvnView::currentUrl() const 0134 { 0135 return m_currentUrl; 0136 } 0137 0138 bool kdesvnView::openUrl(const QUrl &url) 0139 { 0140 /* transform of url must be done in part! otherwise we will run into different troubles! */ 0141 m_currentUrl.clear(); 0142 QUrl _url(url); 0143 bool open = false; 0144 if (_url.isLocalFile()) { 0145 QString query = _url.query(); 0146 _url.setQuery(QString()); 0147 QString _f = _url.path(); 0148 QFileInfo f(_f); 0149 if (!f.isDir()) { 0150 m_currentUrl.clear(); 0151 return open; 0152 } 0153 if (query.length() > 1) { 0154 _url.setQuery(query); 0155 } 0156 } else { 0157 if (!svn::Url::isValid(url.scheme())) { 0158 return open; 0159 } 0160 } 0161 m_LogWindow->clear(); 0162 slotSetTitle(url.toString()); 0163 if (m_TreeWidget->openUrl(url)) { 0164 slotOnURL(i18n("Repository opened")); 0165 m_currentUrl = url; 0166 open = true; 0167 } else { 0168 QString t = m_TreeWidget->lastError(); 0169 if (t.isEmpty()) { 0170 t = i18n("Could not open repository"); 0171 } 0172 slotOnURL(t); 0173 } 0174 return open; 0175 } 0176 0177 void kdesvnView::slotOnURL(const QString &url) 0178 { 0179 emit signalChangeStatusbar(url); 0180 } 0181 0182 void kdesvnView::slotSetTitle(const QString &title) 0183 { 0184 // emit signalChangeCaption(title); 0185 emit setWindowCaption(title); 0186 } 0187 0188 /*! 0189 \fn kdesvnView::closeMe() 0190 */ 0191 void kdesvnView::closeMe() 0192 { 0193 m_TreeWidget->closeMe(); 0194 m_LogWindow->clear(); 0195 slotOnURL(i18n("No repository open")); 0196 } 0197 0198 void kdesvnView::slotDispPopup(const QString &item, QWidget **target) 0199 { 0200 emit sigShowPopup(item, target); 0201 } 0202 0203 /*! 0204 \fn kdesvnView::refreshCurrentTree() 0205 */ 0206 void kdesvnView::refreshCurrentTree() 0207 { 0208 m_TreeWidget->refreshCurrentTree(); 0209 } 0210 0211 /*! 0212 \fn kdesvnView::slotSettingsChanged() 0213 */ 0214 void kdesvnView::slotSettingsChanged() 0215 { 0216 m_TreeWidget->slotSettingsChanged(); 0217 } 0218 0219 /*! 0220 \fn kdesvnView::slotCreateRepo() 0221 */ 0222 void kdesvnView::slotCreateRepo() 0223 { 0224 QPointer<CreaterepoDlg> dlg(new CreaterepoDlg(this)); 0225 if (dlg->exec() != QDialog::Accepted) { 0226 delete dlg; 0227 return; 0228 } 0229 QScopedPointer<svn::repository::Repository> _rep(new svn::repository::Repository(this)); 0230 bool ok = true; 0231 closeMe(); 0232 try { 0233 _rep->CreateOpen(dlg->parameter()); 0234 } catch (const svn::ClientException &e) { 0235 slotAppendLog(e.msg()); 0236 ok = false; 0237 } 0238 if (!ok) { 0239 delete dlg; 0240 return; 0241 } 0242 bool createdirs = dlg->createMain(); 0243 // repo is created on a local path 0244 const QUrl path = QUrl::fromLocalFile(dlg->targetDir()); 0245 delete dlg; 0246 openUrl(path); 0247 if (createdirs) { 0248 emit sigMakeBaseDirs(); 0249 } 0250 } 0251 0252 void kdesvnView::slotHotcopy() 0253 { 0254 QPointer<KSvnSimpleOkDialog> dlg(new KSvnSimpleOkDialog(QStringLiteral("hotcopy_repo_size"), QApplication::activeModalWidget())); 0255 dlg->setWindowTitle(i18nc("@title:window", "Hotcopy a Repository")); 0256 dlg->setWithCancelButton(); 0257 0258 HotcopyDlg_impl *ptr = new HotcopyDlg_impl(dlg); 0259 dlg->addWidget(ptr); 0260 if (dlg->exec() != QDialog::Accepted) { 0261 delete dlg; 0262 return; 0263 } 0264 bool cleanlogs = ptr->cleanLogs(); 0265 QString src = ptr->srcPath(); 0266 QString dest = ptr->destPath(); 0267 delete dlg; 0268 if (src.isEmpty() || dest.isEmpty()) { 0269 return; 0270 } 0271 try { 0272 svn::repository::Repository::hotcopy(src, dest, cleanlogs); 0273 slotAppendLog(i18n("Hotcopy finished.")); 0274 } catch (const svn::ClientException &e) { 0275 slotAppendLog(e.msg()); 0276 } 0277 } 0278 0279 void kdesvnView::slotLoaddump() 0280 { 0281 QPointer<KSvnSimpleOkDialog> dlg(new KSvnSimpleOkDialog(QStringLiteral("loaddump_repo_size"), this)); 0282 dlg->setWindowTitle(i18nc("@title:window", "Load a Repository From an svndump")); 0283 dlg->setWithCancelButton(); 0284 0285 LoadDmpDlg_impl *ptr(new LoadDmpDlg_impl(dlg)); 0286 dlg->addWidget(ptr); 0287 if (dlg->exec() != QDialog::Accepted) { 0288 delete dlg; 0289 return; 0290 } 0291 svn::repository::Repository _rep(this); 0292 m_ReposCancel = false; 0293 0294 try { 0295 _rep.Open(ptr->repository()); 0296 } catch (const svn::ClientException &e) { 0297 slotAppendLog(e.msg()); 0298 return; 0299 } 0300 0301 svn::repository::Repository::LOAD_UUID _act; 0302 switch (ptr->uuidAction()) { 0303 case 1: 0304 _act = svn::repository::Repository::UUID_IGNORE_ACTION; 0305 break; 0306 case 2: 0307 _act = svn::repository::Repository::UUID_FORCE_ACTION; 0308 break; 0309 case 0: 0310 default: 0311 _act = svn::repository::Repository::UUID_DEFAULT_ACTION; 0312 break; 0313 } 0314 0315 const QUrl _uri = ptr->dumpFile(); 0316 QString _input; 0317 QTemporaryFile tmpfile; 0318 if (_uri.isLocalFile()) { 0319 _input = _uri.toLocalFile(); 0320 } else { 0321 tmpfile.open(); 0322 KIO::FileCopyJob *job = KIO::file_copy(_uri, QUrl::fromLocalFile(tmpfile.fileName())); 0323 KJobWidgets::setWindow(job, this); 0324 if (!job->exec()) { 0325 KMessageBox::error(this, job->errorString()); 0326 return; 0327 } 0328 _input = tmpfile.fileName(); 0329 } 0330 0331 try { 0332 StopDlg sdlg(nullptr, this, i18nc("@title:window", "Load Dump"), i18n("Loading a dump into a repository.")); 0333 _rep.loaddump(_input, _act, ptr->parentPath(), ptr->usePre(), ptr->usePost(), ptr->validateProps()); 0334 slotAppendLog(i18n("Loading dump finished.")); 0335 } catch (const svn::ClientException &e) { 0336 slotAppendLog(e.msg()); 0337 } 0338 delete dlg; 0339 } 0340 0341 void kdesvnView::slotDumpRepo() 0342 { 0343 QPointer<KSvnSimpleOkDialog> dlg(new KSvnSimpleOkDialog(QStringLiteral("dump_repo_size"), QApplication::activeModalWidget())); 0344 dlg->setWindowTitle(i18nc("@title:window", "Dump a Repository")); 0345 dlg->setWithCancelButton(); 0346 0347 DumpRepo_impl *ptr(new DumpRepo_impl(dlg)); 0348 dlg->addWidget(ptr); 0349 if (dlg->exec() != QDialog::Accepted) { 0350 delete dlg; 0351 return; 0352 } 0353 0354 const QString re = ptr->reposPath(); 0355 const QString out = ptr->targetFile(); 0356 const bool incr = ptr->incremental(); 0357 const bool diffs = ptr->use_deltas(); 0358 const int s = ptr->startNumber(); 0359 const int e = ptr->endNumber(); 0360 0361 delete dlg; 0362 0363 m_ReposCancel = false; 0364 svn::Revision st = svn::Revision::UNDEFINED; 0365 svn::Revision en = svn::Revision::UNDEFINED; 0366 0367 if (s > -1) { 0368 st = s; 0369 } 0370 if (e > -1) { 0371 en = e; 0372 } 0373 0374 svn::repository::Repository *_rep(new svn::repository::Repository(this)); 0375 try { 0376 _rep->Open(re); 0377 } catch (const svn::ClientException &e) { 0378 slotAppendLog(e.msg()); 0379 delete _rep; 0380 return; 0381 } 0382 0383 try { 0384 StopDlg sdlg(nullptr, this, i18nc("@title:window", "Dump"), i18n("Dumping a repository")); 0385 _rep->dump(out, st, en, incr, diffs); 0386 slotAppendLog(i18n("Dump finished.")); 0387 } catch (const svn::ClientException &e) { 0388 slotAppendLog(e.msg()); 0389 } 0390 delete _rep; 0391 } 0392 0393 /*! 0394 \fn kdesvnView::setupActions() 0395 */ 0396 void kdesvnView::setupActions() 0397 { 0398 } 0399 0400 void kdesvnView::sendWarning(const QString &aMsg) 0401 { 0402 slotAppendLog(aMsg); 0403 } 0404 0405 void kdesvnView::sendError(const QString &aMsg) 0406 { 0407 slotAppendLog(aMsg); 0408 } 0409 0410 bool kdesvnView::isCanceld() 0411 { 0412 if (!m_ReposCancel) { 0413 emit tickProgress(); 0414 return false; 0415 } 0416 return true; 0417 } 0418 0419 void kdesvnView::setCanceled(bool how) 0420 { 0421 m_ReposCancel = how; 0422 } 0423 0424 void kdesvnView::fillCacheStatus(qlonglong current, qlonglong max) 0425 { 0426 if (current > -1 && max > -1) { 0427 if (!m_CacheProgressBar) { 0428 m_CacheProgressBar = new QProgressBar(this); 0429 m_CacheProgressBar->setRange(0, (int)max); 0430 m_topLayout->addWidget(m_CacheProgressBar); 0431 m_CacheProgressBar->setFormat(i18n("Inserted %v not cached log entries of %m.")); 0432 } 0433 if (!m_CacheProgressBar->isVisible()) { 0434 m_CacheProgressBar->show(); 0435 } 0436 m_CacheProgressBar->setValue((int)current); 0437 } else { 0438 delete m_CacheProgressBar; 0439 m_CacheProgressBar = nullptr; 0440 } 0441 } 0442 0443 void kdesvnView::stopCacheThreads() 0444 { 0445 m_TreeWidget->stopLogCache(); 0446 } 0447 0448 void kdesvnView::onCustomLogWindowContextMenuRequested(const QPoint &pos) 0449 { 0450 QPointer<QMenu> menu = m_LogWindow->createStandardContextMenu(); 0451 QAction *clearAction = new QAction(tr("Clear"), menu.data()); 0452 clearAction->setEnabled(!m_LogWindow->toPlainText().isEmpty()); 0453 connect(clearAction, &QAction::triggered, m_LogWindow, &QTextEdit::clear); 0454 menu->addAction(clearAction); 0455 menu->exec(m_LogWindow->mapToGlobal(pos)); 0456 delete menu; 0457 } 0458 0459 #include "moc_kdesvnview.cpp"