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