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 <kmessagebox.h>
35 #include <tqwhatsthis.h>
37 #include <kregexpeditorinterface.h>
38 #include <kparts/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);
62 setButtonCancel( KStdGuiItem::close() );
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);
73 setButtonCancel( KStdGuiItem::close() );
77 KDialogBase(parent, name, true, i18n(
"Replace Text"), Ok | Cancel, Ok),
79 m_replaceExtension (0)
81 d =
new KFindDialogPrivate;
82 setButtonCancel( KStdGuiItem::close() );
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);
116 topLayout->setSpacing( KDialog::spacingHint() );
117 topLayout->setMargin( 0 );
119 m_findGrp =
new TQGroupBox(0, Qt::Vertical, i18n(
"Find"), page);
120 m_findGrp->layout()->setSpacing( KDialog::spacingHint() );
122 m_findLayout =
new TQGridLayout(m_findGrp->layout());
123 m_findLayout->setSpacing( KDialog::spacingHint() );
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);
141 m_replaceGrp->layout()->setSpacing( KDialog::spacingHint() );
143 m_replaceLayout =
new TQGridLayout(m_replaceGrp->layout());
144 m_replaceLayout->setSpacing( KDialog::spacingHint() );
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_backRefItem =
new TQPushButton(i18n(
"Insert Place&holder"), m_replaceGrp);
153 m_backRefItem->setEnabled(
false);
155 m_replaceLayout->addWidget(m_replaceLabel, 0, 0);
156 m_replaceLayout->addMultiCellWidget(m_replace, 1, 1, 0, 1);
157 m_replaceLayout->addWidget(m_backRef, 2, 0);
158 m_replaceLayout->addWidget(m_backRefItem, 2, 1);
159 topLayout->addWidget(m_replaceGrp);
161 m_optionGrp =
new TQGroupBox(0, Qt::Vertical, i18n(
"Options"), page);
162 m_optionGrp->layout()->setSpacing(KDialog::spacingHint());
164 optionsLayout =
new TQGridLayout(m_optionGrp->layout());
165 optionsLayout->setSpacing( KDialog::spacingHint() );
168 m_caseSensitive =
new TQCheckBox(i18n(
"C&ase sensitive"), m_optionGrp);
169 m_wholeWordsOnly =
new TQCheckBox(i18n(
"&Whole words only"), m_optionGrp);
170 m_fromCursor =
new TQCheckBox(i18n(
"From c&ursor"), m_optionGrp);
171 m_findBackwards =
new TQCheckBox(i18n(
"Find &backwards"), m_optionGrp);
172 m_selectedText =
new TQCheckBox(i18n(
"&Selected text"), m_optionGrp);
176 m_selectedText->setChecked( hasSelection );
177 slotSelectedTextToggled( hasSelection );
179 m_promptOnReplace =
new TQCheckBox(i18n(
"&Prompt on replace"), m_optionGrp);
180 m_promptOnReplace->setChecked(
true );
182 optionsLayout->addWidget(m_caseSensitive, 0, 0);
183 optionsLayout->addWidget(m_wholeWordsOnly, 1, 0);
184 optionsLayout->addWidget(m_fromCursor, 2, 0);
185 optionsLayout->addWidget(m_findBackwards, 0, 1);
186 optionsLayout->addWidget(m_selectedText, 1, 1);
187 optionsLayout->addWidget(m_promptOnReplace, 2, 1);
188 topLayout->addWidget(m_optionGrp);
195 connect(m_selectedText, TQT_SIGNAL(toggled(
bool)),
this, TQT_SLOT(slotSelectedTextToggled(
bool)));
196 connect(m_regExp, TQT_SIGNAL(toggled(
bool)), m_regExpItem, TQT_SLOT(setEnabled(
bool)));
197 connect(m_backRef, TQT_SIGNAL(toggled(
bool)), m_backRefItem, TQT_SLOT(setEnabled(
bool)));
198 connect(m_regExpItem, TQT_SIGNAL(clicked()),
this, TQT_SLOT(showPatterns()));
199 connect(m_backRefItem, TQT_SIGNAL(clicked()),
this, TQT_SLOT(showPlaceholders()));
201 connect(m_find, TQT_SIGNAL(textChanged (
const TQString & )),
this, TQT_SLOT(textSearchChanged(
const TQString & )));
204 setTabOrder(m_find, m_regExp);
205 setTabOrder(m_regExp, m_regExpItem);
206 setTabOrder(m_regExpItem, m_replace);
207 setTabOrder(m_replace, m_backRef);
208 setTabOrder(m_backRef, m_backRefItem);
209 setTabOrder(m_backRefItem, m_caseSensitive);
210 setTabOrder(m_caseSensitive, m_wholeWordsOnly);
211 setTabOrder(m_wholeWordsOnly, m_fromCursor);
212 setTabOrder(m_fromCursor, m_findBackwards);
213 setTabOrder(m_findBackwards, m_selectedText);
214 setTabOrder(m_selectedText, m_promptOnReplace);
217 m_findLabel->setBuddy(m_find);
218 m_replaceLabel->setBuddy(m_replace);
222 m_promptOnReplace->hide();
223 m_replaceGrp->hide();
226 d->findStrings = findStrings;
228 enableButtonOK( !
pattern().isEmpty() );
231 setButtonOK(
KGuiItem( i18n(
"&Replace"), TQString::null,
232 i18n(
"Start replace"),
233 i18n(
"<qt>If you press the <b>Replace</b> button, the text you entered "
234 "above is searched for within the document and any occurrence is "
235 "replaced with the replacement text.</qt>")));
239 setButtonOK(
KGuiItem( i18n(
"&Find"),
"find",
240 i18n(
"Start searching"),
241 i18n(
"<qt>If you press the <b>Find</b> button, the text you entered "
242 "above is searched for within the document.</qt>")));
246 TQWhatsThis::add ( m_find, i18n(
247 "Enter a pattern to search for, or select a previous pattern from "
249 TQWhatsThis::add ( m_regExp, i18n(
250 "If enabled, search for a regular expression.") );
251 TQWhatsThis::add ( m_regExpItem, i18n(
252 "Click here to edit your regular expression using a graphical editor.") );
253 TQWhatsThis::add ( m_replace, i18n(
254 "Enter a replacement string, or select a previous one from the list.") );
255 TQWhatsThis::add( m_backRef, i18n(
256 "<qt>If enabled, any occurrence of <code><b>\\N</b></code>, where "
257 "<code><b>N</b></code> is a integer number, will be replaced with "
258 "the corresponding capture (\"parenthesized substring\") from the "
259 "pattern.<p>To include (a literal <code><b>\\N</b></code> in your "
260 "replacement, put an extra backslash in front of it, like "
261 "<code><b>\\\\N</b></code>.</qt>") );
262 TQWhatsThis::add ( m_backRefItem, i18n(
263 "Click for a menu of available captures.") );
264 TQWhatsThis::add ( m_wholeWordsOnly, i18n(
265 "Require word boundaries in both ends of a match to succeed.") );
266 TQWhatsThis::add ( m_fromCursor, i18n(
267 "Start searching at the current cursor location rather than at the top.") );
268 TQWhatsThis::add ( m_selectedText, i18n(
269 "Only search within the current selection.") );
270 TQWhatsThis::add ( m_caseSensitive, i18n(
271 "Perform a case sensitive search: entering the pattern "
272 "'Joe' will not match 'joe' or 'JOE', only 'Joe'.") );
273 TQWhatsThis::add ( m_findBackwards, i18n(
274 "Search backwards.") );
275 TQWhatsThis::add ( m_promptOnReplace, i18n(
276 "Ask before replacing each match found.") );
279 void KFindDialog::textSearchChanged(
const TQString & text)
281 enableButtonOK( !text.isEmpty() );
284 void KFindDialog::showEvent( TQShowEvent *e )
286 if ( !d->m_initialShowDone )
288 d->m_initialShowDone =
true;
290 if (!d->findStrings.isEmpty())
292 d->findStrings = TQStringList();
293 if (!d->pattern.isEmpty()) {
294 m_find->lineEdit()->setText( d->pattern );
295 m_find->lineEdit()->selectAll();
296 d->pattern = TQString::null;
299 KDialogBase::showEvent(e);
306 if (m_caseSensitive->isChecked())
308 if (m_wholeWordsOnly->isChecked())
310 if (m_fromCursor->isChecked())
312 if (m_findBackwards->isChecked())
314 if (m_selectedText->isChecked())
316 if (m_regExp->isChecked())
323 return m_find->currentText();
328 m_find->lineEdit()->setText( pattern );
329 m_find->lineEdit()->selectAll();
336 if (strings.count() > 0)
339 m_find->lineEdit()->setText( strings.first() );
340 m_find->lineEdit()->selectAll();
350 m_selectedText->setEnabled( hasSelection );
353 m_selectedText->setChecked(
false );
354 slotSelectedTextToggled( hasSelection );
358 void KFindDialog::slotSelectedTextToggled(
bool selec)
361 m_fromCursor->setEnabled( !selec && (d->m_enabled &
FromCursor) );
363 m_fromCursor->setChecked(
false );
370 m_fromCursor->setEnabled( hasCursor );
379 m_findBackwards->setEnabled( supports );
388 m_caseSensitive->setEnabled( supports );
397 m_wholeWordsOnly->setEnabled( supports );
406 m_regExp->setEnabled( supports );
422 void KFindDialog::showPatterns()
424 if ( !d->m_regexpDialogQueryDone )
426 d->m_regexpDialog = KParts::ComponentFactory::createInstanceFromQuery<TQDialog>(
"KRegExpEditor/KRegExpEditor", TQString(), TQT_TQOBJECT(
this) );
427 d->m_regexpDialogQueryDone =
true;
430 if ( d->m_regexpDialog )
432 KRegExpEditorInterface *iface = tqt_dynamic_cast<KRegExpEditorInterface *>( d->m_regexpDialog );
436 if ( d->m_regexpDialog->exec() == TQDialog::Accepted )
445 int cursorAdjustment;
447 static const term items[] =
452 {
I18N_NOOP(
"Set of Characters"),
"[]", -1 },
453 {
I18N_NOOP(
"Repeats, Zero or More Times"),
"*", 0 },
454 {
I18N_NOOP(
"Repeats, One or More Times"),
"+", 0 },
459 {
I18N_NOOP(
"Carriage Return"),
"\\r", 0 },
468 m_patterns =
new TQPopupMenu(
this);
469 for (i = 0; (unsigned)i <
sizeof(items) /
sizeof(items[0]); i++)
471 m_patterns->insertItem(i18n(items[i].description), i, i);
476 i = m_patterns->exec(m_regExpItem->mapToGlobal(m_regExpItem->rect().bottomLeft()));
479 TQLineEdit *editor = m_find->lineEdit();
481 editor->insert(items[i].regExp);
482 editor->setCursorPosition(editor->cursorPosition() + items[i].cursorAdjustment);
489 void KFindDialog::showPlaceholders()
494 m_placeholders =
new TQPopupMenu(
this);
495 connect( m_placeholders, TQT_SIGNAL(aboutToShow()),
this, TQT_SLOT(slotPlaceholdersAboutToShow()) );
499 int i = m_placeholders->exec(m_backRefItem->mapToGlobal(m_backRefItem->rect().bottomLeft()));
502 TQLineEdit *editor = m_replace->lineEdit();
503 editor->insert( TQString(
"\\%1").arg( i ) );
507 void KFindDialog::slotPlaceholdersAboutToShow()
509 m_placeholders->clear();
510 m_placeholders->insertItem( i18n(
"Complete Match"), 0 );
513 uint n = r.numCaptures();
514 for ( uint i=0; i < n; i++ )
515 m_placeholders->insertItem( i18n(
"Captured Text (%1)").arg( i+1 ), i+1 );
518 void KFindDialog::slotOk()
527 if (m_regExp->isChecked())
532 if (!regExp.isValid())
540 if ( testWFlags( WShowModal ) )
544 #include "kfinddialog.moc"