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, TQt::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, TQt::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, TQt::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, TQ_SIGNAL(toggled(
bool)),
this, TQ_SLOT(slotSelectedTextToggled(
bool)));
197 connect(m_regExp, TQ_SIGNAL(toggled(
bool)),
this, TQ_SLOT(slotRegexCheckBoxToggled(
bool)));
198 connect(m_backRef, TQ_SIGNAL(toggled(
bool)),
this, TQ_SLOT(slotPlaceholdersCheckBoxToggled(
bool)));
199 connect(m_regExpItem, TQ_SIGNAL(clicked()),
this, TQ_SLOT(showPatterns()));
200 connect(m_backRefItem, TQ_SIGNAL(clicked()),
this, TQ_SLOT(showPlaceholders()));
202 connect(m_find, TQ_SIGNAL(textChanged (
const TQString & )),
this, TQ_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(),
this );
443 d->m_regexpDialogQueryDone =
true;
446 if ( d->m_regexpDialog )
448 KRegExpEditorInterface *iface =
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, TQ_SIGNAL(aboutToShow()),
this, TQ_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"
void setButtonOK(const KGuiItem &item=KStdGuiItem::ok())
void setButtonCancel(const KGuiItem &item=KStdGuiItem::cancel())
void setMainWidget(TQWidget *widget)
void enableButtonOK(bool state)
void setPattern(const TQString &pattern)
Sets the pattern to find.
void setFindHistory(const TQStringList &history)
Provide the list of strings to be displayed as the history of find strings.
virtual ~KFindDialog()
Destructor.
void setSupportsBackwardsFind(bool supports)
Enable/disable the 'Find backwards' option, depending on whether the application supports it.
void setHasCursor(bool hasCursor)
Hide/show the 'from cursor' option, depending on whether the application implements a cursor.
KFindDialog(TQWidget *parent=0, const char *name=0, long options=0, const TQStringList &findStrings=TQStringList(), bool hasSelection=false)
Construct a modal find dialog.
void setSupportsWholeWordsFind(bool supports)
Enable/disable the 'Whole words only' option, depending on whether the application supports it.
void setSupportsCaseSensitiveFind(bool supports)
Enable/disable the 'Case sensitive' option, depending on whether the application supports it.
void setSupportsRegularExpressionFind(bool supports)
Enable/disable the 'Regular expression' option, depending on whether the application supports it.
long options() const
Returns the state of the options.
void setHasSelection(bool hasSelection)
Enable/disable the 'search in selection' option, depending on whether there actually is a selection.
TQStringList findHistory() const
Returns the list of history items.
TQWidget * findExtension()
Returns an empty widget which the user may fill with additional UI elements as required.
TQString pattern() const
Returns the pattern to find.
void setOptions(long options)
Set the options which are checked.
@ FromCursor
Start from current cursor position.
@ WholeWordsOnly
Match whole words only.
@ SelectedText
Only search selected area.
@ CaseSensitive
Consider case when matching.
@ RegularExpression
Interpret the pattern as a regular expression.
@ FindBackwards
Go backwards.
TQStringList historyItems() const
void setHistoryItems(TQStringList items)
void addToHistory(const TQString &item)
static void error(TQWidget *parent, const TQString &text, const TQString &caption=TQString::null, int options=Notify)
kndbgstream & endl(kndbgstream &s)
kdbgstream kdDebug(int area=0)
TQString description(StdAccel id)