00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "fortransupportpart.h"
00017 #include "ftnchekconfigwidget.h"
00018 #include "fixedformparser.h"
00019
00020 #include <qdir.h>
00021 #include <qfileinfo.h>
00022 #include <qpopupmenu.h>
00023 #include <qstringlist.h>
00024 #include <qtextstream.h>
00025 #include <qtimer.h>
00026 #include <qvbox.h>
00027 #include <kapplication.h>
00028 #include <kdebug.h>
00029 #include <kdialogbase.h>
00030 #include <klocale.h>
00031 #include <kmessagebox.h>
00032 #include <kprocess.h>
00033 #include <kregexp.h>
00034 #include <kdevgenericfactory.h>
00035 #include <kaction.h>
00036
00037 #include <kdevcore.h>
00038 #include <kdevproject.h>
00039 #include <kdevmakefrontend.h>
00040 #include <kdevpartcontroller.h>
00041 #include <domutil.h>
00042 #include <codemodel.h>
00043
00044
00045
00046 typedef KDevGenericFactory<FortranSupportPart> FortranSupportFactory;
00047 static const KAboutData data("kdevfortransupport", I18N_NOOP("Language"), "1.0");
00048 K_EXPORT_COMPONENT_FACTORY( libkdevfortransupport, FortranSupportFactory( &data ) )
00049
00050 FortranSupportPart::FortranSupportPart(QObject *parent, const char *name, const QStringList &)
00051 : KDevLanguageSupport("FortranSupport", "fortran", parent, name ? name : "FortranSupportPart")
00052 {
00053 setInstance(FortranSupportFactory::instance());
00054
00055 setXMLFile("kdevfortransupport.rc");
00056
00057 connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)),
00058 this, SLOT(projectConfigWidget(KDialogBase*)) );
00059 connect( core(), SIGNAL(projectOpened()), this, SLOT(projectOpened()) );
00060 connect( core(), SIGNAL(projectClosed()), this, SLOT(projectClosed()) );
00061 connect( partController(), SIGNAL(savedFile(const KURL&)),
00062 this, SLOT(savedFile(const KURL&)) );
00063
00064 KAction *action;
00065
00066 action = new KAction( i18n("&Ftnchek"), 0,
00067 this, SLOT(slotFtnchek()),
00068 actionCollection(), "project_ftnchek" );
00069 action->setToolTip(i18n("Run ftnchek"));
00070 action->setWhatsThis(i18n("<b>Run ftnchek</b><p>Runs <b>ftnchek</b> to check fortran programs for semantic errors. Configure ftnchek options in project settings dialog, <b>Ftnchek</b> tab."));
00071
00072 parser = 0;
00073 }
00074
00075
00076 FortranSupportPart::~FortranSupportPart()
00077 {}
00078
00079
00080 void FortranSupportPart::slotFtnchek()
00081 {
00082
00083 if (makeFrontend()->isRunning()) {
00084 KMessageBox::sorry(0, i18n("There is currently a job running."));
00085 return;
00086 }
00087
00088 partController()->saveAllFiles();
00089
00090 QDomDocument &dom = *projectDom();
00091
00092 QString cmdline = "cd ";
00093 cmdline += KProcess::quote(project()->projectDirectory());
00094 cmdline += "&& ftnchek -nonovice ";
00095
00096 if (DomUtil::readBoolEntry(dom, "/kdevfortransupport/ftnchek/division"))
00097 cmdline += "-division ";
00098 if (DomUtil::readBoolEntry(dom, "/kdevfortransupport/ftnchek/extern"))
00099 cmdline += "-extern ";
00100 if (DomUtil::readBoolEntry(dom, "/kdevfortransupport/ftnchek/declare"))
00101 cmdline += "-declare ";
00102 if (DomUtil::readBoolEntry(dom, "/kdevfortransupport/ftnchek/pure"))
00103 cmdline += "-pure ";
00104
00105 cmdline += "-arguments=";
00106 if (DomUtil::readBoolEntry(dom, "/kdevfortransupport/ftnchek/argumentsall"))
00107 cmdline += "all ";
00108 else
00109 cmdline += DomUtil::readEntry(dom, "/kdevfortransupport/ftnchek/argumentsonly") + " ";
00110
00111 cmdline += "-common=";
00112 if (DomUtil::readBoolEntry(dom, "/kdevfortransupport/ftnchek/commonall"))
00113 cmdline += "all ";
00114 else
00115 cmdline += DomUtil::readEntry(dom, "/kdevfortransupport/ftnchek/commononly") + " ";
00116
00117 cmdline += "-truncation=";
00118 if (DomUtil::readBoolEntry(dom, "/kdevfortransupport/ftnchek/truncationall"))
00119 cmdline += "all ";
00120 else
00121 cmdline += DomUtil::readEntry(dom, "/kdevfortransupport/ftnchek/truncationonly") + " ";
00122
00123 cmdline += "-usage=";
00124 if (DomUtil::readBoolEntry(dom, "/kdevfortransupport/ftnchek/usageall"))
00125 cmdline += "all ";
00126 else
00127 cmdline += DomUtil::readEntry(dom, "/kdevfortransupport/ftnchek/usageonly") + " ";
00128
00129 cmdline += "-f77=";
00130 if (DomUtil::readBoolEntry(dom, "/kdevfortransupport/ftnchek/f77all"))
00131 cmdline += "all ";
00132 else
00133 cmdline += DomUtil::readEntry(dom, "/kdevfortransupport/ftnchek/f77only") + " ";
00134
00135 cmdline += "-portability=";
00136 if (DomUtil::readBoolEntry(dom, "/kdevfortransupport/ftnchek/portabilityall"))
00137 cmdline += "all ";
00138 else
00139 cmdline += DomUtil::readEntry(dom, "/kdevfortransupport/ftnchek/portabilityonly") + " ";
00140
00141 QStringList list = project()->allFiles();
00142 QStringList::ConstIterator it;
00143 for (it = list.begin(); it != list.end(); ++it) {
00144 QFileInfo fi(*it);
00145 QString extension = fi.extension();
00146 if (extension == "f77" || extension == "f" || extension == "for"
00147 || extension == "ftn") {
00148 cmdline += *it + " ";
00149 }
00150 }
00151
00152 makeFrontend()->queueCommand(QString::null, cmdline);
00153 }
00154
00155
00156 void FortranSupportPart::projectConfigWidget(KDialogBase *dlg)
00157 {
00158 QVBox *vbox = dlg->addVBoxPage(i18n("Ftnchek"));
00159 FtnchekConfigWidget *w = new FtnchekConfigWidget(*projectDom(), vbox, "ftnchek config widget");
00160 connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) );
00161 }
00162
00163
00164 void FortranSupportPart::projectOpened()
00165 {
00166 kdDebug(9019) << "projectOpened()" << endl;
00167
00168 connect( project(), SIGNAL(addedFilesToProject(const QStringList &)),
00169 this, SLOT(addedFilesToProject(const QStringList &)) );
00170 connect( project(), SIGNAL(removedFilesFromProject(const QStringList &)),
00171 this, SLOT(removedFilesFromProject(const QStringList &)) );
00172
00173
00174
00175 parser = new FixedFormParser(codeModel());
00176
00177 QTimer::singleShot(0, this, SLOT(initialParse()));
00178 }
00179
00180
00181 void FortranSupportPart::projectClosed()
00182 {
00183 delete parser;
00184 parser = 0;
00185 }
00186
00187
00188 void FortranSupportPart::maybeParse(const QString fileName)
00189 {
00190 QFileInfo fi(fileName);
00191 QString extension = fi.extension();
00192 if (extension == "f77" || extension == "f" || extension == "for" || extension == "ftn") {
00193
00194 if( codeModel()->hasFile(fileName) ){
00195 emit aboutToRemoveSourceInfo( fileName );
00196 codeModel()->removeFile( codeModel()->fileByName(fileName) );
00197 }
00198
00199 parser->parse(fileName);
00200 }
00201 }
00202
00203
00204 void FortranSupportPart::initialParse()
00205 {
00206 kdDebug(9019) << "initialParse()" << endl;
00207
00208 if (project()) {
00209 kapp->setOverrideCursor(waitCursor);
00210 QStringList files = project()->allFiles();
00211 for (QStringList::Iterator it = files.begin(); it != files.end() ;++it) {
00212 QFileInfo fileInfo( project()->projectDirectory(), *it );
00213 kdDebug(9019) << "maybe parse " << fileInfo.absFilePath() << endl;
00214 maybeParse( fileInfo.absFilePath() );
00215 }
00216
00217 emit updatedSourceInfo();
00218 kapp->restoreOverrideCursor();
00219 } else {
00220 kdDebug(9019) << "No project" << endl;
00221 }
00222 }
00223
00224
00225 void FortranSupportPart::addedFilesToProject(const QStringList &fileList)
00226 {
00227 kdDebug(9019) << "addedFilesToProject()" << endl;
00228
00229 QStringList::ConstIterator it;
00230
00231 for ( it = fileList.begin(); it != fileList.end(); ++it )
00232 {
00233 QFileInfo fileInfo( project()->projectDirectory(), *it );
00234 QString path = fileInfo.absFilePath();
00235 maybeParse( path );
00236 emit addedSourceInfo( path );
00237 }
00238
00239
00240 }
00241
00242
00243 void FortranSupportPart::removedFilesFromProject(const QStringList &fileList)
00244 {
00245 kdDebug(9019) << "removedFilesFromProject()" << endl;
00246
00247 QStringList::ConstIterator it;
00248
00249 for ( it = fileList.begin(); it != fileList.end(); ++it )
00250 {
00251 QFileInfo fileInfo( project()->projectDirectory(), *it );
00252 QString path = fileInfo.absFilePath();
00253
00254 if( codeModel()->hasFile(path) ){
00255 emit aboutToRemoveSourceInfo( path );
00256 codeModel()->removeFile( codeModel()->fileByName(path) );
00257 }
00258 }
00259
00260
00261 }
00262
00263
00264 void FortranSupportPart::savedFile(const KURL &fileName)
00265 {
00266 kdDebug(9019) << "savedFile()" << endl;
00267
00268 if (project()->allFiles().contains(fileName.path().mid ( project()->projectDirectory().length() + 1 ))) {
00269 maybeParse(fileName.path());
00270 emit addedSourceInfo( fileName.path() );
00271 }
00272 }
00273
00274
00275 KDevLanguageSupport::Features FortranSupportPart::features()
00276 {
00277 return Features(Functions);
00278 }
00279
00280 #include "fortransupportpart.moc"