21 #include "kfinddialog.h"
22 #include <tqcheckbox.h>
24 #include <tqgroupbox.h>
27 #include <tqpopupmenu.h>
28 #include <tqpushbutton.h>
30 #include <kcombobox.h>
33 #include <tdemessagebox.h>
35 #include <tqwhatsthis.h>
37 #include <kregexpeditorinterface.h>
38 #include <tdeparts/componentfactory.h>
40 class KFindDialog::KFindDialogPrivate
43 KFindDialogPrivate() : m_regexpDialog(0),
44 m_regexpDialogQueryDone(false),
46 TQDialog* m_regexpDialog;
47 bool m_regexpDialogQueryDone;
49 bool m_initialShowDone;
50 TQStringList findStrings;
54 KFindDialog::KFindDialog(TQWidget *parent,
const char *name,
long options,
const TQStringList &findStrings,
bool hasSelection) :
55 KDialogBase(parent, name, true, i18n(
"Find Text"), Ok | Cancel, Ok),
57 m_replaceExtension (0)
59 d =
new KFindDialogPrivate;
60 init(
false, findStrings, hasSelection);
65 KFindDialog::KFindDialog(
bool modal, TQWidget *parent,
const char *name,
long options,
const TQStringList &findStrings,
bool hasSelection) :
66 KDialogBase(parent, name, modal, i18n(
"Find Text"), Ok | Cancel, Ok),
68 m_replaceExtension (0)
70 d =
new KFindDialogPrivate;
71 init(
false, findStrings, hasSelection);
77 KDialogBase(parent, name, true, i18n(
"Replace Text"), Ok | Cancel, Ok),
79 m_replaceExtension (0)
81 d =
new KFindDialogPrivate;
94 m_findExtension =
new TQWidget(m_findGrp);
95 m_findLayout->addMultiCellWidget(m_findExtension, 3, 3, 0, 1);
98 return m_findExtension;
106 void KFindDialog::init(
bool forReplace,
const TQStringList &findStrings,
bool hasSelection)
108 TQVBoxLayout *topLayout;
109 TQGridLayout *optionsLayout;
112 TQWidget *page =
new TQWidget(
this);
115 topLayout =
new TQVBoxLayout(page);
117 topLayout->setMargin( 0 );
119 m_findGrp =
new TQGroupBox(0, Qt::Vertical, i18n(
"Find"), page);
122 m_findLayout =
new TQGridLayout(m_findGrp->layout());
126 m_findLabel =
new TQLabel(i18n(
"&Text to find:"), m_findGrp);
128 m_find->setMaxCount(10);
129 m_find->setDuplicatesEnabled(
false);
130 m_regExp =
new TQCheckBox(i18n(
"Regular e&xpression"), m_findGrp);
131 m_regExpItem =
new TQPushButton(i18n(
"&Edit..."), m_findGrp);
132 m_regExpItem->setEnabled(
false);
134 m_findLayout->addWidget(m_findLabel, 0, 0);
135 m_findLayout->addMultiCellWidget(m_find, 1, 1, 0, 1);
136 m_findLayout->addWidget(m_regExp, 2, 0);
137 m_findLayout->addWidget(m_regExpItem, 2, 1);
138 topLayout->addWidget(m_findGrp);
140 m_replaceGrp =
new TQGroupBox(0, Qt::Vertical, i18n(
"Replace With"), page);
143 m_replaceLayout =
new TQGridLayout(m_replaceGrp->layout());
147 m_replaceLabel =
new TQLabel(i18n(
"Replace&ment text:"), m_replaceGrp);
149 m_replace->setMaxCount(10);
150 m_replace->setDuplicatesEnabled(
false);
151 m_backRef =
new TQCheckBox(i18n(
"Use p&laceholders"), m_replaceGrp);
152 m_backRef->setEnabled(m_regExp->isChecked());
153 m_backRefItem =
new TQPushButton(i18n(
"Insert Place&holder"), m_replaceGrp);
154 m_backRefItem->setEnabled(m_regExp->isChecked() && m_backRef->isChecked());
156 m_replaceLayout->addWidget(m_replaceLabel, 0, 0);
157 m_replaceLayout->addMultiCellWidget(m_replace, 1, 1, 0, 1);
158 m_replaceLayout->addWidget(m_backRef, 2, 0);
159 m_replaceLayout->addWidget(m_backRefItem, 2, 1);
160 topLayout->addWidget(m_replaceGrp);
162 m_optionGrp =
new TQGroupBox(0, Qt::Vertical, i18n(
"Options"), page);
165 optionsLayout =
new TQGridLayout(m_optionGrp->layout());
169 m_caseSensitive =
new TQCheckBox(i18n(
"C&ase sensitive"), m_optionGrp);
170 m_wholeWordsOnly =
new TQCheckBox(i18n(
"&Whole words only"), m_optionGrp);
171 m_fromCursor =
new TQCheckBox(i18n(
"From c&ursor"), m_optionGrp);
172 m_findBackwards =
new TQCheckBox(i18n(
"Find &backwards"), m_optionGrp);
173 m_selectedText =
new TQCheckBox(i18n(
"&Selected text"), m_optionGrp);
177 m_selectedText->setChecked( hasSelection );
178 slotSelectedTextToggled( hasSelection );
180 m_promptOnReplace =
new TQCheckBox(i18n(
"&Prompt on replace"), m_optionGrp);
181 m_promptOnReplace->setChecked(
true );
183 optionsLayout->addWidget(m_caseSensitive, 0, 0);
184 optionsLayout->addWidget(m_wholeWordsOnly, 1, 0);
185 optionsLayout->addWidget(m_fromCursor, 2, 0);
186 optionsLayout->addWidget(m_findBackwards, 0, 1);
187 optionsLayout->addWidget(m_selectedText, 1, 1);
188 optionsLayout->addWidget(m_promptOnReplace, 2, 1);
189 topLayout->addWidget(m_optionGrp);
196 connect(m_selectedText, TQT_SIGNAL(toggled(
bool)),
this, TQT_SLOT(slotSelectedTextToggled(
bool)));
197 connect(m_regExp, TQT_SIGNAL(toggled(
bool)),
this, TQT_SLOT(slotRegexCheckBoxToggled(
bool)));
198 connect(m_backRef, TQT_SIGNAL(toggled(
bool)),
this, TQT_SLOT(slotPlaceholdersCheckBoxToggled(
bool)));
199 connect(m_regExpItem, TQT_SIGNAL(clicked()),
this, TQT_SLOT(showPatterns()));
200 connect(m_backRefItem, TQT_SIGNAL(clicked()),
this, TQT_SLOT(showPlaceholders()));
202 connect(m_find, TQT_SIGNAL(textChanged (
const TQString & )),
this, TQT_SLOT(textSearchChanged(
const TQString & )));
205 setTabOrder(m_find, m_regExp);
206 setTabOrder(m_regExp, m_regExpItem);
207 setTabOrder(m_regExpItem, m_replace);
208 setTabOrder(m_replace, m_backRef);
209 setTabOrder(m_backRef, m_backRefItem);
210 setTabOrder(m_backRefItem, m_caseSensitive);
211 setTabOrder(m_caseSensitive, m_wholeWordsOnly);
212 setTabOrder(m_wholeWordsOnly, m_fromCursor);
213 setTabOrder(m_fromCursor, m_findBackwards);
214 setTabOrder(m_findBackwards, m_selectedText);
215 setTabOrder(m_selectedText, m_promptOnReplace);
218 m_findLabel->setBuddy(m_find);
219 m_replaceLabel->setBuddy(m_replace);
223 m_promptOnReplace->hide();
224 m_replaceGrp->hide();
227 d->findStrings = findStrings;
233 i18n(
"Start replace"),
234 i18n(
"<qt>If you press the <b>Replace</b> button, the text you entered "
235 "above is searched for within the document and any occurrence is "
236 "replaced with the replacement text.</qt>")));
241 i18n(
"Start searching"),
242 i18n(
"<qt>If you press the <b>Find</b> button, the text you entered "
243 "above is searched for within the document.</qt>")));
247 TQWhatsThis::add ( m_find, i18n(
248 "Enter a pattern to search for, or select a previous pattern from "
250 TQWhatsThis::add ( m_regExp, i18n(
251 "If enabled, search for a regular expression.") );
252 TQWhatsThis::add ( m_regExpItem, i18n(
253 "Click here to edit your regular expression using a graphical editor.") );
254 TQWhatsThis::add ( m_replace, i18n(
255 "Enter a replacement string, or select a previous one from the list.") );
256 TQWhatsThis::add( m_backRef, i18n(
257 "<qt>When regular expressions are enabled, you can select part of the searched text by "
258 "enclosing it within parenthesis. Placeholders allow you to insert such text in the "
259 "replacement string, similar to how backreferences are used in sed. When enabled, "
260 "any occurrence of <code><b>\\N</b></code> (where <code><b>N</b></code> "
261 "is a integer number, e.g. \\1, \\2, ...), will be replaced with "
262 "the corresponding capture (\"parenthesized substring\") from the "
263 "pattern.<p>To include a literal <code><b>\\N</b></code> in your "
264 "replacement, put an extra backslash in front of it, like "
265 "<code><b>\\\\N</b></code>.</qt>") );
266 TQWhatsThis::add ( m_backRefItem, i18n(
267 "Click for a menu of available captures.") );
268 TQWhatsThis::add ( m_wholeWordsOnly, i18n(
269 "Require word boundaries in both ends of a match to succeed.") );
270 TQWhatsThis::add ( m_fromCursor, i18n(
271 "Start searching at the current cursor location rather than at the top.") );
272 TQWhatsThis::add ( m_selectedText, i18n(
273 "Only search within the current selection.") );
274 TQWhatsThis::add ( m_caseSensitive, i18n(
275 "Perform a case sensitive search: entering the pattern "
276 "'Joe' will not match 'joe' or 'JOE', only 'Joe'.") );
277 TQWhatsThis::add ( m_findBackwards, i18n(
278 "Search backwards.") );
279 TQWhatsThis::add ( m_promptOnReplace, i18n(
280 "Ask before replacing each match found.") );
283 void KFindDialog::textSearchChanged(
const TQString & text)
288 void KFindDialog::slotRegexCheckBoxToggled(
bool checked)
290 m_regExpItem->setEnabled(checked);
291 m_backRef->setEnabled(checked);
292 m_backRefItem->setEnabled(checked && m_backRef->isChecked());
295 void KFindDialog::slotPlaceholdersCheckBoxToggled(
bool checked)
297 m_backRefItem->setEnabled(checked && m_regExp->isChecked());
300 void KFindDialog::showEvent( TQShowEvent *e )
302 if ( !d->m_initialShowDone )
304 d->m_initialShowDone =
true;
306 if (!d->findStrings.isEmpty())
308 d->findStrings = TQStringList();
309 if (!d->pattern.isEmpty()) {
310 m_find->lineEdit()->setText( d->pattern );
311 m_find->lineEdit()->selectAll();
312 d->pattern = TQString::null;
315 KDialogBase::showEvent(e);
322 if (m_caseSensitive->isChecked())
324 if (m_wholeWordsOnly->isChecked())
326 if (m_fromCursor->isChecked())
328 if (m_findBackwards->isChecked())
330 if (m_selectedText->isChecked())
332 if (m_regExp->isChecked())
339 return m_find->currentText();
344 m_find->lineEdit()->setText(
pattern );
345 m_find->lineEdit()->selectAll();
352 if (strings.count() > 0)
355 m_find->lineEdit()->setText( strings.first() );
356 m_find->lineEdit()->selectAll();
366 m_selectedText->setEnabled( hasSelection );
369 m_selectedText->setChecked(
false );
370 slotSelectedTextToggled( hasSelection );
374 void KFindDialog::slotSelectedTextToggled(
bool selec)
377 m_fromCursor->setEnabled( !selec && (d->m_enabled &
FromCursor) );
379 m_fromCursor->setChecked(
false );
386 m_fromCursor->setEnabled( hasCursor );
395 m_findBackwards->setEnabled( supports );
404 m_caseSensitive->setEnabled( supports );
413 m_wholeWordsOnly->setEnabled( supports );
422 m_regExp->setEnabled( supports );
438 void KFindDialog::showPatterns()
440 if ( !d->m_regexpDialogQueryDone )
442 d->m_regexpDialog = KParts::ComponentFactory::createInstanceFromQuery<TQDialog>(
"KRegExpEditor/KRegExpEditor", TQString(), TQT_TQOBJECT(
this) );
443 d->m_regexpDialogQueryDone =
true;
446 if ( d->m_regexpDialog )
448 KRegExpEditorInterface *iface = tqt_dynamic_cast<KRegExpEditorInterface *>( d->m_regexpDialog );
452 if ( d->m_regexpDialog->exec() == TQDialog::Accepted )
461 int cursorAdjustment;
463 static const term items[] =
468 {
I18N_NOOP(
"Set of Characters"),
"[]", -1 },
469 {
I18N_NOOP(
"Repeats, Zero or More Times"),
"*", 0 },
470 {
I18N_NOOP(
"Repeats, One or More Times"),
"+", 0 },
475 {
I18N_NOOP(
"Carriage Return"),
"\\r", 0 },
484 m_patterns =
new TQPopupMenu(
this);
485 for (i = 0; (unsigned)i <
sizeof(items) /
sizeof(items[0]); i++)
487 m_patterns->insertItem(i18n(items[i].description), i, i);
492 i = m_patterns->exec(m_regExpItem->mapToGlobal(m_regExpItem->rect().bottomLeft()));
495 TQLineEdit *editor = m_find->lineEdit();
497 editor->insert(items[i].regExp);
498 editor->setCursorPosition(editor->cursorPosition() + items[i].cursorAdjustment);
505 void KFindDialog::showPlaceholders()
510 m_placeholders =
new TQPopupMenu(
this);
511 connect( m_placeholders, TQT_SIGNAL(aboutToShow()),
this, TQT_SLOT(slotPlaceholdersAboutToShow()) );
515 int i = m_placeholders->exec(m_backRefItem->mapToGlobal(m_backRefItem->rect().bottomLeft()));
518 TQLineEdit *editor = m_replace->lineEdit();
519 editor->insert( TQString(
"\\%1").arg( i ) );
523 void KFindDialog::slotPlaceholdersAboutToShow()
525 m_placeholders->clear();
526 m_placeholders->insertItem( i18n(
"Complete Match"), 0 );
529 uint n = r.numCaptures();
530 for ( uint i=0; i < n; i++ )
531 m_placeholders->insertItem( i18n(
"Captured Text (%1)").arg( i+1 ), i+1 );
534 void KFindDialog::slotOk()
543 if (m_regExp->isChecked())
548 if (!regExp.isValid())
556 if ( testWFlags( WShowModal ) )
559 #include "kfinddialog.moc"