/*************************************************************************** * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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, TQT_SIGNAL(executed(TQListBoxItem*)), TQT_SLOT(slotRowSelected(TQListBoxItem*))); connect(this, TQT_SIGNAL(rightButtonClicked( TQListBoxItem *, const TQPoint & )), TQT_SLOT(slotContextMenu( TQListBoxItem *, const TQPoint & ))); TDEConfig *config = kapp->config(); config->setGroup("General Options"); setFont(config->readFontEntry("OutputViewFont")); setSelectionMode(TQListBox::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(TQListBoxItem* row) { static TQRegExp assertMatch("ASSERT: \\\"([^\\\"]+)\\\" in ([^\\( ]+) \\(([\\d]+)\\)"); static TQRegExp lineInfoMatch("\\[([^:]+):([\\d]+)\\]"); static TQRegExp 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) { TQString 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 TQCString &line) { // kdDebug(9004) << k_funcinfo << line << endl; if ( !m_part->isViewVisible() ) { m_part->showView(); } TQString sline; if( !stdoutbuf.isEmpty() ) { sline = TQString::fromLocal8Bit( stdoutbuf+line ); stdoutbuf.truncate( 0 ); }else { sline = TQString::fromLocal8Bit( line ); } m_contentList.append(TQString("o-")+sline); if ( filterSingleLine( sline ) ) { ProcessWidget::insertStdoutLine( sline.local8Bit() ); } } void AppOutputWidget::insertStderrLine(const TQCString &line) { // kdDebug(9004) << k_funcinfo << line << endl; if ( !m_part->isViewVisible() ) { m_part->showView(); } TQString sline; if( !stderrbuf.isEmpty() ) { sline = TQString::fromLocal8Bit( stderrbuf+line ); stderrbuf.truncate( 0 ); }else { sline = TQString::fromLocal8Bit( line ); } m_contentList.append(TQString("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() == TQDialog::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 TQString & line) { if ( !m_filter.m_isActive ) return true; if ( m_filter.m_isRegExp ) { return ( line.find( TQRegExp( 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 TQString 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... TQStringList strListFound; if ( m_filter.m_isActive ) { if ( m_filter.m_isRegExp ) { strListFound = m_contentList.grep( TQRegExp(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 ( TQStringList::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( TQListBoxItem *, const TQPoint &p ) { TDEPopupMenu popup(this, "filter output"); int id = popup.insertItem( i18n("Clear output"), this, TQT_SLOT(clearViewAndContents()) ); popup.setItemEnabled( id, m_contentList.size() > 0 ); popup.insertItem( i18n("Copy selected lines"), this, TQT_SLOT(copySelected()) ); popup.insertSeparator(); popup.insertItem( i18n("Save unfiltered"), this, TQT_SLOT(saveAll()) ); id = popup.insertItem( i18n("Save filtered output"), this, TQT_SLOT(saveFiltered()) ); popup.setItemEnabled( id, m_filter.m_isActive ); popup.insertSeparator(); id = popup.insertItem( i18n("Clear filter"), this, TQT_SLOT(clearFilter()) ); popup.setItemEnabled( id, m_filter.m_isActive ); popup.insertItem( i18n("Edit filter"), this, TQT_SLOT(editFilter() ) ); popup.insertSeparator(); popup.insertItem( i18n("Hide view"), this, TQT_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) { TQString filename = KFileDialog::getSaveFileName(); if ( filename.isEmpty() ) return; TQStringList contents; if ( useFilter && m_filter.m_isActive ) { if ( m_filter.m_isRegExp ) { contents = m_contentList.grep( TQRegExp(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; } TQFile file( filename ); if ( file.open( IO_WriteOnly ) ) { TQTextStream ostream( &file ); TQStringList::ConstIterator it = contents.begin(); while( it != contents.end() ) { TQString 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(); TQString buffer; for (uint i = 0; i < n; i++) { if (isSelected(i)) buffer += item(i)->text() + "\n"; } kapp->clipboard()->setText(buffer, TQClipboard::Clipboard); } void AppOutputWidget::addPartialStderrLine(const TQCString & line) { stderrbuf += line; } void AppOutputWidget::addPartialStdoutLine(const TQCString & line) { stdoutbuf += line; } #include "appoutputwidget.moc"