00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "kfinddialog.h"
00022
#include <qcheckbox.h>
00023
#include <qcursor.h>
00024
#include <qgroupbox.h>
00025
#include <qlabel.h>
00026
#include <qlayout.h>
00027
#include <qpopupmenu.h>
00028
#include <qpushbutton.h>
00029
#include <qregexp.h>
00030
#include <kcombobox.h>
00031
#include <kdebug.h>
00032
#include <klocale.h>
00033
#include <kmessagebox.h>
00034
#include <assert.h>
00035
00036
#include <kregexpeditorinterface.h>
00037
#include <kparts/componentfactory.h>
00038
00039
class KFindDialog::KFindDialogPrivate
00040 {
00041
public:
00042 KFindDialogPrivate() : m_regexpDialog(0),
00043 m_regexpDialogQueryDone(false), m_hasCursor(true), m_hasSelection(false),
00044 m_initialShowDone(false) {}
00045
QDialog* m_regexpDialog;
00046
bool m_regexpDialogQueryDone;
00047
bool m_hasCursor;
00048
bool m_hasSelection;
00049
bool m_initialShowDone;
00050
QStringList findStrings;
00051
QString pattern;
00052 };
00053
00054 KFindDialog::KFindDialog(
QWidget *parent,
const char *name,
long options,
const QStringList &findStrings,
bool hasSelection) :
00055
KDialogBase(parent, name, true, i18n("Find Text"), Ok | Cancel, Ok),
00056 m_findExtension (0),
00057 m_replaceExtension (0)
00058 {
00059 d =
new KFindDialogPrivate;
00060 init(
false, findStrings, hasSelection);
00061
setOptions(options);
00062 setButtonCancel( KStdGuiItem::close() );
00063 }
00064
00065 KFindDialog::KFindDialog(
bool modal,
QWidget *parent,
const char *name,
long options,
const QStringList &findStrings,
bool hasSelection) :
00066
KDialogBase(parent, name, modal, i18n("Find Text"), Ok | Cancel, Ok),
00067 m_findExtension (0),
00068 m_replaceExtension (0)
00069 {
00070 d =
new KFindDialogPrivate;
00071 init(
false, findStrings, hasSelection);
00072
setOptions(options);
00073 setButtonCancel( KStdGuiItem::close() );
00074 }
00075
00076 KFindDialog::KFindDialog(
QWidget *parent,
const char *name,
bool ) :
00077
KDialogBase(parent, name, true, i18n("Replace Text"), Ok | Cancel, Ok),
00078 m_findExtension (0),
00079 m_replaceExtension (0)
00080 {
00081 d =
new KFindDialogPrivate;
00082 setButtonCancel( KStdGuiItem::close() );
00083 }
00084
00085 KFindDialog::~KFindDialog()
00086 {
00087
delete d;
00088 }
00089
00090 QWidget *
KFindDialog::findExtension()
00091 {
00092
if (!m_findExtension)
00093 {
00094 m_findExtension =
new QWidget(m_findGrp);
00095 m_findLayout->addMultiCellWidget(m_findExtension, 3, 3, 0, 1);
00096 }
00097
00098
return m_findExtension;
00099 }
00100
00101 QStringList KFindDialog::findHistory()
const
00102
{
00103
return m_find->
historyItems();
00104 }
00105
00106
void KFindDialog::init(
bool forReplace,
const QStringList &findStrings,
bool hasSelection)
00107 {
00108
QVBoxLayout *topLayout;
00109
QGridLayout *optionsLayout;
00110
00111
00112
QWidget *page =
new QWidget(
this);
00113 setMainWidget(page);
00114
00115 topLayout =
new QVBoxLayout(page);
00116 topLayout->setSpacing( KDialog::spacingHint() );
00117 topLayout->setMargin( 0 );
00118
00119 m_findGrp =
new QGroupBox(0, Qt::Vertical, i18n(
"Find"), page);
00120 m_findGrp->layout()->setSpacing( KDialog::spacingHint() );
00121
00122 m_findLayout =
new QGridLayout(m_findGrp->layout());
00123 m_findLayout->setSpacing( KDialog::spacingHint() );
00124
00125
00126 m_findLabel =
new QLabel(i18n(
"&Text to find:"), m_findGrp);
00127 m_find =
new KHistoryCombo(
true, m_findGrp);
00128 m_find->setMaxCount(10);
00129 m_find->setDuplicatesEnabled(
false);
00130 m_regExp =
new QCheckBox(i18n(
"Regular e&xpression"), m_findGrp);
00131 m_regExpItem =
new QPushButton(i18n(
"&Edit..."), m_findGrp);
00132 m_regExpItem->setEnabled(
false);
00133
00134 m_findLayout->addWidget(m_findLabel, 0, 0);
00135 m_findLayout->addMultiCellWidget(m_find, 1, 1, 0, 1);
00136 m_findLayout->addWidget(m_regExp, 2, 0);
00137 m_findLayout->addWidget(m_regExpItem, 2, 1);
00138 topLayout->addWidget(m_findGrp);
00139
00140 m_replaceGrp =
new QGroupBox(0, Qt::Vertical, i18n(
"Replace With"), page);
00141 m_replaceGrp->layout()->setSpacing( KDialog::spacingHint() );
00142
00143 m_replaceLayout =
new QGridLayout(m_replaceGrp->layout());
00144 m_replaceLayout->setSpacing( KDialog::spacingHint() );
00145
00146
00147 m_replaceLabel =
new QLabel(i18n(
"Replace&ment text:"), m_replaceGrp);
00148 m_replace =
new KHistoryCombo(
true, m_replaceGrp);
00149 m_replace->setMaxCount(10);
00150 m_replace->setDuplicatesEnabled(
false);
00151 m_backRef =
new QCheckBox(i18n(
"Use p&laceholders"), m_replaceGrp);
00152 m_backRefItem =
new QPushButton(i18n(
"Insert Place&holder"), m_replaceGrp);
00153 m_backRefItem->setEnabled(
false);
00154
00155 m_replaceLayout->addWidget(m_replaceLabel, 0, 0);
00156 m_replaceLayout->addMultiCellWidget(m_replace, 1, 1, 0, 1);
00157 m_replaceLayout->addWidget(m_backRef, 2, 0);
00158 m_replaceLayout->addWidget(m_backRefItem, 2, 1);
00159 topLayout->addWidget(m_replaceGrp);
00160
00161 m_optionGrp =
new QGroupBox(0, Qt::Vertical, i18n(
"Options"), page);
00162 m_optionGrp->layout()->setSpacing(KDialog::spacingHint());
00163
00164 optionsLayout =
new QGridLayout(m_optionGrp->layout());
00165 optionsLayout->setSpacing( KDialog::spacingHint() );
00166
00167
00168 m_caseSensitive =
new QCheckBox(i18n(
"C&ase sensitive"), m_optionGrp);
00169 m_wholeWordsOnly =
new QCheckBox(i18n(
"&Whole words only"), m_optionGrp);
00170 m_fromCursor =
new QCheckBox(i18n(
"From c&ursor"), m_optionGrp);
00171 m_findBackwards =
new QCheckBox(i18n(
"Find &backwards"), m_optionGrp);
00172 m_selectedText =
new QCheckBox(i18n(
"&Selected text"), m_optionGrp);
00173 setHasSelection( hasSelection );
00174
00175
00176 m_selectedText->setChecked( hasSelection );
00177 slotSelectedTextToggled( hasSelection );
00178
00179 m_promptOnReplace =
new QCheckBox(i18n(
"&Prompt on replace"), m_optionGrp);
00180 m_promptOnReplace->setChecked(
true );
00181
00182 optionsLayout->addWidget(m_caseSensitive, 0, 0);
00183 optionsLayout->addWidget(m_wholeWordsOnly, 1, 0);
00184 optionsLayout->addWidget(m_fromCursor, 2, 0);
00185 optionsLayout->addWidget(m_findBackwards, 0, 1);
00186 optionsLayout->addWidget(m_selectedText, 1, 1);
00187 optionsLayout->addWidget(m_promptOnReplace, 2, 1);
00188 topLayout->addWidget(m_optionGrp);
00189
00190
00191 m_patterns = 0L;
00192 m_placeholders = 0L;
00193
00194
00195 connect(m_selectedText, SIGNAL(toggled(
bool)),
this, SLOT(slotSelectedTextToggled(
bool)));
00196 connect(m_regExp, SIGNAL(toggled(
bool)), m_regExpItem, SLOT(setEnabled(
bool)));
00197 connect(m_backRef, SIGNAL(toggled(
bool)), m_backRefItem, SLOT(setEnabled(
bool)));
00198 connect(m_regExpItem, SIGNAL(clicked()),
this, SLOT(showPatterns()));
00199 connect(m_backRefItem, SIGNAL(clicked()),
this, SLOT(showPlaceholders()));
00200
00201 connect(m_find, SIGNAL(textChanged (
const QString & )),
this, SLOT(textSearchChanged(
const QString & )));
00202
00203
00204 setTabOrder(m_find, m_regExp);
00205 setTabOrder(m_regExp, m_regExpItem);
00206 setTabOrder(m_regExpItem, m_replace);
00207 setTabOrder(m_replace, m_backRef);
00208 setTabOrder(m_backRef, m_backRefItem);
00209 setTabOrder(m_backRefItem, m_caseSensitive);
00210 setTabOrder(m_caseSensitive, m_wholeWordsOnly);
00211 setTabOrder(m_wholeWordsOnly, m_fromCursor);
00212 setTabOrder(m_fromCursor, m_findBackwards);
00213 setTabOrder(m_findBackwards, m_selectedText);
00214 setTabOrder(m_selectedText, m_promptOnReplace);
00215
00216
00217 m_findLabel->setBuddy(m_find);
00218 m_replaceLabel->setBuddy(m_replace);
00219
00220
if (!forReplace)
00221 {
00222 m_promptOnReplace->hide();
00223 m_replaceGrp->hide();
00224 }
00225
00226 d->findStrings = findStrings;
00227 m_find->setFocus();
00228
enableButtonOK( !
pattern().isEmpty() );
00229
if (forReplace)
00230 {
00231
setButtonOKText(i18n(
"&Replace"),
00232 i18n(
"Start replace"),
00233 i18n(
"<qt>If you press the <b>Replace</b> button, the text you entered "
00234
"above is searched for within the document and any occurrence is "
00235
"replaced with the replacement text.</qt>"));
00236 }
00237
else
00238 {
00239
setButtonOK( KGuiItem(i18n(
"&Find"),
"find",
00240 i18n(
"Start searching"),
00241 i18n(
"<qt>If you press the <b>Find</b> button, the text you entered "
00242
"above is searched for within the document.</qt>")) );
00243 }
00244 }
00245
00246
void KFindDialog::textSearchChanged(
const QString & text)
00247 {
00248
enableButtonOK( !text.isEmpty() );
00249 }
00250
00251
void KFindDialog::showEvent(
QShowEvent *e )
00252 {
00253
if ( !d->m_initialShowDone )
00254 {
00255 d->m_initialShowDone =
true;
00256
kdDebug() <<
"showEvent\n";
00257
if (!d->findStrings.isEmpty())
00258
setFindHistory(d->findStrings);
00259 d->findStrings =
QStringList();
00260
if (!d->pattern.isEmpty()) {
00261 m_find->lineEdit()->setText( d->pattern );
00262 m_find->lineEdit()->selectAll();
00263 d->pattern = QString::null;
00264 }
00265 }
00266 KDialogBase::showEvent(e);
00267 }
00268
00269 long KFindDialog::options()
const
00270
{
00271
long options = 0;
00272
00273
if (m_caseSensitive->isChecked())
00274 options |= CaseSensitive;
00275
if (m_wholeWordsOnly->isChecked())
00276 options |= WholeWordsOnly;
00277
if (m_fromCursor->isChecked())
00278 options |= FromCursor;
00279
if (m_findBackwards->isChecked())
00280 options |= FindBackwards;
00281
if (m_selectedText->isChecked())
00282 options |= SelectedText;
00283
if (m_regExp->isChecked())
00284 options |= RegularExpression;
00285
return options;
00286 }
00287
00288 QString
KFindDialog::pattern()
const
00289
{
00290
return m_find->currentText();
00291 }
00292
00293 void KFindDialog::setPattern (
const QString &pattern)
00294 {
00295 m_find->lineEdit()->setText( pattern );
00296 m_find->lineEdit()->selectAll();
00297 d->pattern = pattern;
00298
kdDebug() <<
"setPattern " << pattern<<
endl;
00299 }
00300
00301 void KFindDialog::setFindHistory(
const QStringList &strings)
00302 {
00303
if (strings.count() > 0)
00304 {
00305 m_find->
setHistoryItems(strings,
true);
00306 m_find->lineEdit()->setText( strings.first() );
00307 m_find->lineEdit()->selectAll();
00308 }
00309
else
00310 m_find->
clearHistory();
00311 }
00312
00313 void KFindDialog::setHasSelection(
bool hasSelection)
00314 {
00315 d->m_hasSelection = hasSelection;
00316 m_selectedText->setEnabled( hasSelection );
00317
if ( !hasSelection )
00318 {
00319 m_selectedText->setChecked(
false );
00320 slotSelectedTextToggled( hasSelection );
00321 }
00322 }
00323
00324
void KFindDialog::slotSelectedTextToggled(
bool selec)
00325 {
00326
00327 m_fromCursor->setEnabled( !selec && d->m_hasCursor );
00328
if ( selec )
00329 m_fromCursor->setChecked(
false );
00330 }
00331
00332 void KFindDialog::setHasCursor(
bool hasCursor)
00333 {
00334 d->m_hasCursor = hasCursor;
00335 m_fromCursor->setEnabled( hasCursor );
00336 m_fromCursor->setChecked( hasCursor && (
options() & FromCursor) );
00337 }
00338
00339 void KFindDialog::setOptions(
long options)
00340 {
00341 m_caseSensitive->setChecked(options & CaseSensitive);
00342 m_wholeWordsOnly->setChecked(options & WholeWordsOnly);
00343 m_fromCursor->setChecked(d->m_hasCursor && (options & FromCursor));
00344 m_findBackwards->setChecked(options & FindBackwards);
00345 m_selectedText->setChecked(d->m_hasSelection && (options & SelectedText));
00346 m_regExp->setChecked(options & RegularExpression);
00347 }
00348
00349
00350
00351
void KFindDialog::showPatterns()
00352 {
00353
if ( !d->m_regexpDialogQueryDone )
00354 {
00355 d->m_regexpDialog = KParts::ComponentFactory::createInstanceFromQuery<QDialog>(
"KRegExpEditor/KRegExpEditor", QString::null,
this );
00356 d->m_regexpDialogQueryDone =
true;
00357 }
00358
00359
if ( d->m_regexpDialog )
00360 {
00361 KRegExpEditorInterface *iface = static_cast<KRegExpEditorInterface *>( d->m_regexpDialog->qt_cast(
"KRegExpEditorInterface" ) );
00362 assert( iface );
00363
00364 iface->setRegExp(
pattern() );
00365
if ( d->m_regexpDialog->exec() == QDialog::Accepted )
00366
setPattern( iface->regExp() );
00367 }
00368
else
00369 {
00370
typedef struct
00371
{
00372
const char *
description;
00373
const char *regExp;
00374
int cursorAdjustment;
00375 } term;
00376
static const term items[] =
00377 {
00378 {
I18N_NOOP(
"Any Character"),
".", 0 },
00379 {
I18N_NOOP(
"Start of Line"),
"^", 0 },
00380 {
I18N_NOOP(
"End of Line"),
"$", 0 },
00381 {
I18N_NOOP(
"Set of Characters"),
"[]", -1 },
00382 {
I18N_NOOP(
"Repeats, Zero or More Times"),
"*", 0 },
00383 {
I18N_NOOP(
"Repeats, One or More Times"),
"+", 0 },
00384 {
I18N_NOOP(
"Optional"),
"?", 0 },
00385 {
I18N_NOOP(
"Escape"),
"\\", 0 },
00386 {
I18N_NOOP(
"TAB"),
"\\t", 0 },
00387 {
I18N_NOOP(
"Newline"),
"\\n", 0 },
00388 {
I18N_NOOP(
"Carriage Return"),
"\\r", 0 },
00389 {
I18N_NOOP(
"White Space"),
"\\s", 0 },
00390 {
I18N_NOOP(
"Digit"),
"\\d", 0 },
00391 };
00392
int i;
00393
00394
00395
if (!m_patterns)
00396 {
00397 m_patterns =
new QPopupMenu(
this);
00398
for (i = 0; (
unsigned)i <
sizeof(items) /
sizeof(items[0]); i++)
00399 {
00400 m_patterns->insertItem(i18n(items[i].description), i, i);
00401 }
00402 }
00403
00404
00405 i = m_patterns->exec(m_regExpItem->mapToGlobal(m_regExpItem->rect().bottomLeft()));
00406
if (i != -1)
00407 {
00408
QLineEdit *editor = m_find->lineEdit();
00409
00410 editor->insert(items[i].regExp);
00411 editor->setCursorPosition(editor->cursorPosition() + items[i].cursorAdjustment);
00412 }
00413 }
00414 }
00415
00416
00417
00418
void KFindDialog::showPlaceholders()
00419 {
00420
typedef struct
00421
{
00422
const char *
description;
00423
const char *backRef;
00424 } term;
00425
static const term items[] =
00426 {
00427 {
I18N_NOOP(
"Complete text found"),
"\\0" },
00428 };
00429
int i;
00430
00431
00432
if (!m_placeholders)
00433 {
00434 m_placeholders =
new QPopupMenu(
this);
00435
for (i = 0; (
unsigned)i <
sizeof(items) /
sizeof(items[0]); i++)
00436 {
00437 m_placeholders->insertItem(i18n(items[i].description), i, i);
00438 }
00439 }
00440
00441
00442 i = m_placeholders->exec(m_backRefItem->mapToGlobal(m_backRefItem->rect().bottomLeft()));
00443
if (i != -1)
00444 {
00445
QLineEdit *editor = m_replace->lineEdit();
00446
00447 editor->insert(items[i].backRef);
00448 }
00449 }
00450
00451
void KFindDialog::slotOk()
00452 {
00453
00454
if (
pattern().isEmpty())
00455 {
00456
KMessageBox::error(
this, i18n(
"You must enter some text to search for."));
00457
return;
00458 }
00459
00460
if (m_regExp->isChecked())
00461 {
00462
00463
QRegExp regExp(
pattern());
00464
00465
if (!regExp.isValid())
00466 {
00467
KMessageBox::error(
this, i18n(
"Invalid regular expression."));
00468
return;
00469 }
00470 }
00471 m_find->
addToHistory(
pattern());
00472 emit
okClicked();
00473
if ( testWFlags( WShowModal ) )
00474 accept();
00475 }
00476
00477
#include "kfinddialog.moc"