summaryrefslogtreecommitdiffstats
path: root/parts/outputviews/appoutputwidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'parts/outputviews/appoutputwidget.cpp')
-rw-r--r--parts/outputviews/appoutputwidget.cpp355
1 files changed, 355 insertions, 0 deletions
diff --git a/parts/outputviews/appoutputwidget.cpp b/parts/outputviews/appoutputwidget.cpp
new file mode 100644
index 00000000..e3c3810a
--- /dev/null
+++ b/parts/outputviews/appoutputwidget.cpp
@@ -0,0 +1,355 @@
+/***************************************************************************
+ * Copyright (C) 1999-2001 by Bernd Gehrmann *
+ * bernd@kdevelop.org *
+ * *
+ * Copyright (C) 2003 by Hamish Rodda *
+ * meddie@yoyo.its.monash.edu.au *
+ * *
+ * 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 "appoutputwidget.h"
+
+#include <qregexp.h>
+#include <qbuttongroup.h>
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qclipboard.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kstatusbar.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kpopupmenu.h>
+#include <klineedit.h>
+#include <kfiledialog.h>
+
+#include "appoutputviewpart.h"
+#include "filterdlg.h"
+#include "kdevpartcontroller.h"
+#include "kdevmainwindow.h"
+#include "kdevproject.h"
+
+AppOutputWidget::AppOutputWidget(AppOutputViewPart* part)
+ : ProcessWidget(0, "app output widget"), m_part(part)
+{
+ connect(this, SIGNAL(executed(QListBoxItem*)), SLOT(slotRowSelected(QListBoxItem*)));
+ connect(this, SIGNAL(rightButtonClicked( QListBoxItem *, const QPoint & )),
+ SLOT(slotContextMenu( QListBoxItem *, const QPoint & )));
+ KConfig *config = kapp->config();
+ config->setGroup("General Options");
+ setFont(config->readFontEntry("OutputViewFont"));
+ setSelectionMode(QListBox::Extended);
+}
+
+void AppOutputWidget::clearViewAndContents()
+{
+ m_contentList.clear();
+ clear();
+}
+
+AppOutputWidget::~AppOutputWidget()
+{}
+
+
+void AppOutputWidget::childFinished(bool normal, int status)
+{
+ if( !stdoutbuf.isEmpty() )
+ insertStdoutLine("");
+ if( !stderrbuf.isEmpty() )
+ insertStderrLine("");
+
+ ProcessWidget::childFinished(normal, status);
+}
+
+
+void AppOutputWidget::slotRowSelected(QListBoxItem* row)
+{
+ static QRegExp assertMatch("ASSERT: \\\"([^\\\"]+)\\\" in ([^\\( ]+) \\(([\\d]+)\\)");
+ static QRegExp lineInfoMatch("\\[([^:]+):([\\d]+)\\]");
+ static QRegExp rubyErrorMatch("([^:\\s]+\\.rb):([\\d]+):?.*$");
+
+ if (row) {
+ if (assertMatch.exactMatch(row->text())) {
+ m_part->partController()->editDocument(KURL( assertMatch.cap(2) ), assertMatch.cap(3).toInt() - 1);
+ m_part->mainWindow()->statusBar()->message(i18n("Assertion failed: %1").arg(assertMatch.cap(1)), 10000);
+ m_part->mainWindow()->lowerView(this);
+
+ } else if (lineInfoMatch.search(row->text()) != -1) {
+ m_part->partController()->editDocument(KURL( lineInfoMatch.cap(1) ), lineInfoMatch.cap(2).toInt() - 1);
+ m_part->mainWindow()->statusBar()->message(row->text(), 10000);
+ m_part->mainWindow()->lowerView(this);
+ } else if (rubyErrorMatch.search(row->text()) != -1) {
+ QString file;
+ if (rubyErrorMatch.cap(1).startsWith("/")) {
+ file = rubyErrorMatch.cap(1);
+ } else {
+ file = m_part->project()->projectDirectory() + "/" + rubyErrorMatch.cap(1);
+ }
+ m_part->partController()->editDocument(KURL(rubyErrorMatch.cap(1)), rubyErrorMatch.cap(2).toInt() - 1);
+ m_part->mainWindow()->statusBar()->message(row->text(), 10000);
+ m_part->mainWindow()->lowerView(this);
+ }
+ }
+}
+
+
+void AppOutputWidget::insertStdoutLine(const QCString &line)
+{
+// kdDebug(9004) << k_funcinfo << line << endl;
+
+ if ( !m_part->isViewVisible() )
+ {
+ m_part->showView();
+ }
+
+ QString sline;
+ if( !stdoutbuf.isEmpty() )
+ {
+ sline = QString::fromLocal8Bit( stdoutbuf+line );
+ stdoutbuf.truncate( 0 );
+ }else
+ {
+ sline = QString::fromLocal8Bit( line );
+ }
+
+ m_contentList.append(QString("o-")+sline);
+ if ( filterSingleLine( sline ) )
+ {
+ ProcessWidget::insertStdoutLine( sline.local8Bit() );
+ }
+}
+
+
+void AppOutputWidget::insertStderrLine(const QCString &line)
+{
+// kdDebug(9004) << k_funcinfo << line << endl;
+
+ if ( !m_part->isViewVisible() )
+ {
+ m_part->showView();
+ }
+
+
+ QString sline;
+ if( !stderrbuf.isEmpty() )
+ {
+ sline = QString::fromLocal8Bit( stderrbuf+line );
+ stderrbuf.truncate( 0 );
+ }else
+ {
+ sline = QString::fromLocal8Bit( line );
+ }
+
+ m_contentList.append(QString("e-")+sline);
+ if ( filterSingleLine( sline ) )
+ {
+ ProcessWidget::insertStderrLine( sline.local8Bit() );
+ }
+}
+
+void AppOutputWidget::editFilter()
+{
+ FilterDlg dlg( this );
+ dlg.caseSensitive->setChecked( m_filter.m_caseSensitive );
+ dlg.regularExpression->setChecked( m_filter.m_isRegExp );
+ dlg.filterString->setText( m_filter.m_filterString );
+
+ if ( dlg.exec() == QDialog::Accepted )
+ {
+ m_filter.m_caseSensitive = dlg.caseSensitive->isChecked();
+ m_filter.m_isRegExp = dlg.regularExpression->isChecked();
+ m_filter.m_filterString = dlg.filterString->text();
+
+ m_filter.m_isActive = !m_filter.m_filterString.isEmpty();
+
+ reinsertAndFilter();
+ }
+
+}
+bool AppOutputWidget::filterSingleLine(const QString & line)
+{
+ if ( !m_filter.m_isActive ) return true;
+
+ if ( m_filter.m_isRegExp )
+ {
+ return ( line.find( QRegExp( m_filter.m_filterString, m_filter.m_caseSensitive, false ) ) != -1 );
+ }
+ else
+ {
+ return ( line.find( m_filter.m_filterString, 0, m_filter.m_caseSensitive ) != -1 );
+ }
+}
+
+void AppOutputWidget::reinsertAndFilter()
+{
+ //copy the first item from the listbox
+ //if a programm was started, this contains the issued command
+ QString issuedCommand;
+ if ( count() > 0 )
+ {
+ setTopItem(0);
+ issuedCommand = item(topItem())->text();
+ }
+
+ clear();
+
+ //write back the issued command
+ if ( !issuedCommand.isEmpty() )
+ {
+ insertItem( new ProcessListBoxItem( issuedCommand, ProcessListBoxItem::Diagnostic ) );
+ }
+
+ //grep through the list for items matching the filter...
+ QStringList strListFound;
+ if ( m_filter.m_isActive )
+ {
+ if ( m_filter.m_isRegExp )
+ {
+ strListFound = m_contentList.grep( QRegExp(m_filter.m_filterString, m_filter.m_caseSensitive, false ) );
+ }
+ else
+ {
+ strListFound = m_contentList.grep( m_filter.m_filterString, m_filter.m_caseSensitive );
+ }
+ }
+ else
+ {
+ strListFound = m_contentList;
+ }
+
+ //... and reinsert the found items into the listbox
+ for ( QStringList::Iterator it = strListFound.begin(); it != strListFound.end(); ++it )
+ {
+ if ((*it).startsWith("o-"))
+ {
+ (*it).remove(0,2);
+ insertItem(new ProcessListBoxItem(*it, ProcessListBoxItem::Normal));
+ }
+ else if ((*it).startsWith("e-"))
+ {
+ (*it).remove(0,2);
+ insertItem(new ProcessListBoxItem(*it, ProcessListBoxItem::Error));
+ }
+ }
+}
+
+void AppOutputWidget::clearFilter()
+{
+ m_filter.m_isActive = false;
+ reinsertAndFilter();
+}
+
+void AppOutputWidget::slotContextMenu( QListBoxItem *, const QPoint &p )
+{
+ KPopupMenu popup(this, "filter output");
+
+ int id = popup.insertItem( i18n("Clear output"), this, SLOT(clearViewAndContents()) );
+ popup.setItemEnabled( id, m_contentList.size() > 0 );
+
+ popup.insertItem( i18n("Copy selected lines"), this, SLOT(copySelected()) );
+ popup.insertSeparator();
+
+ popup.insertItem( i18n("Save unfiltered"), this, SLOT(saveAll()) );
+ id = popup.insertItem( i18n("Save filtered output"), this, SLOT(saveFiltered()) );
+ popup.setItemEnabled( id, m_filter.m_isActive );
+ popup.insertSeparator();
+
+ id = popup.insertItem( i18n("Clear filter"), this, SLOT(clearFilter()) );
+ popup.setItemEnabled( id, m_filter.m_isActive );
+
+ popup.insertItem( i18n("Edit filter"), this, SLOT(editFilter() ) );
+
+ popup.insertSeparator();
+ popup.insertItem( i18n("Hide view"), this, SLOT(hideView()) );
+
+ popup.exec(p);
+}
+
+void AppOutputWidget::hideView()
+{
+ m_part->hideView();
+}
+
+void AppOutputWidget::saveAll()
+{
+ saveOutputToFile( false );
+}
+
+void AppOutputWidget::saveFiltered()
+{
+ saveOutputToFile( true );
+}
+
+void AppOutputWidget::saveOutputToFile(bool useFilter)
+{
+ QString filename = KFileDialog::getSaveFileName();
+
+ if ( filename.isEmpty() ) return;
+
+ QStringList contents;
+ if ( useFilter && m_filter.m_isActive )
+ {
+ if ( m_filter.m_isRegExp )
+ {
+ contents = m_contentList.grep( QRegExp(m_filter.m_filterString, m_filter.m_caseSensitive, false ) );
+ }
+ else
+ {
+ contents = m_contentList.grep( m_filter.m_filterString, m_filter.m_caseSensitive );
+ }
+ }
+ else
+ {
+ contents = m_contentList;
+ }
+
+ QFile file( filename );
+ if ( file.open( IO_WriteOnly ) )
+ {
+ QTextStream ostream( &file );
+ QStringList::ConstIterator it = contents.begin();
+ while( it != contents.end() )
+ {
+ QString line = *it;
+ if ( line.startsWith("o-") || line.startsWith("e-") )
+ {
+ line.remove( 0, 2 );
+ }
+ ostream << line << endl;
+ ++it;
+ }
+ file.close();
+ }
+}
+
+void AppOutputWidget::copySelected()
+{
+ uint n = count();
+ QString buffer;
+ for (uint i = 0; i < n; i++)
+ {
+ if (isSelected(i))
+ buffer += item(i)->text() + "\n";
+ }
+ kapp->clipboard()->setText(buffer, QClipboard::Clipboard);
+}
+
+void AppOutputWidget::addPartialStderrLine(const QCString & line)
+{
+ stderrbuf += line;
+}
+
+void AppOutputWidget::addPartialStdoutLine(const QCString & line)
+{
+ stdoutbuf += line;
+}
+
+#include "appoutputwidget.moc"