00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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
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 );
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 ];
00200 }
00201
00202 editIface->insertText( pt.first + insertedLine + 1, 0 , 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"