| # kutils Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# kfinddialog.cpp

    00001 /*
    00002     Copyright (C) 2001, S.R.Haque <srhaque@iee.org>.
    00003     Copyright (C) 2002, David Faure <david@mandrakesoft.com>
    00004     This file is part of the KDE project
    00005
    00006     This library is free software; you can redistribute it and/or
    00007     modify it under the terms of the GNU Library General Public
    00008     License version 2, as published by the Free Software Foundation.
    00009
    00010     This library is distributed in the hope that it will be useful,
    00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013     Library General Public License for more details.
    00014
    00015     You should have received a copy of the GNU Library General Public License
    00016     along with this library; see the file COPYING.LIB.  If not, write to
    00017     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00018     Boston, MA 02111-1307, USA.
    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     QDialog* m_regexpDialog;
    00045     bool m_regexpDialogQueryDone;
    00046     bool m_hasCursor;
    00047     bool m_hasSelection;
    00048     QStringList findStrings;
    00049     QString pattern;
    00050 };
    00051
    00052 KFindDialog::KFindDialog(QWidget *parent, const char *name, long options, const QStringList &findStrings, bool hasSelection) :
    00053     KDialogBase(parent, name, true, i18n("Find Text"), Ok | Cancel, Ok),
    00054     m_findExtension (0),
    00055     m_replaceExtension (0)
    00056 {
    00057     d = new KFindDialogPrivate;
    00058     init(false, findStrings, hasSelection);
    00059     setOptions(options);
    00060 }
    00061
    00062 KFindDialog::KFindDialog(QWidget *parent, const char *name, bool /*forReplace*/) :
    00063     KDialogBase(parent, name, true, i18n("Replace Text"), Ok | Cancel, Ok),
    00064     m_findExtension (0),
    00065     m_replaceExtension (0)
    00066 {
    00067     d = new KFindDialogPrivate;
    00068 }
    00069
    00070 KFindDialog::~KFindDialog()
    00071 {
    00072     delete d;
    00073 }
    00074
    00075 QWidget *KFindDialog::findExtension()
    00076 {
    00077     if (!m_findExtension)
    00078     {
    00079       m_findExtension = new QWidget(m_findGrp);
    00080       m_findLayout->addMultiCellWidget(m_findExtension, 3, 3, 0, 1);
    00081     }
    00082
    00083     return m_findExtension;
    00084 }
    00085
    00086 QStringList KFindDialog::findHistory() const
    00087 {
    00088     return m_find->historyItems();
    00089 }
    00090
    00091 void KFindDialog::init(bool forReplace, const QStringList &findStrings, bool hasSelection)
    00092 {
    00093     QVBoxLayout *topLayout;
    00094     QGridLayout *optionsLayout;
    00095
    00096     // Create common parts of dialog.
    00097     QWidget *page = new QWidget(this);
    00098     setMainWidget(page);
    00099
    00100     topLayout = new QVBoxLayout(page);
    00101     topLayout->setSpacing( KDialog::spacingHint() );
    00102     topLayout->setMargin( KDialog::marginHint() );
    00103
    00104     m_findGrp = new QGroupBox(0, Qt::Vertical, i18n("Find"), page);
    00105     m_findGrp->layout()->setSpacing( KDialog::spacingHint() );
    00106    // m_findGrp->layout()->setMargin( KDialog::marginHint() );
    00107     m_findLayout = new QGridLayout(m_findGrp->layout());
    00108     m_findLayout->setSpacing( KDialog::spacingHint() );
    00109    // m_findLayout->setMargin( KDialog::marginHint() );
    00110
    00111     m_findLabel = new QLabel(i18n("&Text to find:"), m_findGrp);
    00112     m_find = new KHistoryCombo(true, m_findGrp);
    00113     m_find->setMaxCount(10);
    00114     m_find->setDuplicatesEnabled(false);
    00115     m_regExp = new QCheckBox(i18n("&Regular expression"), m_findGrp);
    00116     m_regExpItem = new QPushButton(i18n("&Edit..."), m_findGrp);
    00117     m_regExpItem->setEnabled(false);
    00118
    00119     m_findLayout->addWidget(m_findLabel, 0, 0);
    00120     m_findLayout->addMultiCellWidget(m_find, 1, 1, 0, 1);
    00121     m_findLayout->addWidget(m_regExp, 2, 0);
    00122     m_findLayout->addWidget(m_regExpItem, 2, 1);
    00123     topLayout->addWidget(m_findGrp);
    00124
    00125     m_replaceGrp = new QGroupBox(0, Qt::Vertical, i18n("Replace With"), page);
    00126     m_replaceGrp->layout()->setSpacing( KDialog::spacingHint() );
    00127   //  m_replaceGrp->layout()->setMargin( KDialog::marginHint() );
    00128     m_replaceLayout = new QGridLayout(m_replaceGrp->layout());
    00129     m_replaceLayout->setSpacing( KDialog::spacingHint() );
    00130 //    m_replaceLayout->setMargin( KDialog::marginHint() );
    00131
    00132     m_replaceLabel = new QLabel(i18n("&Replacement text:"), m_replaceGrp);
    00133     m_replace = new KHistoryCombo(true, m_replaceGrp);
    00134     m_replace->setMaxCount(10);
    00135     m_replace->setDuplicatesEnabled(false);
    00136     m_backRef = new QCheckBox(i18n("Us&e placeholders"), m_replaceGrp);
    00137     m_backRefItem = new QPushButton(i18n("Insert Place&holder"), m_replaceGrp);
    00138     m_backRefItem->setEnabled(false);
    00139
    00140     m_replaceLayout->addWidget(m_replaceLabel, 0, 0);
    00141     m_replaceLayout->addMultiCellWidget(m_replace, 1, 1, 0, 1);
    00142     m_replaceLayout->addWidget(m_backRef, 2, 0);
    00143     m_replaceLayout->addWidget(m_backRefItem, 2, 1);
    00144     topLayout->addWidget(m_replaceGrp);
    00145
    00146     m_optionGrp = new QGroupBox(0, Qt::Vertical, i18n("Options"), page);
    00147     m_optionGrp->layout()->setSpacing(KDialog::spacingHint());
    00148   //  m_optionGrp->layout()->setMargin(KDialog::marginHint());
    00149     optionsLayout = new QGridLayout(m_optionGrp->layout());
    00150     optionsLayout->setSpacing( KDialog::spacingHint() );
    00151    // optionsLayout->setMargin( KDialog::marginHint() );
    00152
    00153     m_caseSensitive = new QCheckBox(i18n("C&ase sensitive"), m_optionGrp);
    00154     m_wholeWordsOnly = new QCheckBox(i18n("&Whole words only"), m_optionGrp);
    00155     m_fromCursor = new QCheckBox(i18n("&From cursor"), m_optionGrp);
    00156     m_findBackwards = new QCheckBox(i18n("Find &backwards"), m_optionGrp);
    00157     m_selectedText = new QCheckBox(i18n("&Selected text"), m_optionGrp);
    00158     setHasSelection( hasSelection );
    00159     m_promptOnReplace = new QCheckBox(i18n("&Prompt on replace"), m_optionGrp);
    00160     m_promptOnReplace->setChecked( true );
    00161
    00162     optionsLayout->addWidget(m_caseSensitive, 0, 0);
    00163     optionsLayout->addWidget(m_wholeWordsOnly, 1, 0);
    00164     optionsLayout->addWidget(m_fromCursor, 2, 0);
    00165     optionsLayout->addWidget(m_findBackwards, 0, 1);
    00166     optionsLayout->addWidget(m_selectedText, 1, 1);
    00167     optionsLayout->addWidget(m_promptOnReplace, 2, 1);
    00168     topLayout->addWidget(m_optionGrp);
    00169
    00170     // We delay creation of these until needed.
    00171     m_patterns = 0L;
    00172     m_placeholders = 0L;
    00173
    00174     // signals and slots connections
    00175     connect(m_selectedText, SIGNAL(toggled(bool)), this, SLOT(slotSelectedTextToggled(bool)));
    00176     connect(m_regExp, SIGNAL(toggled(bool)), m_regExpItem, SLOT(setEnabled(bool)));
    00177     connect(m_backRef, SIGNAL(toggled(bool)), m_backRefItem, SLOT(setEnabled(bool)));
    00178     connect(m_regExpItem, SIGNAL(pressed()), this, SLOT(showPatterns()));
    00179     connect(m_backRefItem, SIGNAL(pressed()), this, SLOT(showPlaceholders()));
    00180
    00181     connect(m_find, SIGNAL(textChanged ( const QString & )),this, SLOT(textSearchChanged( const QString & )));
    00182
    00183     // tab order
    00184     setTabOrder(m_find, m_regExp);
    00185     setTabOrder(m_regExp, m_regExpItem);
    00186     setTabOrder(m_regExpItem, m_replace);
    00187     setTabOrder(m_replace, m_backRef);
    00188     setTabOrder(m_backRef, m_backRefItem);
    00189     setTabOrder(m_backRefItem, m_caseSensitive);
    00190     setTabOrder(m_caseSensitive, m_wholeWordsOnly);
    00191     setTabOrder(m_wholeWordsOnly, m_fromCursor);
    00192     setTabOrder(m_fromCursor, m_findBackwards);
    00193     setTabOrder(m_findBackwards, m_selectedText);
    00194     setTabOrder(m_selectedText, m_promptOnReplace);
    00195
    00196     // buddies
    00197     m_findLabel->setBuddy(m_find);
    00198     m_replaceLabel->setBuddy(m_replace);
    00199
    00200     if (!forReplace)
    00201     {
    00202         m_promptOnReplace->hide();
    00203         m_replaceGrp->hide();
    00204     }
    00205
    00206     d->findStrings = findStrings;
    00207     m_find->setFocus();
    00208     enableButtonOK( !pattern().isEmpty() );
    00209 }
    00210
    00211 void KFindDialog::textSearchChanged( const QString & text)
    00212 {
    00213     enableButtonOK( !text.isEmpty() );
    00214 }
    00215
    00216 void KFindDialog::showEvent( QShowEvent *e )
    00217 {
    00218     kdDebug() << "showEvent\n";
    00219     if (!d->findStrings.isEmpty())
    00220         setFindHistory(d->findStrings);
    00221     d->findStrings = QStringList();
    00222     if (!d->pattern.isEmpty()) {
    00223         m_find->lineEdit()->setText( d->pattern );
    00224         m_find->lineEdit()->selectAll();
    00225         d->pattern = QString::null;
    00226     }
    00227     KDialogBase::showEvent(e);
    00228 }
    00229
    00230 long KFindDialog::options() const
    00231 {
    00232     long options = 0;
    00233
    00234     if (m_caseSensitive->isChecked())
    00235         options |= CaseSensitive;
    00236     if (m_wholeWordsOnly->isChecked())
    00237         options |= WholeWordsOnly;
    00238     if (m_fromCursor->isChecked())
    00239         options |= FromCursor;
    00240     if (m_findBackwards->isChecked())
    00241         options |= FindBackwards;
    00242     if (m_selectedText->isChecked())
    00243         options |= SelectedText;
    00244     if (m_regExp->isChecked())
    00245         options |= RegularExpression;
    00246     return options;
    00247 }
    00248
    00249 QString KFindDialog::pattern() const
    00250 {
    00251     return m_find->currentText();
    00252 }
    00253
    00254 void KFindDialog::setPattern (const QString &pattern)
    00255 {
    00256     m_find->lineEdit()->setText( pattern );
    00257     m_find->lineEdit()->selectAll();
    00258     d->pattern = pattern;
    00259     kdDebug() << "setPattern " << pattern<<endl;
    00260 }
    00261
    00262 void KFindDialog::setFindHistory(const QStringList &strings)
    00263 {
    00264     if (strings.count() > 0)
    00265     {
    00266         m_find->setHistoryItems(strings, true);
    00267         m_find->lineEdit()->setText( strings.first() );
    00268         m_find->lineEdit()->selectAll();
    00269     }
    00270     else
    00271         m_find->clearHistory();
    00272 }
    00273
    00274 void KFindDialog::setHasSelection(bool hasSelection)
    00275 {
    00276     d->m_hasSelection = hasSelection;
    00277     m_selectedText->setEnabled( hasSelection );
    00278     // If we have a selection, we make 'find in selection' default
    00279     // and if we don't, then the option has to be unchecked, obviously.
    00280     m_selectedText->setChecked( hasSelection );
    00281     slotSelectedTextToggled( hasSelection );
    00282 }
    00283
    00284 void KFindDialog::slotSelectedTextToggled(bool selec)
    00285 {
    00286     // From cursor doesn't make sense if we have a selection
    00287     m_fromCursor->setEnabled( !selec && d->m_hasCursor );
    00288     if ( selec ) // uncheck if disabled
    00289         m_fromCursor->setChecked( false );
    00290 }
    00291
    00292 void KFindDialog::setHasCursor(bool hasCursor)
    00293 {
    00294     d->m_hasCursor = hasCursor;
    00295     m_fromCursor->setEnabled( hasCursor );
    00296     m_fromCursor->setChecked( hasCursor && (options() & FromCursor) );
    00297 }
    00298
    00299 void KFindDialog::setOptions(long options)
    00300 {
    00301     m_caseSensitive->setChecked(options & CaseSensitive);
    00302     m_wholeWordsOnly->setChecked(options & WholeWordsOnly);
    00303     m_fromCursor->setChecked(d->m_hasCursor && (options & FromCursor));
    00304     m_findBackwards->setChecked(options & FindBackwards);
    00305     m_selectedText->setChecked(d->m_hasSelection && (options & SelectedText));
    00306     m_regExp->setChecked(options & RegularExpression);
    00307 }
    00308
    00309 // Create a popup menu with a list of regular expression terms, to help the user
    00310 // compose a regular expression search pattern.
    00311 void KFindDialog::showPatterns()
    00312 {
    00313     if ( !d->m_regexpDialogQueryDone )
    00314     {
    00315         d->m_regexpDialog = KParts::ComponentFactory::createInstanceFromQuery<QDialog>( "KRegExpEditor/KRegExpEditor", QString::null, this );
    00316         d->m_regexpDialogQueryDone = true;
    00317     }
    00318
    00319     if ( d->m_regexpDialog )
    00320     {
    00321         KRegExpEditorInterface *iface = static_cast<KRegExpEditorInterface *>( d->m_regexpDialog->qt_cast( "KRegExpEditorInterface" ) );
    00322         assert( iface );
    00323
    00324         iface->setRegExp( pattern() );
    00325         if ( d->m_regexpDialog->exec() == QDialog::Accepted )
    00326             setPattern( iface->regExp() );
    00327     }
    00328     else // No complete regexp-editor available, bring up the old popupmenu
    00329     {
    00330         typedef struct
    00331         {
    00332             const char *description;
    00333             const char *regExp;
    00334             int cursorAdjustment;
    00335         } term;
    00336         static const term items[] =
    00337             {
    00338                 { I18N_NOOP("Any Character"),                 ".",        0 },
    00339                 { I18N_NOOP("Start of Line"),                 "^",        0 },
    00340                 { I18N_NOOP("End of Line"),                   "$",        0 },
    00341                 { I18N_NOOP("Set of Characters"),             "[]",       -1 },
    00342                 { I18N_NOOP("Repeats, Zero or More Times"),   "*",        0 },
    00343                 { I18N_NOOP("Repeats, One or More Times"),    "+",        0 },
    00344                 { I18N_NOOP("Optional"),                      "?",        0 },
    00345                 { I18N_NOOP("Escape"),                        "\\",       0 },
    00346                 { I18N_NOOP("TAB"),                           "\\t",      0 },
    00347                 { I18N_NOOP("Newline"),                       "\\n",      0 },
    00348                 { I18N_NOOP("Carriage Return"),               "\\r",      0 },
    00349                 { I18N_NOOP("White Space"),                   "\\s",      0 },
    00350                 { I18N_NOOP("Digit"),                         "\\d",      0 },
    00351             };
    00352         int i;
    00353
    00354         // Populate the popup menu.
    00355         if (!m_patterns)
    00356         {
    00357             m_patterns = new QPopupMenu(this);
    00358             for (i = 0; (unsigned)i < sizeof(items) / sizeof(items[0]); i++)
    00359             {
    00360                 m_patterns->insertItem(i18n(items[i].description), i, i);
    00361             }
    00362         }
    00363
    00364         // Insert the selection into the edit control.
    00365         i = m_patterns->exec(QCursor::pos());
    00366         if (i != -1)
    00367         {
    00368             QLineEdit *editor = m_find->lineEdit();
    00369
    00370             editor->insert(items[i].regExp);
    00371             editor->setCursorPosition(editor->cursorPosition() + items[i].cursorAdjustment);
    00372         }
    00373     }
    00374 }
    00375
    00376 // Create a popup menu with a list of backreference terms, to help the user
    00377 // compose a regular expression replacement pattern.
    00378 void KFindDialog::showPlaceholders()
    00379 {
    00380     typedef struct
    00381     {
    00382         const char *description;
    00383         const char *backRef;
    00384     } term;
    00385     static const term items[] =
    00386     {
    00387         { I18N_NOOP("Complete text found"),             "\\0" },
    00388     };
    00389     int i;
    00390
    00391     // Populate the popup menu.
    00392     if (!m_placeholders)
    00393     {
    00394         m_placeholders = new QPopupMenu(this);
    00395         for (i = 0; (unsigned)i < sizeof(items) / sizeof(items[0]); i++)
    00396         {
    00397             m_placeholders->insertItem(i18n(items[i].description), i, i);
    00398         }
    00399     }
    00400
    00401     // Insert the selection into the edit control.
    00402     i = m_placeholders->exec(QCursor::pos());
    00403     if (i != -1)
    00404     {
    00405         QLineEdit *editor = m_replace->lineEdit();
    00406
    00407         editor->insert(items[i].backRef);
    00408     }
    00409 }
    00410
    00411 void KFindDialog::slotOk()
    00412 {
    00413     // Nothing to find?
    00414     if (pattern().isEmpty())
    00415     {
    00416         KMessageBox::error(this, i18n("You must enter some text to search for."));
    00417         return;
    00418     }
    00419
    00420     if (m_regExp->isChecked())
    00421     {
    00422         // Check for a valid regular expression.
    00423         QRegExp regExp(pattern());
    00424
    00425         if (!regExp.isValid())
    00426         {
    00427             KMessageBox::error(this, i18n("Invalid regular expression."));
    00428             return;
    00429         }
    00430     }
    00431     m_find->addToHistory(pattern());
    00432     emit okClicked();
    00433     accept();
    00434 }
    00435
    00436 #include "kfinddialog.moc"

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:28:04 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001