/*************************************************************************** * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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"