00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "makewidget.h"
00013 #include "kdevcore.h"
00014 #include "kdevmainwindow.h"
00015 #include "kdevproject.h"
00016 #include "kdevpartcontroller.h"
00017 #include "processlinemaker.h"
00018 #include "makeviewpart.h"
00019 #include "makeitem.h"
00020 #include "ktexteditor/document.h"
00021 #include "ktexteditor/cursorinterface.h"
00022 #include "ktexteditor/editinterface.h"
00023 #include "urlutil.h"
00024
00025 #include <kdebug.h>
00026 #include <klocale.h>
00027 #include <knotifyclient.h>
00028 #include <kprocess.h>
00029 #include <kglobal.h>
00030 #include <kstandarddirs.h>
00031 #include <kinstance.h>
00032 #include <kstatusbar.h>
00033 #include <kapplication.h>
00034 #include <kconfig.h>
00035
00036 #include <qmessagebox.h>
00037 #include <qapplication.h>
00038 #include <qdir.h>
00039 #include <qimage.h>
00040 #include <qstylesheet.h>
00041 #include <qtimer.h>
00042 #include <qfileinfo.h>
00043 #include <qclipboard.h>
00044 #include <qpopupmenu.h>
00045 #include <private/qrichtext_p.h>
00046
00047 #include <stdlib.h>
00048 #include <limits.h>
00049
00050 static const char *const error_xpm[] =
00051 {
00052 "11 11 5 1",
00053 ". c None",
00054 "# c #313062",
00055 "a c #6261cd",
00056 "b c #c50000",
00057 "c c #ff8583",
00058 "...........",
00059 "...####....",
00060 ".a#bbbb#a..",
00061 ".#ccbbbb#..",
00062 "#bccbbbbb#.",
00063 "#bbbbbbbb#.",
00064 "#bbbbbbcb#.",
00065 "#bbbbbccb#.",
00066 ".#bbbccb#..",
00067 ".a#bbbb#a..",
00068 "...####...."
00069 };
00070
00071
00072 static const char *const warning_xpm[] =
00073 {
00074 "11 11 5 1",
00075 ". c None",
00076 "# c #313062",
00077 "a c #6261cd",
00078 "b c #c5c600",
00079 "c c #ffff41",
00080 "...........",
00081 "...####....",
00082 ".a#bbbb#a..",
00083 ".#ccbbbb#..",
00084 "#bccbbbbb#.",
00085 "#bbbbbbbb#.",
00086 "#bbbbbbcb#.",
00087 "#bbbbbccb#.",
00088 ".#bbbccb#..",
00089 ".a#bbbb#a..",
00090 "...####...."
00091 };
00092
00093
00094 static const char *const message_xpm[] =
00095 {
00096 "11 11 5 1",
00097 ". c None",
00098 "b c #3100c5",
00099 "# c #313062",
00100 "c c #3189ff",
00101 "a c #6265cd",
00102 "...........",
00103 "...####....",
00104 ".a#bbbb#a..",
00105 ".#ccbbbb#..",
00106 "#bccbbbbb#.",
00107 "#bbbbbbbb#.",
00108 "#bbbbbbcb#.",
00109 "#bbbbbccb#.",
00110 ".#bbbccb#..",
00111 ".a#bbbb#a..",
00112 "...####...."
00113 };
00114
00115
00116 class SelectionPreserver
00117 {
00118 public:
00119 SelectionPreserver( QTextEdit& textEdit, bool stayAtEnd )
00120 : m_textEdit( textEdit )
00121 , m_atEnd( false )
00122 {
00123 int para, index;
00124 m_textEdit.getCursorPosition( ¶, &index );
00125
00126 m_atEnd = stayAtEnd
00127 && para == m_textEdit.paragraphs() - 1
00128 && index == m_textEdit.paragraphLength( para );
00129
00130 m_textEdit.getSelection(¶From, &indexFrom, ¶To, &indexTo, 0);
00131 }
00132
00133 ~SelectionPreserver()
00134 {
00135 m_textEdit.setSelection(paraFrom, indexFrom, paraTo, indexTo, 0);
00136
00137 if ( m_atEnd )
00138 {
00139 m_textEdit.moveCursor(QTextEdit::MoveEnd, false);
00140 m_textEdit.moveCursor(QTextEdit::MoveLineStart, false);
00141 }
00142 }
00143
00144 QTextEdit& m_textEdit;
00145 bool m_atEnd;
00146 int paraFrom, indexFrom, paraTo, indexTo;
00147 };
00148
00149 MakeWidget::MakeWidget(MakeViewPart *part)
00150 : QTextEdit(0, "make widget")
00151 , m_directoryStatusFilter( m_errorFilter )
00152 , m_errorFilter( m_continuationFilter )
00153 , m_continuationFilter( m_actionFilter )
00154 , m_actionFilter( m_otherFilter )
00155 , m_pendingItem(0)
00156 , m_paragraphs(0)
00157 , m_lastErrorSelected(-1)
00158 , m_part(part)
00159 , m_vertScrolling(false)
00160 , m_horizScrolling(false)
00161 , m_bCompiling(false)
00162 {
00163 updateSettingsFromConfig();
00164
00165
00166
00167
00168
00169
00170
00171 setTextFormat( Qt::RichText );
00172
00173
00174 if ( m_bLineWrapping )
00175 setWordWrap(WidgetWidth);
00176 setWrapPolicy(Anywhere);
00177 setReadOnly(true);
00178 setMimeSourceFactory(new QMimeSourceFactory);
00179 mimeSourceFactory()->setImage("error", QImage((const char**)error_xpm));
00180 mimeSourceFactory()->setImage("warning", QImage((const char**)warning_xpm));
00181 mimeSourceFactory()->setImage("message", QImage((const char**)message_xpm));
00182
00183 childproc = new KShellProcess("/bin/sh");
00184 procLineMaker = new ProcessLineMaker( childproc );
00185
00186 connect( procLineMaker, SIGNAL(receivedStdoutLine(const QString&)),
00187 this, SLOT(insertStdoutLine(const QString&) ));
00188 connect( procLineMaker, SIGNAL(receivedStderrLine(const QString&)),
00189 this, SLOT(insertStderrLine(const QString&) ));
00190
00191 connect( childproc, SIGNAL(processExited(KProcess*)),
00192 this, SLOT(slotProcessExited(KProcess*) )) ;
00193
00194 connect( &m_directoryStatusFilter, SIGNAL(item(EnteringDirectoryItem*)),
00195 this, SLOT(slotEnteredDirectory(EnteringDirectoryItem*)) );
00196 connect( &m_directoryStatusFilter, SIGNAL(item(ExitingDirectoryItem*)),
00197 this, SLOT(slotExitedDirectory(ExitingDirectoryItem*)) );
00198 connect( &m_errorFilter, SIGNAL(item(MakeItem*)),
00199 this, SLOT(insertItem(MakeItem*)) );
00200 connect( &m_actionFilter, SIGNAL(item(MakeItem*)),
00201 this, SLOT(insertItem(MakeItem*)) );
00202 connect( &m_otherFilter, SIGNAL(item(MakeItem*)),
00203 this, SLOT(insertItem(MakeItem*)) );
00204
00205 connect( verticalScrollBar(), SIGNAL(sliderPressed()),
00206 this, SLOT(verticScrollingOn()) );
00207 connect( verticalScrollBar(), SIGNAL(sliderReleased()),
00208 this, SLOT(verticScrollingOff()) );
00209 connect( horizontalScrollBar(), SIGNAL(sliderPressed()),
00210 this, SLOT(horizScrollingOn()) );
00211 connect( horizontalScrollBar(), SIGNAL(sliderReleased()),
00212 this, SLOT(horizScrollingOff()) );
00213
00214 connect( m_part->partController(), SIGNAL(loadedFile(const KURL&)),
00215 this, SLOT(slotDocumentOpened(const KURL&)) );
00216 }
00217
00218 MakeWidget::~MakeWidget()
00219 {
00220 delete mimeSourceFactory();
00221 delete childproc;
00222 delete procLineMaker;
00223 }
00224
00225 void MakeWidget::queueJob(const QString &dir, const QString &command)
00226 {
00227 commandList.append(command);
00228 dirList.append(dir);
00229 if (!isRunning())
00230 {
00231
00232
00233 m_part->mainWindow()->storeOutputViewTab();
00234 startNextJob();
00235 }
00236 }
00237
00238 void MakeWidget::startNextJob()
00239 {
00240 QStringList::Iterator it = commandList.begin();
00241 if ( it == commandList.end() )
00242 return;
00243
00244 currentCommand = *it;
00245 commandList.remove(it);
00246
00247 int i = currentCommand.findRev(" gmake");
00248 if ( i == -1 )
00249 i = currentCommand.findRev(" make");
00250 if ( i == -1 )
00251 m_bCompiling = false;
00252 else
00253 {
00254 QString s = currentCommand.right(currentCommand.length() - i);
00255 if ( s.contains("configure ") ||
00256 s.contains(" Makefile.cvs") ||
00257 s.contains(" clean") ||
00258 s.contains(" distclean") ||
00259 s.contains(" package-messages") ||
00260 s.contains(" install") )
00261 {
00262 m_bCompiling = false;
00263 }
00264 else {
00265 m_bCompiling = true;
00266 }
00267 }
00268
00269 it = dirList.begin();
00270 QString dir = *it;
00271 dirList.remove(it);
00272
00273 clear();
00274 for ( QValueVector<MakeItem*>::iterator it = m_items.begin(); it != m_items.end(); ++it )
00275 delete *it;
00276 m_items.clear();
00277 m_paragraphToItem.clear();
00278 m_paragraphs = 0;
00279 m_lastErrorSelected = -1;
00280
00281 insertItem( new CommandItem( currentCommand ) );
00282
00283 childproc->clearArguments();
00284 *childproc << currentCommand;
00285 childproc->start(KProcess::NotifyOnExit, KProcess::AllOutput);
00286
00287 dirstack.clear();
00288 dirstack.push(new QString(dir));
00289
00290 m_part->mainWindow()->raiseView(this);
00291 m_part->core()->running(m_part, true);
00292 }
00293
00294 void MakeWidget::killJob()
00295 {
00296 childproc->kill();
00297 }
00298
00299 bool MakeWidget::isRunning()
00300 {
00301 return childproc->isRunning();
00302 }
00303
00304 void MakeWidget::copy()
00305 {
00306 int parafrom=0, indexfrom=0, parato=0, indexto=0;
00307 getSelection(¶from, &indexfrom, ¶to, &indexto);
00308 if( parafrom < 0 || indexfrom < 0 || parato < 0 || indexto < 0
00309 || ((parafrom == parato) && (indexfrom == indexto)) )
00310 {
00311 return;
00312 }
00313
00314 QString selection;
00315 for(int i = parafrom; i<=parato; i++)
00316 selection += text(i) + "\n";
00317
00318
00319 if(m_compilerOutputLevel == eShort ||
00320 m_compilerOutputLevel == eVeryShort )
00321 {
00322 QRegExp regexp("<.*>");
00323 regexp.setMinimal(true);
00324 selection.remove(regexp);
00325 }
00326 else
00327 {
00328 selection.remove(0, indexfrom);
00329 int removeend = text(parato).length() - indexto;
00330
00331 selection.remove((selection.length()-1) - removeend, removeend);
00332 }
00333
00334 selection.replace("<","<");
00335 selection.replace(">",">");
00336 selection.replace(""","\"");
00337 selection.replace("&","&");
00338
00339 kapp->clipboard()->setText(selection, QClipboard::Clipboard);
00340 }
00341
00342 void MakeWidget::nextError()
00343 {
00344 int parag;
00345 if (m_lastErrorSelected != -1)
00346 parag = m_lastErrorSelected;
00347 else
00348 parag = 0;
00349
00350
00351 if (!scanErrorForward(parag))
00352 if (m_lastErrorSelected != -1)
00353 {
00354 m_lastErrorSelected = -1;
00355 if (!scanErrorForward(0))
00356 KNotifyClient::beep();
00357 }
00358 else
00359 KNotifyClient::beep();
00360 }
00361
00362 void MakeWidget::prevError()
00363 {
00364 int parag;
00365 if (m_lastErrorSelected != -1)
00366 parag = m_lastErrorSelected;
00367 else
00368 parag = 0;
00369
00370
00371 if (!scanErrorBackward(parag))
00372 if (m_lastErrorSelected != -1)
00373 {
00374 m_lastErrorSelected = -1;
00375 #if QT_VERSION >= 0x030100
00376 parag = (int)m_items.count();
00377 #else
00378 parag = m_items.size();
00379 #endif
00380 if (!scanErrorBackward(parag))
00381 KNotifyClient::beep();
00382 }
00383 else
00384 KNotifyClient::beep();
00385 }
00386
00387 void MakeWidget::contentsMouseReleaseEvent( QMouseEvent* e )
00388 {
00389 QTextEdit::contentsMouseReleaseEvent(e);
00390 if ( e->button() != LeftButton )
00391 return;
00392 searchItem(paragraphAt(e->pos()));
00393 }
00394
00395 void MakeWidget::keyPressEvent(QKeyEvent *e)
00396 {
00397 if (e->key() == Key_Return || e->key() == Key_Enter)
00398 {
00399 int parag, index;
00400 getCursorPosition(¶g, &index);
00401 searchItem(parag);
00402 }
00403 else
00404 QTextEdit::keyPressEvent(e);
00405 }
00406
00407
00408 QString MakeWidget::directory(int parag) const
00409 {
00410 QValueVector<MakeItem*>::const_iterator it = qFind( m_items.begin(), m_items.end(), m_paragraphToItem[parag] );
00411 if ( it == m_items.end() )
00412 return QString::null;
00413
00414 while ( it != m_items.begin() ) {
00415 --it;
00416 EnteringDirectoryItem* edi = dynamic_cast<EnteringDirectoryItem*>( *it );
00417 if ( edi )
00418 return edi->directory + "/";
00419 }
00420 return QString::null;
00421 }
00422
00423
00424
00425 static bool checkFileExists( const QString& file, QString& fName )
00426 {
00427 if ( QFile::exists( file ) ) {
00428 fName = file;
00429 return true;
00430 }
00431 return false;
00432 }
00433
00434 QString MakeWidget::guessFileName( const QString& fName, int parag ) const
00435 {
00436
00437 if ( ! m_part->project() ) return fName;
00438
00439 QString name;
00440 QString dir = directory( parag );
00441
00442 if ( fName.startsWith( "/" ) )
00443 {
00444
00445 name = fName;
00446 }
00447 else if ( !dir.isEmpty() )
00448 {
00449 name = dir + fName;
00450 }
00451 else
00452 {
00453
00454
00455 name = fName;
00456 if ( !checkFileExists( m_part->project()->projectDirectory() + "/" + fName, name ) &&
00457 !checkFileExists( m_part->project()->projectDirectory() + "/" + m_part->project()->activeDirectory() + "/" + fName, name ) )
00458 checkFileExists( m_part->project()->buildDirectory() + "/" + fName, name );
00459 }
00460
00461 kdDebug(9004) << "Opening file: " << fName << endl;
00462
00463
00464
00465
00466 QStringList projectFiles = m_part->project()->symlinkProjectFiles();
00467 QStringList::iterator it = projectFiles.begin();
00468 while ( it != projectFiles.end() )
00469 {
00470 QString file = m_part->project()->projectDirectory() + "/" + *it;
00471 if ( name == URLUtil::canonicalPath( file ) )
00472 {
00473 kdDebug(9004) << "Found file in project - " << file << " == " << name << endl;
00474 return file;
00475 }
00476 ++it;
00477 }
00478
00479
00480 return name;
00481 }
00482
00483 void MakeWidget::searchItem(int parag)
00484 {
00485 ErrorItem* item = dynamic_cast<ErrorItem*>( m_paragraphToItem[parag] );
00486 if ( item )
00487 {
00488
00489 kdDebug(9004) << "Opening file: " << guessFileName(item->fileName, parag) << endl;
00490 if (item->m_cursor) {
00491 uint line, col;
00492 item->m_cursor->position(&line, &col);
00493 kdDebug() << "Cursor new position: " << col << endl;
00494 m_part->partController()->editDocument(KURL( guessFileName(item->fileName, parag) ), line, col);
00495 } else {
00496 m_part->partController()->editDocument(KURL( guessFileName(item->fileName, parag) ), item->lineNum);
00497 }
00498 m_part->mainWindow()->statusBar()->message( item->m_error, 10000 );
00499 m_part->mainWindow()->lowerView(this);
00500 m_lastErrorSelected = parag;
00501 }
00502 }
00503
00504 void MakeWidget::insertStdoutLine( const QString& line )
00505 {
00506 if ( !appendToLastLine( line ) )
00507 m_directoryStatusFilter.processLine( line );
00508 }
00509
00510 void MakeWidget::insertStderrLine( const QString& line )
00511 {
00512 if ( !appendToLastLine( line ) )
00513 {
00514 kdDebug() << "inserting stderr line: " << line << endl;
00515 m_errorFilter.processLine( line );
00516 }
00517 }
00518
00519 void MakeWidget::slotProcessExited(KProcess *)
00520 {
00521 if (childproc->normalExit())
00522 {
00523 if (childproc->exitStatus())
00524 {
00525 KNotifyClient::event( "ProcessError", i18n("The process has finished with errors"));
00526 emit m_part->commandFailed(currentCommand);
00527 }
00528 else
00529 {
00530 KNotifyClient::event( "ProcessSuccess", i18n("The process has finished successfully"));
00531 emit m_part->commandFinished(currentCommand);
00532 }
00533 }
00534
00535 MakeItem* item = new ExitStatusItem( childproc->normalExit(), childproc->exitStatus() );
00536 insertItem( item );
00537 displayPendingItem();
00538
00539 m_part->mainWindow()->statusBar()->message( QString("%1: %2").arg(currentCommand).arg(item->m_text), 3000);
00540 m_part->core()->running(m_part, false);
00541
00542
00543
00544
00545 if (childproc->normalExit() && !childproc->exitStatus())
00546 {
00547 QTimer::singleShot(0, this, SLOT(startNextJob()));
00548 if (commandList.isEmpty())
00549
00550
00551 m_part->mainWindow()->restoreOutputViewTab();
00552 }
00553 else
00554 {
00555 commandList.clear();
00556 dirList.clear();
00557 }
00558 }
00559
00560 void MakeWidget::slotEnteredDirectory( EnteringDirectoryItem* item )
00561 {
00562
00563 QString* dir = new QString( item->directory );
00564 dirstack.push( dir );
00565 insertItem( item );
00566 }
00567
00568 void MakeWidget::slotExitedDirectory( ExitingDirectoryItem* item )
00569 {
00570 QString eDir = item->directory;
00571
00572 QString *dir = dirstack.pop();
00573 if (!dir)
00574 {
00575 kdWarning(9004) << "Left more directories than entered: " << eDir;
00576 }
00577 else if (dir->compare(eDir) != 0)
00578 {
00579 kdWarning(9004) << "Expected directory: \"" << *dir << "\" but got \"" << eDir << "\"" << endl;
00580 }
00581 insertItem( item );
00582 delete dir;
00583 }
00584
00585 void MakeWidget::displayPendingItem()
00586 {
00587 if (!m_pendingItem) return;
00588
00589
00590
00591
00592 if (!m_items.empty()
00593 && m_items.last() == m_pendingItem) return;
00594
00595 m_items.push_back(m_pendingItem);
00596
00597 if ( m_bCompiling && !m_pendingItem->visible( m_compilerOutputLevel ) )
00598 return;
00599
00600 SelectionPreserver preserveSelection( *this, !m_vertScrolling && !m_horizScrolling );
00601 m_paragraphToItem.insert( m_paragraphs++, m_pendingItem );
00602 append( m_pendingItem->formattedText( m_compilerOutputLevel, brightBg() ) );
00603 }
00604
00605 bool MakeWidget::appendToLastLine( const QString& text )
00606 {
00607 if ( !m_pendingItem ) return false;
00608 if ( !m_pendingItem->append( text ) )
00609 {
00610 displayPendingItem();
00611 m_pendingItem = 0;
00612 return false;
00613 }
00614
00615 int mode = m_pendingItem -> displayMode();
00616 if ((mode & MakeItem::Append) && (mode & MakeItem::ImmDisplay))
00617 {
00618 removeParagraph(paragraphs() - 1);
00619 SelectionPreserver preserveSelection( *this, !m_vertScrolling && !m_horizScrolling );
00620 append( m_pendingItem->formattedText( m_compilerOutputLevel, brightBg() ) );
00621 }
00622
00623 return true;
00624 }
00625
00626 void MakeWidget::insertItem( MakeItem* new_item )
00627 {
00628 ErrorItem* e = dynamic_cast<ErrorItem*>(new_item);
00629 if (e)
00630 createCursor(e, 0L);
00631
00632 displayPendingItem();
00633 m_pendingItem = new_item;
00634
00635 if (!new_item) return;
00636
00637 int mode = new_item -> displayMode();
00638 if (mode & MakeItem::ImmDisplay)
00639 {
00640 displayPendingItem();
00641 if (!(mode & MakeItem::Append))
00642 m_pendingItem = 0;
00643 }
00644 }
00645
00646 void MakeWidget::slotDocumentOpened( const KURL & filename )
00647 {
00648 KParts::Part* part = m_part->partController()->partForURL(filename);
00649 KTextEditor::Document* doc = dynamic_cast<KTextEditor::Document*>(part);
00650
00651 if (!doc) {
00652 kdWarning() << k_funcinfo << "Couldn't find the document that was just opened." << endl;
00653 return;
00654 }
00655
00656 connect(part, SIGNAL(destroyed(QObject*)), this, SLOT(slotDocumentClosed(QObject*)) );
00657
00658 for (QValueVector<MakeItem*>::iterator it = m_items.begin(); it != m_items.end(); ++it) {
00659 ErrorItem* e = dynamic_cast<ErrorItem*>(*it);
00660
00661 if (!e || e->m_cursor) continue;
00662
00663 if (filename.path().endsWith(e->fileName))
00664 createCursor(e, doc);
00665 }
00666 }
00667
00668 void MakeWidget::createCursor(ErrorItem* e, KTextEditor::Document* doc)
00669 {
00670
00671 return;
00672
00673
00674
00675 if (!doc)
00676 doc = dynamic_cast<KTextEditor::Document*>(m_part->partController()->partForURL(KURL( guessFileName(e->fileName, m_paragraphs + 1 ))));
00677
00678 if (doc) {
00679 KTextEditor::EditInterface* edit = dynamic_cast<KTextEditor::EditInterface*>(doc);
00680 KTextEditor::CursorInterface* cursor = dynamic_cast<KTextEditor::CursorInterface*>(doc);
00681 if (cursor) {
00682 e->m_cursor = cursor->createCursor();
00683 uint col = 0;
00684 static QRegExp startOfText("[\\S]");
00685 if (edit) {
00686 int newcol = edit->textLine(e->lineNum).find(startOfText);
00687 if (newcol != -1) col = uint(newcol);
00688 }
00689 e->m_cursor->setPosition(e->lineNum, col);
00690 e->m_doc = doc;
00691 }
00692 }
00693 }
00694
00695 void MakeWidget::slotDocumentClosed(QObject* doc)
00696 {
00697 KTextEditor::Document* document = static_cast<KTextEditor::Document*>(doc);
00698
00699 for (QValueVector<MakeItem*>::iterator it = m_items.begin(); it != m_items.end(); ++it) {
00700 ErrorItem* e = dynamic_cast<ErrorItem*>(*it);
00701
00702 if (!e || e->m_doc != document) continue;
00703
00704 e->m_cursor = 0L;
00705 e->m_doc = 0L;
00706 }
00707 }
00708
00709 bool MakeWidget::brightBg()
00710 {
00711 int h,s,v;
00712 paletteBackgroundColor().hsv( &h, &s, &v );
00713 return (v > 127);
00714 }
00715
00716 QPopupMenu* MakeWidget::createPopupMenu( const QPoint& pos )
00717 {
00718 QPopupMenu* pMenu = QTextEdit::createPopupMenu(pos);
00719 pMenu->setCheckable(true);
00720
00721 pMenu->insertSeparator();
00722 int id = pMenu->insertItem(i18n("Line Wrapping"), this, SLOT(toggleLineWrapping()) );
00723 pMenu->setItemChecked(id, m_bLineWrapping);
00724 pMenu->setWhatsThis(id, i18n("<b>Line wrapping</b><p>Enables or disables wrapping of command lines displayed."));
00725
00726 pMenu->insertSeparator();
00727 id = pMenu->insertItem(i18n("Very Short Compiler Output"), this, SLOT(slotVeryShortCompilerOutput()) );
00728 pMenu->setWhatsThis(id, i18n("<b>Very short compiler output</b><p>Displays only warnings, errors and the file names which are compiled."));
00729 pMenu->setItemChecked(id, m_compilerOutputLevel == eVeryShort);
00730 id = pMenu->insertItem(i18n("Short Compiler Output"), this, SLOT(slotShortCompilerOutput()) );
00731 pMenu->setWhatsThis(id, i18n("<b>Short compiler output</b><p>Suppresses all the compiler flags and formats to something readable."));
00732 pMenu->setItemChecked(id, m_compilerOutputLevel == eShort);
00733 id = pMenu->insertItem(i18n("Full Compiler Output"), this, SLOT(slotFullCompilerOutput()) );
00734 pMenu->setWhatsThis(id, i18n("<b>Full compiler output</b><p>Displays unmodified compiler output."));
00735 pMenu->setItemChecked(id, m_compilerOutputLevel == eFull);
00736
00737 pMenu->insertSeparator();
00738 id = pMenu->insertItem(i18n("Show Directory Navigation Messages"), this, SLOT(toggleShowDirNavigMessages()));
00739 pMenu->setWhatsThis(id, i18n("<b>Show directory navigation messages</b><p>Shows <b>cd</b> commands that are executed while building."));
00740 pMenu->setItemChecked(id, DirectoryItem::getShowDirectoryMessages());
00741
00742 return pMenu;
00743 }
00744
00745 void MakeWidget::toggleLineWrapping()
00746 {
00747 m_bLineWrapping = !m_bLineWrapping;
00748 KConfig *pConfig = kapp->config();
00749 pConfig->setGroup("MakeOutputView");
00750 pConfig->writeEntry("LineWrapping", m_bLineWrapping);
00751 pConfig->sync();
00752 if (m_bLineWrapping) {
00753 setWordWrap(WidgetWidth);
00754 }
00755 else
00756 {
00757 setWordWrap(NoWrap);
00758 }
00759 }
00760
00761 void MakeWidget::refill()
00762 {
00763 clear();
00764 m_paragraphToItem.clear();
00765 m_paragraphs = 0;
00766 for( uint i = 0; i < m_items.size(); i++ )
00767 {
00768 if ( m_bCompiling && !m_items[i]->visible( m_compilerOutputLevel ) )
00769 continue;
00770 m_paragraphToItem.insert( m_paragraphs++, m_items[i] );
00771 append( m_items[i]->formattedText( m_compilerOutputLevel, brightBg() ) );
00772 }
00773
00774 }
00775
00776 void MakeWidget::slotVeryShortCompilerOutput() { setTextFormat( Qt::RichText ); setCompilerOutputLevel(eVeryShort); }
00777 void MakeWidget::slotShortCompilerOutput() { setTextFormat( Qt::RichText ); setCompilerOutputLevel(eShort); }
00778 void MakeWidget::slotFullCompilerOutput() { setTextFormat( Qt::RichText ); setCompilerOutputLevel(eFull); }
00779
00780 void MakeWidget::setCompilerOutputLevel(EOutputLevel level)
00781 {
00782 m_compilerOutputLevel = level;
00783 KConfig *pConfig = kapp->config();
00784 pConfig->setGroup("MakeOutputView");
00785 pConfig->writeEntry("CompilerOutputLevel", (int) level);
00786 pConfig->sync();
00787 refill();
00788 }
00789
00790 void MakeWidget::toggleShowDirNavigMessages()
00791 {
00792 DirectoryItem::setShowDirectoryMessages( !DirectoryItem::getShowDirectoryMessages() );
00793 KConfig *pConfig = kapp->config();
00794 pConfig->setGroup("MakeOutputView");
00795 pConfig->writeEntry("ShowDirNavigMsg", DirectoryItem::getShowDirectoryMessages());
00796 pConfig->sync();
00797 refill();
00798 }
00799
00800 void MakeWidget::updateSettingsFromConfig()
00801 {
00802 KConfig *pConfig = kapp->config();
00803 pConfig->setGroup("MakeOutputView");
00804 setFont(pConfig->readFontEntry("Messages Font"));
00805 m_bLineWrapping = pConfig->readBoolEntry("LineWrapping", true);
00806 m_compilerOutputLevel = (EOutputLevel) pConfig->readNumEntry("CompilerOutputLevel", (int) eVeryShort);
00807 DirectoryItem::setShowDirectoryMessages( pConfig->readBoolEntry("ShowDirNavigMsg", false) );
00808 }
00809
00810 bool MakeWidget::scanErrorForward( int parag )
00811 {
00812 for ( int it = parag + 1;
00813 it < (int)m_items.count();
00814 ++it )
00815 {
00816 ErrorItem* item = dynamic_cast<ErrorItem*>( m_paragraphToItem[it] );
00817 if ( !item )
00818 continue;
00819 parag = it;
00820 document()->removeSelection(0);
00821 setSelection(parag, 0, parag+1, 0, 0);
00822 setCursorPosition(parag, 0);
00823 ensureCursorVisible();
00824 searchItem( it );
00825 return true;
00826 }
00827 return false;
00828 }
00829
00830 bool MakeWidget::scanErrorBackward( int parag )
00831 {
00832 for ( int it = parag - 1; it >= 0; --it)
00833 {
00834 ErrorItem* item = dynamic_cast<ErrorItem*>( m_paragraphToItem[it] );
00835 if ( !item )
00836 continue;
00837 parag = it;
00838 document()->removeSelection(0);
00839 setSelection(parag, 0, parag+1, 0, 0);
00840 setCursorPosition(parag, 0);
00841 ensureCursorVisible();
00842 searchItem( it );
00843 return true;
00844 }
00845 return false;
00846 }
00847
00848 #include "makewidget.moc"