summaryrefslogtreecommitdiffstats
path: root/vcs/cvsservice/cvsprocesswidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'vcs/cvsservice/cvsprocesswidget.cpp')
-rw-r--r--vcs/cvsservice/cvsprocesswidget.cpp288
1 files changed, 288 insertions, 0 deletions
diff --git a/vcs/cvsservice/cvsprocesswidget.cpp b/vcs/cvsservice/cvsprocesswidget.cpp
new file mode 100644
index 00000000..2d41a356
--- /dev/null
+++ b/vcs/cvsservice/cvsprocesswidget.cpp
@@ -0,0 +1,288 @@
+/***************************************************************************
+ * 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 <qpainter.h>
+#include <qregexp.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, QWidget *parent, const char *name )
+ : DCOPObject( "CvsProcessWidgetDCOPIface" ),
+ QTextEdit( parent, name ),
+ m_part( part ), m_service( service ), m_job( 0 )
+{
+ setReadOnly( true );
+ setTextFormat( Qt::LogText );
+
+ QStyleSheetItem *style = 0;
+ style = new QStyleSheetItem( styleSheet(), "goodtag" );
+ style->setColor( "black" );
+
+ style = new QStyleSheetItem( styleSheet(), "errortag" );
+ style->setColor( "red" );
+ style->setFontWeight( QFont::Bold );
+
+ style = new QStyleSheetItem( styleSheet(), "infotag" );
+ style->setColor( "blue" );
+
+ style = new QStyleSheetItem( styleSheet(), "cvs_conflict" );
+ style->setColor( "red" );
+
+ style = new QStyleSheetItem( styleSheet(), "cvs_added" );
+ style->setColor( "green" );
+
+ style = new QStyleSheetItem( styleSheet(), "cvs_removed" );
+ style->setColor( "yellow" );
+
+ style = new QStyleSheetItem( styleSheet(), "cvs_updated" );
+ style->setColor( "lightblue" );
+
+ style = new QStyleSheetItem( styleSheet(), "cvs_modified" );
+ style->setColor( "darkgreen" );
+
+ style = new QStyleSheetItem( 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()
+{
+ QTextEdit::clear();
+ this->m_errors = QString::null;
+ this->m_output = QString::null;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+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(QString)", "slotReceivedOutput(QString)", true );
+ connectDCOPSignal( m_job->app(), m_job->obj(), "receivedStderr(QString)", "slotReceivedErrors(QString)", true );
+
+ // get command line and add it to output buffer
+ QString cmdLine = m_job->cvsCommand();
+ m_part->mainWindow()->statusBar()->message( cmdLine );
+
+ kdDebug(9006) << "Running: " << cmdLine << endl;
+
+ // disconnect 3rd party slots from our signals
+ disconnect( 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(QString)", "slotReceivedOutput(QString)" );
+ disconnectDCOPSignal( m_job->app(), m_job->obj(), "receivedStderr(QString)", "slotReceivedErrors(QString)" );
+ delete m_job;
+ m_job = 0;
+ }
+ QString 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( QString someOutput )
+{
+ kdDebug(9006) << "CvsProcessWidget::slotReceivedOutput(QString) here!" << endl;
+#ifdef MYDCOPDEBUG
+ g_dcopOutCounter++;
+ kdDebug(9006) << "MYDCOPDEBUG: dcopOutCounter == " << g_dcopOutCounter << endl;
+#endif
+
+ QStringList strings = m_outputBuffer.process( someOutput );
+ if (strings.count() > 0)
+ {
+ m_output += strings;
+ showOutput( strings );
+ scrollToBottom();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void CvsProcessWidget::slotReceivedErrors( QString someErrors )
+{
+ kdDebug(9006) << "CvsProcessWidget::slotReceivedErrors(QString) here!" << endl;
+#ifdef MYDCOPDEBUG
+ g_dcopErrCounter++;
+ kdDebug(9006) << "MYDCOPDEBUG: dcopErrCounter == " << g_dcopErrCounter << endl;
+#endif
+
+ QStringList strings = m_errorBuffer.process( someErrors );
+ if (strings.count() > 0)
+ {
+ m_errors += strings;
+ showError( strings );
+ scrollToBottom();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void CvsProcessWidget::showInfo( const QStringList &msg )
+{
+ for (QStringList::const_iterator it = msg.begin(); it != msg.end(); ++it)
+ append( "<infotag>" + (*it) + "</infotag>" );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void CvsProcessWidget::showError( const QStringList &msg )
+{
+ for (QStringList::const_iterator it = msg.begin(); it != msg.end(); ++it)
+ append( "<errortag>" + (*it) + "</errortag>" );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void CvsProcessWidget::showOutput( const QStringList &msg )
+{
+ for (QStringList::const_iterator it = msg.begin(); it != msg.end(); ++it)
+ {
+ // @todo here we can interpret lines as [C], [M], ...
+ const QString &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 QTextEdit from crashing on trying to parse the tags.
+ //This should fix BUG:99590
+ QString 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"