summaryrefslogtreecommitdiffstats
path: root/languages/cpp/addmethoddialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'languages/cpp/addmethoddialog.cpp')
-rw-r--r--languages/cpp/addmethoddialog.cpp420
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;
+