/*************************************************************************** * Copyright (C) 2002 by Yann Hodique * * Yann.Hodique@lifl.fr * * * * 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. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include "generalinfowidget.h" #include "generalinfowidget.moc" #include "domutil.h" #include "projectmanager.h" TQString makeRelativePath(const TQString& fromPath, const TQString& toPath); GeneralInfoWidget::GeneralInfoWidget(TQDomDocument &projectDom, TQWidget *parent, const char *name) : GeneralInfoWidgetBase(parent, name), m_projectDom(projectDom) { connect(project_directory_edit, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(slotProjectDirectoryChanged(const TQString&))); connect(project_directory_combo, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotProjectDirectoryComboChanged())); readConfig(); } GeneralInfoWidget::~GeneralInfoWidget() {} void GeneralInfoWidget::readConfig() { if(DomUtil::readBoolEntry(m_projectDom,"/general/absoluteprojectpath",false)) this->project_directory_combo->setCurrentItem(0); else this->project_directory_combo->setCurrentItem(1); this->project_directory_edit->setText(DomUtil::readEntry(m_projectDom,"/general/projectdirectory",".")); this->author_edit->setText(DomUtil::readEntry(m_projectDom,"/general/author")); this->email_edit->setText(DomUtil::readEntry(m_projectDom,"/general/email")); this->version_edit->setText(DomUtil::readEntry(m_projectDom,"/general/version")); this->description_edit->setText(DomUtil::readEntry(m_projectDom,"/general/description")); TQStringList encodings; encodings << i18n("Use global editor settings"); encodings += TDEGlobal::charsets()->descriptiveEncodingNames(); TQStringList::const_iterator it = encodings.constBegin(); while ( it != encodings.constEnd() ) { encoding_combo->insertItem( *it ); ++it; } encoding_combo->setCurrentItem( 0 ); // const TQString DefaultEncoding = TDEGlobal::charsets()->encodingForName( DomUtil::readEntry( m_projectDom, "/general/defaultencoding", TQString() ) ); const TQString DefaultEncoding = DomUtil::readEntry( m_projectDom, "/general/defaultencoding", TQString() ); for ( int i = 0; i < encoding_combo->count(); i++ ) { if ( TDEGlobal::charsets()->encodingForName( encoding_combo->text( i ) ) == DefaultEncoding ) { encoding_combo->setCurrentItem( i ); break; } } } /** * Update the configure.in, configure.in or configure.ac file with the version value from project options. * Very basic updating - uses regex to update the field in * AC_INIT, AM_INIT_AUTOMAKE, and AC_DEFINE macros. * On next make, the build system re-runs configure to update config.h * version info. * * @param configureinpath Full path to configure.in file * @param newVersion The new version number or string */ void GeneralInfoWidget::configureinUpdateVersion( TQString configureinpath, TQString newVersion ) { TQFile configurein(configureinpath); if ( !configurein.open( IO_ReadOnly ) ){ KMessageBox::error(this, i18n("Could not open %1 for reading.").arg(configureinpath)); return; } TQTextStream stream( &configurein); TQStringList list; // Options for version: // we ignore old AC_INIT that had no version.. // only match the if there is a comma and at least two args.. // AC_INIT (package, version, [bug-report], [tarname]) TQRegExp ac_init("^AC_INIT\\s*\\(\\s*([^,]+),([^,\\)]+)(.*)"); // AM_INIT_AUTOMAKE([OPTIONS]) // example: AM_INIT_AUTOMAKE([gnits 1.5 no-define dist-bzip2]) TQRegExp am_autoSpace("^AM_INIT_AUTOMAKE\\s{0,}\\(\\s{0,}([\\[\\s]{0,}[^\\s]+)\\s+([^\\s\\)\\]]+)(.*)"); // AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) TQRegExp am_autoComma("^AM_INIT_AUTOMAKE\\s*\\(\\s*([^,]+),([^,\\)]+)(.*)"); // look for version in a define. // AC_DEFINE(VERSION, "5.6") TQRegExp ac_define("^AC_DEFINE\\s*\\("); TQRegExp version("(\\bversion\\b)"); version.setCaseSensitive(FALSE); while ( !stream.eof() ) { TQString line = stream.readLine(); if ( ac_init.search(line) >= 0){ line = "AC_INIT(" + ac_init.cap(1).stripWhiteSpace(); line += ", "; line += newVersion; line += ac_init.cap(3).stripWhiteSpace(); } else if ( am_autoComma.search(line) >= 0 ){ line="AM_INIT_AUTOMAKE("; line += am_autoComma.cap(1).stripWhiteSpace(); line += ", "; line += newVersion; line += am_autoComma.cap(3).stripWhiteSpace(); } else if ( am_autoSpace.search(line) >= 0 ){ line = "AM_INIT_AUTOMAKE(" + am_autoSpace.cap(1).stripWhiteSpace(); line += " "; line += newVersion; line += " "; line += am_autoSpace.cap(3).stripWhiteSpace(); } else if ( ac_define.search(line) >=0 && version.search(line) >=0) { // replace version in: AC_DEFINE(VERSION,"0.1") line="AC_DEFINE(" + version.cap(1).stripWhiteSpace()+", \"" + newVersion +"\")"; } list.push_back(line); } configurein.close(); // write our changes.. TQFile configureout(configureinpath); if ( !configureout.open( IO_WriteOnly ) ){ KMessageBox::error(this, i18n("Could not open %1 for writing.").arg(configureinpath)); return ; } TQTextStream output( &configureout); for(TQStringList::iterator iter = list.begin();iter!=list.end();iter++){ output << (*iter) <<"\n"; } configureout.close(); } void GeneralInfoWidget::writeConfig() { DomUtil::writeEntry(m_projectDom,"/general/projectdirectory",project_directory_edit->text()); DomUtil::writeBoolEntry(m_projectDom,"/general/absoluteprojectpath",isProjectDirectoryAbsolute()); DomUtil::writeEntry(m_projectDom,"/general/email",email_edit->text()); DomUtil::writeEntry(m_projectDom,"/general/author",author_edit->text()); DomUtil::writeEntry(m_projectDom,"/general/email",email_edit->text()); if ( DomUtil::readEntry(m_projectDom,"/general/version") != version_edit->text() && !DomUtil::elementByPath( m_projectDom, "/kdevautoproject").isNull() ){ // update the configure.in.in, configure.in or configure.ac file. TQFile inInFile(projectDirectory() + "/configure.in.in"); TQFile inFile(projectDirectory() + "/configure.in"); TQFile acFile(projectDirectory() + "/configure.ac"); if ( inInFile.exists()){ configureinUpdateVersion( inInFile.name(), version_edit->text() ); } if ( inFile.exists()){ configureinUpdateVersion( inFile.name(), version_edit->text() ); } if (acFile.exists()){ configureinUpdateVersion( acFile.name(), version_edit->text() ); } if (! inInFile.exists()&& !inFile.exists() && !acFile.exists()) { KMessageBox::error(this, i18n("Could not find configure.in.in, configure.in or configure.ac to update the project version.")); } } DomUtil::writeEntry(m_projectDom,"/general/version",version_edit->text()); DomUtil::writeEntry(m_projectDom,"/general/description",description_edit->text()); TQString DefaultEncoding = TQString(); if ( encoding_combo->currentItem() > 0 ) { DefaultEncoding = TDEGlobal::charsets()->encodingForName( encoding_combo->currentText() ); } DomUtil::writeEntry( m_projectDom, "/general/defaultencoding", DefaultEncoding ); } void GeneralInfoWidget::accept() { writeConfig(); } bool GeneralInfoWidget::isProjectDirectoryAbsolute() { return project_directory_combo->currentItem() == 0; } TQString GeneralInfoWidget::projectDirectory() { return ProjectManager::projectDirectory( project_directory_edit->text(), isProjectDirectoryAbsolute() ); } void GeneralInfoWidget::slotProjectDirectoryChanged( const TQString& text ) { if(text.isEmpty()) { setProjectDirectoryError(i18n("Please enter a path.")); } else if(isProjectDirectoryAbsolute() && text[0] != '/') { setProjectDirectoryError( i18n("'%1' is not an absolute path.").arg( project_directory_edit->text())); } else if(!isProjectDirectoryAbsolute() && text[0] == '/') { setProjectDirectoryError( i18n("'%1' is not a relative path.").arg( project_directory_edit->text())); } else { TQFileInfo info(projectDirectory()); if(!info.exists()) setProjectDirectoryError( i18n("'%1' does not exist.").arg( project_directory_edit->text())); else if(!info.isDir()) setProjectDirectoryError( i18n("'%1' is not a directory.").arg( project_directory_edit->text())); else setProjectDirectorySuccess(); } } void GeneralInfoWidget::slotProjectDirectoryComboChanged() { TQString text = project_directory_edit->text(); if(isProjectDirectoryAbsolute() && text[0] != '/' ) project_directory_edit->setText(ProjectManager::projectDirectory(text,false)); else if(!isProjectDirectoryAbsolute() && text[0] == '/') { project_directory_edit->setText(KURL(ProjectManager::getInstance()->projectFile(), text).url()); } } void GeneralInfoWidget::setProjectDirectoryError( const TQString& error ) { project_directory_diagnostic_icon->setPixmap(SmallIcon("no")); project_directory_diagnostic_label->setText( error ); } void GeneralInfoWidget::setProjectDirectorySuccess() { project_directory_diagnostic_icon->setPixmap(SmallIcon("ok")); if(isProjectDirectoryAbsolute()) project_directory_diagnostic_label->setText( i18n("'%1' is a valid project directory.").arg(projectDirectory())); else project_directory_diagnostic_label->setText( i18n("'%1' is a valid project directory.").arg(projectDirectory())); } TQString makeRelativePath(const TQString& fromPath, const TQString& toPath) { if ( fromPath == toPath ) return "."; TQStringList fromDirs = TQStringList::split( '/', fromPath ); TQStringList toDirs = TQStringList::split( '/', toPath ); TQStringList::iterator fromIt = fromDirs.begin(); TQStringList::iterator toIt = toDirs.begin(); TQString relative; for ( ; (*fromIt) == (*toIt); ++fromIt, ++toIt ) ; for ( ; fromIt != fromDirs.end(); ++fromIt ) relative += "../"; for ( ; toIt != toDirs.end(); ++toIt ) relative += *toIt + "/"; return relative; }