You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
258 lines
8.4 KiB
258 lines
8.4 KiB
/***************************************************************************
|
|
* Copyright (C) 2005 by Robert Gruber *
|
|
* rgruber@users.sourceforge.net *
|
|
* *
|
|
* 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 <tqlayout.h>
|
|
#include <tqregexp.h>
|
|
#include <tqstringlist.h>
|
|
#include <tqdatetime.h>
|
|
#include <tqlabel.h>
|
|
|
|
#include <kmessagebox.h>
|
|
#include <kcursor.h>
|
|
#include <klocale.h>
|
|
#include <kdebug.h>
|
|
#include <krfcdate.h>
|
|
#include <klineedit.h>
|
|
#include <kpushbutton.h>
|
|
#include <kdialogbase.h>
|
|
#include <kmessagebox.h>
|
|
|
|
#include <dcopref.h>
|
|
#include <cvsjob_stub.h>
|
|
#include <cvsservice_stub.h>
|
|
|
|
#include "annotatepage.h"
|
|
#include "annotateview.h"
|
|
|
|
AnnotatePage::AnnotatePage( CvsService_stub *cvsService, TQWidget *parent, const char *name, int )
|
|
: DCOPObject( "CvsAnnotatePageDCOPIface" ),
|
|
TQWidget( parent, name? name : "annotateformpage" ),
|
|
m_cvsService( cvsService ), m_cvsAnnotateJob( 0 )
|
|
{
|
|
kdDebug(9006) << "AnnotatePage::AnnotatePage()" << endl;
|
|
|
|
TQLayout *dialogLayout = new TQVBoxLayout( this );
|
|
|
|
//First create the top-line where user can choose a revision
|
|
TQWidget * LayoutWidget = new TQWidget( this );
|
|
TQHBoxLayout * AnnotateLayout = new TQHBoxLayout( LayoutWidget );
|
|
|
|
TQLabel * lblRevision = new TQLabel( LayoutWidget );
|
|
AnnotateLayout->addWidget( lblRevision );
|
|
lblRevision->setText( tr( "Revision:" ) );
|
|
|
|
m_leRevision = new KLineEdit( LayoutWidget );
|
|
AnnotateLayout->addWidget( m_leRevision );
|
|
|
|
m_btnAnnotate = new KPushButton( LayoutWidget );
|
|
AnnotateLayout->addWidget( m_btnAnnotate );
|
|
m_btnAnnotate->setText( tr( "&Annotate" ) );
|
|
m_btnAnnotate->setAccel( TQKeySequence( tr( "Alt+A" ) ) );
|
|
|
|
dialogLayout->add( LayoutWidget );
|
|
|
|
connect( m_btnAnnotate, TQT_SIGNAL(clicked()),
|
|
this, TQT_SLOT(slotNewAnnotate()) );
|
|
connect( m_leRevision, TQT_SIGNAL( returnPressed() ),
|
|
m_btnAnnotate, TQT_SLOT( setFocus() ) );
|
|
|
|
//Nest create the AnnotateView; it will do the actual displaying
|
|
m_annotateView = new AnnotateView(this, "annotateview");
|
|
dialogLayout->add( m_annotateView );
|
|
}
|
|
|
|
AnnotatePage::~AnnotatePage()
|
|
{
|
|
kdDebug(9006) << "AnnotatePage::~Annotate()" << endl;
|
|
cancel();
|
|
delete m_cvsAnnotateJob;
|
|
}
|
|
|
|
void AnnotatePage::startAnnotate( const TQString pathName, const TQString revision )
|
|
{
|
|
kdDebug(9006) << "AnnotatePage::startAnnotate() pathName = " << pathName <<
|
|
"revision = " << revision << endl;
|
|
|
|
m_leRevision->setText(revision);
|
|
|
|
m_pathName = pathName;
|
|
|
|
DCOPRef job = m_cvsService->annotate( pathName, revision );
|
|
m_cvsAnnotateJob = 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 );
|
|
connectDCOPSignal( job.app(), job.obj(), "receivedStdout(TQString)", "slotReceivedOutput(TQString)", true );
|
|
|
|
//clear both the outputbuffer and the AnnotateView
|
|
m_output = "";
|
|
((KListView*)m_annotateView)->clear();
|
|
|
|
kdDebug(9006) << "Running: " << m_cvsAnnotateJob->cvsCommand() << endl;
|
|
m_cvsAnnotateJob->execute();
|
|
}
|
|
|
|
void AnnotatePage::slotJobExited( bool normalExit, int exitStatus )
|
|
{
|
|
kdDebug(9006) << "AnnotatePage::slotJobExited(bool, int)" << endl;
|
|
|
|
if (!normalExit)
|
|
{
|
|
KMessageBox::sorry( this, i18n("Annotate failed with exitStatus == %1").arg( exitStatus), i18n("Annotate Failed") );
|
|
return;
|
|
}
|
|
|
|
//split the collected output and pass the lines to the parser function
|
|
TQStringList lines = TQStringList::split("\n", m_output);
|
|
parseAnnotateOutput(lines);
|
|
}
|
|
|
|
void AnnotatePage::slotReceivedOutput( TQString someOutput )
|
|
{
|
|
kdDebug(9006) << "AnnotatePage::slotReceivedOutput(TQString)" << endl;
|
|
m_output += someOutput;
|
|
}
|
|
|
|
void AnnotatePage::slotReceivedErrors( TQString )
|
|
{
|
|
kdDebug(9006) << "AnnotatePage::slotReceivedErrors(TQString)" << endl;
|
|
}
|
|
|
|
void AnnotatePage::cancel()
|
|
{
|
|
if (m_cvsAnnotateJob && m_cvsAnnotateJob->isRunning())
|
|
m_cvsAnnotateJob->cancel();
|
|
}
|
|
|
|
void AnnotatePage::parseAnnotateOutput(TQStringList& lines)
|
|
{
|
|
kdDebug(9006) << "AnnotatePage::parseAnnotateOutput(TQStringList)" << endl;
|
|
|
|
/**
|
|
* First we need to parse the output of "cvs log" which the dcop-interface delivers
|
|
* everytime annotate is requested.
|
|
* The TQMap m_comments stores the revisions together with the matching comments.
|
|
* The comments will be passed to the AnnotateView in order to display them as TQToolTip
|
|
*/
|
|
TQString line, comment, rev;
|
|
|
|
enum { Begin, Tags, Admin, Revision,
|
|
Author, Branches, Comment, Finished } state;
|
|
|
|
TQStringList::Iterator it = lines.begin();
|
|
state = Begin;
|
|
do
|
|
{
|
|
line = *it;
|
|
|
|
switch( state )
|
|
{
|
|
case Begin:
|
|
if( line == "symbolic names:" )
|
|
state = Tags;
|
|
break;
|
|
case Tags:
|
|
if( line[0] != '\t' )
|
|
state = Admin;
|
|
break;
|
|
case Admin:
|
|
if( line == "----------------------------" )
|
|
state = Revision;
|
|
break;
|
|
case Revision:
|
|
rev = line.section(' ', 1, 1);
|
|
state = Author;
|
|
break;
|
|
case Author:
|
|
state = Branches;
|
|
break;
|
|
case Branches:
|
|
if( !line.startsWith("branches:") )
|
|
{
|
|
state = Comment;
|
|
comment = line;
|
|
}
|
|
break;
|
|
case Comment:
|
|
if( line == "----------------------------" )
|
|
state = Revision;
|
|
else if( line == "=============================================================================" )
|
|
state = Finished;
|
|
if( state == Comment )
|
|
comment += TQString("\n") + line;
|
|
else
|
|
m_comments[rev] = comment;
|
|
break;
|
|
case Finished:
|
|
;
|
|
}
|
|
|
|
if (state == Finished)
|
|
break;
|
|
} while( ++it != lines.end());
|
|
|
|
// move forward until we get to the actual output of "cvs annotate"
|
|
bool notEof = true;
|
|
while( notEof && !(*it).startsWith("*****") ) {
|
|
notEof = (++it != lines.end());
|
|
}
|
|
|
|
//if the upper loop hit the ent of the list, this can only mean, that
|
|
//the selected revision is unknown to CVS
|
|
if (!notEof) {
|
|
KMessageBox::error(this, i18n("The selected revision does not exist."));
|
|
((KListView*)m_annotateView)->clear();
|
|
return;
|
|
}
|
|
++it;
|
|
|
|
TQString author, content;
|
|
TQString oldRevision = ""; //we always store the last revision to recognice...
|
|
bool changeColor = false; //...when the AnnotateView needs to change the coloring
|
|
TQDateTime logDate;
|
|
|
|
do
|
|
{
|
|
line = *it;
|
|
|
|
//the log date should be printed according to the user's global setting
|
|
//so we pass it as TQDateTime to the AnnotateView below
|
|
TQString dateString = line.mid(23, 9);
|
|
if( !dateString.isEmpty() )
|
|
logDate.setTime_t(KRFCDate::parseDate(dateString), Qt::UTC);
|
|
|
|
rev = line.left(13).stripWhiteSpace();
|
|
author = line.mid(14, 8).stripWhiteSpace();
|
|
content = line.mid(35, line.length()-35);
|
|
|
|
comment = m_comments[rev];
|
|
if( comment.isNull() )
|
|
comment = "";
|
|
|
|
if( rev != oldRevision )
|
|
{
|
|
oldRevision = rev;
|
|
changeColor = !changeColor;
|
|
}
|
|
|
|
//finished parsing the annotate line
|
|
//We pass the needed data to the AnnotateView
|
|
m_annotateView->addLine(rev, author, logDate, content, m_comments[rev], changeColor);
|
|
} while (++it != lines.end());
|
|
}
|
|
|
|
void AnnotatePage::slotNewAnnotate()
|
|
{
|
|
startAnnotate(m_pathName, m_leRevision->text());
|
|
}
|
|
|
|
#include "annotatepage.moc"
|