/*************************************************************************** * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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, TQT_SIGNAL( clicked() ), TQT_SLOT( find() ) ); connect( _replace, TQT_SIGNAL( clicked() ), TQT_SLOT( replace() ) ); connect( _cancel, TQT_SIGNAL( clicked() ), TQT_SLOT( clear() ) ); connect( _listview, TQT_SIGNAL( editDocument( const TQString &, int ) ), TQT_SLOT( editDocument( const TQString &, int ) ) ); connect( m_part->core(), TQT_SIGNAL( stopButtonClicked( KDevPlugin * ) ), TQT_SLOT( stopButtonClicked( KDevPlugin * ) ) ); } //BEGIN Slots void ReplaceWidget::showDialog() { if ( ! m_part->project() ) return; /// @todo feedback? TQString currentWord; KParts::ReadOnlyPart *part = dynamic_cast ( m_part->partController()->activePart() ); if ( part ) { if ( part->url().isLocalFile() ) { calledUrl = part->url().path(); cursorPos ( part, &calledCol, &calledLine ); KTextEditor::EditInterface* editIface = dynamic_cast( 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 ( 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(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(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 * partlist = m_part-> partController()->parts() ) { TQPtrListIterator it( *partlist ); while ( KParts::Part* part = it.current() ) { if ( KTextEditor::Editor * ed = dynamic_cast( 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 * partlist = m_part-> partController()->parts() ) { TQPtrListIterator it( *partlist ); while ( KParts::Part* part = it.current() ) { if ( KTextEditor::Editor * ed = dynamic_cast( part ) ) { if ( file == ed->url().path() ) { return dynamic_cast( 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"