📄 revisiontree.cpp
字号:
/*************************************************************************** * Copyright (C) 2005-2007 by Rajko Albrecht * * ral@alwins-world.de * * * * 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 "revisiontree.h"#include "../stopdlg.h"#include "src/svnqt/log_entry.hpp"#include "src/svnqt/cache/LogCache.hpp"#include "src/svnqt/cache/ReposLog.hpp"#include "helpers/sub2qt.h"#include "revtreewidget.h"#include "revgraphview.h"#include "elogentry.h"#include "src/svnfrontend/fronthelpers/cursorstack.h"#include <kdebug.h>#include <kprogress.h>#include <klocale.h>#include <kapp.h>#include <klistview.h>#include <kmdcodec.h>#include <kmessagebox.h>#include <qwidget.h>#include <qdatetime.h>#include <qlabel.h>#include <qfile.h>#include <qtextstream.h>#include <qregexp.h>#define INTERNALCOPY 1#define INTERNALRENAME 2class RtreeData{public: RtreeData(); virtual ~RtreeData(); QMap<long,eLog_Entry> m_History; svn::LogEntriesMap m_OldHistory; long max_rev,min_rev; KProgressDialog*progress; QTime m_stopTick; QWidget*dlgParent; RevTreeWidget*m_TreeDisplay; svn::Client*m_Client; QObject* m_Listener; bool getLogs(const QString&,const svn::Revision&startr,const svn::Revision&endr,const QString&origin);};RtreeData::RtreeData() : max_rev(-1),min_rev(-1){ progress=0; m_TreeDisplay = 0; m_Client = 0; dlgParent = 0; m_Listener = 0;}RtreeData::~RtreeData(){ delete progress;}bool RtreeData::getLogs(const QString&reposRoot,const svn::Revision&startr,const svn::Revision&endr,const QString&origin){ if (!m_Listener||!m_Client) { return false; } try { CursorStack a(Qt::BusyCursor); StopDlg sdlg(m_Listener,dlgParent, 0,"Logs",i18n("Getting logs - hit cancel for abort")); //m_Client->log(reposRoot,endr,startr,m_OldHistory,startr,true,false,0); svn::cache::ReposLog rl(m_Client,reposRoot); rl.simpleLog(m_OldHistory,startr,endr,true); } catch (svn::ClientException ce) { kdDebug()<<ce.msg() << endl; KMessageBox::error(0,i18n("Could not retrieve logs, reason:\n%1").arg(ce.msg())); return false; } return true;}RevisionTree::RevisionTree(svn::Client*aClient, QObject*aListener, const QString& reposRoot, const svn::Revision&startr,const svn::Revision&endr, const QString&origin, const svn::Revision& baserevision, QWidget*treeParent,QWidget*parent) :m_InitialRevsion(0),m_Path(origin),m_Valid(false){ m_Data = new RtreeData; m_Data->m_Client=aClient; m_Data->m_Listener=aListener; m_Data->dlgParent=parent; if (!m_Data->getLogs(reposRoot,startr,endr,origin)) { return; } long possible_rev=-1; kdDebug()<<"Origin: "<<origin << endl; m_Data->progress=new KProgressDialog( parent,"progressdlg",i18n("Scanning logs"),i18n("Scanning the logs for %1").arg(origin),true); m_Data->progress->setMinimumDuration(100); m_Data->progress->show(); m_Data->progress->setAllowCancel(true); m_Data->progress->progressBar()->setTotalSteps(m_Data->m_OldHistory.size()); m_Data->progress->setAutoClose(false); m_Data->progress->show(); bool cancel=false; svn::LogEntriesMap::Iterator it; unsigned count = 0; for (it=m_Data->m_OldHistory.begin();it!=m_Data->m_OldHistory.end();++it) { m_Data->progress->progressBar()->setProgress(count); kapp->processEvents(); if (m_Data->progress->wasCancelled()) { cancel=true; break; } if (it.key()>m_Data->max_rev) { m_Data->max_rev=it.key(); } if (it.key()<m_Data->min_rev||m_Data->min_rev==-1) { m_Data->min_rev=it.key(); } if (baserevision.kind()==svn_opt_revision_date) { if (baserevision.date()<=it.data().date && possible_rev==-1||possible_rev>it.key()) { possible_rev=it.key(); } } ++count; } if (baserevision.kind()==svn_opt_revision_head||baserevision.kind()==svn_opt_revision_working) { m_Baserevision=m_Data->max_rev; } else if (baserevision.kind()==svn_opt_revision_number) { m_Baserevision=baserevision.revnum(); } else if (baserevision.kind()==svn_opt_revision_date) { m_Baserevision=possible_rev; } if (!cancel) { kdDebug( )<<" max revision " << m_Data->max_rev << " min revision " << m_Data->min_rev << endl; if (topDownScan()) { kdDebug()<<"topdown end"<<endl; m_Data->progress->setAutoReset(true); m_Data->progress->progressBar()->setTotalSteps(100); m_Data->progress->progressBar()->setPercentageVisible(false); m_Data->m_stopTick.restart(); m_Data->m_TreeDisplay=new RevTreeWidget(m_Data->m_Listener,m_Data->m_Client,treeParent); if (bottomUpScan(m_InitialRevsion,0,m_Path,0)) { kdDebug()<<"Bottom up end"<<endl; m_Valid=true; m_Data->m_TreeDisplay->setBasePath(reposRoot); m_Data->m_TreeDisplay->dumpRevtree(); } else { delete m_Data->m_TreeDisplay; m_Data->m_TreeDisplay = 0; } } } else { kdDebug()<<"Canceld"<<endl; } m_Data->progress->hide();}RevisionTree::~RevisionTree(){ delete m_Data;}bool RevisionTree::isDeleted(long revision,const QString&path){ for (unsigned i = 0;i<m_Data->m_History[revision].changedPaths.count();++i) { if (isParent(m_Data->m_History[revision].changedPaths[i].path,path) && m_Data->m_History[revision].changedPaths[i].action=='D') { return true; } } return false;}bool RevisionTree::topDownScan(){ m_Data->progress->progressBar()->setTotalSteps(m_Data->max_rev-m_Data->min_rev); bool cancel=false; QString label; QString olabel = m_Data->progress->labelText(); for (long j=m_Data->max_rev;j>=m_Data->min_rev;--j) { m_Data->progress->progressBar()->setProgress(m_Data->max_rev-j); kapp->processEvents(); if (m_Data->progress->wasCancelled()) { cancel=true; break; } for (unsigned i = 0; i<m_Data->m_OldHistory[j].changedPaths.count();++i) { if (i>0 && i%100==0) { if (m_Data->progress->wasCancelled()) { cancel=true; break; } label = i18n("%1<br>Check change entry %2 of %3") .arg(olabel).arg(i).arg(m_Data->m_OldHistory[j].changedPaths.count()); m_Data->progress->setLabel(label); kapp->processEvents(); } /* find min revision of item */ if (m_Data->m_OldHistory[j].changedPaths[i].action=='A'&& isParent(m_Data->m_OldHistory[j].changedPaths[i].path,m_Path)) { if (!m_Data->m_OldHistory[j].changedPaths[i].copyFromPath.isEmpty()) { if (m_InitialRevsion<m_Data->m_OldHistory[j].revision) { QString tmpPath = m_Path; QString r = m_Path.mid(m_Data->m_OldHistory[j].changedPaths[i].path.length()); m_Path=m_Data->m_OldHistory[j].changedPaths[i].copyFromPath; m_Path+=r; } } else if (m_Data->m_OldHistory[j].changedPaths[i].path==m_Path && m_Data->m_OldHistory[j].changedPaths[i].copyToPath.isEmpty()){ // here it is added m_InitialRevsion = m_Data->m_OldHistory[j].revision; } } } } kdDebug()<<"Stage one done"<<endl; if (cancel==true) { return false; } m_Data->progress->setLabel(olabel); /* find forward references and filter them out */ for (long j=m_Data->max_rev;j>=m_Data->min_rev;--j) { m_Data->progress->progressBar()->setProgress(m_Data->max_rev-j); kapp->processEvents(); if (m_Data->progress->wasCancelled()) { cancel=true; break; } for (unsigned i = 0; i<m_Data->m_OldHistory[j].changedPaths.count();++i) { if (i>0 && i%100==0) { if (m_Data->progress->wasCancelled()) { cancel=true; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -