KDevelop API Documentation

replace_widget.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2003 by Jens Dagerbo                                    *
00003  *   jens.dagerbo@swipnet.se                                               *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  ***************************************************************************/
00011 
00012 //BEGIN Includes
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 //END Includes
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     // setup outputview
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     //  setup signals
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 //BEGIN Slots
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 //END Slots
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                     // pre 3.1.3 katepart clears undo history on setText()
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     // Telling the project about the edited files
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 //BEGIN Helpers
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 * /* e*/ )
00403 {
00404     _listview->setFocus();
00405 }
00406 
00407 //END Helpers
00408 
00409 #include "replace_widget.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Feb 22 09:22:41 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003