00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "javasupportpart.h"
00017 #include "javasupport_events.h"
00018 #include "problemreporter.h"
00019 #include "backgroundparser.h"
00020 #include "KDevJavaSupportIface.h"
00021 #include "javasupportfactory.h"
00022 #include "catalog.h"
00023 #include "kdevdriver.h"
00024 #include "javasupport_utils.h"
00025
00026 #include "JavaStoreWalker.hpp"
00027 #include "JavaAST.hpp"
00028
00029 #include <qheader.h>
00030 #include <qdir.h>
00031 #include <qdom.h>
00032 #include <qfileinfo.h>
00033 #include <qguardedptr.h>
00034 #include <qpopupmenu.h>
00035 #include <qprogressdialog.h>
00036 #include <qstringlist.h>
00037 #include <qtimer.h>
00038 #include <qstatusbar.h>
00039 #include <qprogressbar.h>
00040 #include <qregexp.h>
00041 #include <qlabel.h>
00042 #include <qvbox.h>
00043 #include <kmessagebox.h>
00044 #include <kaction.h>
00045 #include <kapplication.h>
00046 #include <kdebug.h>
00047 #include <kdialogbase.h>
00048 #include <kgenericfactory.h>
00049 #include <klocale.h>
00050 #include <kmessagebox.h>
00051 #include <kmainwindow.h>
00052 #include <kstatusbar.h>
00053 #include <kconfig.h>
00054 #include <kdeversion.h>
00055 #include <kstandarddirs.h>
00056 #include <kiconloader.h>
00057
00058 #include <ktexteditor/document.h>
00059 #include <ktexteditor/editinterface.h>
00060 #include <ktexteditor/view.h>
00061 #include <ktexteditor/selectioninterface.h>
00062 #include <ktexteditor/viewcursorinterface.h>
00063 #include <ktexteditor/clipboardinterface.h>
00064
00065 #if defined(KDE_MAKE_VERSION)
00066 # if KDE_VERSION >= KDE_MAKE_VERSION(3,1,90)
00067 # include <ktexteditor/texthintinterface.h>
00068 # else
00069 # include <kde30x_texthintinterface.h>
00070 # endif
00071 #else
00072 # include <kde30x_texthintinterface.h>
00073 #endif
00074
00075 #include <kdevcore.h>
00076 #include <kdevproject.h>
00077 #include <kdevmainwindow.h>
00078 #include <kdevpartcontroller.h>
00079 #include <kdevmakefrontend.h>
00080 #include <kdevcoderepository.h>
00081
00082 #include <domutil.h>
00083 #include <urlutil.h>
00084 #include <config.h>
00085
00086 enum { KDEV_DB_VERSION = 3 };
00087 enum { KDEV_PCS_VERSION = 3 };
00088
00089 class JavaDriver: public KDevDriver
00090 {
00091 public:
00092 JavaDriver( JavaSupportPart* javaSupport )
00093 : KDevDriver( javaSupport )
00094 {
00095 }
00096
00097 void fileParsed( const QString& fileName )
00098 {
00099
00100 RefJavaAST ast = takeTranslationUnit( fileName );
00101
00102 if( javaSupport()->problemReporter() ){
00103 javaSupport()->problemReporter()->removeAllProblems( fileName );
00104
00105 QValueList<Problem> pl = problems( fileName );
00106 QValueList<Problem>::ConstIterator it = pl.begin();
00107 while( it != pl.end() ){
00108 const Problem& p = *it++;
00109 javaSupport()->problemReporter()->reportProblem( fileName, p );
00110 }
00111 }
00112
00113 if( javaSupport()->codeModel()->hasFile(fileName) ){
00114 FileDom file = javaSupport()->codeModel()->fileByName( fileName );
00115 javaSupport()->removeWithReferences( fileName );
00116 }
00117
00118 FileDom file = javaSupport()->codeModel()->create<FileModel>();
00119 file->setName( fileName );
00120 JavaStoreWalker walker;
00121 walker.setFile( file );
00122 walker.setCodeModel( javaSupport()->codeModel() );
00123 walker.compilationUnit( ast );
00124 javaSupport()->codeModel()->addFile( file );
00125
00126 remove( fileName );
00127 }
00128 };
00129
00130 JavaSupportPart::JavaSupportPart(QObject *parent, const char *name, const QStringList &)
00131 : KDevLanguageSupport("JavaSupport", "java", parent, name ? name : "KDevJavaSupport"),
00132 m_activeDocument( 0 ), m_activeView( 0 ), m_activeSelection( 0 ), m_activeEditor( 0 ),
00133 m_activeViewCursor( 0 ), m_projectClosed( true ), m_valid( false )
00134 {
00135 setInstance(JavaSupportFactory::instance());
00136
00137 m_driver = new JavaDriver( this );
00138
00139 setXMLFile( "kdevjavasupport.rc" );
00140
00141 m_catalogList.setAutoDelete( true );
00142 setupCatalog();
00143
00144 m_backgroundParser = new BackgroundParser( this, &m_eventConsumed );
00145 m_backgroundParser->start();
00146
00147 connect( core(), SIGNAL(projectOpened()), this, SLOT(projectOpened()) );
00148 connect( core(), SIGNAL(projectClosed()), this, SLOT(projectClosed()) );
00149 connect( partController(), SIGNAL(savedFile(const KURL&)),
00150 this, SLOT(savedFile(const KURL&)) );
00151 connect( core(), SIGNAL(contextMenu(QPopupMenu *, const Context *)),
00152 this, SLOT(contextMenu(QPopupMenu *, const Context *)) );
00153 connect( partController(), SIGNAL(activePartChanged(KParts::Part*)),
00154 this, SLOT(activePartChanged(KParts::Part*)));
00155 connect( partController(), SIGNAL(partRemoved(KParts::Part*)),
00156 this, SLOT(partRemoved(KParts::Part*)));
00157
00158 m_problemReporter = new ProblemReporter( this );
00159 m_problemReporter->setIcon( SmallIcon("info") );
00160 mainWindow( )->embedOutputView( m_problemReporter, i18n("Problems"), i18n("Problem reporter"));
00161
00162 connect( core(), SIGNAL(configWidget(KDialogBase*)),
00163 m_problemReporter, SLOT(configWidget(KDialogBase*)) );
00164 connect( core(), SIGNAL(configWidget(KDialogBase*)),
00165 this, SLOT(configWidget(KDialogBase*)) );
00166
00167 KAction *action;
00168
00169 action = new KAction(i18n("New Class..."), "classnew", 0,
00170 this, SLOT(slotNewClass()),
00171 actionCollection(), "project_newclass");
00172 action->setToolTip( i18n("Generate a new class") );
00173 action->setWhatsThis( i18n("<b>New Class</b>Generates a new class.<p>") );
00174
00175
00176 connect( core( ), SIGNAL( projectConfigWidget( KDialogBase* ) ), this,
00177 SLOT( projectConfigWidget( KDialogBase* ) ) );
00178
00179 new KDevJavaSupportIface( this );
00180
00181 }
00182
00183
00184 JavaSupportPart::~JavaSupportPart()
00185 {
00186 delete( m_driver );
00187 m_driver = 0;
00188
00189 if( m_backgroundParser ){
00190 m_backgroundParser->close();
00191 m_backgroundParser->wait();
00192 delete m_backgroundParser;
00193 m_backgroundParser = 0;
00194 }
00195
00196 codeRepository()->setMainCatalog( 0 );
00197
00198 QPtrListIterator<Catalog> it( m_catalogList );
00199 while( Catalog* catalog = it.current() ){
00200 ++it;
00201 codeRepository()->unregisterCatalog( catalog );
00202 }
00203
00204 mainWindow( )->removeView( m_problemReporter );
00205
00206 delete m_problemReporter;
00207 m_problemReporter = 0;
00208 }
00209
00210 void JavaSupportPart::customEvent( QCustomEvent* ev )
00211 {
00212
00213
00214 if( ev->type() == int(Event_FileParsed) ){
00215 FileParsedEvent* event = (FileParsedEvent*) ev;
00216 QString fileName = event->fileName();
00217
00218 if( m_problemReporter ){
00219 m_problemReporter->removeAllProblems( fileName );
00220
00221 bool hasErrors = false;
00222 QValueList<Problem> problems = event->problems();
00223 QValueList<Problem>::ConstIterator it = problems.begin();
00224 while( it != problems.end() ){
00225 const Problem& p = *it++;
00226 if( p.level() == Problem::Level_Error )
00227 hasErrors = true;
00228
00229 m_problemReporter->reportProblem( fileName, p );
00230 }
00231
00232 m_backgroundParser->lock();
00233 if( RefJavaAST ast = m_backgroundParser->translationUnit(fileName) ){
00234
00235 if( !hasErrors ){
00236 if( codeModel()->hasFile(fileName) ){
00237 FileDom file = codeModel()->fileByName( fileName );
00238 removeWithReferences( fileName );
00239 }
00240
00241 FileDom file = codeModel()->create<FileModel>();
00242 file->setName( fileName );
00243 JavaStoreWalker walker;
00244 walker.setFile( file );
00245 walker.setCodeModel( codeModel() );
00246
00247 walker.compilationUnit( ast );
00248 codeModel()->addFile( file );
00249
00250 emit addedSourceInfo( fileName );
00251 }
00252 }
00253 m_backgroundParser->unlock();
00254 }
00255 emit fileParsed( fileName );
00256 }
00257 }
00258
00259 void JavaSupportPart::projectConfigWidget( KDialogBase* )
00260 {
00261 }
00262
00263 void JavaSupportPart::configWidget(KDialogBase *)
00264 {
00265 }
00266
00267 void JavaSupportPart::activePartChanged(KParts::Part *part)
00268 {
00269 kdDebug(9032) << "JavaSupportPart::activePartChanged()" << endl;
00270
00271 bool enabled = false;
00272
00273 m_activeDocument = dynamic_cast<KTextEditor::Document*>( part );
00274 m_activeView = part ? dynamic_cast<KTextEditor::View*>( part->widget() ) : 0;
00275 m_activeEditor = dynamic_cast<KTextEditor::EditInterface*>( part );
00276 m_activeSelection = dynamic_cast<KTextEditor::SelectionInterface*>( part );
00277 m_activeViewCursor = part ? dynamic_cast<KTextEditor::ViewCursorInterface*>( m_activeView ) : 0;
00278
00279 m_activeFileName = QString::null;
00280
00281 if (m_activeDocument) {
00282 m_activeFileName = URLUtil::canonicalPath( m_activeDocument->url().path() );
00283 QFileInfo fi( m_activeFileName );
00284 QString ext = fi.extension();
00285 if (fileExtensions().contains(ext))
00286 enabled = true;
00287 }
00288
00289 if( !part )
00290 return;
00291
00292 if( !m_activeView )
00293 return;
00294
00295 #if 0
00296 KTextEditor::TextHintInterface* textHintIface = dynamic_cast<KTextEditor::TextHintInterface*>( m_activeView );
00297 if( !textHintIface )
00298 return;
00299
00300 connect( view, SIGNAL(needTextHint(int,int,QString&)),
00301 this, SLOT(slotNeedTextHint(int,int,QString&)) );
00302
00303 textHintIface->enableTextHints( 1000 );
00304 #endif
00305 }
00306
00307
00308 void JavaSupportPart::projectOpened( )
00309 {
00310 kdDebug( 9013 ) << "projectOpened( )" << endl;
00311
00312 m_projectDirectory = URLUtil::canonicalPath( project()->projectDirectory() );
00313
00314 connect( project( ), SIGNAL( addedFilesToProject( const QStringList & ) ),
00315 this, SLOT( addedFilesToProject( const QStringList & ) ) );
00316 connect( project( ), SIGNAL( removedFilesFromProject( const QStringList &) ),
00317 this, SLOT( removedFilesFromProject( const QStringList & ) ) );
00318 connect( project( ), SIGNAL( changedFilesInProject( const QStringList & ) ),
00319 this, SLOT( changedFilesInProject( const QStringList & ) ) );
00320 connect( project(), SIGNAL(projectCompiled()),
00321 this, SLOT(slotProjectCompiled()) );
00322
00323 QDir::setCurrent( m_projectDirectory );
00324
00325 m_timestamp.clear();
00326
00327 m_projectClosed = false;
00328
00329 QTimer::singleShot( 500, this, SLOT( initialParse( ) ) );
00330 }
00331
00332
00333 void JavaSupportPart::projectClosed( )
00334 {
00335 kdDebug( 9013 ) << "projectClosed( )" << endl;
00336
00337 saveProjectSourceInfo();
00338
00339 if( m_backgroundParser )
00340 m_backgroundParser->removeAllFiles();
00341
00342 m_projectClosed = true;
00343 }
00344
00345 void JavaSupportPart::contextMenu(QPopupMenu *, const Context *context)
00346 {
00347 m_activeClass = 0;
00348 m_activeFunction = 0;
00349 m_activeVariable = 0;
00350
00351 if( context->hasType(Context::EditorContext) ){
00352
00353 } else if( context->hasType(Context::CodeModelItemContext) ){
00354 const CodeModelItemContext* mcontext = static_cast<const CodeModelItemContext*>( context );
00355
00356 if( mcontext->item()->isClass() ){
00357 m_activeClass = (ClassModel*) mcontext->item();
00358 } else if( mcontext->item()->isFunction() ){
00359 m_activeFunction = (FunctionModel*) mcontext->item();
00360 }
00361 }
00362 }
00363
00364 void JavaSupportPart::addedFilesToProject(const QStringList &fileList)
00365 {
00366 QStringList files = fileList;
00367
00368 for ( QStringList::ConstIterator it = files.begin(); it != files.end(); ++it )
00369 {
00370 QString path = URLUtil::canonicalPath( m_projectDirectory + "/" + (*it) );
00371
00372 maybeParse( path );
00373 emit addedSourceInfo( path );
00374 }
00375 }
00376
00377 void JavaSupportPart::removedFilesFromProject(const QStringList &fileList)
00378 {
00379 for ( QStringList::ConstIterator it = fileList.begin(); it != fileList.end(); ++it )
00380 {
00381 QString path = URLUtil::canonicalPath( m_projectDirectory + "/" + *it );
00382
00383 removeWithReferences( path );
00384 m_backgroundParser->removeFile( path );
00385 }
00386 }
00387
00388 void JavaSupportPart::changedFilesInProject( const QStringList & fileList )
00389 {
00390 QStringList files = fileList;
00391
00392 for ( QStringList::ConstIterator it = files.begin(); it != files.end(); ++it )
00393 {
00394 QString path = URLUtil::canonicalPath( m_projectDirectory + "/" + *it );
00395
00396 maybeParse( path );
00397 emit addedSourceInfo( path );
00398 }
00399 }
00400
00401 void JavaSupportPart::savedFile(const KURL &fileName)
00402 {
00403 Q_UNUSED( fileName.path() );
00404
00405 #if 0 // not needed anymore
00406 kdDebug(9013) << "savedFile(): " << fileName.mid ( m_projectDirectory.length() + 1 ) << endl;
00407
00408 QStringList projectFileList = project()->allFiles();
00409 if (projectFileList.contains(fileName.mid ( m_projectDirectory.length() + 1 ))) {
00410 maybeParse( fileName );
00411 emit addedSourceInfo( fileName );
00412 }
00413 #endif
00414 }
00415
00416 QString JavaSupportPart::findSourceFile()
00417 {
00418 QFileInfo fi( m_activeFileName );
00419 QString path = fi.filePath();
00420 QString ext = fi.extension();
00421 QString base = path.left( path.length() - ext.length() );
00422 QStringList candidates;
00423
00424 if (ext == "h" || ext == "H" || ext == "hh" || ext == "hxx" || ext == "hpp" || ext == "tlh") {
00425 candidates << (base + "c");
00426 candidates << (base + "cc");
00427 candidates << (base + "java");
00428 candidates << (base + "java");
00429 candidates << (base + "cxx");
00430 candidates << (base + "C");
00431 candidates << (base + "m");
00432 candidates << (base + "mm");
00433 candidates << (base + "M");
00434 candidates << (base + "inl");
00435 }
00436
00437 QStringList::ConstIterator it;
00438 for (it = candidates.begin(); it != candidates.end(); ++it) {
00439 kdDebug(9013) << "Trying " << (*it) << endl;
00440 if (QFileInfo(*it).exists()) {
00441 return *it;
00442 }
00443 }
00444
00445 return m_activeFileName;
00446 }
00447
00448 KDevLanguageSupport::Features JavaSupportPart::features()
00449 {
00450 return Features( Classes | Functions | Variables );
00451 }
00452
00453 QString JavaSupportPart::formatClassName(const QString &name)
00454 {
00455 return name;
00456 }
00457
00458 QString JavaSupportPart::unformatClassName(const QString &name)
00459 {
00460 return name;
00461 }
00462
00463 QStringList JavaSupportPart::fileExtensions() const
00464 {
00465 return QStringList::split(",", "java");
00466 }
00467
00468 void JavaSupportPart::slotNewClass()
00469 {
00470 }
00471
00472 void JavaSupportPart::addMethod( ClassDom )
00473 {
00474 }
00475
00476 void JavaSupportPart::addAttribute( ClassDom )
00477 {
00478 }
00479
00480 void JavaSupportPart::initialParse( )
00481 {
00482
00483 if( !project( ) ){
00484
00485 kdDebug( 9013 ) << "No project" << endl;
00486 return;
00487 }
00488
00489 parseProject( );
00490 emit updatedSourceInfo();
00491 m_valid = true;
00492 return;
00493 }
00494
00495 #if QT_VERSION < 0x030100
00496
00497 uint toTime_t(QDateTime t)
00498 {
00499 tm brokenDown;
00500 brokenDown.tm_sec = t.time().second();
00501 brokenDown.tm_min = t.time().minute();
00502 brokenDown.tm_hour = t.time().hour();
00503 brokenDown.tm_mday = t.date().day();
00504 brokenDown.tm_mon = t.date().month() - 1;
00505 brokenDown.tm_year = t.date().year() - 1900;
00506 brokenDown.tm_isdst = -1;
00507 int secsSince1Jan1970UTC = (int) mktime( &brokenDown );
00508 if ( secsSince1Jan1970UTC < -1 )
00509 secsSince1Jan1970UTC = -1;
00510 return (uint) secsSince1Jan1970UTC;
00511 }
00512 #endif
00513
00514 bool
00515 JavaSupportPart::parseProject( )
00516 {
00517
00518
00519
00520
00521
00522 mainWindow()->statusBar()->message( i18n("Updating...") );
00523
00524 kapp->processEvents( );
00525 kapp->setOverrideCursor( waitCursor );
00526
00527 QStringList files = modifiedFileList();
00528
00529 QProgressBar* bar = new QProgressBar( files.count( ), mainWindow( )->statusBar( ) );
00530 bar->setMinimumWidth( 120 );
00531 bar->setCenterIndicator( true );
00532 mainWindow( )->statusBar( )->addWidget( bar );
00533 bar->show( );
00534
00535 QDir d( m_projectDirectory );
00536
00537 QDataStream stream;
00538 QMap< QString, QPair<uint, Q_LONG> > pcs;
00539
00540 QFile f( project()->projectDirectory() + "/" + project()->projectName() + ".pcs" );
00541 if( f.open(IO_ReadOnly) ){
00542 stream.setDevice( &f );
00543
00544 QString sig;
00545 int pcs_version = 0;
00546 stream >> sig >> pcs_version;
00547 if( sig == "PCS" && pcs_version == KDEV_PCS_VERSION ){
00548
00549 int numFiles = 0;
00550 stream >> numFiles;
00551
00552 for( int i=0; i<numFiles; ++i ){
00553 QString fn;
00554 uint ts;
00555 Q_LONG offset;
00556
00557 stream >> fn >> ts >> offset;
00558 pcs[ fn ] = qMakePair( ts, offset );
00559 }
00560 }
00561 }
00562
00563 int n = 0;
00564 for( QStringList::Iterator it = files.begin( ); it != files.end( ); ++it ) {
00565 bar->setProgress( n++ );
00566 QFileInfo fileInfo( d, *it );
00567
00568 if( fileInfo.exists() && fileInfo.isFile() && fileInfo.isReadable() ){
00569 QString absFilePath = URLUtil::canonicalPath( fileInfo.absFilePath() );
00570 kdDebug(9013) << "parse file: " << absFilePath << endl;
00571
00572 if( (n%5) == 0 ){
00573 kapp->processEvents();
00574
00575 if( m_projectClosed ){
00576 delete( bar );
00577 return false;
00578 }
00579 }
00580
00581 if( isValidSource(absFilePath) ){
00582 QDateTime t = fileInfo.lastModified();
00583 if( m_timestamp.contains(absFilePath) && m_timestamp[absFilePath] == t )
00584 continue;
00585
00586 #if QT_VERSION >= 0x030100
00587 if( pcs.contains(absFilePath) && t.toTime_t() == pcs[absFilePath].first ){
00588 #else
00589 if( pcs.contains(absFilePath) && toTime_t(t) == pcs[absFilePath].first ){
00590 #endif
00591 stream.device()->at( pcs[absFilePath].second );
00592 FileDom file = codeModel()->create<FileModel>();
00593 file->read( stream );
00594 codeModel()->addFile( file );
00595 } else {
00596 m_driver->parseFile( absFilePath );
00597 }
00598
00599 m_timestamp[ absFilePath ] = t;
00600 }
00601 }
00602
00603 if( m_projectClosed ){
00604 kdDebug(9013) << "ABORT" << endl;
00605 kapp->restoreOverrideCursor( );
00606 return false;
00607 }
00608 }
00609
00610 kdDebug( 9013 ) << "updating sourceinfo" << endl;
00611 emit updatedSourceInfo();
00612
00613 mainWindow( )->statusBar( )->removeWidget( bar );
00614 delete bar;
00615
00616
00617
00618 kapp->restoreOverrideCursor( );
00619 mainWindow( )->statusBar( )->message( i18n( "Done" ), 2000 );
00620
00621 return true;
00622 }
00623
00624 void JavaSupportPart::maybeParse( const QString& fileName )
00625 {
00626 if( !isValidSource(fileName) )
00627 return;
00628
00629 QFileInfo fileInfo( fileName );
00630 QString path = URLUtil::canonicalPath( fileName );
00631 QDateTime t = fileInfo.lastModified();
00632
00633 if( !fileInfo.exists() ){
00634 removeWithReferences( path );
00635 return;
00636 }
00637
00638 QMap<QString, QDateTime>::Iterator it = m_timestamp.find( path );
00639 if( it != m_timestamp.end() && *it == t ){
00640 return;
00641 }
00642
00643 m_timestamp[ path ] = t;
00644 m_driver->parseFile( path );
00645 }
00646
00647 void JavaSupportPart::slotNeedTextHint( int , int , QString& )
00648 {
00649 }
00650
00651 QStringList JavaSupportPart::subclassWidget(const QString& )
00652 {
00653 QStringList newFileNames;
00654 return newFileNames;
00655 }
00656
00657 QStringList JavaSupportPart::updateWidget(const QString& , const QString& )
00658 {
00659 QStringList dummy;
00660 return dummy;
00661 }
00662
00663 void JavaSupportPart::partRemoved( KParts::Part* part )
00664 {
00665 kdDebug(9032) << "JavaSupportPart::partRemoved()" << endl;
00666
00667 if( KTextEditor::Document* doc = dynamic_cast<KTextEditor::Document*>( part ) ){
00668
00669 QString fileName = doc->url().path();
00670 if( fileName.isEmpty() )
00671 return;
00672
00673 QString canonicalFileName = URLUtil::canonicalPath( fileName );
00674 m_backgroundParser->removeFile( canonicalFileName );
00675 m_backgroundParser->addFile( canonicalFileName, true );
00676 }
00677 }
00678
00679 void JavaSupportPart::slotProjectCompiled()
00680 {
00681 kdDebug(9013) << "JavaSupportPart::slotProjectCompiled()" << endl;
00682 parseProject();
00683 }
00684
00685 QStringList JavaSupportPart::modifiedFileList()
00686 {
00687 QStringList lst;
00688
00689 QStringList fileList = project()->allFiles();
00690 QStringList::Iterator it = fileList.begin();
00691 while( it != fileList.end() ){
00692 QString fileName = *it;
00693 ++it;
00694
00695 QFileInfo fileInfo( m_projectDirectory, fileName );
00696
00697 if( !fileExtensions().contains(fileInfo.extension()) )
00698 continue;
00699
00700 QDateTime t = fileInfo.lastModified();
00701 QString path = URLUtil::canonicalPath( fileInfo.absFilePath() );
00702 QMap<QString, QDateTime>::Iterator dictIt = m_timestamp.find( path );
00703 if( fileInfo.exists() && dictIt != m_timestamp.end() && *dictIt == t )
00704 continue;
00705
00706 lst << fileName;
00707 }
00708
00709 return lst;
00710 }
00711
00712 KTextEditor::Document * JavaSupportPart::findDocument( const KURL & url )
00713 {
00714 if( !partController()->parts() )
00715 return 0;
00716
00717 QPtrList<KParts::Part> parts( *partController()->parts() );
00718 QPtrListIterator<KParts::Part> it( parts );
00719 while( KParts::Part* part = it.current() ){
00720 KTextEditor::Document* doc = dynamic_cast<KTextEditor::Document*>( part );
00721 if( doc && doc->url() == url )
00722 return doc;
00723 ++it;
00724 }
00725
00726 return 0;
00727 }
00728
00729 void JavaSupportPart::setupCatalog( )
00730 {
00731 kdDebug(9013) << "JavaSupportPart::setupCatalog()" << endl;
00732
00733 QStringList indexList = QStringList() << "kind" << "name" << "scope" << "fileName";
00734
00735 KStandardDirs *dirs = JavaSupportFactory::instance()->dirs();
00736 QStringList pcsList = dirs->findAllResources( "pcs", "*.db", false, true );
00737 QStringList pcsIdxList = dirs->findAllResources( "pcs", "*.idx", false, true );
00738
00739 if( pcsList.size() && pcsVersion() < KDEV_DB_VERSION ){
00740 QStringList l = pcsList + pcsIdxList;
00741 int rtn = KMessageBox::questionYesNoList( 0, i18n("Persistant class store will be disabled!! You have a wrong version of pcs installed.\nRemove old pcs files?"), l, i18n("Java Support") );
00742 if( rtn == KMessageBox::Yes ){
00743 QStringList::Iterator it = l.begin();
00744 while( it != l.end() ){
00745 QFile::remove( *it );
00746 ++it;
00747 }
00748
00749 pcsList.clear();
00750 } else {
00751 return;
00752 }
00753 }
00754
00755 QStringList::Iterator it = pcsList.begin();
00756 while( it != pcsList.end() ){
00757 Catalog* catalog = new Catalog();
00758 catalog->open( *it );
00759 ++it;
00760
00761 for( QStringList::Iterator idxIt=indexList.begin(); idxIt!=indexList.end(); ++idxIt )
00762 catalog->addIndex( (*idxIt).utf8() );
00763
00764 m_catalogList.append( catalog );
00765 codeRepository()->registerCatalog( catalog );
00766 }
00767
00768 setPcsVersion( KDEV_DB_VERSION );
00769 }
00770
00771 KMimeType::List JavaSupportPart::mimeTypes( )
00772 {
00773 KMimeType::List list;
00774 KMimeType::Ptr mime;
00775
00776 mime = KMimeType::mimeType( "text/x-java" );
00777 if( mime )
00778 list << mime;
00779
00780 return list;
00781 }
00782
00783 int JavaSupportPart::pcsVersion()
00784 {
00785 KConfig* config = JavaSupportFactory::instance()->config();
00786 KConfigGroupSaver cgs( config, "PCS" );
00787 return config->readNumEntry( "Version", 0 );
00788 }
00789
00790 void JavaSupportPart::setPcsVersion( int version )
00791 {
00792 KConfig* config = JavaSupportFactory::instance()->config();
00793 KConfigGroupSaver cgs( config, "PCS" );
00794 config->writeEntry( "Version", version );
00795 config->sync();
00796 }
00797
00798 QString JavaSupportPart::formatTag( const Tag & )
00799 {
00800 return QString::null;
00801 }
00802
00803 void JavaSupportPart::removeWithReferences( const QString & fileName )
00804 {
00805 kdDebug(9013) << "remove with references: " << fileName << endl;
00806 m_timestamp.remove( fileName );
00807 if( !codeModel()->hasFile(fileName) )
00808 return;
00809
00810 emit aboutToRemoveSourceInfo( fileName );
00811
00812 codeModel()->removeFile( codeModel()->fileByName(fileName) );
00813 }
00814
00815 bool JavaSupportPart::isValidSource( const QString& fileName ) const
00816 {
00817 QFileInfo fileInfo( fileName );
00818 return fileExtensions().contains( fileInfo.extension() ) && !QFile::exists(fileInfo.dirPath(true) + "/.kdev_ignore");
00819 }
00820
00821 QString JavaSupportPart::formatModelItem( const CodeModelItem *item, bool shortDescription )
00822 {
00823 if (item->isFunction())
00824 {
00825 const FunctionModel *model = static_cast<const FunctionModel*>(item);
00826 QString function;
00827 QString args;
00828 ArgumentList argumentList = model->argumentList();
00829 for (ArgumentList::const_iterator it = argumentList.begin(); it != argumentList.end(); ++it)
00830 {
00831 args.isEmpty() ? args += "" : args += ", " ;
00832 args += formatModelItem((*it).data());
00833 }
00834 if( !shortDescription )
00835 function += model->resultType() + " ";
00836
00837 function += model->name() + "(" + args + ")" +
00838 (model->isAbstract() ? QString(" = 0") : QString("") );
00839
00840 return function;
00841 }
00842 else if (item->isVariable())
00843 {
00844 const VariableModel *model = static_cast<const VariableModel*>(item);
00845 if( shortDescription )
00846 return model->name();
00847 return model->type() + " " + model->name();
00848 }
00849 else if (item->isArgument())
00850 {
00851 const ArgumentModel *model = static_cast<const ArgumentModel*>(item);
00852 QString arg;
00853 if( !shortDescription )
00854 arg += model->type() + " ";
00855 arg += model->name();
00856 if( !shortDescription )
00857 arg += model->defaultValue().isEmpty() ? QString("") : QString(" = ") + model->defaultValue();
00858 return arg.stripWhiteSpace();
00859 }
00860 else
00861 return KDevLanguageSupport::formatModelItem( item, shortDescription );
00862 }
00863
00864 void JavaSupportPart::addClass( )
00865 {
00866 slotNewClass();
00867 }
00868
00869 void JavaSupportPart::saveProjectSourceInfo( )
00870 {
00871 const FileList fileList = codeModel()->fileList();
00872
00873 if( !project() || fileList.isEmpty() )
00874 return;
00875
00876 QFile f( project()->projectDirectory() + "/" + project()->projectName() + ".pcs" );
00877 if( !f.open( IO_WriteOnly ) )
00878 return;
00879
00880 QDataStream stream( &f );
00881 QMap<QString, Q_ULONG> offsets;
00882
00883 QString pcs( "PCS" );
00884 stream << pcs << KDEV_PCS_VERSION;
00885
00886 stream << int( fileList.size() );
00887 for( FileList::ConstIterator it=fileList.begin(); it!=fileList.end(); ++it ){
00888 const FileDom dom = (*it);
00889 #if QT_VERSION >= 0x030100
00890 stream << dom->name() << m_timestamp[ dom->name() ].toTime_t();
00891 #else
00892 stream << dom->name() << toTime_t(m_timestamp[ dom->name() ]);
00893 #endif
00894 offsets.insert( dom->name(), stream.device()->at() );
00895 stream << (Q_ULONG)0;
00896 }
00897
00898 for( FileList::ConstIterator it=fileList.begin(); it!=fileList.end(); ++it ){
00899 const FileDom dom = (*it);
00900 int offset = stream.device()->at();
00901
00902 dom->write( stream );
00903
00904 int end = stream.device()->at();
00905
00906 stream.device()->at( offsets[dom->name()] );
00907 stream << offset;
00908 stream.device()->at( end );
00909 }
00910 }
00911
00912 #include "javasupportpart.moc"