00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qlabel.h>
00022 #include <kapplication.h>
00023 #include <kdebug.h>
00024
00025 #include <klocale.h>
00026 #include <kmessagebox.h>
00027 #include "kreplace.h"
00028 #include "kreplacedialog.h"
00029 #include <qregexp.h>
00030
00031
00032 #define INDEX_NOMATCH -1
00033
00034 class KReplaceNextDialog : public KDialogBase
00035 {
00036 public:
00037 KReplaceNextDialog( QWidget *parent );
00038 void setLabel( const QString& pattern, const QString& replacement );
00039 private:
00040 QLabel* m_mainLabel;
00041 };
00042
00043 KReplaceNextDialog::KReplaceNextDialog(QWidget *parent) :
00044 KDialogBase(parent, 0, false,
00045 i18n("Replace"),
00046 User3 | User2 | User1 | Close,
00047 User3,
00048 false,
00049 i18n("&All"), i18n("&Skip"), i18n("Replace"))
00050 {
00051 m_mainLabel = new QLabel( this );
00052 setMainWidget( m_mainLabel );
00053 resize(minimumSize());
00054 }
00055
00056 void KReplaceNextDialog::setLabel( const QString& pattern, const QString& replacement )
00057 {
00058 m_mainLabel->setText( i18n("Replace '%1' with '%2'?").arg(pattern).arg(replacement) );
00059 }
00060
00062
00063 KReplace::KReplace(const QString &pattern, const QString &replacement, long options, QWidget *parent) :
00064 KFind( pattern, options, parent )
00065 {
00066 m_replacements = 0;
00067 m_replacement = replacement;
00068 }
00069
00070 KReplace::KReplace(const QString &pattern, const QString &replacement, long options, QWidget *parent, QWidget *dlg) :
00071 KFind( pattern, options, parent, dlg )
00072 {
00073 m_replacements = 0;
00074 m_replacement = replacement;
00075 }
00076
00077 KReplace::~KReplace()
00078 {
00079
00080 }
00081
00082 KDialogBase* KReplace::replaceNextDialog( bool create )
00083 {
00084 if ( m_dialog || create )
00085 return dialog();
00086 return 0L;
00087 }
00088
00089 KReplaceNextDialog* KReplace::dialog()
00090 {
00091 if ( !m_dialog )
00092 {
00093 m_dialog = new KReplaceNextDialog( parentWidget() );
00094 connect( m_dialog, SIGNAL( user1Clicked() ), this, SLOT( slotReplaceAll() ) );
00095 connect( m_dialog, SIGNAL( user2Clicked() ), this, SLOT( slotSkip() ) );
00096 connect( m_dialog, SIGNAL( user3Clicked() ), this, SLOT( slotReplace() ) );
00097 connect( m_dialog, SIGNAL( finished() ), this, SLOT( slotDialogClosed() ) );
00098 }
00099 return static_cast<KReplaceNextDialog *>(m_dialog);
00100 }
00101
00102 void KReplace::displayFinalDialog() const
00103 {
00104 if ( !m_replacements )
00105 KMessageBox::information(parentWidget(), i18n("No text was replaced."));
00106 else
00107 KMessageBox::information(parentWidget(), i18n("1 replacement done.", "%n replacements done.", m_replacements ) );
00108 }
00109
00110 KFind::Result KReplace::replace()
00111 {
00112 #ifdef DEBUG_REPLACE
00113 kdDebug() << k_funcinfo << "m_index=" << m_index << endl;
00114 #endif
00115 if ( m_index == INDEX_NOMATCH && m_lastResult == Match )
00116 {
00117 m_lastResult = NoMatch;
00118 return NoMatch;
00119 }
00120
00121 do
00122 {
00123 #ifdef DEBUG_REPLACE
00124 kdDebug() << k_funcinfo << "beginning of loop: m_index=" << m_index << endl;
00125 #endif
00126
00127 if ( m_options & KReplaceDialog::RegularExpression )
00128 m_index = KFind::find(m_text, *m_regExp, m_index, m_options, &m_matchedLength);
00129 else
00130 m_index = KFind::find(m_text, m_pattern, m_index, m_options, &m_matchedLength);
00131 #ifdef DEBUG_REPLACE
00132 kdDebug() << k_funcinfo << "KFind::find returned m_index=" << m_index << endl;
00133 #endif
00134 if ( m_index != -1 )
00135 {
00136
00137 if ( validateMatch( m_text, m_index, m_matchedLength ) )
00138 {
00139 if ( m_options & KReplaceDialog::PromptOnReplace )
00140 {
00141 #ifdef DEBUG_REPLACE
00142 kdDebug() << k_funcinfo << "PromptOnReplace" << endl;
00143 #endif
00144
00145 QString matchedText = m_text.mid( m_index, m_matchedLength );
00146 QString rep = matchedText;
00147 KReplace::replace(rep, m_replacement, 0, m_options, m_matchedLength);
00148 dialog()->setLabel( matchedText, rep );
00149 dialog()->show();
00150
00151
00152
00153 emit highlight(m_text, m_index, m_matchedLength);
00154
00155 m_lastResult = Match;
00156 return Match;
00157 }
00158 else
00159 {
00160 doReplace();
00161 }
00162 }
00163 else
00164 {
00165
00166 if (m_options & KFindDialog::FindBackwards)
00167 m_index--;
00168 else
00169 m_index++;
00170 }
00171 } else
00172 m_index = INDEX_NOMATCH;
00173 }
00174 while (m_index != INDEX_NOMATCH);
00175
00176 m_lastResult = NoMatch;
00177 return NoMatch;
00178 }
00179
00180 int KReplace::replace(QString &text, const QString &pattern, const QString &replacement, int index, long options, int *replacedLength)
00181 {
00182 int matchedLength;
00183
00184 index = KFind::find(text, pattern, index, options, &matchedLength);
00185 if (index != -1)
00186 {
00187 *replacedLength = replace(text, replacement, index, options, matchedLength);
00188 if (options & KReplaceDialog::FindBackwards)
00189 index--;
00190 else
00191 index += *replacedLength;
00192 }
00193 return index;
00194 }
00195
00196 int KReplace::replace(QString &text, const QRegExp &pattern, const QString &replacement, int index, long options, int *replacedLength)
00197 {
00198 int matchedLength;
00199
00200 index = KFind::find(text, pattern, index, options, &matchedLength);
00201 if (index != -1)
00202 {
00203 *replacedLength = replace(text, replacement, index, options, matchedLength);
00204 if (options & KReplaceDialog::FindBackwards)
00205 index--;
00206 else
00207 index += *replacedLength;
00208 }
00209 return index;
00210 }
00211
00212 int KReplace::replace(QString &text, const QString &replacement, int index, long options, int length)
00213 {
00214 QString rep = replacement;
00215
00216 if ( options & KReplaceDialog::BackReference )
00217 rep.replace( "\\0", text.mid( index, length ) );
00218
00219 text.replace(index, length, rep);
00220 return rep.length();
00221 }
00222
00223 void KReplace::slotReplaceAll()
00224 {
00225 doReplace();
00226 m_options &= ~KReplaceDialog::PromptOnReplace;
00227 emit optionsChanged();
00228 emit findNext();
00229 }
00230
00231 void KReplace::slotSkip()
00232 {
00233 if (m_options & KReplaceDialog::FindBackwards)
00234 m_index--;
00235 else
00236 m_index++;
00237 if ( m_dialogClosed ) {
00238 delete m_dialog;
00239 m_dialog = 0L;
00240 } else
00241 emit findNext();
00242 }
00243
00244 void KReplace::slotReplace()
00245 {
00246 doReplace();
00247 if ( m_dialogClosed ) {
00248 delete m_dialog;
00249 m_dialog = 0L;
00250 } else
00251 emit findNext();
00252 }
00253
00254 void KReplace::doReplace()
00255 {
00256 int replacedLength = KReplace::replace(m_text, m_replacement, m_index, m_options, m_matchedLength);
00257
00258
00259
00260 emit replace(m_text, m_index, replacedLength, m_matchedLength);
00261 #ifdef DEBUG_REPLACE
00262 kdDebug() << k_funcinfo << "after replace() signal: m_index=" << m_index << " replacedLength=" << replacedLength << endl;
00263 #endif
00264 m_replacements++;
00265 if (m_options & KReplaceDialog::FindBackwards)
00266 m_index--;
00267 else {
00268 m_index += replacedLength;
00269
00270 if ( m_pattern.isEmpty() )
00271 ++m_index;
00272 }
00273 #ifdef DEBUG_REPLACE
00274 kdDebug() << k_funcinfo << "after adjustement: m_index=" << m_index << endl;
00275 #endif
00276 }
00277
00278 void KReplace::resetCounts()
00279 {
00280 KFind::resetCounts();
00281 m_replacements = 0;
00282 }
00283
00284 bool KReplace::shouldRestart( bool forceAsking, bool showNumMatches ) const
00285 {
00286
00287
00288
00289
00290 if ( !forceAsking && (m_options & KFindDialog::FromCursor) == 0
00291 && (m_options & KReplaceDialog::PromptOnReplace) == 0 )
00292 {
00293 displayFinalDialog();
00294 return false;
00295 }
00296 QString message;
00297 if ( showNumMatches )
00298 {
00299 if ( !m_replacements )
00300 message = i18n("No text was replaced.");
00301 else
00302 message = i18n("1 replacement done.", "%n replacements done.", m_replacements );
00303 }
00304 else
00305 {
00306 if ( m_options & KFindDialog::FindBackwards )
00307 message = i18n( "Beginning of document reached." );
00308 else
00309 message = i18n( "End of document reached." );
00310 }
00311
00312 message += "\n";
00313
00314 message +=
00315 ( m_options & KFindDialog::FindBackwards ) ?
00316 i18n("Do you want to restart search from the end?")
00317 : i18n("Do you want to restart search at the beginning?");
00318
00319 int ret = KMessageBox::questionYesNo( parentWidget(), message, QString::null, i18n("Restart"), i18n("Stop") );
00320 return( ret == KMessageBox::Yes );
00321 }
00322
00323 void KReplace::closeReplaceNextDialog()
00324 {
00325 closeFindNextDialog();
00326 }
00327
00328 #include "kreplace.moc"