00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
#include "problemreporter.h"
00020
#include "cppsupportpart.h"
00021
#include "configproblemreporter.h"
00022
#include "backgroundparser.h"
00023
00024
#include <kdevpartcontroller.h>
00025
#include <kdevmainwindow.h>
00026
00027
#include <kdeversion.h>
00028
#include <kparts/part.h>
00029
#include <ktexteditor/editinterface.h>
00030
#include <ktexteditor/document.h>
00031
#include <ktexteditor/markinterface.h>
00032
00033
#if (KDE_VERSION > 305)
00034
# include <ktexteditor/markinterfaceextension.h>
00035
#else
00036
# include "kde30x_markinterfaceextension.h"
00037
#endif
00038
#include <ktexteditor/view.h>
00039
00040
#include <kdebug.h>
00041
#include <klocale.h>
00042
#include <kstatusbar.h>
00043
#include <kurl.h>
00044
#include <kapplication.h>
00045
#include <kiconloader.h>
00046
#include <kdialogbase.h>
00047
00048
#include <kconfig.h>
00049
00050
#include <qtimer.h>
00051
#include <qregexp.h>
00052
#include <qvbox.h>
00053
#include <qfileinfo.h>
00054
#include <qwhatsthis.h>
00055
00056
00057
class ProblemItem:
public KListViewItem
00058 {
00059
public:
00060 ProblemItem(
QListView* parent,
const QString& level,
const QString& problem,
00061
const QString& file,
const QString& line,
const QString& column )
00062 :
KListViewItem( parent, level, problem,
file, line, column ) {}
00063
00064 ProblemItem(
QListViewItem* parent,
const QString& level,
const QString& problem,
00065
const QString& file,
const QString& line,
const QString& column )
00066 :
KListViewItem( parent, level, problem,
file, line, column ) {}
00067
00068 int compare(
QListViewItem* item,
int column,
bool ascending )
const {
00069
if( column == 2 || column == 3 ){
00070
int a =
text( column ).toInt();
00071
int b = item->text( column ).toInt();
00072
if( a == b )
00073
return 0;
00074
return( a > b ? 1 : -1 );
00075 }
00076
return KListViewItem::compare( item, column, ascending );
00077 }
00078
00079 };
00080
00081 ProblemReporter::ProblemReporter(
CppSupportPart* part,
QWidget* parent,
const char* name )
00082 :
KListView( parent, name ),
00083 m_cppSupport( part ),
00084 m_document( 0 ),
00085 m_markIface( 0 )
00086 {
00087 QWhatsThis::add(
this, i18n(
"<b>Problem reporter</b><p>This window shows various \"problems\" in your project. "
00088
"It displays TODO entries, FIXME's and errors reported by a language parser. "
00089
"To add a TODO or FIXME entry, just type<br>"
00090
"<tt>//@todo my todo</tt><br>"
00091
"<tt>//TODO: my todo</tt><br>"
00092
"<tt>//FIXME fix this</tt>"));
00093
00094
m_canParseFile =
true;
00095
00096 addColumn( i18n(
"Level") );
00097 addColumn( i18n(
"File") );
00098 addColumn( i18n(
"Line") );
00099 addColumn( i18n(
"Column") );
00100 addColumn( i18n(
"Problem") );
00101 setAllColumnsShowFocus( TRUE );
00102
00103
m_timer =
new QTimer(
this );
00104
00105 connect( part->
partController(), SIGNAL(activePartChanged(
KParts::Part*)),
00106
this, SLOT(
slotActivePartChanged(
KParts::Part*)) );
00107 connect( part->
partController(), SIGNAL(partAdded(
KParts::Part*)),
00108
this, SLOT(
slotPartAdded(
KParts::Part*)) );
00109 connect( part->
partController(), SIGNAL(partRemoved(
KParts::Part*)),
00110
this, SLOT(
slotPartRemoved(
KParts::Part*)) );
00111
00112 connect( part, SIGNAL(fileParsed(
const QString&)),
this, SLOT(
slotFileParsed(
const QString&)) );
00113
00114 connect(
m_timer, SIGNAL(timeout()),
this, SLOT(
reparse()) );
00115
00116 connect(
this, SIGNAL(executed(
QListViewItem*)),
00117
this, SLOT(
slotSelected(
QListViewItem*)) );
00118
00119 connect(
this, SIGNAL(returnPressed(
QListViewItem*)),
00120
this, SLOT(
slotSelected(
QListViewItem* )) );
00121
00122
configure();
00123
00124
slotActivePartChanged( part->
partController()->
activePart() );
00125 }
00126
00127
ProblemReporter::~ProblemReporter()
00128 {
00129 }
00130
00131
void ProblemReporter::slotActivePartChanged(
KParts::Part* part )
00132 {
00133
if( !part )
00134
return;
00135
00136
m_timer->stop();
00137
00138
if(
m_document )
00139 disconnect( m_document, 0,
this, 0 );
00140
00141
m_document = dynamic_cast<KTextEditor::Document*>( part );
00142
m_markIface = 0;
00143
00144
if( !
m_document )
00145
return;
00146
00147
m_fileName =
m_document->
url().
path();
00148
00149
if( !
m_cppSupport->
isValidSource(m_fileName) )
00150
return;
00151
00152 connect( m_document, SIGNAL(textChanged()),
this, SLOT(
slotTextChanged()) );
00153
m_markIface = dynamic_cast<KTextEditor::MarkInterface*>( part );
00154
00155
if( !
m_cppSupport->
backgroundParser() )
00156
return;
00157
00158
m_cppSupport->
backgroundParser()->
lock();
00159
bool needReparse =
false;
00160
if( !
m_cppSupport->
backgroundParser()->
translationUnit(m_fileName) )
00161 needReparse =
true;
00162
m_cppSupport->
backgroundParser()->
unlock();
00163
00164
if( needReparse )
00165
reparse();
00166 }
00167
00168
void ProblemReporter::slotTextChanged()
00169 {
00170
if( !
m_active )
00171
return;
00172
00173
m_timer->changeInterval( m_delay );
00174 }
00175
00176 void ProblemReporter::removeAllProblems(
const QString& filename )
00177 {
00178
QListViewItem* current = firstChild();
00179
while( current ){
00180
QListViewItem* i = current;
00181 current = current->nextSibling();
00182
00183
if( i->text(1) == filename )
00184
delete( i );
00185 }
00186
00187
if(
m_document &&
m_markIface ){
00188
QPtrList<KTextEditor::Mark> marks =
m_markIface->
marks();
00189
QPtrListIterator<KTextEditor::Mark> it( marks );
00190
while( it.current() ){
00191
m_markIface->
removeMark( it.current()->line, KTextEditor::MarkInterface::markType10 );
00192 ++it;
00193 }
00194 }
00195 }
00196
00197
void ProblemReporter::reparse()
00198 {
00199 m_timer->stop();
00200
00201
if( !m_cppSupport->
isValid() )
00202
return;
00203
00204
if( m_canParseFile ){
00205 m_cppSupport->
backgroundParser()->
addFile( m_fileName );
00206 m_canParseFile =
false;
00207
kdDebug(9007) <<
"---> file added" <<
endl;
00208 }
00209 }
00210
00211
void ProblemReporter::slotSelected(
QListViewItem* item )
00212 {
00213
KURL url( item->text(1) );
00214
int line = item->text( 2 ).toInt();
00215
00216
m_cppSupport->
partController()->
editDocument( url, line-1 );
00217
m_cppSupport->
mainWindow()->
lowerView(
this );
00218 }
00219
00220 void ProblemReporter::reportProblem(
const QString& fileName,
const Problem& p )
00221 {
00222
int markType =
levelToMarkType( p.
level() );
00223
if( markType != -1 &&
m_document &&
m_markIface &&
m_fileName == fileName ){
00224
m_markIface->
addMark( p.
line(), markType );
00225 }
00226
00227
QString msg = p.
text();
00228 msg = msg.replace(
QRegExp(
"\n"),
"" );
00229
00230
new ProblemItem(
this,
00231
levelToString( p.
level() ),
00232 fileName,
00233 QString::number( p.
line() + 1 ),
00234 QString::number( p.
column() + 1 ),
00235 msg );
00236 }
00237
00238
void ProblemReporter::configure()
00239 {
00240
kdDebug(9007) <<
"ProblemReporter::configure()" <<
endl;
00241
KConfig* config = kapp->config();
00242 config->
setGroup(
"General Options" );
00243 m_active = config->
readBoolEntry(
"EnableCppBgParser", TRUE );
00244 m_delay = config->
readNumEntry(
"CppBgParserDelay", 250 );
00245 }
00246
00247
void ProblemReporter::configWidget(
KDialogBase* dlg )
00248 {
00249
QVBox *vbox = dlg->
addVBoxPage(i18n(
"C++ Parsing"));
00250
ConfigureProblemReporter* w =
new ConfigureProblemReporter( vbox );
00251 w->
setPart( m_cppSupport );
00252 connect(dlg, SIGNAL(okClicked()), w, SLOT(accept()));
00253 connect(dlg, SIGNAL(okClicked()),
this, SLOT(
configure()));
00254 }
00255
00256
void ProblemReporter::slotPartAdded(
KParts::Part* part )
00257 {
00258
KTextEditor::MarkInterfaceExtension* iface = dynamic_cast<KTextEditor::MarkInterfaceExtension*>( part );
00259
00260
if( !iface )
00261
return;
00262
00263 iface->
setPixmap( KTextEditor::MarkInterface::markType10, SmallIcon(
"stop") );
00264 }
00265
00266
void ProblemReporter::slotPartRemoved(
KParts::Part* part )
00267 {
00268
kdDebug(9007) <<
"ProblemReporter::slotPartRemoved()" <<
endl;
00269
if( part ==
m_document ){
00270
m_document = 0;
00271
m_timer->stop();
00272 }
00273 }
00274
00275 QString ProblemReporter::levelToString(
int level )
const
00276
{
00277
switch( level )
00278 {
00279
case Problem::Level_Error:
00280
return QString::fromLatin1(
"Error" );
00281
case Problem::Level_Warning:
00282
return QString::fromLatin1(
"Warning" );
00283
case Problem::Level_Todo:
00284
return QString::fromLatin1(
"Todo" );
00285
case Problem::Level_Fixme:
00286
return QString::fromLatin1(
"Fixme" );
00287
default:
00288
return QString::null;
00289 }
00290 }
00291
00292 int ProblemReporter::levelToMarkType(
int level )
const
00293
{
00294
switch( level )
00295 {
00296
case Problem::Level_Error:
00297
return KTextEditor::MarkInterface::markType10;
00298
case Problem::Level_Warning:
00299
return -1;
00300
case Problem::Level_Todo:
00301
return -1;
00302
case Problem::Level_Fixme:
00303
return -1;
00304
default:
00305
return -1;
00306 }
00307 }
00308
00309 void ProblemReporter::slotFileParsed(
const QString& fileName )
00310 {
00311
if(
m_active && fileName ==
m_fileName ){
00312
m_canParseFile =
true;
00313 }
00314 }
00315
00316
#include "problemreporter.moc"