KDevelop API Documentation

grepviewwidget.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 1999-2001 by Bernd Gehrmann                             *
00003  *   bernd@kdevelop.org                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  ***************************************************************************/
00011 
00012 #include <qdir.h>
00013 #include <qlayout.h>
00014 #include <qregexp.h>
00015 #include <qpainter.h>
00016 #include <kdialogbase.h>
00017 #include <klocale.h>
00018 #include <kprocess.h>
00019 #include <kparts/part.h>
00020 #include <ktexteditor/selectioninterface.h>
00021 #include <kaction.h>
00022 #include <kpopupmenu.h>
00023 using namespace KTextEditor;
00024 
00025 #include "kdevcore.h"
00026 #include "kdevproject.h"
00027 #include "kdevmainwindow.h"
00028 #include "kdevpartcontroller.h"
00029 
00030 #include "grepdlg.h"
00031 #include "grepviewpart.h"
00032 #include "grepviewwidget.h"
00033 
00034 
00035 class GrepListBoxItem : public ProcessListBoxItem
00036 {
00037 public:
00038     GrepListBoxItem(const QString &fileName, const QString &lineNumber, const QString &text, bool showFilename);
00039     QString filename()
00040         { return fileName; }
00041     int linenumber()
00042         { return lineNumber.toInt(); }
00043     virtual bool isCustomItem();
00044 
00045 private:
00046     virtual void paint(QPainter *p);
00047     QString fileName, lineNumber, text;
00048     bool show;
00049 };
00050 
00051 
00052 GrepListBoxItem::GrepListBoxItem(const QString &fileName, const QString &lineNumber, const QString &text, bool showFilename)
00053     : ProcessListBoxItem( QString::null, Normal),
00054     fileName(fileName), lineNumber(lineNumber), text(text.stripWhiteSpace()),
00055     show(showFilename)
00056 {}
00057 
00058 
00059 bool GrepListBoxItem::isCustomItem()
00060 {
00061     return true;
00062 }
00063 
00064 
00065 void GrepListBoxItem::paint(QPainter *p)
00066 {
00067     QFontMetrics fm = p->fontMetrics();
00068     QString stx = lineNumber + ":  ";
00069     int y = fm.ascent()+fm.leading()/2;
00070     int x = 3;
00071     if (show)
00072     {
00073         p->setPen(Qt::darkGreen);
00074         p->drawText(x, y, fileName);
00075         x += fm.width(fileName);
00076     }
00077     else {
00078     p->setPen(Qt::black);
00079     QFont font1(p->font());
00080     QFont font2(font1);
00081     font2.setBold(true);
00082     p->setFont(font2);
00083     p->drawText(x, y, stx);
00084     p->setFont(font1);
00085     x += fm.width(stx);
00086 
00087     p->setPen(Qt::blue);
00088     p->drawText(x, y, text);
00089     }
00090 }
00091 
00092 
00093 GrepViewWidget::GrepViewWidget(GrepViewPart *part)
00094     : ProcessWidget(0, "grep widget")
00095     , m_matchCount(0)
00096 {
00097     connect( this, SIGNAL( contextMenuRequested ( QListBoxItem *, const QPoint & ) ),
00098              this, SLOT( popupMenu( QListBoxItem *, const QPoint & ) ) );
00099 
00100     grepdlg = new GrepDialog( part, this, "grep widget");
00101     connect( grepdlg, SIGNAL(searchClicked()),
00102          this, SLOT(searchActivated()) );
00103     connect( this, SIGNAL(clicked(QListBoxItem*)),
00104              this, SLOT(slotExecuted(QListBoxItem*)) );
00105     connect( this, SIGNAL(returnPressed(QListBoxItem*)),
00106              this, SLOT(slotExecuted(QListBoxItem*)) );
00107 
00108     m_part = part;
00109 }
00110 
00111 
00112 GrepViewWidget::~GrepViewWidget()
00113 {}
00114 
00115 
00116 void GrepViewWidget::showDialog()
00117 {
00118     // Get the selected text if there is any
00119     KParts::ReadOnlyPart *ro_part = dynamic_cast<KParts::ReadOnlyPart*>(m_part->partController()->activePart());
00120     if (ro_part)
00121     {
00122         SelectionInterface *selectIface = dynamic_cast<SelectionInterface*>(ro_part);
00123         if(selectIface && selectIface->hasSelection())
00124         {
00125             QString selText = selectIface->selection();
00126             if(!selText.contains('\n'))
00127             {
00128                 grepdlg->setPattern(selText);
00129             }
00130         }
00131     }
00132     grepdlg->show();
00133 }
00134 
00135 // @todo - put this somewhere common - or just use Qt if possible
00136 static QString escape(const QString &str)
00137 {
00138     QString escaped("[]{}()\\^$?.+-*");
00139     QString res;
00140 
00141     for (uint i=0; i < str.length(); ++i) {
00142         if (escaped.find(str[i]) != -1)
00143             res += "\\";
00144         res += str[i];
00145     }
00146 
00147     return res;
00148 }
00149 
00150 
00151 void GrepViewWidget::showDialogWithPattern(QString pattern)
00152 {
00153     // Before anything, this removes line feeds from the
00154     // beginning and the end.
00155     int len = pattern.length();
00156     if (len > 0 && pattern[0] == '\n')
00157     {
00158         pattern.remove(0, 1);
00159         len--;
00160     }
00161     if (len > 0 && pattern[len-1] == '\n')
00162     pattern.truncate(len-1);
00163     grepdlg->setPattern( pattern );
00164     grepdlg->show();
00165 }
00166 
00167 
00168 void GrepViewWidget::searchActivated()
00169 {
00170     m_matchCount = 0;
00171     _lastfilename = "";
00172 
00173     QString files;
00174     // waba: code below breaks on filenames containing a ',' !!!
00175     QStringList filelist = QStringList::split(",", grepdlg->filesString());
00176     if (!filelist.isEmpty())
00177         {
00178             QStringList::Iterator it(filelist.begin());
00179             files = KShellProcess::quote(*it);
00180             ++it;
00181             for (; it != filelist.end(); ++it)
00182                 files += " -o -name " + KShellProcess::quote(*it);
00183         }
00184 
00185     QString pattern = grepdlg->templateString();
00186 //    pattern.replace(QRegExp("%s"), grepdlg->patternString());
00187     pattern.replace(QRegExp("%s"), escape( grepdlg->patternString() ) );
00188     pattern.replace(QRegExp("'"), "'\\''");
00189 
00190     QString filepattern = "find ";
00191     filepattern += KShellProcess::quote(grepdlg->directoryString());
00192     if (!grepdlg->recursiveFlag())
00193         filepattern += " -maxdepth 1";
00194     filepattern += " \\( -name ";
00195     filepattern += files;
00196     filepattern += " \\) -print -follow";
00197 
00198     QString command = filepattern + " " ;
00199     if (grepdlg->ignoreSCMDirsFlag()) {
00200         command += "| grep -v \"SCCS/\" ";
00201         command += "| grep -v \"CVS/\" ";
00202     }
00203 
00204     // quote spaces in filenames going to xargs
00205     command += "| sed \"s/ /\\\\\\ /g\" ";
00206 
00207     command += "| xargs " ;
00208 
00209 #ifndef USE_SOLARIS
00210     command += "egrep -H -n ";
00211     if (!grepdlg->caseSensitiveFlag()) {
00212       command += "-i ";
00213     }
00214     command += "-e ";
00215 #else
00216     // -H reported as not being available on Solaris,
00217     // but we're buggy without it on Linux.
00218     command += "egrep -n ";
00219     if (!grepdlg->caseSensitiveFlag()) {
00220       command += "-i ";
00221     }
00222     command += "-e ";
00223 #endif
00224 
00225     command += KShellProcess::quote(pattern);
00226     startJob("", command);
00227 
00228     m_part->mainWindow()->raiseView(this);
00229     m_part->core()->running(m_part, true);
00230 }
00231 
00232 
00233 void GrepViewWidget::childFinished(bool normal, int status)
00234 {
00235     // When xargs executes grep several times (because the command line
00236     // generated would be too large for a single grep) and one of those
00237     // sets of files passed to grep does not contain a match, then an
00238     // error status of 123 is set by xargs, even if there is a match in
00239     // another set of files.
00240     // Reset this false status here.
00241     if (status == 123 && numRows() > 1)
00242         status = 0;
00243 
00244     insertItem(new ProcessListBoxItem(i18n("*** %n match found. ***", "*** %n matches found. ***", m_matchCount), ProcessListBoxItem::Diagnostic));
00245     maybeScrollToBottom();
00246 
00247     ProcessWidget::childFinished(normal, status);
00248     m_part->core()->running(m_part, false);
00249 }
00250 
00251 
00252 void GrepViewWidget::slotExecuted(QListBoxItem* item)
00253 {
00254     ProcessListBoxItem *i = static_cast<ProcessListBoxItem*>(item);
00255     if (!i || !i->isCustomItem())
00256         return;
00257 
00258     GrepListBoxItem *gi = static_cast<GrepListBoxItem*>(i);
00259     m_part->partController()->editDocument( KURL( gi->filename() ), gi->linenumber()-1 );
00260 //    m_part->mainWindow()->lowerView(this);
00261 }
00262 
00263 
00264 void GrepViewWidget::insertStdoutLine(const QString &line)
00265 {
00266     int pos;
00267     QString filename, linenumber, rest;
00268 
00269     QString str = line;
00270     if ( (pos = str.find(':')) != -1)
00271         {
00272             filename = str.left(pos);
00273             str.remove( 0, pos+1 );
00274             if ( ( pos = str.find(':') ) != -1)
00275                 {
00276                     linenumber = str.left(pos);
00277                     str.remove( 0, pos+1 );
00278                     // filename will be displayed only once
00279                     // selecting filename will display line 1 of file,
00280                     // otherwise, line of requested search
00281                     if ( _lastfilename != filename )
00282                     {
00283                         _lastfilename = filename;
00284                         insertItem(new GrepListBoxItem(filename, "0", str, true));
00285                         insertItem(new GrepListBoxItem(filename, linenumber, str, false));
00286                     }
00287                     else
00288                     {
00289                         insertItem(new GrepListBoxItem(filename, linenumber, str, false));
00290                     }
00291                     maybeScrollToBottom();
00292                 }
00293             m_matchCount++;
00294         }
00295 }
00296 
00297 
00298 void GrepViewWidget::projectChanged(KDevProject *project)
00299 {
00300     QString dir = project? project->projectDirectory() : QDir::homeDirPath();
00301     grepdlg->setDirectory(dir);
00302 }
00303 
00304 void GrepViewWidget::popupMenu(QListBoxItem *, const QPoint &p)
00305 {
00306     if(isRunning()) return;
00307     if(KAction *findAction = m_part->actionCollection()->action("edit_grep")) {
00308         KPopupMenu rmbMenu;
00309         rmbMenu.insertTitle(i18n("Find in Files"));
00310         findAction->plug(&rmbMenu);
00311         rmbMenu.exec(p);
00312     }
00313 }
00314 #include "grepviewwidget.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 23 00:03:57 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003