00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <dcopclient.h>
00015 #include <kapplication.h>
00016 #include <kparts/part.h>
00017 #include <kparts/componentfactory.h>
00018 #include <klibloader.h>
00019 #include <ktrader.h>
00020 #include <kurl.h>
00021 #include <kurlrequester.h>
00022 #include <klineedit.h>
00023 #include <kdebug.h>
00024 #include <ktexteditor/editinterface.h>
00025 #include <ktexteditor/editor.h>
00026 #include <kdevcore.h>
00027 #include <kdevmainwindow.h>
00028 #include <kdevproject.h>
00029 #include <kdevpartcontroller.h>
00030 #include <kcombobox.h>
00031 #include <klocale.h>
00032 #include <kstdguiitem.h>
00033
00034 #include <qlayout.h>
00035 #include <qpushbutton.h>
00036 #include <qlineedit.h>
00037 #include <qradiobutton.h>
00038 #include <qstringlist.h>
00039 #include <qptrlist.h>
00040 #include <qregexp.h>
00041 #include <qdialog.h>
00042 #include <qfile.h>
00043 #include <qdir.h>
00044 #include <qtextstream.h>
00045 #include <qdatastream.h>
00046
00047 #include <sys/types.h>
00048 #include <unistd.h>
00049
00050 #include "replace_part.h"
00051 #include "replace_widget.h"
00052 #include "replacedlgimpl.h"
00053 #include "replaceitem.h"
00054 #include "replaceview.h"
00055
00056
00057
00058 ReplaceWidget::ReplaceWidget(ReplacePart *part)
00059 : QWidget(0, "replace widget"), m_part( part ),
00060 m_dialog( new ReplaceDlgImpl( this, "replace widget" ) ),
00061 _terminateOperation( false )
00062 {
00063
00064 QVBoxLayout * layout = new QVBoxLayout( this );
00065 QHBoxLayout * buttonlayout = new QHBoxLayout( layout );
00066
00067 _cancel = new KPushButton( KStdGuiItem::cancel(), this );
00068 _replace = new QPushButton( i18n("Replace"), this );
00069
00070 _cancel->setEnabled( false );
00071 _replace->setEnabled( false );
00072
00073 buttonlayout->addWidget( _replace );
00074 buttonlayout->addWidget( _cancel );
00075
00076 _listview = new ReplaceView( this );
00077 layout->addWidget( _listview );
00078
00079
00080 connect( m_dialog->find_button, SIGNAL( clicked() ), SLOT( find() ) );
00081
00082 connect( _replace, SIGNAL( clicked() ), SLOT( replace() ) );
00083 connect( _cancel, SIGNAL( clicked() ), SLOT( clear() ) );
00084 connect( _listview, SIGNAL( editDocument( const QString &, int ) ), SLOT( editDocument( const QString &, int ) ) );
00085
00086 connect( m_part->core(), SIGNAL( stopButtonClicked( KDevPlugin * ) ), SLOT( stopButtonClicked( KDevPlugin * ) ) );
00087 }
00088
00089
00090
00091 void ReplaceWidget::showDialog()
00092 {
00093 if ( ! m_part->project() )
00094 return;
00095
00096 m_dialog->show( m_part->project()->projectDirectory() + "/" + m_part->project()->activeDirectory() + "/" );
00097 }
00098
00099 void ReplaceWidget::find()
00100 {
00101 _listview->clear();
00102 m_part->mainWindow()->raiseView(this);
00103
00104 _listview->setReplacementData( m_dialog->expressionPattern(), m_dialog->replacementString() );
00105
00106 if ( showReplacements() )
00107 {
00108 _cancel->setEnabled( true );
00109 _replace->setEnabled( true );
00110 }
00111 else
00112 {
00113 clear();
00114 }
00115 }
00116
00117 void ReplaceWidget::replace()
00118 {
00119 makeReplacements();
00120 clear();
00121 }
00122
00123 void ReplaceWidget::clear()
00124 {
00125 _listview->clear();
00126
00127 _cancel->setEnabled( false );
00128 _replace->setEnabled( false );
00129 }
00130
00131 void ReplaceWidget::editDocument( QString const & file, int line )
00132 {
00133 m_part->partController()->editDocument( KURL( file ), line );
00134 }
00135
00136 void ReplaceWidget::stopButtonClicked( KDevPlugin * which )
00137 {
00138 if ( which != 0 && which != m_part )
00139 return;
00140
00141 _terminateOperation = true;
00142 }
00143
00144
00145
00146 bool ReplaceWidget::showReplacements()
00147 {
00148 ReplaceItem::s_listview_done = false;
00149
00150 m_part->core()->running( m_part, true );
00151
00152 bool completed = true;
00153 _terminateOperation = false;
00154
00155 QStringList files = workFiles();
00156 QStringList openfiles = openProjectFiles();
00157
00158 QStringList::ConstIterator it = files.begin();
00159 while ( it != files.end() )
00160 {
00161 if ( shouldTerminate() )
00162 {
00163 completed = false;
00164 break;
00165 }
00166
00167 if ( openfiles.contains( *it ) )
00168 {
00169 if ( KTextEditor::EditInterface * ei = getEditInterfaceForFile( *it ) )
00170 {
00171 QString buffer = ei->text();
00172 QTextIStream stream( &buffer );
00173 _listview->showReplacementsForFile( stream, *it );
00174 }
00175 }
00176 else
00177 {
00178 QFile file( *it );
00179 if ( file.open ( IO_ReadOnly ) )
00180 {
00181 QTextStream stream( &file );
00182 _listview->showReplacementsForFile( stream, *it );
00183 }
00184 }
00185 ++it;
00186
00187 kapp->processEvents( 100 );
00188 }
00189
00190 m_part->core()->running( m_part, false );
00191
00192 ReplaceItem::s_listview_done = true;
00193
00194 return completed;
00195 }
00196
00197 bool ReplaceWidget::makeReplacements()
00198 {
00199 m_part->core()->running( m_part, true );
00200
00201 bool completed = true;
00202 _terminateOperation = false;
00203
00204 QStringList openfiles = openProjectFiles();
00205 QStringList changedFiles;
00206
00207 ReplaceItem const * fileitem = _listview->firstChild();
00208 while ( fileitem )
00209 {
00210 if ( fileitem->isOn() )
00211 {
00212 QString currentfile = fileitem->file();
00213
00214 if ( openfiles.contains( currentfile ) )
00215 {
00216 if ( KTextEditor::EditInterface * ei = getEditInterfaceForFile( currentfile ) )
00217 {
00218 QString ibuffer = ei->text();
00219 QString obuffer;
00220 QTextStream istream( &ibuffer, IO_ReadOnly );
00221 QTextStream ostream( &obuffer, IO_WriteOnly );
00222
00223 _listview->makeReplacementsForFile( istream, ostream, fileitem );
00224
00225
00226 #if defined(KDE_MAKE_VERSION)
00227 # if KDE_VERSION > KDE_MAKE_VERSION(3,1,2)
00228 ei->setText( obuffer );
00229 # else
00230 ei->removeText( 0, 0, ei->numLines()-1, UINT_MAX );
00231 ei->insertText( 0, 0, obuffer );
00232 # endif
00233 #else
00234 ei->removeText( 0, 0, ei->numLines()-1, UINT_MAX );
00235 ei->insertText( 0, 0, obuffer );
00236 #endif
00237 }
00238 }
00239 else
00240 {
00241 QFile file( currentfile );
00242 QString buffer;
00243
00244 if ( file.open( IO_ReadOnly ) )
00245 {
00246 QTextStream istream( &file );
00247 QTextStream buffer_stream( &buffer, IO_WriteOnly );
00248
00249 _listview->makeReplacementsForFile( istream, buffer_stream, fileitem );
00250
00251 file.close();
00252
00253 if ( file.open( IO_WriteOnly ) )
00254 {
00255 QTextStream ostream( &file );
00256 ostream << buffer;
00257 file.close();
00258 }
00259 }
00260 }
00261 changedFiles << relativeProjectPath( ( currentfile ) );
00262 }
00263 fileitem = fileitem->nextSibling();
00264
00265 kapp->processEvents( 100 );
00266 }
00267
00268
00269 if ( ! changedFiles.isEmpty() )
00270 {
00271 m_part->project()->changedFiles( changedFiles );
00272 }
00273
00274 m_part->partController()->saveAllFiles();
00275
00276 m_part->core()->running( m_part, false );
00277
00278 return completed;
00279 }
00280
00281
00282
00283 QStringList ReplaceWidget::workFiles()
00284 {
00285 if ( m_dialog->files_all_radio->isChecked() )
00286 {
00287 return allProjectFiles();
00288 }
00289 else if ( m_dialog->files_open_radio->isChecked() )
00290 {
00291 return openProjectFiles();
00292 }
00293 return subProjectFiles( m_dialog->path_urlreq->lineEdit()->text() );
00294 }
00295
00296 QString ReplaceWidget::relativeProjectPath( QString path )
00297 {
00298 QString project = m_part->project()->projectDirectory() + "/";
00299 if ( path.left( project.length() ) == project )
00300 {
00301 path = path.mid( project.length() );
00302 }
00303 return path;
00304 }
00305
00306 QString ReplaceWidget::fullProjectPath( QString path )
00307 {
00308 QString project = m_part->project()->projectDirectory() + "/";
00309 if ( path.left( project.length() ) != project )
00310 {
00311 path = project + path;
00312 }
00313 return path;
00314 }
00315
00316
00317 QStringList ReplaceWidget::allProjectFiles()
00318 {
00319 QStringList allfiles = m_part->project()->allFiles();
00320
00321 QStringList::iterator it = allfiles.begin();
00322 while ( it != allfiles.end() )
00323 {
00324 *it = fullProjectPath( *it );
00325 ++it;
00326 }
00327 return allfiles;
00328 }
00329
00330 QStringList ReplaceWidget::subProjectFiles( QString const & subpath )
00331 {
00332 QStringList projectfiles = allProjectFiles();
00333
00334 QStringList::Iterator it = projectfiles.begin();
00335 while ( it != projectfiles.end() )
00336 {
00337 if ( (*it).left( subpath.length() ) != subpath)
00338 {
00339 it = projectfiles.remove( it );
00340 }
00341 else
00342 {
00343 ++it;
00344 }
00345 }
00346 return projectfiles;
00347 }
00348
00349 QStringList ReplaceWidget::openProjectFiles()
00350 {
00351 QStringList projectfiles = allProjectFiles();
00352 QStringList openfiles;
00353
00354 if( const QPtrList<KParts::Part> * partlist = m_part->
00355 partController()->parts() )
00356 {
00357 QPtrListIterator<KParts::Part> it( *partlist );
00358 while ( KParts::Part* part = it.current() )
00359 {
00360 if ( KTextEditor::Editor * ed = dynamic_cast<KTextEditor::Editor *>( part ) )
00361 {
00362 QString editorpath = ed->url().path();
00363 if ( projectfiles.contains( editorpath ) )
00364 {
00365 openfiles.append( editorpath );
00366 }
00367 }
00368 ++it;
00369 }
00370 }
00371 return openfiles;
00372 }
00373
00374 KTextEditor::EditInterface * ReplaceWidget::getEditInterfaceForFile( QString const & file )
00375 {
00376 if( const QPtrList<KParts::Part> * partlist = m_part->
00377 partController()->parts() )
00378 {
00379 QPtrListIterator<KParts::Part> it( *partlist );
00380 while ( KParts::Part* part = it.current() )
00381 {
00382 if ( KTextEditor::Editor * ed = dynamic_cast<KTextEditor::Editor *>( part ) )
00383 {
00384 if ( file == ed->url().path() )
00385 {
00386 return dynamic_cast<KTextEditor::EditInterface *>( part );
00387 }
00388 }
00389 ++it;
00390 }
00391 }
00392 return 0;
00393 }
00394
00395 bool ReplaceWidget::shouldTerminate()
00396 {
00397 bool b = _terminateOperation;
00398 _terminateOperation = false;
00399 return b;
00400 }
00401
00402 void ReplaceWidget::focusInEvent( QFocusEvent * )
00403 {
00404 _listview->setFocus();
00405 }
00406
00407
00408
00409 #include "replace_widget.moc"