KDevelop API Documentation

addmethoddialog.cpp

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2003 Roberto Raggi (roberto@kdevelop.org)
00003  *
00004  *  This program is free software; you can redistribute it and/or
00005  *  modify it under the terms of the GNU General Public
00006  *  License as published by the Free Software Foundation; either
00007  *  version 2 of the License, or (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  *  Library General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; see the file COPYING.LIB.  If not, write to
00016  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  *  Boston, MA 02111-1307, USA.
00018  *
00019  */
00020 
00021 #include "addmethoddialog.h"
00022 #include "cppsupportpart.h"
00023 #include "backgroundparser.h"
00024 #include "cppsupport_utils.h"
00025 
00026 #include <kdevpartcontroller.h>
00027 #include <kdevcreatefile.h>
00028 
00029 #include <klocale.h>
00030 #include <kfiledialog.h>
00031 #include <kparts/part.h>
00032 #include <ktexteditor/editinterface.h>
00033 #include <kdebug.h>
00034 
00035 #include <qregexp.h>
00036 #include <qfileinfo.h>
00037 #include <qcombobox.h>
00038 #include <qlineedit.h>
00039 #include <qlistview.h>
00040 #include <qcheckbox.h>
00041 #include <qpushbutton.h>
00042 #include <qtoolbutton.h>
00043 #include <qtextstream.h>
00044 
00045 AddMethodDialog::AddMethodDialog(CppSupportPart* cppSupport, ClassDom klass,
00046                  QWidget* parent, const char* name, bool modal, WFlags fl)
00047     : AddMethodDialogBase(parent,name, modal,fl), m_cppSupport( cppSupport ), m_klass( klass ), m_count( 0 )
00048 {
00049     QString fileName = m_klass->fileName();
00050 
00051     access->insertStringList( QStringList() << "Public" << "Protected" << "Private" << "Signals" <<
00052         "Public Slots" << "Protected Slots" << "Private Slots" );
00053     
00054     storage->insertStringList( QStringList() << "Normal" << "Static" << "Virtual" << "Pure Virtual" << "Friend" );
00055     
00056     // setup sourceFile combo
00057     QMap<QString, bool> m;
00058 #if 0 
00059     FunctionList l = m_klass->functionList();
00060     {
00061     for( FunctionList::Iterator it = l.begin(); it != l.end(); ++it ){
00062         if( (*it)->hasImplementation() )
00063             m.insert( (*it)->implementedInFile(), true );
00064     }
00065     }
00066 #endif
00067 
00068     {
00069         QStringList headers = QStringList::split( ",", "h,H,hh,hxx,hpp,inl,tlh,diff,ui.h" );
00070         QStringList fileList;
00071     QMap<QString, bool>::Iterator it = m.begin();
00072     while( it != m.end() ){
00073             QString ext = QFileInfo(it.key()).extension();
00074             if( !headers.contains(ext) )
00075                 sourceFile->insertItem( it.key() );
00076         ++it;
00077     }
00078 
00079         if( sourceFile->count() == 0 ){
00080             QFileInfo info( fileName );
00081             sourceFile->insertItem( info.dirPath(true) + "/" + info.baseName() + ".cpp" );
00082         }
00083     }
00084 
00085     returnType->setAutoCompletion( true );
00086     returnType->insertStringList( QStringList()
00087         << "void"
00088             << "char"
00089         << "wchar_t"
00090         << "bool"
00091         << "short"
00092         << "int"
00093         << "long"
00094         << "signed"
00095         << "unsigned"
00096         << "float"
00097         << "double" );
00098 
00099     returnType->insertStringList( typeNameList(m_cppSupport->codeModel()) );
00100 
00101     updateGUI();
00102     addMethod();
00103 }
00104 
00105 AddMethodDialog::~AddMethodDialog()
00106 {
00107 }
00108 
00109 void AddMethodDialog::reject()
00110 {
00111     QDialog::reject();
00112 }
00113 
00114 QString AddMethodDialog::accessID( FunctionDom fun ) const
00115 {
00116     if( fun->isSignal() )
00117     return QString::fromLatin1( "Signals" );
00118 
00119     switch( fun->access() )
00120     {
00121     case CodeModelItem::Public:
00122         if( fun->isSlot() )
00123         return QString::fromLatin1( "Public Slots" );
00124         return QString::fromLatin1( "Public" );
00125 
00126     case CodeModelItem::Protected:
00127         if( fun->isSlot() )
00128         return QString::fromLatin1( "Protected Slots" );
00129         return QString::fromLatin1( "Protected" );
00130 
00131     case CodeModelItem::Private:
00132         if( fun->isSlot() )
00133         return QString::fromLatin1( "Private Slots" );
00134         return QString::fromLatin1( "Private" );
00135     }
00136 
00137     return QString::null;
00138 }
00139 
00140 void AddMethodDialog::accept()
00141 {
00142     m_cppSupport->partController()->editDocument( KURL( m_klass->fileName() ) );
00143     KTextEditor::EditInterface* editIface = dynamic_cast<KTextEditor::EditInterface*>( m_cppSupport->partController()->activePart() );
00144     if( !editIface ){
00146     QDialog::accept();
00147     return;
00148     }
00149 
00150     int line, column;
00151     m_klass->getEndPosition( &line, &column );
00152 
00153     // compute the insertion point map
00154     QMap<QString, QPair<int,int> > points;
00155     QStringList accessList;
00156 
00157     const FunctionList functionList = m_klass->functionList();
00158     for( FunctionList::ConstIterator it=functionList.begin(); it!=functionList.end(); ++it )
00159     {
00160     int funEndLine, funEndColumn;
00161     (*it)->getEndPosition( &funEndLine, &funEndColumn );
00162     QString access = accessID( *it );
00163     QPair<int, int> funEndPoint = qMakePair( funEndLine, funEndColumn );
00164 
00165     if( !points.contains(access) || points[access] < funEndPoint ){
00166             accessList.remove( access );
00167             accessList.push_back( access ); // move 'access' at the end of the list
00168 
00169         points[ access ] = funEndPoint;
00170     }
00171     }
00172 
00173     int insertedLine = 0;
00174 
00175     accessList += newAccessList( accessList );
00176 
00177     for( QStringList::iterator it=accessList.begin(); it!=accessList.end(); ++it )
00178     {
00179     QListViewItem* item = methods->firstChild();
00180     while( item ){
00181         QListViewItem* currentItem = item;
00182 
00183         item = item->nextSibling();
00184 
00185         if( currentItem->text(1) != *it )
00186         continue;
00187 
00188             QString access = (*it).lower();
00189 
00190             bool isInline = currentItem->text( 0 ) == "True";
00191             QString str = isInline ? functionDefinition( currentItem ) : functionDeclaration( currentItem );
00192 
00193         QPair<int, int> pt;
00194             if( points.contains(*it) ) {
00195                 pt = points[ *it ];
00196             } else {
00197                 str.prepend( access + ":\n" );
00198                 points[ *it ] = qMakePair( line-1, 0 );
00199                 pt = points[ *it ]; // end of class declaration
00200             }
00201 
00202         editIface->insertText( pt.first + insertedLine + 1, 0 /*pt.second*/, str );
00203             insertedLine += str.contains( QChar('\n') );
00204     }
00205     }
00206 
00207     m_cppSupport->backgroundParser()->addFile( m_klass->fileName() );
00208 
00209     QString str;
00210     QListViewItem* item = methods->firstChild();
00211     while( item ){
00212         QListViewItem* currentItem = item;
00213 
00214         item = item->nextSibling();
00215 
00216     QString str = functionDefinition( currentItem );
00217     if( str.isEmpty() )
00218         continue;
00219     
00220         QString implementationFile = currentItem->text( 5 );
00221         if( currentItem->text(0) == "True" )
00222             implementationFile = m_klass->fileName();
00223 
00224         QFileInfo fileInfo( implementationFile );
00225         if( !QFile::exists(fileInfo.absFilePath()) ){
00226             m_cppSupport->createFileSupport()->createNewFile( fileInfo.extension(), fileInfo.dirPath(true), fileInfo.baseName() );
00227         }
00228 
00229         m_cppSupport->partController()->editDocument( KURL( implementationFile ) );
00230         editIface = dynamic_cast<KTextEditor::EditInterface*>( m_cppSupport->partController()->activePart() );
00231         if( !editIface )
00232             continue;
00233 
00234         bool isInline = currentItem->text( 0 ) == "True";
00235         if( !isInline ){
00236             editIface->insertLine( editIface->numLines(), QString::fromLatin1("") );
00237             editIface->insertText( editIface->numLines()-1, 0, str );
00238             m_cppSupport->backgroundParser()->addFile( implementationFile );
00239         }
00240     }
00241 
00242     QDialog::accept();
00243 }
00244 
00245 void AddMethodDialog::updateGUI()
00246 {
00247     bool enable = methods->selectedItem() != 0;
00248 
00249     returnType->setEnabled( enable );
00250     declarator->setEnabled( enable );
00251     access->setEnabled( enable );
00252     storage->setEnabled( enable );
00253     isInline->setEnabled( enable );
00254 
00255     sourceFile->setEnabled( enable );
00256     browseButton->setEnabled( enable );
00257 
00258     deleteMethodButton->setEnabled( enable );
00259 
00260     if( enable ){
00261     QListViewItem* item = methods->selectedItem();
00262     item->setText( 0, isInline->isChecked() ? "True" : "False" );
00263     item->setText( 1, access->currentText() );
00264     item->setText( 2, storage->currentText() );
00265     item->setText( 3, returnType->currentText() );
00266     item->setText( 4, declarator->text() );
00267     item->setText( 5, sourceFile->currentText() );
00268 
00269     if( isInline->isChecked() || storage->currentText() == "Friend" || storage->currentText() == "Pure Virtual" ){
00270         sourceFile->setEnabled( false );
00271         browseButton->setEnabled( false );
00272     }
00273     }
00274 }
00275 
00276 void AddMethodDialog::addMethod()
00277 {
00278     QListViewItem* item = new QListViewItem( methods, "False", "Public", "Normal", "void", QString("method_%1()").arg(++m_count),
00279             sourceFile->currentText() );
00280     methods->setCurrentItem( item );
00281     methods->setSelected( item, true );
00282 
00283     returnType->setFocus();
00284 }
00285 
00286 void AddMethodDialog::deleteCurrentMethod()
00287 {
00288     delete( methods->currentItem() );
00289     updateGUI();
00290 }
00291 
00292 void AddMethodDialog::currentChanged( QListViewItem* item )
00293 {
00294     if( item ){
00295         QString _isInline = item->text( 0 );
00296         QString _access = item->text( 1 );
00297         QString _storage = item->text( 2 );
00298         QString _returnType = item->text( 3 );
00299         QString _declarator = item->text( 4 );
00300         QString _sourceFile = item->text( 5 );
00301 
00302     isInline->setChecked( _isInline == "True" ? true : false );
00303     access->setCurrentText( _access );
00304     storage->setCurrentText( _storage );
00305     returnType->setCurrentText( _returnType );
00306     declarator->setText( _declarator );
00307     sourceFile->setCurrentText( _sourceFile );
00308     }
00309 
00310     updateGUI();
00311 }
00312 
00313 void AddMethodDialog::browseImplementationFile()
00314 {
00315     QString fileName = KFileDialog::getOpenFileName();
00316     sourceFile->setCurrentText( fileName );
00317     updateGUI();
00318 }
00319 
00320 QString AddMethodDialog::functionDeclaration( QListViewItem * item ) const
00321 {
00322     QString str;
00323     QTextStream stream( &str, IO_WriteOnly );
00324 
00325     QString access = item->text( 1 ).lower();
00326 
00327     stream << "    "; 
00328     if( item->text(2) == "Virtual" || item->text(2) == "Pure Virtual" )
00329     stream << "virtual ";
00330     else if( item->text(2) == "Friend" )
00331     stream << "friend ";
00332     else if( item->text(2) == "Static" )
00333     stream << "static ";
00334     stream << item->text( 3 ) << " " << item->text( 4 );
00335     if( item->text(2) == "Pure Virtual" )
00336     stream << " = 0";
00337     stream << ";\n";
00338 
00339     return str;
00340 }
00341 
00342 QString AddMethodDialog::functionDefinition( QListViewItem* item ) const
00343 {
00344     if( item->text( 1 ) == "Signals" || item->text(2) == "Pure Virtual" || item->text(2) == "Friend" )
00345         return QString::null;
00346 
00347     QString className = m_klass->name();
00348     QString fullName = m_klass->scope().join( "::" );
00349     if( !fullName.isEmpty() )
00350         fullName += "::";
00351     fullName += className;
00352 
00353     QString str;
00354     QTextStream stream( &str, IO_WriteOnly );
00355 
00356     bool isInline = item->text(0) == "True";
00357 
00358     QString ind;
00359     if( isInline )
00360         ind.fill( QChar(' '), 4 );
00361 
00362     stream << "\n"
00363        << ind << "\n";
00366 
00367     stream
00368         << ind << item->text( 3 ) << " " << (isInline ? QString::fromLatin1("") : fullName + "::") << item->text( 4 ) << "\n"
00369         << ind << "{\n"
00370         << ind << "    /// @todo implement me\n"
00371         << ind << "}\n";
00372 
00373     return str;
00374 }
00375 
00376 QStringList AddMethodDialog::newAccessList( const QStringList& accessList ) const
00377 {
00378     QStringList newAccessList;
00379 
00380     QListViewItem* item = methods->firstChild();
00381     while( item ){
00382         QListViewItem* currentItem = item;
00383 
00384         item = item->nextSibling();
00385 
00386         QString access = currentItem->text( 1 );
00387         if( !(accessList.contains(access) || newAccessList.contains(access)) )
00388             newAccessList.push_back( access );
00389     }
00390 
00391     return newAccessList;
00392 }
00393 
00394 #include "addmethoddialog.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 Wed Mar 23 00:03:45 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003