kate Library API Documentation

kategrepdialog.cpp

00001 /* This file is part of the KDE project 00002 Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org> 00003 Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org> 00004 Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License version 2 as published by the Free Software Foundation. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 Boston, MA 02111-1307, USA. 00019 */ 00020 00021 #include "kategrepdialog.h" 00022 #include "katemainwindow.h" 00023 00024 #include <qobject.h> 00025 #include <qlayout.h> 00026 #include <qpushbutton.h> 00027 #include <qlineedit.h> 00028 #include <qlabel.h> 00029 #include <qcombobox.h> 00030 #include <qcheckbox.h> 00031 #include <qevent.h> 00032 #include <qlistbox.h> 00033 #include <qregexp.h> 00034 #include <qwhatsthis.h> 00035 #include <qcursor.h> 00036 00037 #include <kapplication.h> 00038 #include <kaccelmanager.h> 00039 #include <kbuttonbox.h> 00040 #include <kfiledialog.h> 00041 #include <kprocess.h> 00042 #include <kapplication.h> 00043 #include <klocale.h> 00044 #include <kiconloader.h> 00045 #include <kmessagebox.h> 00046 #include <kurlrequester.h> 00047 #include <kurlcompletion.h> 00048 #include <kcombobox.h> 00049 #include <klineedit.h> 00050 00051 const char *template_desc[] = { 00052 "normal", 00053 "assignment", 00054 "->MEMBER(", 00055 "class::MEMBER(", 00056 "OBJECT->member(", 00057 0 00058 }; 00059 00060 const char *template_str[] = { 00061 "%s", 00062 "\\<%s\\>[\t ]*=[^=]", 00063 "\\->[\\t ]*\\<%s\\>[\\t ]*(", 00064 "[a-z0-9_$]\\+[\\t ]*::[\\t ]*\\<%s\\>[\\t ]*(", 00065 "\\<%s\\>[\\t ]*\\->[\\t ]*[a-z0-9_$]\\+[\\t ]*(", 00066 0 00067 }; 00068 00069 00070 GrepTool::GrepTool(KateMainWindow *parent, const char *name) 00071 : QWidget(parent, name/*, false*/), childproc(0) 00072 { 00073 setCaption(i18n("Find in Files")); 00074 config = KGlobal::config(); 00075 config->setGroup("GrepTool"); 00076 lastSearchItems = config->readListEntry("LastSearchItems"); 00077 lastSearchPaths = config->readListEntry("LastSearchPaths"); 00078 00079 QGridLayout *layout = new QGridLayout(this, 6, 3, 4, 4); 00080 layout->setColStretch(0, 10); 00081 layout->addColSpacing(1, 10); 00082 layout->setColStretch(1, 0); 00083 layout->setColStretch(2, 1); 00084 layout->setRowStretch(1, 0); 00085 layout->setRowStretch(2, 10); 00086 layout->setRowStretch(4, 0); 00087 00088 QGridLayout *input_layout = new QGridLayout(4, 2, 4); 00089 layout->addLayout(input_layout, 0, 0); 00090 input_layout->setColStretch(0, 0); 00091 input_layout->setColStretch(1, 20); 00092 00093 QLabel *pattern_label = new QLabel(i18n("Pattern:"), this); 00094 pattern_label->setFixedSize(pattern_label->sizeHint()); 00095 input_layout->addWidget(pattern_label, 0, 0, AlignRight | AlignVCenter); 00096 00097 pattern_combo = new QComboBox(true, this); 00098 pattern_combo->insertStringList(lastSearchItems); 00099 pattern_combo->setEditText(QString::null); 00100 pattern_combo->setInsertionPolicy(QComboBox::NoInsertion); 00101 pattern_label->setBuddy(pattern_combo); 00102 pattern_combo->setFocus(); 00103 pattern_combo->setMinimumSize(pattern_combo->sizeHint()); 00104 input_layout->addWidget(pattern_combo, 0, 1); 00105 00106 QLabel *template_label = new QLabel(i18n("Template:"), this); 00107 template_label->setFixedSize(template_label->sizeHint()); 00108 input_layout->addWidget(template_label, 1, 0, AlignRight | AlignVCenter); 00109 00110 QBoxLayout *template_layout = new QHBoxLayout(4); 00111 input_layout->addLayout(template_layout, 1, 1); 00112 00113 template_edit = new QLineEdit(this); 00114 template_label->setBuddy(template_edit); 00115 template_edit->setText(template_str[0]); 00116 template_edit->setMinimumSize(template_edit->sizeHint()); 00117 template_layout->addWidget(template_edit); 00118 00119 QComboBox *template_combo = new QComboBox(false, this); 00120 template_combo->insertStrList(template_desc); 00121 template_combo->adjustSize(); 00122 template_combo->setFixedSize(template_combo->size()); 00123 template_layout->addWidget(template_combo); 00124 00125 QLabel *files_label = new QLabel(i18n("Files:"), this); 00126 files_label->setFixedSize(files_label->sizeHint()); 00127 input_layout->addWidget(files_label, 2, 0, AlignRight | AlignVCenter); 00128 00129 files_combo = new QComboBox(true, this); 00130 files_label->setBuddy(files_combo->focusProxy()); 00131 files_combo->setMinimumSize(files_combo->sizeHint()); 00132 files_combo->insertItem("*.h,*.hxx,*.cpp,*.cc,*.C,*.cxx,*.idl,*.c"); 00133 files_combo->insertItem("*.cpp,*.cc,*.C,*.cxx,*.c"); 00134 files_combo->insertItem("*.h,*.hxx,*.idl"); 00135 files_combo->insertItem("*"); 00136 input_layout->addWidget(files_combo, 2, 1); 00137 00138 QLabel *dir_label = new QLabel(i18n("Directory:"), this); 00139 dir_label->setFixedSize(dir_label->sizeHint()); 00140 input_layout->addWidget(dir_label, 3, 0, AlignRight | AlignVCenter); 00141 00142 QBoxLayout *dir_layout = new QHBoxLayout(3); 00143 input_layout->addLayout(dir_layout, 3, 1); 00144 00145 dir_combo = new KURLRequester( new KComboBox(true, this), this, "dir combo" ); 00146 dir_combo->completionObject()->setMode(KURLCompletion::DirCompletion); 00147 dir_combo->comboBox()->insertStringList(lastSearchPaths); 00148 dir_combo->setMode( KFile::Directory|KFile::LocalOnly ); 00149 dir_layout->addWidget(dir_combo); 00150 dir_label->setBuddy(dir_combo); 00151 00152 recursive_box = new QCheckBox(i18n("Recursive"), this); 00153 recursive_box->setMinimumWidth(recursive_box->sizeHint().width()); 00154 recursive_box->setChecked(true); 00155 dir_layout->addSpacing(10); 00156 dir_layout->addWidget(recursive_box); 00157 00158 KButtonBox *actionbox = new KButtonBox(this, Qt::Vertical); 00159 layout->addWidget(actionbox, 0, 2); 00160 actionbox->addStretch(); 00161 search_button = actionbox->addButton(i18n("Search")); 00162 search_button->setDefault(true); 00163 clear_button = actionbox->addButton(i18n("Clear")); 00164 actionbox->addStretch(); 00165 actionbox->layout(); 00166 00167 resultbox = new QListBox(this); 00168 QFontMetrics rb_fm(resultbox->fontMetrics()); 00169 layout->addMultiCellWidget(resultbox, 2, 2, 0, 2); 00170 00171 layout->activate(); 00172 00173 KAcceleratorManager::manage( this ); 00174 00175 QWhatsThis::add(pattern_combo, 00176 i18n("Enter the regular expression you want to search for here.<br>" 00177 "Possible meta characters are:<br>" 00178 "<b>.</b> - Matches any character<br>" 00179 "<b>^</b> - Matches the beginning of a line<br>" 00180 "<b>$</b> - Matches the end of a line<br>" 00181 "<b>\\\\\\&lt;</b> - Matches the beginning of a word<br>" 00182 "<b>\\\\\\&gt;</b> - Matches the end of a word<br>" 00183 "<br>" 00184 "The following repetition operators exist:<br>" 00185 "<b>?</b> - The preceding item is matched at most once<br>" 00186 "<b>*</b> - The preceding item is matched zero or more times<br>" 00187 "<b>+</b> - The preceding item is matched one or more times<br>" 00188 "<b>{<i>n</i>}</b> - The preceding item is matched exactly <i>n</i> times<br>" 00189 "<b>{<i>n</i>,}</b> - The preceding item is matched <i>n</i> or more times<br>" 00190 "<b>{,<i>n</i>}</b> - The preceding item is matched at most <i>n</i> times<br>" 00191 "<b>{<i>n</i>,<i>m</i>}</b> - The preceding item is matched at least <i>n</i>,<br>" 00192 " but at most <i>m</i> times.<br>" 00193 "<br>" 00194 "Furthermore, backreferences to bracketed subexpressions are<br>" 00195 "available via the notation \\\\<i>n</i>." 00196 )); 00197 QWhatsThis::add(files_combo, 00198 i18n("Enter the file name pattern of the files to search here.\n" 00199 "You may give several patterns separated by commas")); 00200 QWhatsThis::add(template_edit, 00201 i18n("You can choose a template for the pattern from the combo box\n" 00202 "and edit it here. The string %s in the template is replaced\n" 00203 "by the pattern input field, resulting in the regular expression\n" 00204 "to search for.")); 00205 QWhatsThis::add(dir_combo, 00206 i18n("Enter the directory which contains the files you want to search in.")); 00207 QWhatsThis::add(recursive_box, 00208 i18n("Check this box to search in all subdirectories.")); 00209 QWhatsThis::add(resultbox, 00210 i18n("The results of the grep run are listed here. Select a\n" 00211 "filename/line number combination and press Enter or doubleclick\n" 00212 "on the item to show the respective line in the editor.")); 00213 00214 // event filter, do something relevant for RETURN 00215 pattern_combo->installEventFilter( this ); 00216 template_edit->installEventFilter( this ); 00217 pattern_combo->installEventFilter( this ); 00218 files_combo->installEventFilter( this ); 00219 dir_combo->comboBox()->installEventFilter( this ); 00220 00221 connect( template_combo, SIGNAL(activated(int)), 00222 SLOT(templateActivated(int)) ); 00223 connect( resultbox, SIGNAL(selected(const QString&)), 00224 SLOT(itemSelected(const QString&)) ); 00225 connect( search_button, SIGNAL(clicked()), 00226 SLOT(slotSearch()) ); 00227 connect( clear_button, SIGNAL(clicked()), 00228 SLOT(slotClear()) ); 00229 connect( pattern_combo->lineEdit(), SIGNAL(textChanged ( const QString & )), 00230 SLOT( patternTextChanged( const QString & ))); 00231 00232 patternTextChanged( pattern_combo->lineEdit()->text()); 00233 } 00234 00235 00236 GrepTool::~GrepTool() 00237 { 00238 delete childproc; 00239 } 00240 00241 void GrepTool::patternTextChanged( const QString & _text) 00242 { 00243 search_button->setEnabled( !_text.isEmpty() ); 00244 } 00245 00246 void GrepTool::templateActivated(int index) 00247 { 00248 template_edit->setText(template_str[index]); 00249 } 00250 00251 void GrepTool::itemSelected(const QString& item) 00252 { 00253 int pos; 00254 QString filename, linenumber; 00255 00256 QString str = item; 00257 if ( (pos = str.find(':')) != -1) 00258 { 00259 filename = str.left(pos); 00260 str = str.right(str.length()-1-pos); 00261 if ( (pos = str.find(':')) != -1) 00262 { 00263 linenumber = str.left(pos); 00264 emit itemSelected(filename,linenumber.toInt()-1); 00265 } 00266 } 00267 } 00268 00269 void GrepTool::processOutput() 00270 { 00271 int pos; 00272 while ( (pos = buf.find('\n')) != -1) 00273 { 00274 QString item = buf.left(pos); 00275 if (!item.isEmpty()) 00276 resultbox->insertItem(item); 00277 buf = buf.right(buf.length()-pos-1); 00278 } 00279 kapp->processEvents(); 00280 } 00281 00282 void GrepTool::slotSearch() 00283 { 00284 if ( childproc && childproc->isRunning() ) 00285 { 00286 childproc->kill(); 00287 return; 00288 } 00289 00290 if (pattern_combo->currentText().isEmpty()) 00291 return; 00292 00293 slotClear (); 00294 00295 QString files; 00296 QString files_temp = files_combo->currentText(); 00297 if (files_temp.right(1) != ",") 00298 files_temp = files_temp + ","; 00299 00300 QStringList tokens = QStringList::split ( ",", files_temp, FALSE ); 00301 QStringList::Iterator it = tokens.begin(); 00302 if (it != tokens.end()) 00303 files = " '"+(*it++)+"'" ; 00304 00305 for ( ; it != tokens.end(); it++ ) 00306 files = files + " -o -name " + "'"+(*it)+ "'"; 00307 00308 QString pattern = template_edit->text(); 00309 pattern.replace("%s", pattern_combo->currentText()); 00310 pattern.replace("'", "'\\''"); 00311 00312 QString filepattern = "find "; 00313 filepattern += KProcess::quote(dir_combo->/*currentText*/url()); 00314 if (!recursive_box->isChecked()) 00315 filepattern += " -maxdepth 1"; 00316 filepattern += " \\( -name "; 00317 filepattern += files; 00318 filepattern += " \\) -exec "; 00319 00320 childproc = new KShellProcess(); 00321 *childproc << filepattern; 00322 *childproc << "grep"; 00323 *childproc << "-n"; 00324 *childproc << "-H"; 00325 *childproc << (QString("-e ") + KProcess::quote(pattern)); 00326 *childproc << "{}"; 00327 *childproc << "/dev/null"; 00328 *childproc << "';'"; 00329 00330 connect( childproc, SIGNAL(processExited(KProcess *)), 00331 SLOT(childExited()) ); 00332 connect( childproc, SIGNAL(receivedStdout(KProcess *, char *, int)), 00333 SLOT(receivedOutput(KProcess *, char *, int)) ); 00334 connect( childproc, SIGNAL(receivedStderr(KProcess *, char *, int)), 00335 SLOT(receivedErrOutput(KProcess *, char *, int)) ); 00336 00337 // actually it should be checked whether the process was started successfully 00338 resultbox->setCursor( QCursor(Qt::WaitCursor) ); 00339 clear_button->setEnabled( false ); 00340 search_button->setText( i18n("Cancel") ); 00341 childproc->start(KProcess::NotifyOnExit, KProcess::AllOutput); 00342 } 00343 00344 void GrepTool::slotSearchFor(const QString &pattern) 00345 { 00346 slotClear(); 00347 pattern_combo->setEditText(pattern); 00348 slotSearch(); 00349 } 00350 00351 void GrepTool::finish() 00352 { 00353 search_button->setEnabled( !pattern_combo->lineEdit()->text().isEmpty() ); 00354 00355 buf += '\n'; 00356 processOutput(); 00357 delete childproc; 00358 childproc = 0; 00359 00360 config->setGroup("GrepTool"); 00361 00362 if (lastSearchItems.contains(pattern_combo->currentText()) == 0) 00363 { 00364 pattern_combo->insertItem(pattern_combo->currentText(), 0); 00365 lastSearchItems.prepend(pattern_combo->currentText()); 00366 if (lastSearchItems.count() > 10) { 00367 lastSearchItems.remove(lastSearchItems.fromLast()); 00368 pattern_combo->removeItem(pattern_combo->count() - 1); 00369 } 00370 config->writeEntry("LastSearchItems", lastSearchItems); 00371 } 00372 00373 if (lastSearchPaths.contains(dir_combo->url()) == 0) 00374 { 00375 dir_combo->comboBox()->insertItem(dir_combo->url(), 0); 00376 lastSearchPaths.prepend(dir_combo->url()); 00377 if (lastSearchPaths.count() > 10) 00378 { 00379 lastSearchPaths.remove(lastSearchPaths.fromLast()); 00380 dir_combo->comboBox()->removeItem(dir_combo->comboBox()->count() - 1); 00381 } 00382 config->writeEntry("LastSearchPaths", lastSearchPaths); 00383 } 00384 } 00385 00386 void GrepTool::slotCancel() 00387 { 00388 finish(); 00389 } 00390 00391 void GrepTool::childExited() 00392 { 00393 // int status = childproc->exitStatus(); 00394 resultbox->unsetCursor(); 00395 clear_button->setEnabled( true ); 00396 search_button->setText( i18n("Search") ); 00397 00398 if ( ! errbuf.isEmpty() ) 00399 { 00400 KMessageBox::information( parentWidget(), i18n("<strong>Error:</strong><p>") + errbuf, i18n("Grep tool error") ); 00401 errbuf.truncate(0); 00402 } 00403 else 00404 finish(); 00405 } 00406 00407 void GrepTool::receivedOutput(KProcess */*proc*/, char *buffer, int buflen) 00408 { 00409 buf += QCString(buffer, buflen+1); 00410 processOutput(); 00411 } 00412 00413 void GrepTool::receivedErrOutput(KProcess */*proc*/, char *buffer, int buflen) 00414 { 00415 errbuf += QCString( buffer, buflen + 1 ); 00416 } 00417 00418 void GrepTool::slotClear() 00419 { 00420 finish(); 00421 resultbox->clear(); 00422 } 00423 00424 void GrepTool::updateDirName(const QString &dir) 00425 { 00426 if (m_lastUpdatedDir != dir) 00427 { 00428 setDirName (dir); 00429 m_lastUpdatedDir = dir; 00430 } 00431 } 00432 00433 void GrepTool::setDirName(const QString &dir){ 00434 dir_combo->setURL(dir); 00435 } 00436 00437 bool GrepTool::eventFilter( QObject *o, QEvent *e ) 00438 { 00439 if ( e->type() == QEvent::KeyPress && ( 00440 ((QKeyEvent*)e)->key() == Qt::Key_Return || 00441 ((QKeyEvent*)e)->key() == Qt::Key_Enter ) ) 00442 { 00443 if ( pattern_combo->currentText().isEmpty() ) 00444 pattern_combo->setFocus(); 00445 else if ( template_edit->text().isEmpty() ) 00446 template_edit->setFocus(); 00447 else if ( files_combo->currentText().isEmpty() ) 00448 files_combo->setFocus(); 00449 else if ( dir_combo->url().isEmpty() ) 00450 dir_combo->setFocus(); 00451 00452 else 00453 slotSearch(); 00454 00455 return true; 00456 } 00457 00458 return QWidget::eventFilter( o, e ); 00459 } 00460 00461 #include "kategrepdialog.moc"
KDE Logo
This file is part of the documentation for kate Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Dec 16 19:08:36 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003