You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdevelop/parts/replace/replace_widget.cpp

487 lines
13 KiB

/***************************************************************************
* Copyright (C) 2003 by Jens Dagerbo *
* jens.dagerbo@swipnet.se *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
//BEGIN Includes
#include <dcopclient.h>
#include <tdeapplication.h>
#include <tdeparts/part.h>
#include <tdeparts/componentfactory.h>
#include <klibloader.h>
#include <ktrader.h>
#include <kurl.h>
#include <kurlrequester.h>
#include <klineedit.h>
#include <kdebug.h>
#include <tdetexteditor/editinterface.h>
#include <tdetexteditor/editor.h>
#include <tdetexteditor/document.h>
#include <tdetexteditor/viewcursorinterface.h>
#include <tdetexteditor/selectioninterface.h>
#include <kdevpartcontroller.h>
#include <kdevcore.h>
#include <kdevmainwindow.h>
#include <kdevproject.h>
#include <kdevpartcontroller.h>
#include <kcombobox.h>
#include <tdelocale.h>
#include <kstdguiitem.h>
#include <tqlayout.h>
#include <tqpushbutton.h>
#include <tqlineedit.h>
#include <tqradiobutton.h>
#include <tqstringlist.h>
#include <tqptrlist.h>
#include <tqregexp.h>
#include <tqdialog.h>
#include <tqfile.h>
#include <tqdir.h>
#include <tqtextstream.h>
#include <tqdatastream.h>
#include <sys/types.h>
#include <unistd.h>
#include "replace_part.h"
#include "replace_widget.h"
#include "replacedlgimpl.h"
#include "replaceitem.h"
#include "replaceview.h"
//END Includes
ReplaceWidget::ReplaceWidget(ReplacePart *part)
: TQWidget(0, "replace widget"), m_part( part ),
m_dialog( new ReplaceDlgImpl( this, "replace widget" ) ),
_terminateOperation( false )
{
// setup outputview
TQVBoxLayout * layout = new TQVBoxLayout( this );
TQHBoxLayout * buttonlayout = new TQHBoxLayout( layout );
_cancel = new KPushButton( KStdGuiItem::cancel(), this );
_replace = new KPushButton( KGuiItem(i18n("Replace"),"filefind"), this );
_cancel->setEnabled( false );
_replace->setEnabled( false );
buttonlayout->addWidget( _replace );
buttonlayout->addWidget( _cancel );
_listview = new ReplaceView( this );
layout->addWidget( _listview );
// setup signals
connect( m_dialog->find_button, TQ_SIGNAL( clicked() ), TQ_SLOT( find() ) );
connect( _replace, TQ_SIGNAL( clicked() ), TQ_SLOT( replace() ) );
connect( _cancel, TQ_SIGNAL( clicked() ), TQ_SLOT( clear() ) );
connect( _listview, TQ_SIGNAL( editDocument( const TQString &, int ) ), TQ_SLOT( editDocument( const TQString &, int ) ) );
connect( m_part->core(), TQ_SIGNAL( stopButtonClicked( KDevPlugin * ) ), TQ_SLOT( stopButtonClicked( KDevPlugin * ) ) );
}
//BEGIN Slots
void ReplaceWidget::showDialog()
{
if ( ! m_part->project() )
return; /// @todo feedback?
TQString currentWord;
KParts::ReadOnlyPart *part = dynamic_cast<KParts::ReadOnlyPart*> ( m_part->partController()->activePart() );
if ( part )
{
if ( part->url().isLocalFile() )
{
calledUrl = part->url().path();
cursorPos ( part, &calledCol, &calledLine );
KTextEditor::EditInterface* editIface = dynamic_cast<KTextEditor::EditInterface*>( m_part->partController()->activePart() );
TQString str = editIface->textLine ( calledCol );
int i;
uint start, end;
for (i =calledLine; i< str.length();i++){
if ( ! (str[i].isLetter() || str[i].isNumber() || str[i] == '_' ) ){
break;
}
}
end=i;
for ( i = calledLine; i >= 0; --i ){
if ( ! ( str[i].isLetter() ||str[i].isNumber()|| str[i] == '_' ) ){
i+=1;
break;
}
}
start = i < 0 ? 0 : i;
currentWord = str.mid ( start, end-start );
}
}
m_dialog->show ( m_part->project()->projectDirectory() + "/" + m_part->project()->activeDirectory() + "/" );
KTextEditor::SelectionInterface *sel_iface
= dynamic_cast<KTextEditor::SelectionInterface*> ( m_part->partController()->activePart() );
if ( sel_iface && sel_iface->hasSelection() )
{
m_dialog->find_combo->setCurrentText ( sel_iface->selection() );
}
else
{
m_dialog->find_combo->setCurrentText ( currentWord );
}
}
void ReplaceWidget::find()
{
_listview->clear();
m_part->mainWindow()->raiseView( this );
m_part->mainWindow()->setViewAvailable( this, true );
_listview->setReplacementData( m_dialog->expressionPattern(), m_dialog->replacementString() );
if ( showReplacements() )
{
_cancel->setEnabled( true );
_replace->setEnabled( true );
}
else
{
clear();
m_part->mainWindow()->setViewAvailable( this, false );
}
}
void ReplaceWidget::replace()
{
makeReplacements();
clear();
m_part->mainWindow()->setViewAvailable( this, false );
}
void ReplaceWidget::clear()
{
_listview->clear();
_cancel->setEnabled( false );
_replace->setEnabled( false );
m_part->mainWindow()->setViewAvailable( this, false );
}
void ReplaceWidget::editDocument( TQString const & file, int line )
{
m_part->partController()->editDocument( KURL( file ), line );
}
void ReplaceWidget::stopButtonClicked( KDevPlugin * which )
{
if ( which != 0 && which != m_part )
return;
_terminateOperation = true;
}
//END Slots
bool ReplaceWidget::showReplacements()
{
ReplaceItem::s_listview_done = false;
m_part->core()->running( m_part, true );
bool completed = true;
_terminateOperation = false;
TQStringList files = workFiles();
TQStringList openfiles = openProjectFiles();
TQStringList::ConstIterator it = files.begin();
while ( it != files.end() )
{
if ( shouldTerminate() )
{
completed = false;
break;
}
if ( openfiles.contains( *it ) )
{
if ( KTextEditor::EditInterface * ei = getEditInterfaceForFile( *it ) )
{
TQString buffer = ei->text();
TQTextIStream stream( &buffer );
_listview->showReplacementsForFile( stream, *it );
}
}
else
{
TQFile file( *it );
if ( file.open ( IO_ReadOnly ) )
{
TQTextStream stream( &file );
_listview->showReplacementsForFile( stream, *it );
}
}
++it;
kapp->processEvents( 100 );
}
m_part->core()->running( m_part, false );
ReplaceItem::s_listview_done = true;
return completed;
}
void ReplaceWidget::cursorPos( KParts::Part *part, uint * line, uint * col )
{
if (!part || !part->inherits("KTextEditor::Document")) return;
KTextEditor::ViewCursorInterface *iface = dynamic_cast<KTextEditor::ViewCursorInterface*>(part->widget());
if (iface)
{
iface->cursorPositionReal( line, col );
}
}
void ReplaceWidget::setCursorPos( KParts::Part *part, uint line, uint col )
{
if (!part || !part->inherits("KTextEditor::Document")) return;
KTextEditor::ViewCursorInterface *iface = dynamic_cast<KTextEditor::ViewCursorInterface*>(part->widget());
if (iface)
{
iface->setCursorPositionReal( line, col );
}
}
bool ReplaceWidget::makeReplacements()
{
uint col=0;
uint line=0;
cursorPos( m_part->partController()->activePart(), &col, &line );
m_part->core()->running( m_part, true );
bool completed = true;
_terminateOperation = false;
TQStringList openfiles = openProjectFiles();
TQStringList changedFiles;
ReplaceItem const * fileitem = _listview->firstChild();
while ( fileitem )
{
if ( fileitem->isOn() )
{
TQString currentfile = fileitem->file();
if ( openfiles.contains( currentfile ) )
{
if ( KTextEditor::EditInterface * ei = getEditInterfaceForFile( currentfile ) )
{
TQString ibuffer = ei->text();
TQString obuffer;
TQTextStream istream( &ibuffer, IO_ReadOnly );
TQTextStream ostream( &obuffer, IO_WriteOnly );
_listview->makeReplacementsForFile( istream, ostream, fileitem );
ei->setText( obuffer );
}
}
else
{
TQFile file( currentfile );
TQString buffer;
if ( file.open( IO_ReadOnly ) )
{
TQTextStream istream( &file );
TQTextStream buffer_stream( &buffer, IO_WriteOnly );
_listview->makeReplacementsForFile( istream, buffer_stream, fileitem );
file.close();
if ( file.open( IO_WriteOnly ) )
{
TQTextStream ostream( &file );
ostream << buffer;
file.close();
}
}
}
changedFiles << relativeProjectPath( ( currentfile ) );
}
fileitem = fileitem->nextSibling();
kapp->processEvents( 100 );
}
// Telling the project about the edited files
if ( ! changedFiles.isEmpty() )
{
m_part->project()->changedFiles( changedFiles );
}
m_part->partController()->saveAllFiles();
m_part->core()->running( m_part, false );
if ( calledUrl != TQString() )
{
m_part->partController()->editDocument( calledUrl, calledLine );
setCursorPos( m_part->partController()->activePart(), calledCol, calledLine );
}
else{
setCursorPos( m_part->partController()->activePart(), col, line );
}
return completed;
}
//BEGIN Helpers
TQStringList ReplaceWidget::workFiles()
{
if ( m_dialog->files_all_radio->isChecked() )
{
return allProjectFiles();
}
else if ( m_dialog->files_open_radio->isChecked() )
{
return openProjectFiles();
}
return subProjectFiles( m_dialog->path_urlreq->lineEdit()->text() );
}
TQString ReplaceWidget::relativeProjectPath( TQString path )
{
TQString project = m_part->project()->projectDirectory() + "/";
if ( path.left( project.length() ) == project )
{
path = path.mid( project.length() );
}
return path;
}
TQString ReplaceWidget::fullProjectPath( TQString path )
{
TQString project = m_part->project()->projectDirectory() + "/";
if ( path.left( project.length() ) != project )
{
path = project + path;
}
return path;
}
TQStringList ReplaceWidget::allProjectFiles()
{
TQStringList allfiles = m_part->project()->allFiles();
TQStringList::iterator it = allfiles.begin();
while ( it != allfiles.end() )
{
*it = fullProjectPath( *it );
++it;
}
return allfiles;
}
TQStringList ReplaceWidget::subProjectFiles( TQString const & subpath )
{
TQStringList projectfiles = allProjectFiles();
TQStringList::Iterator it = projectfiles.begin();
while ( it != projectfiles.end() )
{
if ( (*it).left( subpath.length() ) != subpath)
{
it = projectfiles.remove( it );
}
else
{
++it;
}
}
return projectfiles;
}
TQStringList ReplaceWidget::openProjectFiles()
{
TQStringList projectfiles = allProjectFiles();
TQStringList openfiles;
if( const TQPtrList<KParts::Part> * partlist = m_part->
partController()->parts() )
{
TQPtrListIterator<KParts::Part> it( *partlist );
while ( KParts::Part* part = it.current() )
{
if ( KTextEditor::Editor * ed = dynamic_cast<KTextEditor::Editor *>( part ) )
{
TQString editorpath = ed->url().path();
if ( projectfiles.contains( editorpath ) )
{
openfiles.append( editorpath );
}
}
++it;
}
}
return openfiles;
}
KTextEditor::EditInterface * ReplaceWidget::getEditInterfaceForFile( TQString const & file )
{
if( const TQPtrList<KParts::Part> * partlist = m_part->
partController()->parts() )
{
TQPtrListIterator<KParts::Part> it( *partlist );
while ( KParts::Part* part = it.current() )
{
if ( KTextEditor::Editor * ed = dynamic_cast<KTextEditor::Editor *>( part ) )
{
if ( file == ed->url().path() )
{
return dynamic_cast<KTextEditor::EditInterface *>( part );
}
}
++it;
}
}
return 0;
}
bool ReplaceWidget::shouldTerminate()
{
bool b = _terminateOperation;
_terminateOperation = false;
return b;
}
void ReplaceWidget::focusInEvent( TQFocusEvent * /* e*/ )
{
_listview->setFocus();
}
//END Helpers
#include "replace_widget.moc"