• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kate
 

kate

  • kate
  • app
kategrepdialog.cpp
1 /* This file is part of the KDE project
2  Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
3  Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
4  Copyright (C) 2001, 2004 Anders Lund <anders.lund@lund.tdcadsl.dk>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License version 2 as published by the Free Software Foundation.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 */
20 
21 #include "kategrepdialog.h"
22 #include "katemainwindow.h"
23 
24 #include <tqobject.h>
25 #include <tqlayout.h>
26 #include <tqlabel.h>
27 #include <tqcheckbox.h>
28 #include <tqevent.h>
29 #include <tqlistbox.h>
30 #include <tqregexp.h>
31 #include <tqwhatsthis.h>
32 #include <tqcursor.h>
33 
34 #include <tdeapplication.h>
35 #include <tdeaccelmanager.h>
36 #include <kbuttonbox.h>
37 #include <tdefiledialog.h>
38 #include <kprocess.h>
39 #include <tdeapplication.h>
40 #include <tdelocale.h>
41 #include <kiconloader.h>
42 #include <tdemessagebox.h>
43 #include <kpushbutton.h>
44 #include <kurlrequester.h>
45 #include <kurlcompletion.h>
46 #include <kcombobox.h>
47 #include <klineedit.h>
48 
49 const char *template_desc[] = {
50  "normal",
51  "assignment",
52  "->MEMBER(",
53  "class::MEMBER(",
54  "OBJECT->member(",
55  0
56 };
57 
58 const char *strTemplate[] = {
59  "%s",
60  "\\<%s\\>[\t ]*=[^=]",
61  "\\->[\\t ]*\\<%s\\>[\\t ]*(",
62  "[a-z0-9_$]\\+[\\t ]*::[\\t ]*\\<%s\\>[\\t ]*(",
63  "\\<%s\\>[\\t ]*\\->[\\t ]*[a-z0-9_$]\\+[\\t ]*(",
64  0
65 };
66 
67 
68 GrepTool::GrepTool(TQWidget *parent, const char *name)
69  : TQWidget(parent, name/*, false*/), m_fixFocus(true), childproc(0)
70 {
71  setCaption(i18n("Find in Files"));
72  config = TDEGlobal::config();
73  config->setGroup("GrepTool");
74  lastSearchItems = config->readListEntry("LastSearchItems");
75  lastSearchPaths = config->readListEntry("LastSearchPaths");
76  lastSearchFiles = config->readListEntry("LastSearchFiles");
77 
78  if( lastSearchFiles.isEmpty() )
79  {
80  // if there are no entries, most probably the first Kate start.
81  // Initialize with default values.
82  lastSearchFiles << "*.h,*.hxx,*.cpp,*.cc,*.C,*.cxx,*.idl,*.c"
83  << "*.cpp,*.cc,*.C,*.cxx,*.c"
84  << "*.h,*.hxx,*.idl"
85  << "*";
86  }
87 
88  TQGridLayout *layout = new TQGridLayout(this, 6, 3, 4, 4);
89  layout->setColStretch(0, 10);
90  layout->addColSpacing(1, 10);
91  layout->setColStretch(1, 0);
92  layout->setColStretch(2, 1);
93  layout->setRowStretch(1, 0);
94  layout->setRowStretch(2, 10);
95  layout->setRowStretch(4, 0);
96 
97  TQGridLayout *loInput = new TQGridLayout(4, 2, 4);
98  layout->addLayout(loInput, 0, 0);
99  loInput->setColStretch(0, 0);
100  loInput->setColStretch(1, 20);
101 
102  TQLabel *lPattern = new TQLabel(i18n("Pattern:"), this);
103  lPattern->setFixedSize(lPattern->sizeHint());
104  loInput->addWidget(lPattern, 0, 0, Qt::AlignRight | Qt::AlignVCenter);
105 
106  TQBoxLayout *loPattern = new TQHBoxLayout( 4 );
107  loInput->addLayout( loPattern, 0, 1 );
108  cmbPattern = new KComboBox(true, this);
109  cmbPattern->setDuplicatesEnabled(false);
110  cmbPattern->insertStringList(lastSearchItems);
111  cmbPattern->setEditText(TQString::null);
112  cmbPattern->setInsertionPolicy(TQComboBox::NoInsertion);
113  lPattern->setBuddy(cmbPattern);
114  cmbPattern->setFocus();
115  cmbPattern->setMinimumSize(cmbPattern->sizeHint());
116  loPattern->addWidget( cmbPattern );
117 
118  cbCasesensitive = new TQCheckBox(i18n("Case sensitive"), this);
119  cbCasesensitive->setMinimumWidth(cbCasesensitive->sizeHint().width());
120  cbCasesensitive->setChecked(config->readBoolEntry("CaseSensitive", true));
121  loPattern->addWidget(cbCasesensitive);
122 
123  cbRegex = new TQCheckBox( i18n("Regular expression"), this );
124  cbRegex->setMinimumWidth( cbRegex->sizeHint().width() );
125  cbRegex->setChecked( config->readBoolEntry( "Regex", true ) );
126  loPattern->addWidget( cbRegex );
127  loPattern->setStretchFactor( cmbPattern, 100 );
128 
129  TQLabel *lTemplate = new TQLabel(i18n("Template:"), this);
130  lTemplate->setFixedSize(lTemplate->sizeHint());
131  loInput->addWidget(lTemplate, 1, 0, Qt::AlignRight | Qt::AlignVCenter);
132 
133  TQBoxLayout *loTemplate = new TQHBoxLayout(4);
134  loInput->addLayout(loTemplate, 1, 1);
135 
136  leTemplate = new KLineEdit(this);
137  lTemplate->setBuddy(leTemplate);
138  leTemplate->setText(strTemplate[0]);
139  leTemplate->setMinimumSize(leTemplate->sizeHint());
140  loTemplate->addWidget(leTemplate);
141 
142  KComboBox *cmbTemplate = new KComboBox(false, this);
143  cmbTemplate->insertStrList(template_desc);
144  cmbTemplate->adjustSize();
145  cmbTemplate->setFixedSize(cmbTemplate->size());
146  loTemplate->addWidget(cmbTemplate);
147 
148  TQLabel *lFiles = new TQLabel(i18n("Files:"), this);
149  lFiles->setFixedSize(lFiles->sizeHint());
150  loInput->addWidget(lFiles, 2, 0, Qt::AlignRight | Qt::AlignVCenter);
151 
152  cmbFiles = new KComboBox(true, this);
153  lFiles->setBuddy(TQT_TQWIDGET(cmbFiles->focusProxy()));
154  cmbFiles->setMinimumSize(cmbFiles->sizeHint());
155  cmbFiles->setInsertionPolicy(TQComboBox::NoInsertion);
156  cmbFiles->setDuplicatesEnabled(false);
157  cmbFiles->insertStringList(lastSearchFiles);
158  loInput->addWidget(cmbFiles, 2, 1);
159 
160  TQLabel *lDir = new TQLabel(i18n("Folder:"), this);
161  lDir->setFixedSize(lDir->sizeHint());
162  loInput->addWidget(lDir, 3, 0, Qt::AlignRight | Qt::AlignVCenter);
163 
164  TQBoxLayout *loDir = new TQHBoxLayout(3);
165  loInput->addLayout(loDir, 3, 1);
166 
167  KComboBox* cmbUrl = new KComboBox(true, this);
168  cmbUrl->setMinimumWidth(80); // make sure that 800x600 res works
169  cmbUrl->setDuplicatesEnabled(false);
170  cmbUrl->setInsertionPolicy(TQComboBox::NoInsertion);
171  cmbDir = new KURLRequester( cmbUrl, this, "dir combo" );
172  cmbDir->completionObject()->setMode(KURLCompletion::DirCompletion);
173  cmbDir->comboBox()->insertStringList(lastSearchPaths);
174  cmbDir->setMode( KFile::Directory|KFile::LocalOnly );
175  loDir->addWidget(cmbDir, 1);
176  lDir->setBuddy(cmbDir);
177 
178  cbRecursive = new TQCheckBox(i18n("Recursive"), this);
179  cbRecursive->setMinimumWidth(cbRecursive->sizeHint().width());
180  cbRecursive->setChecked(config->readBoolEntry("Recursive", true));
181  loDir->addWidget(cbRecursive);
182 
183  KButtonBox *actionbox = new KButtonBox(this, Qt::Vertical);
184  layout->addWidget(actionbox, 0, 2);
185  actionbox->addStretch();
186  btnSearch = static_cast<KPushButton*>(actionbox->addButton(KGuiItem(i18n("Find"),"edit-find")));
187  btnSearch->setDefault(true);
188  btnClear = static_cast<KPushButton*>(actionbox->addButton( KStdGuiItem::clear() ));
189  actionbox->addStretch();
190  actionbox->layout();
191 
192  lbResult = new TQListBox(this);
193  TQFontMetrics rb_fm(lbResult->fontMetrics());
194  layout->addMultiCellWidget(lbResult, 2, 2, 0, 2);
195 
196  layout->activate();
197 
198  TDEAcceleratorManager::manage( this );
199 
200  TQWhatsThis::add(lPattern,
201  i18n("<p>Enter the expression you want to search for here."
202  "<p>If 'regular expression' is unchecked, any non-space letters in your "
203  "expression will be escaped with a backslash character."
204  "<p>Possible meta characters are:<br>"
205  "<b>.</b> - Matches any character<br>"
206  "<b>^</b> - Matches the beginning of a line<br>"
207  "<b>$</b> - Matches the end of a line<br>"
208  "<b>\\&lt;</b> - Matches the beginning of a word<br>"
209  "<b>\\&gt;</b> - Matches the end of a word"
210  "<p>The following repetition operators exist:<br>"
211  "<b>?</b> - The preceding item is matched at most once<br>"
212  "<b>*</b> - The preceding item is matched zero or more times<br>"
213  "<b>+</b> - The preceding item is matched one or more times<br>"
214  "<b>{<i>n</i>}</b> - The preceding item is matched exactly <i>n</i> times<br>"
215  "<b>{<i>n</i>,}</b> - The preceding item is matched <i>n</i> or more times<br>"
216  "<b>{,<i>n</i>}</b> - The preceding item is matched at most <i>n</i> times<br>"
217  "<b>{<i>n</i>,<i>m</i>}</b> - The preceding item is matched at least <i>n</i>, "
218  "but at most <i>m</i> times."
219  "<p>Furthermore, backreferences to bracketed subexpressions are available "
220  "via the notation <code>\\#</code>."
221  "<p>See the grep(1) documentation for the full documentation."
222  ));
223  TQWhatsThis::add(lFiles,
224  i18n("Enter the file name pattern of the files to search here.\n"
225  "You may give several patterns separated by commas."));
226  TQWhatsThis::add(lTemplate,
227  i18n("You can choose a template for the pattern from the combo box\n"
228  "and edit it here. The string %s in the template is replaced\n"
229  "by the pattern input field, resulting in the regular expression\n"
230  "to search for."));
231  TQWhatsThis::add(lDir,
232  i18n("Enter the folder which contains the files in which you want to search."));
233  TQWhatsThis::add(cbRecursive,
234  i18n("Check this box to search in all subfolders."));
235  TQWhatsThis::add(cbCasesensitive,
236  i18n("If this option is enabled (the default), the search will be case sensitive."));
237  TQWhatsThis::add( cbRegex, i18n(
238  "<p>If this is enabled, your pattern will be passed unmodified to "
239  "<em>grep(1)</em>. Otherwise, all characters that are not letters will be "
240  "escaped using a backslash character to prevent grep from interpreting "
241  "them as part of the expression.") );
242  TQWhatsThis::add(lbResult,
243  i18n("The results of the grep run are listed here. Select a\n"
244  "filename/line number combination and press Enter or doubleclick\n"
245  "on the item to show the respective line in the editor."));
246 
247  // event filter, do something relevant for RETURN
248  cmbPattern->installEventFilter( this );
249  leTemplate->installEventFilter( this );
250  cmbFiles->installEventFilter( this );
251  cmbDir->comboBox()->installEventFilter( this );
252 
253  connect( cmbTemplate, TQT_SIGNAL(activated(int)),
254  TQT_SLOT(templateActivated(int)) );
255  connect( lbResult, TQT_SIGNAL(selected(const TQString&)),
256  TQT_SLOT(itemSelected(const TQString&)) );
257  connect( btnSearch, TQT_SIGNAL(clicked()),
258  TQT_SLOT(slotSearch()) );
259  connect( btnClear, TQT_SIGNAL(clicked()),
260  TQT_SLOT(slotClear()) );
261  connect( cmbPattern->lineEdit(), TQT_SIGNAL(textChanged ( const TQString & )),
262  TQT_SLOT( patternTextChanged( const TQString & )));
263 
264  patternTextChanged( cmbPattern->lineEdit()->text());
265 }
266 
267 
268 GrepTool::~GrepTool()
269 {
270  delete childproc;
271 }
272 
273 void GrepTool::patternTextChanged( const TQString & _text)
274 {
275  btnSearch->setEnabled( !_text.isEmpty() );
276 }
277 
278 void GrepTool::templateActivated(int index)
279 {
280  leTemplate->setText(strTemplate[index]);
281 }
282 
283 void GrepTool::itemSelected(const TQString& item)
284 {
285  int pos;
286  TQString filename, linenumber;
287 
288  TQString str = item;
289  if ( (pos = str.find(':')) != -1)
290  {
291  filename = str.left(pos);
292  str = str.mid(pos+1);
293  if ( (pos = str.find(':')) != -1)
294  {
295  filename = m_workingDir + TQDir::separator() + filename;
296  linenumber = str.left(pos);
297  emit itemSelected(filename,linenumber.toInt()-1);
298  }
299  }
300 }
301 
302 void GrepTool::processOutput()
303 {
304  int pos;
305  while ( (pos = buf.find('\n')) != -1)
306  {
307  TQString item = buf.mid(2,pos-2);
308  if (!item.isEmpty())
309  lbResult->insertItem(item);
310  buf = buf.mid(pos+1);
311  }
312  kapp->processEvents();
313 }
314 
315 void GrepTool::slotSearch()
316 {
317  if ( cmbPattern->currentText().isEmpty() )
318  {
319  cmbPattern->setFocus();
320  return;
321  }
322 
323  if ( cmbDir->url().isEmpty() || ! TQDir(cmbDir->url()).exists() )
324  {
325  cmbDir->setFocus();
326  KMessageBox::information( this, i18n(
327  "You must enter an existing local folder in the 'Folder' entry."),
328  i18n("Invalid Folder"), "Kate grep tool: invalid folder" );
329  return;
330  }
331 
332  if ( ! leTemplate->text().contains("%s") )
333  {
334  leTemplate->setFocus();
335  return;
336  }
337 
338  if ( childproc && childproc->isRunning() )
339  {
340  childproc->kill();
341  return;
342  }
343 
344  slotClear ();
345 
346  m_workingDir = cmbDir->url();
347 
348  TQString s = cmbPattern->currentText();
349  if ( ! cbRegex->isChecked() )
350  s.replace( TQRegExp( "([^\\w'()<>])" ), "\\\\1" );
351  TQString pattern = leTemplate->text();
352  pattern.replace( "%s", s );
353 
354  childproc = new TDEProcess();
355  childproc->setWorkingDirectory( m_workingDir );
356  *childproc << "find" << ".";
357  if (!cbRecursive->isChecked())
358  *childproc << "-maxdepth" << "1";
359  if (!cmbFiles->currentText().isEmpty() )
360  {
361  TQStringList files = TQStringList::split ( ",", cmbFiles->currentText(), FALSE );
362  *childproc << "(";
363  bool first = true;
364  for ( TQStringList::Iterator it = files.begin(); it != files.end(); ++it )
365  {
366  if (!first)
367  *childproc << "-o";
368  *childproc << "-name" << (*it);
369  first = false;
370  }
371  *childproc << ")";
372  }
373  *childproc << "-exec" << "grep";
374  if (!cbCasesensitive->isChecked())
375  *childproc << "-i";
376  *childproc << "-n" << "-e" << pattern << "{}";
377  *childproc << "/dev/null"; //trick to have grep always display the filename
378  *childproc << ";";
379 
380  connect( childproc, TQT_SIGNAL(processExited(TDEProcess *)),
381  TQT_SLOT(childExited()) );
382  connect( childproc, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)),
383  TQT_SLOT(receivedOutput(TDEProcess *, char *, int)) );
384  connect( childproc, TQT_SIGNAL(receivedStderr(TDEProcess *, char *, int)),
385  TQT_SLOT(receivedErrOutput(TDEProcess *, char *, int)) );
386 
387  // actually it should be checked whether the process was started successfully
388  lbResult->setCursor( TQCursor(Qt::WaitCursor) );
389  btnClear->setEnabled( false );
390  btnSearch->setGuiItem( KGuiItem(i18n("Cancel"), "button_cancel"));
391  childproc->start(TDEProcess::NotifyOnExit, TDEProcess::AllOutput);
392 }
393 
394 void GrepTool::slotSearchFor(const TQString &pattern)
395 {
396  slotClear();
397  cmbPattern->setEditText(pattern);
398  slotSearch();
399 }
400 
401 void GrepTool::finish()
402 {
403  btnSearch->setEnabled( !cmbPattern->lineEdit()->text().isEmpty() );
404 
405  buf += '\n';
406  processOutput();
407  delete childproc;
408  childproc = 0;
409 
410  config->setGroup("GrepTool");
411 
412  TQString cmbText = cmbPattern->currentText();
413  bool itemsRemoved = lastSearchItems.remove(cmbText) > 0;
414  lastSearchItems.prepend(cmbText);
415  if (itemsRemoved)
416  {
417  cmbPattern->removeItem(cmbPattern->currentItem());
418  }
419  cmbPattern->insertItem(cmbText, 0);
420  cmbPattern->setCurrentItem(0);
421  if (lastSearchItems.count() > 10) {
422  lastSearchItems.pop_back();
423  cmbPattern->removeItem(cmbPattern->count() - 1);
424  }
425  config->writeEntry("LastSearchItems", lastSearchItems);
426 
427 
428  cmbText = cmbDir->url();
429  itemsRemoved = lastSearchPaths.remove(cmbText) > 0;
430  lastSearchPaths.prepend(cmbText);
431  if (itemsRemoved)
432  {
433  cmbDir->comboBox()->removeItem(cmbDir->comboBox()->currentItem());
434  }
435  cmbDir->comboBox()->insertItem(cmbText, 0);
436  cmbDir->comboBox()->setCurrentItem(0);
437  if (lastSearchPaths.count() > 10)
438  {
439  lastSearchPaths.pop_back();
440  cmbDir->comboBox()->removeItem(cmbDir->comboBox()->count() - 1);
441  }
442  config->writeEntry("LastSearchPaths", lastSearchPaths);
443 
444 
445  cmbText = cmbFiles->currentText();
446  itemsRemoved = lastSearchFiles.remove(cmbText) > 0;
447  lastSearchFiles.prepend(cmbText);
448  if (itemsRemoved)
449  {
450  cmbFiles->removeItem(cmbFiles->currentItem());
451  }
452  cmbFiles->insertItem(cmbText, 0);
453  cmbFiles->setCurrentItem(0);
454  if (lastSearchFiles.count() > 10) {
455  lastSearchFiles.pop_back();
456  cmbFiles->removeItem(cmbFiles->count() - 1);
457  }
458  config->writeEntry("LastSearchFiles", lastSearchFiles);
459 
460  config->writeEntry("Recursive", cbRecursive->isChecked());
461  config->writeEntry("CaseSensitive", cbCasesensitive->isChecked());
462  config->writeEntry("Regex", cbRegex->isChecked());
463 }
464 
465 void GrepTool::slotCancel()
466 {
467  finish();
468 }
469 
470 void GrepTool::childExited()
471 {
472 // int status = childproc->exitStatus();
473  lbResult->unsetCursor();
474  btnClear->setEnabled( true );
475  btnSearch->setGuiItem( KGuiItem(i18n("Find"), "edit-find") );
476 
477  if ( ! errbuf.isEmpty() )
478  {
479  KMessageBox::information( parentWidget(), i18n("<strong>Error:</strong><p>") + errbuf, i18n("Grep Tool Error") );
480  errbuf.truncate(0);
481  }
482  else
483  finish();
484 }
485 
486 void GrepTool::receivedOutput(TDEProcess */*proc*/, char *buffer, int buflen)
487 {
488  buf += TQCString(buffer, buflen+1);
489  processOutput();
490 }
491 
492 void GrepTool::receivedErrOutput(TDEProcess */*proc*/, char *buffer, int buflen)
493 {
494  errbuf += TQCString( buffer, buflen + 1 );
495 }
496 
497 void GrepTool::slotClear()
498 {
499  finish();
500  lbResult->clear();
501 }
502 
503 void GrepTool::updateDirName(const TQString &dir)
504 {
505  if (m_lastUpdatedDir != dir)
506  {
507  setDirName (dir);
508  m_lastUpdatedDir = dir;
509  }
510 }
511 
512 void GrepTool::setDirName(const TQString &dir){
513  cmbDir->setURL(dir);
514 }
515 
516 bool GrepTool::eventFilter( TQObject *o, TQEvent *e )
517 {
518  if ( e->type() == TQEvent::KeyPress && (
519  ((TQKeyEvent*)e)->key() == Qt::Key_Return ||
520  ((TQKeyEvent*)e)->key() == Qt::Key_Enter ) )
521  {
522  slotSearch();
523  return true;
524  }
525 
526  return TQWidget::eventFilter( o, e );
527 }
528 
529 void GrepTool::focusInEvent ( TQFocusEvent * ev )
530 {
531  TQWidget::focusInEvent(ev);
532  if (m_fixFocus) {
533  m_fixFocus = false;
534  cmbPattern->setFocus();
535  }
536 }
537 
538 void GrepTool::showEvent( TQShowEvent * ev )
539 {
540  TQWidget::showEvent(ev);
541  m_fixFocus = true;
542 }
543 
544 #include "kategrepdialog.moc"

kate

Skip menu "kate"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

kate

Skip menu "kate"
  • kate
  • libkonq
  • twin
  •   lib
Generated for kate by doxygen 1.8.1.2
This website is maintained by Timothy Pearson.