/*************************************************************************** * 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 #include #include #include #include #include #include #include "kdevpartcontroller.h" #include "kdevmainwindow.h" #include "kdevcore.h" #include "cvspart.h" #include "cvsprocesswidget.h" #include "processwidget.h" #include #include // 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 *parent, const char *name ) : DCOPObject( "CvsProcessWidgetDCOPIface" ), TQTextEdit( parent, 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").arg( 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.arg( 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( "" + (*it) + "" ); } /////////////////////////////////////////////////////////////////////////////// void CvsProcessWidget::showError( const TQStringList &msg ) { for (TQStringList::const_iterator it = msg.begin(); it != msg.end(); ++it) append( "" + (*it) + "" ); } /////////////////////////////////////////////////////////////////////////////// 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("<", "<"); lineNew.replace(">", ">"); lineNew.replace("&", "&"); if (line.startsWith( "C " )) append( "" + lineNew + "" ); else if (line.startsWith( "M " )) append( "" + lineNew + "" ); else if (line.startsWith( "A " )) append( "" + lineNew + "" ); else if (line.startsWith( "R " )) append( "" + lineNew + "" ); else if (line.startsWith( "U " )) append( "" + lineNew + "" ); else if (line.startsWith( "? " )) append( "" + lineNew + "" ); else // default append( "" + lineNew + "" ); } } #include "cvsprocesswidget.moc"