• 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 <tdeprocess.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
49const char *template_desc[] = {
50 "normal",
51 "assignment",
52 "->MEMBER(",
53 "class::MEMBER(",
54 "OBJECT->member(",
55 0
56};
57
58const 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
68GrepTool::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, TQt::AlignRight | TQt::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, TQt::AlignRight | TQt::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, TQt::AlignRight | TQt::AlignVCenter);
151
152 TQBoxLayout *loFiles = new TQHBoxLayout( 2 );
153 loInput->addLayout( loFiles, 2, 1 );
154
155 cmbFiles = new KComboBox(true, this);
156 lFiles->setBuddy(cmbFiles->focusProxy());
157 cmbFiles->setMinimumSize(cmbFiles->sizeHint());
158 cmbFiles->setInsertionPolicy(TQComboBox::NoInsertion);
159 cmbFiles->setDuplicatesEnabled(false);
160 cmbFiles->insertStringList(lastSearchFiles);
161 loFiles->addWidget(cmbFiles);
162
163 cbHideErrors = new TQCheckBox( i18n("Hide errors"), this );
164 cbHideErrors->setMinimumWidth( cbHideErrors->sizeHint().width() );
165 cbHideErrors->setChecked( config->readBoolEntry( "HideErrors", false ) );
166 loFiles->addWidget(cbHideErrors);
167 loFiles->setStretchFactor(cmbFiles, 100);
168
169 TQLabel *lDir = new TQLabel(i18n("Folder:"), this);
170 lDir->setFixedSize(lDir->sizeHint());
171 loInput->addWidget(lDir, 3, 0, TQt::AlignRight | TQt::AlignVCenter);
172
173 TQBoxLayout *loDir = new TQHBoxLayout(3);
174 loInput->addLayout(loDir, 3, 1);
175
176 KComboBox* cmbUrl = new KComboBox(true, this);
177 cmbUrl->setMinimumWidth(80); // make sure that 800x600 res works
178 cmbUrl->setDuplicatesEnabled(false);
179 cmbUrl->setInsertionPolicy(TQComboBox::NoInsertion);
180 cmbDir = new KURLRequester( cmbUrl, this, "dir combo" );
181 cmbDir->completionObject()->setMode(KURLCompletion::DirCompletion);
182 cmbDir->comboBox()->insertStringList(lastSearchPaths);
183 cmbDir->setMode( KFile::Directory|KFile::LocalOnly );
184 loDir->addWidget(cmbDir, 1);
185 lDir->setBuddy(cmbDir);
186
187 cbRecursive = new TQCheckBox(i18n("Recursive"), this);
188 cbRecursive->setMinimumWidth(cbRecursive->sizeHint().width());
189 cbRecursive->setChecked(config->readBoolEntry("Recursive", true));
190 loDir->addWidget(cbRecursive);
191
192 KButtonBox *actionbox = new KButtonBox(this, TQt::Vertical);
193 layout->addWidget(actionbox, 0, 2);
194 actionbox->addStretch();
195 btnSearch = static_cast<KPushButton*>(actionbox->addButton(KGuiItem(i18n("Find"),"edit-find")));
196 btnSearch->setDefault(true);
197 btnClear = static_cast<KPushButton*>(actionbox->addButton( KStdGuiItem::clear() ));
198 actionbox->addStretch();
199 actionbox->layout();
200
201 lbResult = new TQListBox(this);
202 TQFontMetrics rb_fm(lbResult->fontMetrics());
203 layout->addMultiCellWidget(lbResult, 2, 2, 0, 2);
204
205 layout->activate();
206
207 TDEAcceleratorManager::manage( this );
208
209 TQWhatsThis::add(lPattern,
210 i18n("<p>Enter the expression you want to search for here."
211 "<p>If 'regular expression' is unchecked, all characters that are not "
212 "letters in your expression will be escaped with a backslash character."
213 "<p>Possible meta characters are:<br>"
214 "<b>.</b> - Matches any character<br>"
215 "<b>^</b> - Matches the beginning of a line<br>"
216 "<b>$</b> - Matches the end of a line<br>"
217 "<b>\\&lt;</b> - Matches the beginning of a word<br>"
218 "<b>\\&gt;</b> - Matches the end of a word"
219 "<p>The following repetition operators exist:<br>"
220 "<b>?</b> - The preceding item is matched at most once<br>"
221 "<b>*</b> - The preceding item is matched zero or more times<br>"
222 "<b>+</b> - The preceding item is matched one or more times<br>"
223 "<b>{<i>n</i>}</b> - The preceding item is matched exactly <i>n</i> times<br>"
224 "<b>{<i>n</i>,}</b> - The preceding item is matched <i>n</i> or more times<br>"
225 "<b>{,<i>n</i>}</b> - The preceding item is matched at most <i>n</i> times<br>"
226 "<b>{<i>n</i>,<i>m</i>}</b> - The preceding item is matched at least <i>n</i>, "
227 "but at most <i>m</i> times."
228 "<p>Furthermore, backreferences to bracketed subexpressions are available "
229 "via the notation <code>\\#</code>."
230 "<p>See the grep(1) documentation for the full documentation."
231 ));
232 TQWhatsThis::add(lFiles,
233 i18n("Enter the file name pattern of the files to search here.\n"
234 "You may give several patterns separated by commas."));
235 TQWhatsThis::add(lTemplate,
236 i18n("You can choose a template for the pattern from the combo box\n"
237 "and edit it here. The string %s in the template is replaced\n"
238 "by the pattern input field, resulting in the regular expression\n"
239 "to search for."));
240 TQWhatsThis::add(lDir,
241 i18n("Enter the folder which contains the files in which you want to search."));
242 TQWhatsThis::add(cbRecursive,
243 i18n("Check this box to search in all subfolders."));
244 TQWhatsThis::add(cbCasesensitive,
245 i18n("If this option is enabled (the default), the search will be case sensitive."));
246 TQWhatsThis::add( cbRegex, i18n(
247 "<p>If this is enabled, your pattern will be passed unmodified to "
248 "<em>grep(1)</em>. Otherwise, all characters that are not letters will be "
249 "escaped using a backslash character to prevent grep from interpreting "
250 "them as part of the expression.") );
251 TQWhatsThis::add(lbResult,
252 i18n("The results of the grep run are listed here. Select a\n"
253 "filename/line number combination and press Enter or doubleclick\n"
254 "on the item to show the respective line in the editor."));
255 TQWhatsThis::add( cbHideErrors, i18n(
256 "<p>If this is checked, the dialog window showing the search errors "
257 "will not be displayed at the end of the search.") );
258
259 // event filter, do something relevant for RETURN
260 cmbPattern->installEventFilter( this );
261 leTemplate->installEventFilter( this );
262 cmbFiles->installEventFilter( this );
263 cmbDir->comboBox()->installEventFilter( this );
264
265 connect( cmbTemplate, TQ_SIGNAL(activated(int)),
266 TQ_SLOT(templateActivated(int)) );
267 connect( lbResult, TQ_SIGNAL(selected(const TQString&)),
268 TQ_SLOT(itemSelected(const TQString&)) );
269 connect( btnSearch, TQ_SIGNAL(clicked()),
270 TQ_SLOT(slotSearch()) );
271 connect( btnClear, TQ_SIGNAL(clicked()),
272 TQ_SLOT(slotClear()) );
273 connect( cmbPattern->lineEdit(), TQ_SIGNAL(textChanged ( const TQString & )),
274 TQ_SLOT( patternTextChanged( const TQString & )));
275
276 patternTextChanged( cmbPattern->lineEdit()->text());
277}
278
279
280GrepTool::~GrepTool()
281{
282 delete childproc;
283}
284
285void GrepTool::patternTextChanged( const TQString & _text)
286{
287 btnSearch->setEnabled( !_text.isEmpty() );
288}
289
290void GrepTool::templateActivated(int index)
291{
292 leTemplate->setText(strTemplate[index]);
293}
294
295void GrepTool::itemSelected(const TQString& item)
296{
297 int pos;
298 TQString filename, linenumber;
299
300 TQString str = item;
301 if ( (pos = str.find(':')) != -1)
302 {
303 filename = str.left(pos);
304 str = str.mid(pos+1);
305 if ( (pos = str.find(':')) != -1)
306 {
307 filename = m_workingDir + TQDir::separator() + filename;
308 linenumber = str.left(pos);
309 emit itemSelected(filename,linenumber.toInt()-1);
310 }
311 }
312}
313
314void GrepTool::processOutput()
315{
316 int pos;
317 while ( (pos = buf.find('\n')) != -1)
318 {
319 TQString item = buf.mid(2,pos-2);
320 if (!item.isEmpty())
321 lbResult->insertItem(item);
322 buf = buf.mid(pos+1);
323 }
324 tdeApp->processEvents();
325}
326
327void GrepTool::slotSearch()
328{
329 if ( cmbPattern->currentText().isEmpty() )
330 {
331 cmbPattern->setFocus();
332 return;
333 }
334
335 if ( cmbDir->url().isEmpty() || ! TQDir(cmbDir->url()).exists() )
336 {
337 cmbDir->setFocus();
338 KMessageBox::information( this, i18n(
339 "You must enter an existing local folder in the 'Folder' entry."),
340 i18n("Invalid Folder"), "Kate grep tool: invalid folder" );
341 return;
342 }
343
344 if ( ! leTemplate->text().contains("%s") )
345 {
346 leTemplate->setFocus();
347 return;
348 }
349
350 if ( childproc && childproc->isRunning() )
351 {
352 childproc->kill();
353 return;
354 }
355
356 slotClear ();
357
358 m_workingDir = cmbDir->url();
359
360 TQString s = cmbPattern->currentText();
361 if ( ! cbRegex->isChecked() )
362 s.replace( TQRegExp( "([^\\w'()<>])" ), "\\\\1" );
363 TQString pattern = leTemplate->text();
364 pattern.replace( "%s", s );
365
366 childproc = new TDEProcess();
367 childproc->setWorkingDirectory( m_workingDir );
368 *childproc << "find" << ".";
369 if (!cbRecursive->isChecked())
370 *childproc << "-maxdepth" << "1";
371 if (!cmbFiles->currentText().isEmpty() )
372 {
373 TQStringList files = TQStringList::split ( ",", cmbFiles->currentText(), FALSE );
374 *childproc << "(";
375 bool first = true;
376 for ( TQStringList::Iterator it = files.begin(); it != files.end(); ++it )
377 {
378 if (!first)
379 *childproc << "-o";
380 *childproc << "-name" << (*it);
381 first = false;
382 }
383 *childproc << ")";
384 }
385 *childproc << "-exec" << "grep";
386 if (!cbCasesensitive->isChecked())
387 *childproc << "-i";
388 *childproc << "-n" << "-e" << pattern << "{}";
389 *childproc << "/dev/null"; //trick to have grep always display the filename
390 *childproc << ";";
391
392 connect( childproc, TQ_SIGNAL(processExited(TDEProcess *)),
393 TQ_SLOT(childExited()) );
394 connect( childproc, TQ_SIGNAL(receivedStdout(TDEProcess *, char *, int)),
395 TQ_SLOT(receivedOutput(TDEProcess *, char *, int)) );
396 connect( childproc, TQ_SIGNAL(receivedStderr(TDEProcess *, char *, int)),
397 TQ_SLOT(receivedErrOutput(TDEProcess *, char *, int)) );
398
399 // actually it should be checked whether the process was started successfully
400 lbResult->setCursor( TQCursor(TQt::WaitCursor) );
401 btnClear->setEnabled( false );
402 btnSearch->setGuiItem( KGuiItem(i18n("Cancel"), "button_cancel"));
403 childproc->start(TDEProcess::NotifyOnExit, TDEProcess::AllOutput);
404}
405
406void GrepTool::slotSearchFor(const TQString &pattern)
407{
408 slotClear();
409 cmbPattern->setEditText(pattern);
410 slotSearch();
411}
412
413void GrepTool::finish()
414{
415 btnSearch->setEnabled( !cmbPattern->lineEdit()->text().isEmpty() );
416
417 buf += '\n';
418 processOutput();
419 delete childproc;
420 childproc = 0;
421
422 config->setGroup("GrepTool");
423
424 TQString cmbText = cmbPattern->currentText();
425 bool itemsRemoved = lastSearchItems.remove(cmbText) > 0;
426 lastSearchItems.prepend(cmbText);
427 if (itemsRemoved)
428 {
429 cmbPattern->removeItem(cmbPattern->currentItem());
430 }
431 cmbPattern->insertItem(cmbText, 0);
432 cmbPattern->setCurrentItem(0);
433 if (lastSearchItems.count() > 10) {
434 lastSearchItems.pop_back();
435 cmbPattern->removeItem(cmbPattern->count() - 1);
436 }
437 config->writeEntry("LastSearchItems", lastSearchItems);
438
439
440 cmbText = cmbDir->url();
441 itemsRemoved = lastSearchPaths.remove(cmbText) > 0;
442 lastSearchPaths.prepend(cmbText);
443 if (itemsRemoved)
444 {
445 cmbDir->comboBox()->removeItem(cmbDir->comboBox()->currentItem());
446 }
447 cmbDir->comboBox()->insertItem(cmbText, 0);
448 cmbDir->comboBox()->setCurrentItem(0);
449 if (lastSearchPaths.count() > 10)
450 {
451 lastSearchPaths.pop_back();
452 cmbDir->comboBox()->removeItem(cmbDir->comboBox()->count() - 1);
453 }
454 config->writeEntry("LastSearchPaths", lastSearchPaths);
455
456
457 cmbText = cmbFiles->currentText();
458 itemsRemoved = lastSearchFiles.remove(cmbText) > 0;
459 lastSearchFiles.prepend(cmbText);
460 if (itemsRemoved)
461 {
462 cmbFiles->removeItem(cmbFiles->currentItem());
463 }
464 cmbFiles->insertItem(cmbText, 0);
465 cmbFiles->setCurrentItem(0);
466 if (lastSearchFiles.count() > 10) {
467 lastSearchFiles.pop_back();
468 cmbFiles->removeItem(cmbFiles->count() - 1);
469 }
470 config->writeEntry("LastSearchFiles", lastSearchFiles);
471
472 config->writeEntry("Recursive", cbRecursive->isChecked());
473 config->writeEntry("CaseSensitive", cbCasesensitive->isChecked());
474 config->writeEntry("Regex", cbRegex->isChecked());
475 config->writeEntry("HideErrors", cbHideErrors->isChecked());
476}
477
478void GrepTool::slotCancel()
479{
480 finish();
481}
482
483void GrepTool::childExited()
484{
485// int status = childproc->exitStatus();
486 lbResult->unsetCursor();
487 btnClear->setEnabled( true );
488 btnSearch->setGuiItem( KGuiItem(i18n("Find"), "edit-find") );
489
490 if ( !errbuf.isEmpty())
491 {
492 if (!cbHideErrors->isChecked())
493 {
494 KMessageBox::information( parentWidget(), i18n("<strong>Error:</strong><p>") + errbuf, i18n("Grep Tool Error") );
495 }
496 errbuf.truncate(0);
497 }
498 else
499 finish();
500}
501
502void GrepTool::receivedOutput(TDEProcess */*proc*/, char *buffer, int buflen)
503{
504 buf += TQCString(buffer, buflen+1);
505 processOutput();
506}
507
508void GrepTool::receivedErrOutput(TDEProcess */*proc*/, char *buffer, int buflen)
509{
510 errbuf += TQCString( buffer, buflen + 1 );
511}
512
513void GrepTool::slotClear()
514{
515 finish();
516 lbResult->clear();
517}
518
519void GrepTool::updateDirName(const TQString &dir)
520{
521 if (m_lastUpdatedDir != dir)
522 {
523 setDirName (dir);
524 m_lastUpdatedDir = dir;
525 }
526}
527
528void GrepTool::setDirName(const TQString &dir){
529 cmbDir->setURL(dir);
530}
531
532bool GrepTool::eventFilter( TQObject *o, TQEvent *e )
533{
534 if ( e->type() == TQEvent::KeyPress && (
535 ((TQKeyEvent*)e)->key() == TQt::Key_Return ||
536 ((TQKeyEvent*)e)->key() == TQt::Key_Enter ) )
537 {
538 slotSearch();
539 return true;
540 }
541
542 return TQWidget::eventFilter( o, e );
543}
544
545void GrepTool::focusInEvent ( TQFocusEvent * ev )
546{
547 TQWidget::focusInEvent(ev);
548 if (m_fixFocus) {
549 m_fixFocus = false;
550 cmbPattern->setFocus();
551 }
552}
553
554void GrepTool::showEvent( TQShowEvent * ev )
555{
556 TQWidget::showEvent(ev);
557 m_fixFocus = true;
558}
559
560#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.9.4
This website is maintained by Timothy Pearson.