diff options
Diffstat (limited to 'languages/cpp/addmethoddialog.cpp')
-rw-r--r-- | languages/cpp/addmethoddialog.cpp | 420 |
1 files changed, 420 insertions, 0 deletions
diff --git a/languages/cpp/addmethoddialog.cpp b/languages/cpp/addmethoddialog.cpp new file mode 100644 index 00000000..943f15d7 --- /dev/null +++ b/languages/cpp/addmethoddialog.cpp @@ -0,0 +1,420 @@ +/* +* Copyright (C) 2003 Roberto Raggi (roberto@kdevelop.org) +* +* 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. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Library General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; see the file COPYING.LIB. If not, write to +* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +* Boston, MA 02111-1307, USA. +* +*/ + +#include "addmethoddialog.h" +#include "cppsupportpart.h" +#include "backgroundparser.h" +#include "cppsupport_utils.h" +#include "domutil.h" + +#include <kdevpartcontroller.h> +#include <kdevcreatefile.h> + +#include <klocale.h> +#include <kfiledialog.h> +#include <kparts/part.h> +#include <ktexteditor/editinterface.h> +#include <kdebug.h> +#include <klineedit.h> + +#include <qregexp.h> +#include <qfileinfo.h> +#include <qcombobox.h> +#include <qlistview.h> +#include <qcheckbox.h> +#include <qpushbutton.h> +#include <qtoolbutton.h> +#include <qtextstream.h> + +AddMethodDialog::AddMethodDialog( CppSupportPart* cppSupport, ClassDom klass, + QWidget* parent, const char* name, bool modal, WFlags fl ) +: AddMethodDialogBase( parent, name, modal, fl ), m_cppSupport( cppSupport ), m_klass( klass ), m_count( 0 ) +{ + QString fileName = m_klass->fileName(); + + access->insertStringList( QStringList() << "Public" << "Protected" << "Private" << "Signals" << + "Public Slots" << "Protected Slots" << "Private Slots" ); + + storage->insertStringList( QStringList() << "Normal" << "Static" << "Virtual" << "Pure Virtual" << "Friend" ); + + // setup sourceFile combo + QMap<QString, bool> m; +#if 0 /// \FIXME ROBE + + FunctionList l = m_klass->functionList(); + { + for ( FunctionList::Iterator it = l.begin(); it != l.end(); ++it ) + { + if ( ( *it ) ->hasImplementation() ) + m.insert( ( *it ) ->implementedInFile(), true ); + } + } +#endif + + { + QStringList headers = QStringList::split( ",", "h,H,hh,hxx,hpp,inl,tlh,diff,ui.h" ); + QStringList fileList; + QMap<QString, bool>::Iterator it = m.begin(); + while ( it != m.end() ) + { + QString ext = QFileInfo( it.key() ).extension(); + if ( !headers.contains( ext ) ) + sourceFile->insertItem( it.key() ); + ++it; + } + + if ( sourceFile->count() == 0 ) + { + QFileInfo info( fileName ); + QString impl = DomUtil::readEntry( *cppSupport->projectDom(), "/cppsupportpart/filetemplates/implementationsuffix", "cpp" ); + sourceFile->insertItem( info.dirPath( true ) + "/" + info.baseName() + impl ); + } + } + + returnType->setAutoCompletion( true ); + returnType->insertStringList( QStringList() + << "void" + << "char" + << "wchar_t" + << "bool" + << "short" + << "int" + << "long" + << "signed" + << "unsigned" + << "float" + << "double" ); + + returnType->insertStringList( typeNameList( m_cppSupport->codeModel() ) ); + + updateGUI(); + addMethod(); +} + +AddMethodDialog::~AddMethodDialog() +{} + +void AddMethodDialog::reject() +{ + QDialog::reject(); +} + +QString AddMethodDialog::accessID( FunctionDom fun ) const +{ + if ( fun->isSignal() ) + return QString::fromLatin1( "Signals" ); + + switch ( fun->access() ) + { + case CodeModelItem::Public: + if ( fun->isSlot() ) + return QString::fromLatin1( "Public Slots" ); + return QString::fromLatin1( "Public" ); + + case CodeModelItem::Protected: + if ( fun->isSlot() ) + return QString::fromLatin1( "Protected Slots" ); + return QString::fromLatin1( "Protected" ); + + case CodeModelItem::Private: + if ( fun->isSlot() ) + return QString::fromLatin1( "Private Slots" ); + return QString::fromLatin1( "Private" ); + } + + return QString::null; +} + +void AddMethodDialog::accept() +{ + m_cppSupport->partController() ->editDocument( KURL( m_klass->fileName() ) ); + KTextEditor::EditInterface* editIface = dynamic_cast<KTextEditor::EditInterface*>( m_cppSupport->partController() ->activePart() ); + if ( !editIface ) + { + /// @todo show messagebox + QDialog::accept(); + return ; + } + + int line, column; + m_klass->getEndPosition( &line, &column ); + + // compute the insertion point map + QMap<QString, QPair<int, int> > points; + QStringList accessList; + + const FunctionList functionList = m_klass->functionList(); + for ( FunctionList::ConstIterator it = functionList.begin(); it != functionList.end(); ++it ) + { + int funEndLine, funEndColumn; + ( *it ) ->getEndPosition( &funEndLine, &funEndColumn ); + QString access = accessID( *it ); + QPair<int, int> funEndPoint = qMakePair( funEndLine, funEndColumn ); + + if ( !points.contains( access ) || points[ access ] < funEndPoint ) + { + accessList.remove( access ); + accessList.push_back( access ); // move 'access' at the end of the list + + points[ access ] = funEndPoint; + } + } + + int insertedLine = 0; + + accessList += newAccessList( accessList ); + + for ( QStringList::iterator it = accessList.begin(); it != accessList.end(); ++it ) + { + QListViewItem* item = methods->firstChild(); + while ( item ) + { + QListViewItem * currentItem = item; + + item = item->nextSibling(); + + if ( currentItem->text( 1 ) != *it ) + continue; + + QString access = ( *it ).lower(); + + bool isInline = currentItem->text( 0 ) == "True"; + QString str = isInline ? functionDefinition( currentItem ) : functionDeclaration( currentItem ); + + QPair<int, int> pt; + if ( points.contains( *it ) ) + { + pt = points[ *it ]; + } + else + { + str.prepend( access + ":\n" ); + points[ *it ] = qMakePair( line - 1, 0 ); + pt = points[ *it ]; // end of class declaration + } + + editIface->insertText( pt.first + insertedLine + 1, 0 /*pt.second*/, str ); + insertedLine += str.contains( QChar( '\n' ) ); + } + } + + m_cppSupport->backgroundParser() ->addFile( m_klass->fileName() ); + + QString str; + QListViewItem* item = methods->firstChild(); + while ( item ) + { + QListViewItem * currentItem = item; + + item = item->nextSibling(); + + QString str = functionDefinition( currentItem ); + if ( str.isEmpty() ) + continue; + + QString implementationFile = currentItem->text( 5 ); + if ( currentItem->text( 0 ) == "True" ) + implementationFile = m_klass->fileName(); + + QFileInfo fileInfo( implementationFile ); + if ( !QFile::exists( fileInfo.absFilePath() ) ) + { + if ( KDevCreateFile * createFileSupp = m_cppSupport->extension<KDevCreateFile>( "KDevelop/CreateFile" ) ) + createFileSupp->createNewFile( fileInfo.extension(), fileInfo.dirPath( true ), fileInfo.baseName() ); + } + + m_cppSupport->partController() ->editDocument( KURL( implementationFile ) ); + editIface = dynamic_cast<KTextEditor::EditInterface*>( m_cppSupport->partController() ->activePart() ); + if ( !editIface ) + continue; + + bool isInline = currentItem->text( 0 ) == "True"; + if ( !isInline ) + { + editIface->insertLine( editIface->numLines(), QString::fromLatin1( "" ) ); + editIface->insertText( editIface->numLines() - 1, 0, str ); + m_cppSupport->backgroundParser() ->addFile( implementationFile ); + } + } + + QDialog::accept(); +} + +void AddMethodDialog::updateGUI() +{ + bool enable = methods->selectedItem() != 0; + + returnType->setEnabled( enable ); + declarator->setEnabled( enable ); + access->setEnabled( enable ); + storage->setEnabled( enable ); + isInline->setEnabled( enable ); + + sourceFile->setEnabled( enable ); + browseButton->setEnabled( enable ); + + deleteMethodButton->setEnabled( enable ); + + if ( enable ) + { + QListViewItem * item = methods->selectedItem(); + item->setText( 0, isInline->isChecked() ? "True" : "False" ); + item->setText( 1, access->currentText() ); + item->setText( 2, storage->currentText() ); + item->setText( 3, returnType->currentText() ); + item->setText( 4, declarator->text() ); + item->setText( 5, sourceFile->currentText() ); + + if ( isInline->isChecked() || storage->currentText() == "Friend" || storage->currentText() == "Pure Virtual" ) + { + sourceFile->setEnabled( false ); + browseButton->setEnabled( false ); + } + } +} + +void AddMethodDialog::addMethod() +{ + QListViewItem * item = new QListViewItem( methods, "False", "Public", "Normal", + "void", QString( "method_%1()" ).arg( ++m_count ), + sourceFile->currentText() ); + methods->setCurrentItem( item ); + methods->setSelected( item, true ); + + returnType->setFocus(); +} + +void AddMethodDialog::deleteCurrentMethod() +{ + delete( methods->currentItem() ); + updateGUI(); +} + +void AddMethodDialog::currentChanged( QListViewItem* item ) +{ + if ( item ) + { + QString _isInline = item->text( 0 ); + QString _access = item->text( 1 ); + QString _storage = item->text( 2 ); + QString _returnType = item->text( 3 ); + QString _declarator = item->text( 4 ); + QString _sourceFile = item->text( 5 ); + + isInline->setChecked( _isInline == "True" ? true : false ); + access->setCurrentText( _access ); + storage->setCurrentText( _storage ); + returnType->setCurrentText( _returnType ); + declarator->setText( _declarator ); + sourceFile->setCurrentText( _sourceFile ); + } + + updateGUI(); +} + +void AddMethodDialog::browseImplementationFile() +{ + QString fileName = KFileDialog::getOpenFileName(); + sourceFile->setCurrentText( fileName ); + updateGUI(); +} + +QString AddMethodDialog::functionDeclaration( QListViewItem * item ) const +{ + QString str; + QTextStream stream( &str, IO_WriteOnly ); + + QString access = item->text( 1 ).lower(); + + stream << " "; /// @todo use AStyle + if ( item->text( 2 ) == "Virtual" || item->text( 2 ) == "Pure Virtual" ) + stream << "virtual "; + else if ( item->text( 2 ) == "Friend" ) + stream << "friend "; + else if ( item->text( 2 ) == "Static" ) + stream << "static "; + stream << item->text( 3 ) << " " << item->text( 4 ); + if ( item->text( 2 ) == "Pure Virtual" ) + stream << " = 0"; + stream << ";\n"; + + return str; +} + +QString AddMethodDialog::functionDefinition( QListViewItem* item ) const +{ + if ( item->text( 1 ) == "Signals" || item->text( 2 ) == "Pure Virtual" || + item->text( 2 ) == "Friend" ) + { + return QString::null; + } + + QString className = m_klass->name(); + QString fullName = m_klass->scope().join( "::" ); + if ( !fullName.isEmpty() ) + fullName += "::"; + fullName += className; + + QString str; + QTextStream stream( &str, IO_WriteOnly ); + + bool isInline = item->text( 0 ) == "True"; + + QString ind; + if ( isInline ) + ind.fill( QChar( ' ' ), 4 ); + + stream << "\n" + << ind << "/*!\n" + << ind << " \\fn " << fullName << "::" << item->text( 4 ) << "\n" + << ind << " */\n"; + + stream + << ind << item->text( 3 ) << " " << ( isInline ? QString::fromLatin1( "" ) : fullName + "::" ) + << item->text( 4 ) << "\n" + << ind << "{\n" + << ind << " /// @todo implement me\n" + << ind << "}\n"; + + return str; +} + +QStringList AddMethodDialog::newAccessList( const QStringList& accessList ) const +{ + QStringList newAccessList; + + QListViewItem* item = methods->firstChild(); + while ( item ) + { + QListViewItem * currentItem = item; + + item = item->nextSibling(); + + QString access = currentItem->text( 1 ); + if ( !( accessList.contains( access ) || newAccessList.contains( access ) ) ) + newAccessList.push_back( access ); + } + + return newAccessList; +} + +#include "addmethoddialog.moc" +//kate: indent-mode csands; tab-width 4; space-indent off; + |