diff options
Diffstat (limited to 'vcs/cvsservice/cvslogpage.cpp')
-rw-r--r-- | vcs/cvsservice/cvslogpage.cpp | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/vcs/cvsservice/cvslogpage.cpp b/vcs/cvsservice/cvslogpage.cpp new file mode 100644 index 00000000..cf8645e9 --- /dev/null +++ b/vcs/cvsservice/cvslogpage.cpp @@ -0,0 +1,212 @@ +/*************************************************************************** + * Copyright (C) 200?-2003 by KDevelop Authors * + * www.kdevelop.org * + * * + * 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. * + * * + ***************************************************************************/ + +#include <qtextbrowser.h> +#include <qlayout.h> +#include <qregexp.h> +#include <qdir.h> +#include <qstringlist.h> + +#include <kmessagebox.h> +#include <kcursor.h> +#include <klocale.h> +#include <kdebug.h> +#include <dcopref.h> + +#include <cvsjob_stub.h> +#include <cvsservice_stub.h> + +#include "cvsoptions.h" +#include "cvslogpage.h" +#include "cvsdiffpage.h" + +/////////////////////////////////////////////////////////////////////////////// +// class CVSLogPage +/////////////////////////////////////////////////////////////////////////////// + +CVSLogPage::CVSLogPage( CvsService_stub *cvsService, QWidget *parent, const char *name, int ) + : DCOPObject( "CvsLogPageDCOPIface" ), + QWidget( parent, name? name : "logformpage" ), + m_cvsService( cvsService ), m_cvsLogJob( 0 ) +{ + QLayout *thisLayout = new QVBoxLayout( this ); + + m_textBrowser = new QTextBrowser( this, "logbrowser" ); + thisLayout->add( m_textBrowser ); + + /// \FIXME a better way? + m_textBrowser->setMinimumWidth(fontMetrics().width('X')*50); + m_textBrowser->setMinimumHeight(fontMetrics().width('X')*43); + + connect( m_textBrowser, SIGNAL(linkClicked( const QString& )), this, SLOT(slotLinkClicked( const QString& )) ); +} + +/////////////////////////////////////////////////////////////////////////////// + +CVSLogPage::~CVSLogPage() +{ + kdDebug(9006) << "CVSLogPage::~CVSLogPage()" << endl; + cancel(); + delete m_cvsLogJob; +} + +/////////////////////////////////////////////////////////////////////////////// + +void CVSLogPage::startLog( const QString &workDir, const QString &pathName ) +{ + kdDebug(9006) << "CVSLogPage::start() here! workDir = " << workDir << + ", pathName = " << pathName << endl; + +// CvsOptions *options = CvsOptions::instance(); + // "cvs log" needs to be done on relative-path basis + m_pathName = pathName; + m_diffStrings.clear(); + + DCOPRef job = m_cvsService->log( pathName ); + m_cvsLogJob = new CvsJob_stub( job.app(), job.obj() ); + + // establish connections to the signals of the cvs m_job + connectDCOPSignal( job.app(), job.obj(), "jobExited(bool, int)", "slotJobExited(bool, int)", true ); + // We'll read the ouput directly from the job ... + connectDCOPSignal( job.app(), job.obj(), "receivedStdout(QString)", "slotReceivedOutput(QString)", true ); +// connectDCOPSignal( job.app(), job.obj(), "receivedStderr(QString)", "slotReceivedErrors(QString)", true ); + + kdDebug(9006) << "Running: " << m_cvsLogJob->cvsCommand() << endl; + m_cvsLogJob->execute(); +} + +/////////////////////////////////////////////////////////////////////////////// +/* +void CVSLogPage::parseLogContent( const QString& text ) +{ + kdDebug(9006) << "CVSLogPage::parseLogContent()" << endl; + + m_base->contents->clear(); + + QStringList l = QStringList::split( "----------------------------", text ); + QString header = l.front(); + l.pop_front(); + + for( QStringList::Iterator it=l.begin(); it!=l.end(); ++it ) + { + const QString &s = *it; + if (s) + { + m_base->contents->append( s ); + m_base->contents->append( "<hr>" ); + } + } +} +*/ +/////////////////////////////////////////////////////////////////////////////// + +void CVSLogPage::slotJobExited( bool normalExit, int exitStatus ) +{ +// m_part->core()->running( m_part, false ); + if (!normalExit) + { + KMessageBox::sorry( this, i18n("Log failed with exitStatus == %1").arg( exitStatus), i18n("Log Failed") ); + return; + } + + static QRegExp rx_sep( "\\-+" ); + static QRegExp rx_sep2( "=+" ); + static QRegExp rx_date( "date: .* author: .* state: .* lines: .*" ); + // "revision" followed by one or more decimals followed by a optional dot + static QRegExp rx_rev( "revision ((\\d+\\.?)+)" ); + m_textBrowser->setTextFormat( QTextBrowser::PlainText ); + + for (size_t i=0; i<m_diffStrings.count(); ++i) { + QString s = m_diffStrings[i]; + kdDebug(9006) << "Examining line: " << s << endl; + if ( rx_rev.exactMatch(s) ) + { + QString ver = rx_rev.cap( 1 ); + QString dstr = "<b>" + s + "</b> "; + int lastVer = ver.section( '.', -1 ).toInt() - 1; + if ( lastVer > 0 ) { + QString lv = ver.left( ver.findRev( "." ) + 1 ) + QString::number( lastVer ); + dstr += " [<a href=\"diff:/" + m_pathName + "/" + lv + "_" + ver + "\">diff to " + lv + "</a>]"; + } + m_textBrowser->setTextFormat( QTextBrowser::RichText ); + m_textBrowser->append( dstr ); + m_textBrowser->setTextFormat( QTextBrowser::PlainText ); + } + else if ( rx_date.exactMatch(s) ) + { + m_textBrowser->setTextFormat( QTextBrowser::RichText ); + m_textBrowser->append( "<i>" + s + "</i>" ); + m_textBrowser->setTextFormat( QTextBrowser::PlainText ); + } + else if ( rx_sep.exactMatch(s) || rx_sep2.exactMatch(s) ) + { + m_textBrowser->append( "\n" ); + m_textBrowser->setTextFormat( QTextBrowser::RichText ); + m_textBrowser->append( "<hr>" ); + m_textBrowser->setTextFormat( QTextBrowser::PlainText ); + } else + { + m_textBrowser->append( s ); + } + } + m_logTextBackup = m_textBrowser->source(); + +// emit jobFinished( normalExit, exitStatus ); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CVSLogPage::slotLinkClicked( const QString &link ) +{ + kdDebug(9006) << "CVSLogPage::slotLinkClicked()" << endl; + + // The text browser clears the page so we go back to our old one + /// \FIXME in this way I lose the source + m_textBrowser->setSource( m_logTextBackup ); + + QString ver = link.mid( link.findRev( "/" ) + 1 ); + QString v1 = ver.section( '_', 0, 0 ); + QString v2 = ver.section( '_', 1, 1 ); + if ( v1.isEmpty() || v2.isEmpty() ) + { + m_textBrowser->append( i18n( "invalid link clicked" ) ); + return; + } + + emit diffRequested( m_pathName, v1, v2 ); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CVSLogPage::slotReceivedOutput( QString someOutput ) +{ + kdDebug(9006) << "CVSLogPage::slotReceivedOutput(QString)" << endl; + + kdDebug(9006) << "OUTPUT: " << someOutput << endl; + m_diffStrings += m_outputBuffer.process(someOutput); +} + +/////////////////////////////////////////////////////////////////////////////// + +void CVSLogPage::slotReceivedErrors( QString someErrors ) +{ + kdDebug(9006) << "ERRORS: " << someErrors << endl; +} + +/////////////////////////////////////////////////////////////////////////////// + +void CVSLogPage::cancel() +{ + if (m_cvsLogJob && m_cvsLogJob->isRunning()) + m_cvsLogJob->cancel(); +} + +#include "cvslogpage.moc" |