00001
00002
00003
00004
00005
00006
00007
00008
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
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
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
00154
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
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
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
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
00217
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
00236
00237
00238
00239
00240
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
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
00279
00280
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"