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"), KStdGuiItem::yes())
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_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, 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, 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, int length)
00213 {
00214
00215 QString rep = replacement;
00216 rep.replace( QRegExp("/0"), text.mid( index, length ) );
00217
00218 text.replace(index, length, rep);
00219 return rep.length();
00220 }
00221
00222 void KReplace::slotReplaceAll()
00223 {
00224 doReplace();
00225 m_options &= ~KReplaceDialog::PromptOnReplace;
00226 emit optionsChanged();
00227 emit findNext();
00228 }
00229
00230 void KReplace::slotSkip()
00231 {
00232 if (m_options & KReplaceDialog::FindBackwards)
00233 m_index--;
00234 else
00235 m_index++;
00236 if ( m_dialogClosed ) {
00237 delete m_dialog;
00238 m_dialog = 0L;
00239 } else
00240 emit findNext();
00241 }
00242
00243 void KReplace::slotReplace()
00244 {
00245 doReplace();
00246 if ( m_dialogClosed ) {
00247 delete m_dialog;
00248 m_dialog = 0L;
00249 } else
00250 emit findNext();
00251 }
00252
00253 void KReplace::doReplace()
00254 {
00255 int replacedLength = KReplace::replace(m_text, m_replacement, m_index, m_matchedLength);
00256
00257
00258
00259 emit replace(m_text, m_index, replacedLength, m_matchedLength);
00260 #ifdef DEBUG_REPLACE
00261 kdDebug() << k_funcinfo << "after replace() signal: m_index=" << m_index << " replacedLength=" << replacedLength << endl;
00262 #endif
00263 m_replacements++;
00264 if (m_options & KReplaceDialog::FindBackwards)
00265 m_index--;
00266 else
00267 m_index += replacedLength;
00268 #ifdef DEBUG_REPLACE
00269 kdDebug() << k_funcinfo << "after adjustement: m_index=" << m_index << endl;
00270 #endif
00271 }
00272
00273 void KReplace::resetCounts()
00274 {
00275 KFind::resetCounts();
00276 m_replacements = 0;
00277 }
00278
00279 bool KReplace::shouldRestart( bool forceAsking, bool showNumMatches ) const
00280 {
00281
00282
00283
00284
00285 if ( !forceAsking && (m_options & KFindDialog::FromCursor) == 0
00286 && (m_options & KReplaceDialog::PromptOnReplace) == 0 )
00287 {
00288 displayFinalDialog();
00289 return false;
00290 }
00291 QString message;
00292 if ( showNumMatches )
00293 {
00294 if ( !m_replacements )
00295 message = i18n("No text was replaced.");
00296 else
00297 message = i18n("1 replacement done.", "%n replacements done.", m_replacements );
00298 }
00299 else
00300 {
00301 if ( m_options & KFindDialog::FindBackwards )
00302 message = i18n( "Beginning of document reached." );
00303 else
00304 message = i18n( "End of document reached." );
00305 }
00306
00307 message += "\n";
00308
00309 message +=
00310 ( m_options & KFindDialog::FindBackwards ) ?
00311 i18n("Do you want to restart search from the end?")
00312 : i18n("Do you want to restart search at the beginning?");
00313
00314 int ret = KMessageBox::questionYesNo( parentWidget(), message );
00315 return( ret == KMessageBox::Yes );
00316 }
00317
00318 void KReplace::closeReplaceNextDialog()
00319 {
00320 closeFindNextDialog();
00321 }
00322
00323 #include "kreplace.moc"