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.
tdevelop/vcs/cvsservice/cvsprocesswidget.cpp

289 lines
9.3 KiB

/***************************************************************************
* Copyright (C) 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 <tqpainter.h>
#include <tqregexp.h>
#include <dcopref.h>
#include <kstatusbar.h>
#include <kdebug.h>
#include <klocale.h>
#include <kmessagebox.h>
#include "kdevpartcontroller.h"
#include "kdevmainwindow.h"
#include "kdevcore.h"
#include "cvspart.h"
#include "cvsprocesswidget.h"
#include "processwidget.h"
#include <cvsjob_stub.h>
#include <cvsservice_stub.h>
// Undef
//#define MYDCOPDEBUG
///////////////////////////////////////////////////////////////////////////////
// class CvsProcessWidget
///////////////////////////////////////////////////////////////////////////////
#ifdef MYDCOPDEBUG
int g_dcopExitCounter = 0;
int g_dcopOutCounter = 0;
int g_dcopErrCounter = 0;
#endif
CvsProcessWidget::CvsProcessWidget( CvsService_stub *service, CvsServicePart *part, TQWidget *tqparent, const char *name )
: DCOPObject( "CvsProcessWidgetDCOPIface" ),
TQTextEdit( tqparent, name ),
m_part( part ), m_service( service ), m_job( 0 )
{
setReadOnly( true );
setTextFormat( TQt::LogText );
TQStyleSheetItem *style = 0;
style = new TQStyleSheetItem( styleSheet(), "goodtag" );
style->setColor( "black" );
style = new TQStyleSheetItem( styleSheet(), "errortag" );
style->setColor( "red" );
style->setFontWeight( TQFont::Bold );
style = new TQStyleSheetItem( styleSheet(), "infotag" );
style->setColor( "blue" );
style = new TQStyleSheetItem( styleSheet(), "cvs_conflict" );
style->setColor( "red" );
style = new TQStyleSheetItem( styleSheet(), "cvs_added" );
style->setColor( "green" );
style = new TQStyleSheetItem( styleSheet(), "cvs_removed" );
style->setColor( "yellow" );
style = new TQStyleSheetItem( styleSheet(), "cvs_updated" );
style->setColor( "lightblue" );
style = new TQStyleSheetItem( styleSheet(), "cvs_modified" );
style->setColor( "darkgreen" );
style = new TQStyleSheetItem( styleSheet(), "cvs_unknown" );
style->setColor( "gray" );
}
///////////////////////////////////////////////////////////////////////////////
CvsProcessWidget::~CvsProcessWidget()
{
if (m_job)
{
delete m_job;
}
}
///////////////////////////////////////////////////////////////////////////////
bool CvsProcessWidget::isAlreadyWorking() const
{
if (m_job)
return m_job->isRunning();
else
return false;
}
///////////////////////////////////////////////////////////////////////////////
void CvsProcessWidget::clear()
{
TQTextEdit::clear();
this->m_errors = TQString();
this->m_output = TQString();
}
///////////////////////////////////////////////////////////////////////////////
bool CvsProcessWidget::startJob( const DCOPRef &aJob )
{
kdDebug(9006) << "CvsProcessWidget::startJob(const DCOPRef &) here!" << endl;
clear();
m_part->mainWindow()->raiseView( this );
m_part->core()->running( m_part, true );
// create a DCOP stub for the non-concurrent cvs job
if (m_job)
{
delete m_job;
m_job = 0;
}
m_job = new CvsJob_stub( aJob.app(), aJob.obj() );
// establish connections to the signals of the cvs m_job
connectDCOPSignal( m_job->app(), m_job->obj(), "jobExited(bool, int)", "slotJobExited(bool, int)", true );
connectDCOPSignal( m_job->app(), m_job->obj(), "receivedStdout(TQString)", "slotReceivedOutput(TQString)", true );
connectDCOPSignal( m_job->app(), m_job->obj(), "receivedStderr(TQString)", "slotReceivedErrors(TQString)", true );
// get command line and add it to output buffer
TQString cmdLine = m_job->cvsCommand();
m_part->mainWindow()->statusBar()->message( cmdLine );
kdDebug(9006) << "Running: " << cmdLine << endl;
// disconnect 3rd party slots from our signals
disconnect( TQT_SIGNAL(jobFinished(bool, int)) );
showInfo( i18n("Started job: %1").tqarg( cmdLine ) );
#ifdef MYDCOPDEBUG
g_dcopExitCounter = 0;
g_dcopOutCounter = 0;
g_dcopErrCounter = 0;
#endif
return m_job->execute();
}
///////////////////////////////////////////////////////////////////////////////
void CvsProcessWidget::cancelJob()
{
kdDebug(9006) << "CvsProcessWidget::cancelJob() here!" << endl;
if (!m_job || !m_job->isRunning())
return;
m_job->cancel();
delete m_job; m_job = 0;
showInfo( i18n("*** Job canceled by user request ***") );
m_part->core()->running( m_part, false );
}
///////////////////////////////////////////////////////////////////////////////
void CvsProcessWidget::slotJobExited( bool normalExit, int exitStatus )
{
kdDebug(9006) << "CvsProcessWidget::slotJobExited(bool, int) here!" << endl;
#ifdef MYDCOPDEBUG
g_dcopExitCounter++;
kdDebug(9006) << "MYDCOPDEBUG: dcopExitCounter == " << g_dcopExitCounter << endl;
#endif
if (m_job)
{
disconnectDCOPSignal( m_job->app(), m_job->obj(), "jobExited(bool, int)", "slotJobExited(bool, int)" );
disconnectDCOPSignal( m_job->app(), m_job->obj(), "receivedStdout(TQString)", "slotReceivedOutput(TQString)" );
disconnectDCOPSignal( m_job->app(), m_job->obj(), "receivedStderr(TQString)", "slotReceivedErrors(TQString)" );
delete m_job;
m_job = 0;
}
TQString exitMsg = i18n("Job finished with exitCode == %1");
showInfo( exitMsg.tqarg( exitStatus) );
m_part->core()->running( m_part, false );
m_part->mainWindow()->statusBar()->message( i18n("Done CVS command ..."), 2000 );
emit jobFinished( normalExit, exitStatus );
}
///////////////////////////////////////////////////////////////////////////////
void CvsProcessWidget::slotReceivedOutput( TQString someOutput )
{
kdDebug(9006) << "CvsProcessWidget::slotReceivedOutput(TQString) here!" << endl;
#ifdef MYDCOPDEBUG
g_dcopOutCounter++;
kdDebug(9006) << "MYDCOPDEBUG: dcopOutCounter == " << g_dcopOutCounter << endl;
#endif
TQStringList strings = m_outputBuffer.process( someOutput );
if (strings.count() > 0)
{
m_output += strings;
showOutput( strings );
scrollToBottom();
}
}
///////////////////////////////////////////////////////////////////////////////
void CvsProcessWidget::slotReceivedErrors( TQString someErrors )
{
kdDebug(9006) << "CvsProcessWidget::slotReceivedErrors(TQString) here!" << endl;
#ifdef MYDCOPDEBUG
g_dcopErrCounter++;
kdDebug(9006) << "MYDCOPDEBUG: dcopErrCounter == " << g_dcopErrCounter << endl;
#endif
TQStringList strings = m_errorBuffer.process( someErrors );
if (strings.count() > 0)
{
m_errors += strings;
showError( strings );
scrollToBottom();
}
}
///////////////////////////////////////////////////////////////////////////////
void CvsProcessWidget::showInfo( const TQStringList &msg )
{
for (TQStringList::const_iterator it = msg.begin(); it != msg.end(); ++it)
append( "<infotag>" + (*it) + "</infotag>" );
}
///////////////////////////////////////////////////////////////////////////////
void CvsProcessWidget::showError( const TQStringList &msg )
{
for (TQStringList::const_iterator it = msg.begin(); it != msg.end(); ++it)
append( "<errortag>" + (*it) + "</errortag>" );
}
///////////////////////////////////////////////////////////////////////////////
void CvsProcessWidget::showOutput( const TQStringList &msg )
{
for (TQStringList::const_iterator it = msg.begin(); it != msg.end(); ++it)
{
// @todo here we can interpret lines as [C], [M], ...
const TQString &line = (*it);
//If the line already contains tags we need to replace the
//delimiters with the corresponding HTML code so that they are no longer
//recognized as tags.
//This will prevent TQTextEdit from crashing on trying to parse the tags.
//This should fix BUG:99590
TQString lineNew(line);
lineNew.replace("<", "&lt;");
lineNew.replace(">", "&gt;");
lineNew.replace("&", "&amp;");
if (line.startsWith( "C " ))
append( "<cvs_conflict>" + lineNew + "</cvs_conflict>" );
else if (line.startsWith( "M " ))
append( "<cvs_modified>" + lineNew + "</cvs_modified>" );
else if (line.startsWith( "A " ))
append( "<cvs_added>" + lineNew + "</cvs_added>" );
else if (line.startsWith( "R " ))
append( "<cvs_removed>" + lineNew + "</cvs_removed>" );
else if (line.startsWith( "U " ))
append( "<cvs_updated>" + lineNew + "</cvs_updated>" );
else if (line.startsWith( "? " ))
append( "<cvs_unknown>" + lineNew + "</cvs_unknown>" );
else // default
append( "<goodtag>" + lineNew + "</goodtag>" );
}
}
#include "cvsprocesswidget.moc"