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("&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()
00071 {
00072
00073 }
00074
00075 KDialogBase* KReplace::replaceNextDialog( bool create )
00076 {
00077 if ( m_dialog || create )
00078 return dialog();
00079 return 0L;
00080 }
00081
00082 KReplaceNextDialog* KReplace::dialog()
00083 {
00084 if ( !m_dialog )
00085 {
00086 m_dialog = new KReplaceNextDialog( parentWidget() );
00087 connect( m_dialog, SIGNAL( user1Clicked() ), this, SLOT( slotReplaceAll() ) );
00088 connect( m_dialog, SIGNAL( user2Clicked() ), this, SLOT( slotSkip() ) );
00089 connect( m_dialog, SIGNAL( user3Clicked() ), this, SLOT( slotReplace() ) );
00090 connect( m_dialog, SIGNAL( finished() ), this, SLOT( slotDialogClosed() ) );
00091 }
00092 return static_cast<KReplaceNextDialog *>(m_dialog);
00093 }
00094
00095 void KReplace::displayFinalDialog() const
00096 {
00097 if ( !m_replacements )
00098 KMessageBox::information(parentWidget(), i18n("No text was replaced."));
00099 else
00100 KMessageBox::information(parentWidget(), i18n("1 replacement done.", "%n replacements done.", m_replacements ) );
00101 }
00102
00103 KFind::Result KReplace::replace()
00104 {
00105 #ifdef DEBUG_REPLACE
00106 kdDebug() << k_funcinfo << "m_index=" << m_index << endl;
00107 #endif
00108 Q_ASSERT( m_index != INDEX_NOMATCH );
00109
00110 if ( m_lastResult == Match )
00111 {
00112
00113 if (m_options & KFindDialog::FindBackwards) {
00114 m_index--;
00115 if ( m_index == -1 )
00116 {
00117 m_lastResult = NoMatch;
00118 return NoMatch;
00119 }
00120 } else
00121 m_index++;
00122 }
00123
00124 do
00125 {
00126 #ifdef DEBUG_REPLACE
00127 kdDebug() << k_funcinfo << "beginning of loop: m_index=" << m_index << endl;
00128 #endif
00129
00130 if ( m_options & KReplaceDialog::RegularExpression )
00131 m_index = KFind::find(m_text, *m_regExp, m_index, m_options, &m_matchedLength);
00132 else
00133 m_index = KFind::find(m_text, m_pattern, m_index, m_options, &m_matchedLength);
00134 #ifdef DEBUG_REPLACE
00135 kdDebug() << k_funcinfo << "KFind::find returned m_index=" << m_index << endl;
00136 #endif
00137 if ( m_index != -1 )
00138 {
00139
00140 if ( validateMatch( m_text, m_index, m_matchedLength ) )
00141 {
00142 if ( m_options & KReplaceDialog::PromptOnReplace )
00143 {
00144 #ifdef DEBUG_REPLACE
00145 kdDebug() << k_funcinfo << "PromptOnReplace" << endl;
00146 #endif
00147
00148 QString matchedText = m_text.mid( m_index, m_matchedLength );
00149 QString rep = matchedText;
00150 KReplace::replace(rep, m_replacement, 0, m_matchedLength);
00151 dialog()->setLabel( matchedText, rep );
00152 dialog()->show();
00153
00154
00155
00156 emit highlight(m_text, m_index, m_matchedLength);
00157
00158 m_lastResult = Match;
00159 return Match;
00160 }
00161 else
00162 {
00163 doReplace();
00164 }
00165 }
00166
00167 if (m_options & KFindDialog::FindBackwards)
00168 m_index--;
00169 else
00170 m_index++;
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 ) 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 ( m_options & KFindDialog::FindBackwards )
00293 message = i18n( "Beginning of document reached.\n"\
00294 "Continue from the end?" );
00295 else
00296 message = i18n( "End of document reached.\n"\
00297 "Continue from the beginning?" );
00298
00299 int ret = KMessageBox::questionYesNo( parentWidget(), message );
00300 return( ret == KMessageBox::Yes );
00301 }
00302
00303 void KReplace::closeReplaceNextDialog()
00304 {
00305 closeFindNextDialog();
00306 }
00307
00308 #include "kreplace.moc"