File indexing completed on 2024-05-05 04:41:00
0001 /* 0002 SPDX-FileCopyrightText: 2007 Andreas Pakulat <apaku@gmx.de> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "svnblamejob.h" 0008 0009 #include "svnblamejob_p.h" 0010 0011 #include <QMutexLocker> 0012 0013 #include <KLocalizedString> 0014 0015 #include "svnclient.h" 0016 #include <QDateTime> 0017 0018 SvnInternalBlameJob::SvnInternalBlameJob( SvnJobBase* parent ) 0019 : SvnInternalJobBase( parent ) 0020 { 0021 m_startRevision.setRevisionValue(QVariant::fromValue(KDevelop::VcsRevision::Start), 0022 KDevelop::VcsRevision::Special ); 0023 m_endRevision.setRevisionValue(QVariant::fromValue(KDevelop::VcsRevision::Head), 0024 KDevelop::VcsRevision::Special ); 0025 } 0026 0027 void SvnInternalBlameJob::run(ThreadWeaver::JobPointer /*self*/, ThreadWeaver::Thread* /*thread*/) 0028 { 0029 initBeforeRun(); 0030 0031 QByteArray ba = location().toString( QUrl::PreferLocalFile | QUrl::StripTrailingSlash ).toUtf8(); 0032 0033 svn::Client cli(m_ctxt); 0034 svn::AnnotatedFile* file; 0035 try 0036 { 0037 file = cli.annotate( ba.data(), 0038 createSvnCppRevisionFromVcsRevision( startRevision() ), 0039 createSvnCppRevisionFromVcsRevision( endRevision() ) ); 0040 }catch( const svn::ClientException& ce ) 0041 { 0042 qCDebug(PLUGIN_SVN) << "Exception while blaming file: " 0043 << location() 0044 << QString::fromUtf8( ce.message() ); 0045 setErrorMessage( QString::fromUtf8( ce.message() ) ); 0046 m_success = false; 0047 return; 0048 } 0049 svn_revnum_t minrev = -1, maxrev = -1; 0050 for (const auto& line : *file) { 0051 const svn_revnum_t lineRevision = line.revision(); 0052 if (lineRevision < minrev || minrev == -1) { 0053 minrev = lineRevision; 0054 } 0055 if (lineRevision > maxrev || maxrev == -1 ) { 0056 maxrev = lineRevision; 0057 } 0058 } 0059 QHash<svn_revnum_t,QString> commitMessages; 0060 try 0061 { 0062 const svn::LogEntries* entries = cli.log( ba.data(), svn::Revision(minrev), svn::Revision(maxrev), false, false ); 0063 for (const auto& entry : *entries) { 0064 commitMessages[entry.revision] = QString::fromUtf8(entry.message.c_str() ); 0065 } 0066 }catch( const svn::ClientException& ce ) 0067 { 0068 qCDebug(PLUGIN_SVN) << "Exception while fetching log messages for blame: " 0069 << location() 0070 << QString::fromUtf8( ce.message() ); 0071 setErrorMessage( QString::fromUtf8( ce.message() ) ); 0072 m_success = false; 0073 } 0074 for (const auto& svnLine : *file) { 0075 KDevelop::VcsAnnotationLine line; 0076 line.setAuthor(QString::fromUtf8(svnLine.author().c_str())); 0077 line.setDate(QDateTime::fromString(QString::fromUtf8(svnLine.date().c_str()), Qt::ISODate)); 0078 line.setText(QString::fromUtf8(svnLine.line().c_str())); 0079 KDevelop::VcsRevision rev; 0080 rev.setRevisionValue(QVariant(qlonglong(svnLine.revision())), KDevelop::VcsRevision::GlobalNumber); 0081 line.setRevision( rev ); 0082 line.setLineNumber(svnLine.lineNumber()); 0083 line.setCommitMessage(commitMessages[svnLine.revision()]); 0084 emit blameLine( line ); 0085 } 0086 } 0087 0088 void SvnInternalBlameJob::setLocation( const QUrl &url ) 0089 { 0090 QMutexLocker l( &m_mutex ); 0091 m_location = url; 0092 } 0093 0094 QUrl SvnInternalBlameJob::location() const 0095 { 0096 QMutexLocker l( &m_mutex ); 0097 return m_location; 0098 } 0099 0100 KDevelop::VcsRevision SvnInternalBlameJob::startRevision() const 0101 { 0102 QMutexLocker l( &m_mutex ); 0103 return m_startRevision; 0104 } 0105 0106 KDevelop::VcsRevision SvnInternalBlameJob::endRevision() const 0107 { 0108 QMutexLocker l( &m_mutex ); 0109 return m_endRevision; 0110 } 0111 0112 void SvnInternalBlameJob::setStartRevision( const KDevelop::VcsRevision& rev ) 0113 { 0114 QMutexLocker l( &m_mutex ); 0115 m_startRevision = rev; 0116 } 0117 0118 void SvnInternalBlameJob::setEndRevision( const KDevelop::VcsRevision& rev ) 0119 { 0120 QMutexLocker l( &m_mutex ); 0121 m_endRevision = rev; 0122 } 0123 0124 SvnBlameJob::SvnBlameJob( KDevSvnPlugin* parent ) 0125 : SvnJobBaseImpl( parent, KDevelop::OutputJob::Silent ) 0126 { 0127 setType( KDevelop::VcsJob::Annotate ); 0128 connect(m_job.data(), &SvnInternalBlameJob::blameLine, 0129 this, &SvnBlameJob::blameLineReceived); 0130 setObjectName(i18n("Subversion Annotate")); 0131 } 0132 0133 QVariant SvnBlameJob::fetchResults() 0134 { 0135 QList<QVariant> results = m_annotations; 0136 m_annotations.clear(); 0137 return results; 0138 } 0139 0140 void SvnBlameJob::start() 0141 { 0142 if ( !m_job->location().isValid() ) { 0143 internalJobFailed(); 0144 setErrorText( i18n( "Not enough information to blame location" ) ); 0145 } else { 0146 qCDebug(PLUGIN_SVN) << "blaming url:" << m_job->location(); 0147 startInternalJob(); 0148 } 0149 } 0150 0151 void SvnBlameJob::setLocation( const QUrl &url ) 0152 { 0153 if( status() == KDevelop::VcsJob::JobNotStarted ) 0154 m_job->setLocation( url ); 0155 } 0156 0157 void SvnBlameJob::setStartRevision( const KDevelop::VcsRevision& rev ) 0158 { 0159 if( status() == KDevelop::VcsJob::JobNotStarted ) 0160 m_job->setStartRevision( rev ); 0161 } 0162 0163 void SvnBlameJob::setEndRevision( const KDevelop::VcsRevision& rev ) 0164 { 0165 if( status() == KDevelop::VcsJob::JobNotStarted ) 0166 m_job->setEndRevision( rev ); 0167 } 0168 0169 void SvnBlameJob::blameLineReceived( const KDevelop::VcsAnnotationLine& line ) 0170 { 0171 m_annotations.append(QVariant::fromValue(line)); 0172 emit resultsReady( this ); 0173 } 0174 0175 #include "moc_svnblamejob_p.cpp" 0176 #include "moc_svnblamejob.cpp"