1
/***************************************************************************
2
* Copyright (C) 1999-2001 by Bernd Gehrmann *
5
* Copyright (C) 2003 by Hamish Rodda *
6
* meddie@yoyo.its.monash.edu.au *
8
* This program is free software; you can redistribute it and/or modify *
9
* it under the terms of the GNU General Public License as published by *
10
* the Free Software Foundation; either version 2 of the License, or *
11
* (at your option) any later version. *
13
***************************************************************************/
15
#include "appoutputwidget.h"
18
#include <qbuttongroup.h>
19
#include <qcheckbox.h>
20
#include <qradiobutton.h>
22
#include <qtextstream.h>
23
#include <qclipboard.h>
27
#include <kstatusbar.h>
28
#include <kapplication.h>
30
#include <kpopupmenu.h>
31
#include <klineedit.h>
32
#include <kfiledialog.h>
34
#include "appoutputviewpart.h"
35
#include "filterdlg.h"
36
#include "kdevpartcontroller.h"
37
#include "kdevmainwindow.h"
38
#include "kdevproject.h"
40
AppOutputWidget::AppOutputWidget(AppOutputViewPart* part)
41
: ProcessWidget(0, "app output widget"), m_part(part)
43
connect(this, SIGNAL(executed(QListBoxItem*)), SLOT(slotRowSelected(QListBoxItem*)));
44
connect(this, SIGNAL(rightButtonClicked( QListBoxItem *, const QPoint & )),
45
SLOT(slotContextMenu( QListBoxItem *, const QPoint & )));
46
KConfig *config = kapp->config();
47
config->setGroup("General Options");
48
setFont(config->readFontEntry("OutputViewFont"));
49
setSelectionMode(QListBox::Extended);
52
void AppOutputWidget::clearViewAndContents()
54
m_contentList.clear();
58
AppOutputWidget::~AppOutputWidget()
62
void AppOutputWidget::childFinished(bool normal, int status)
64
if( !stdoutbuf.isEmpty() )
66
if( !stderrbuf.isEmpty() )
69
ProcessWidget::childFinished(normal, status);
73
void AppOutputWidget::slotRowSelected(QListBoxItem* row)
75
static QRegExp assertMatch("ASSERT: \\\"([^\\\"]+)\\\" in ([^\\( ]+) \\(([\\d]+)\\)");
76
static QRegExp lineInfoMatch("\\[([^:]+):([\\d]+)\\]");
77
static QRegExp rubyErrorMatch("([^:\\s]+\\.rb):([\\d]+):?.*$");
80
if (assertMatch.exactMatch(row->text())) {
81
m_part->partController()->editDocument(KURL( assertMatch.cap(2) ), assertMatch.cap(3).toInt() - 1);
82
m_part->mainWindow()->statusBar()->message(i18n("Assertion failed: %1").arg(assertMatch.cap(1)), 10000);
83
m_part->mainWindow()->lowerView(this);
85
} else if (lineInfoMatch.search(row->text()) != -1) {
86
m_part->partController()->editDocument(KURL( lineInfoMatch.cap(1) ), lineInfoMatch.cap(2).toInt() - 1);
87
m_part->mainWindow()->statusBar()->message(row->text(), 10000);
88
m_part->mainWindow()->lowerView(this);
89
} else if (rubyErrorMatch.search(row->text()) != -1) {
91
if (rubyErrorMatch.cap(1).startsWith("/")) {
92
file = rubyErrorMatch.cap(1);
94
file = m_part->project()->projectDirectory() + "/" + rubyErrorMatch.cap(1);
96
m_part->partController()->editDocument(KURL(rubyErrorMatch.cap(1)), rubyErrorMatch.cap(2).toInt() - 1);
97
m_part->mainWindow()->statusBar()->message(row->text(), 10000);
98
m_part->mainWindow()->lowerView(this);
104
void AppOutputWidget::insertStdoutLine(const QCString &line)
106
// kdDebug(9004) << k_funcinfo << line << endl;
108
if ( !m_part->isViewVisible() )
114
if( !stdoutbuf.isEmpty() )
116
sline = QString::fromLocal8Bit( stdoutbuf+line );
117
stdoutbuf.truncate( 0 );
120
sline = QString::fromLocal8Bit( line );
123
m_contentList.append(QString("o-")+sline);
124
if ( filterSingleLine( sline ) )
126
ProcessWidget::insertStdoutLine( sline.local8Bit() );
131
void AppOutputWidget::insertStderrLine(const QCString &line)
133
// kdDebug(9004) << k_funcinfo << line << endl;
135
if ( !m_part->isViewVisible() )
142
if( !stderrbuf.isEmpty() )
144
sline = QString::fromLocal8Bit( stderrbuf+line );
145
stderrbuf.truncate( 0 );
148
sline = QString::fromLocal8Bit( line );
151
m_contentList.append(QString("e-")+sline);
152
if ( filterSingleLine( sline ) )
154
ProcessWidget::insertStderrLine( sline.local8Bit() );
158
void AppOutputWidget::editFilter()
160
FilterDlg dlg( this );
161
dlg.caseSensitive->setChecked( m_filter.m_caseSensitive );
162
dlg.regularExpression->setChecked( m_filter.m_isRegExp );
163
dlg.filterString->setText( m_filter.m_filterString );
165
if ( dlg.exec() == QDialog::Accepted )
167
m_filter.m_caseSensitive = dlg.caseSensitive->isChecked();
168
m_filter.m_isRegExp = dlg.regularExpression->isChecked();
169
m_filter.m_filterString = dlg.filterString->text();
171
m_filter.m_isActive = !m_filter.m_filterString.isEmpty();
177
bool AppOutputWidget::filterSingleLine(const QString & line)
179
if ( !m_filter.m_isActive ) return true;
181
if ( m_filter.m_isRegExp )
183
return ( line.find( QRegExp( m_filter.m_filterString, m_filter.m_caseSensitive, false ) ) != -1 );
187
return ( line.find( m_filter.m_filterString, 0, m_filter.m_caseSensitive ) != -1 );
191
void AppOutputWidget::reinsertAndFilter()
193
//copy the first item from the listbox
194
//if a programm was started, this contains the issued command
195
QString issuedCommand;
199
issuedCommand = item(topItem())->text();
204
//write back the issued command
205
if ( !issuedCommand.isEmpty() )
207
insertItem( new ProcessListBoxItem( issuedCommand, ProcessListBoxItem::Diagnostic ) );
210
//grep through the list for items matching the filter...
211
QStringList strListFound;
212
if ( m_filter.m_isActive )
214
if ( m_filter.m_isRegExp )
216
strListFound = m_contentList.grep( QRegExp(m_filter.m_filterString, m_filter.m_caseSensitive, false ) );
220
strListFound = m_contentList.grep( m_filter.m_filterString, m_filter.m_caseSensitive );
225
strListFound = m_contentList;
228
//... and reinsert the found items into the listbox
229
for ( QStringList::Iterator it = strListFound.begin(); it != strListFound.end(); ++it )
231
if ((*it).startsWith("o-"))
234
insertItem(new ProcessListBoxItem(*it, ProcessListBoxItem::Normal));
236
else if ((*it).startsWith("e-"))
239
insertItem(new ProcessListBoxItem(*it, ProcessListBoxItem::Error));
244
void AppOutputWidget::clearFilter()
246
m_filter.m_isActive = false;
250
void AppOutputWidget::slotContextMenu( QListBoxItem *, const QPoint &p )
252
KPopupMenu popup(this, "filter output");
254
int id = popup.insertItem( i18n("Clear output"), this, SLOT(clearViewAndContents()) );
255
popup.setItemEnabled( id, m_contentList.size() > 0 );
257
popup.insertItem( i18n("Copy selected lines"), this, SLOT(copySelected()) );
258
popup.insertSeparator();
260
popup.insertItem( i18n("Save unfiltered"), this, SLOT(saveAll()) );
261
id = popup.insertItem( i18n("Save filtered output"), this, SLOT(saveFiltered()) );
262
popup.setItemEnabled( id, m_filter.m_isActive );
263
popup.insertSeparator();
265
id = popup.insertItem( i18n("Clear filter"), this, SLOT(clearFilter()) );
266
popup.setItemEnabled( id, m_filter.m_isActive );
268
popup.insertItem( i18n("Edit filter"), this, SLOT(editFilter() ) );
270
popup.insertSeparator();
271
popup.insertItem( i18n("Hide view"), this, SLOT(hideView()) );
276
void AppOutputWidget::hideView()
281
void AppOutputWidget::saveAll()
283
saveOutputToFile( false );
286
void AppOutputWidget::saveFiltered()
288
saveOutputToFile( true );
291
void AppOutputWidget::saveOutputToFile(bool useFilter)
293
QString filename = KFileDialog::getSaveFileName();
295
if ( filename.isEmpty() ) return;
297
QStringList contents;
298
if ( useFilter && m_filter.m_isActive )
300
if ( m_filter.m_isRegExp )
302
contents = m_contentList.grep( QRegExp(m_filter.m_filterString, m_filter.m_caseSensitive, false ) );
306
contents = m_contentList.grep( m_filter.m_filterString, m_filter.m_caseSensitive );
311
contents = m_contentList;
314
QFile file( filename );
315
if ( file.open( IO_WriteOnly ) )
317
QTextStream ostream( &file );
318
QStringList::ConstIterator it = contents.begin();
319
while( it != contents.end() )
322
if ( line.startsWith("o-") || line.startsWith("e-") )
326
ostream << line << endl;
333
void AppOutputWidget::copySelected()
337
for (uint i = 0; i < n; i++)
340
buffer += item(i)->text() + "\n";
342
kapp->clipboard()->setText(buffer, QClipboard::Clipboard);
345
void AppOutputWidget::addPartialStderrLine(const QCString & line)
350
void AppOutputWidget::addPartialStdoutLine(const QCString & line)
355
#include "appoutputwidget.moc"