00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "configureoptionswidget.h"
00013
00014 #include <qcombobox.h>
00015 #include <qdir.h>
00016 #include <qfile.h>
00017 #include <qfileinfo.h>
00018 #include <qgroupbox.h>
00019 #include <qlabel.h>
00020 #include <qlineedit.h>
00021 #include <qpushbutton.h>
00022 #include <qtimer.h>
00023 #include <qvalidator.h>
00024 #include <kdebug.h>
00025 #include <kfiledialog.h>
00026 #include <klibloader.h>
00027 #include <klocale.h>
00028 #include <kmessagebox.h>
00029 #include <kservice.h>
00030 #include <ktrader.h>
00031
00032 #include "kdevcompileroptions.h"
00033 #include "autoprojectpart.h"
00034 #include "environmentvariableswidget.h"
00035
00036
00037 class ServiceComboBox
00038 {
00039 public:
00040 static void insertStringList(QComboBox *combo, const QValueList<KService::Ptr> &list,
00041 QStringList *names, QStringList *execs)
00042 {
00043 QValueList<KService::Ptr>::ConstIterator it;
00044 for (it = list.begin(); it != list.end(); ++it) {
00045 combo->insertItem((*it)->comment());
00046 (*names) << (*it)->desktopEntryName();
00047 (*execs) << (*it)->exec();
00048 kdDebug(9020) << "insertStringList item " << (*it)->name() << "," << (*it)->exec() << endl;
00049 }
00050 }
00051 static QString currentText(QComboBox *combo, const QStringList &names)
00052 {
00053 if (combo->currentItem() == -1)
00054 return QString::null;
00055 return names[combo->currentItem()];
00056 }
00057 static void setCurrentText(QComboBox *combo, const QString &str, const QStringList &names)
00058 {
00059 QStringList::ConstIterator it;
00060 int i = 0;
00061 for (it = names.begin(); it != names.end(); ++it) {
00062 if (*it == str) {
00063 combo->setCurrentItem(i);
00064 break;
00065 }
00066 ++i;
00067 }
00068 }
00069 };
00070
00071
00072 ConfigureOptionsWidget::ConfigureOptionsWidget(AutoProjectPart *part, QWidget *parent, const char *name)
00073 : ConfigureOptionsWidgetBase(parent, name)
00074 {
00075 config_combo->setValidator(new QRegExpValidator(QRegExp("^\\D.*"), this));
00076
00077 m_part = part;
00078 env_groupBox->setColumnLayout( 1, Qt::Vertical );
00079 QDomDocument &dom = *part->projectDom();
00080 m_environmentVariablesWidget = new EnvironmentVariablesWidget(dom, "/kdevautoproject/general/envvars", env_groupBox);
00081
00082 coffers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'C'");
00083 cxxoffers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'C++'");
00084 f77offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Fortran'");
00085
00086 ServiceComboBox::insertStringList(cservice_combo, coffers, &cservice_names, &cservice_execs);
00087 ServiceComboBox::insertStringList(cxxservice_combo, cxxoffers, &cxxservice_names, &cxxservice_execs);
00088 ServiceComboBox::insertStringList(f77service_combo, f77offers, &f77service_names, &f77service_execs);
00089
00090 if (coffers.isEmpty())
00091 cflags_button->setEnabled(false);
00092 if (cxxoffers.isEmpty())
00093 cxxflags_button->setEnabled(false);
00094 if (f77offers.isEmpty())
00095 f77flags_button->setEnabled(false);
00096
00097 allConfigs = part->allBuildConfigs();
00098 config_combo->insertStringList(allConfigs);
00099
00100 dirty = false;
00101 currentConfig = QString::null;
00102 configChanged(part->currentBuildConfig());
00103
00104 fixLayout();
00105 }
00106
00107
00108 ConfigureOptionsWidget::~ConfigureOptionsWidget()
00109 {}
00110
00111
00112 void ConfigureOptionsWidget::fixLayout()
00113 {
00114 int w1 = ccompiler_label->sizeHint().width();
00115 int w2 = cbinary_label->sizeHint().width();
00116 int w3 = cflags_label->sizeHint().width();
00117 int w4 = cxxcompiler_label->sizeHint().width();
00118 int w5 = cxxbinary_label->sizeHint().width();
00119 int w6 = cxxflags_label->sizeHint().width();
00120 int w7 = f77compiler_label->sizeHint().width();
00121 int w8 = f77binary_label->sizeHint().width();
00122 int w9 = f77flags_label->sizeHint().width();
00123
00124 int w = QMAX(w1, QMAX(w2, w3));
00125 w = QMAX(w, QMAX(w4, w5));
00126 w = QMAX(w, QMAX(w6, w7));
00127 w = QMAX(w, QMAX(w8, w9));
00128
00129 ccompiler_label->setMinimumWidth(w);
00130 cxxcompiler_label->setMinimumWidth(w);
00131 f77compiler_label->setMinimumWidth(w);
00132 }
00133
00134
00135 void ConfigureOptionsWidget::readSettings(const QString &config)
00136 {
00137 QDomDocument dom = *m_part->projectDom();
00138 QString prefix = "/kdevautoproject/configurations/" + config + "/";
00139 kdDebug(9020) << "Reading config from " << prefix << endl;
00140
00141 configargs_edit->setText(DomUtil::readEntry(dom, prefix + "configargs"));
00142 QString builddir = DomUtil::readEntry(dom, prefix + "builddir");
00143 if (builddir.isEmpty() && config != "default")
00144 builddir = config;
00145 builddir_edit->setText(builddir);
00146
00147 topsourcedir_edit->setText(DomUtil::readEntry(dom, prefix + "topsourcedir"));
00148
00149 cppflags_edit->setText(DomUtil::readEntry(dom, prefix + "cppflags"));
00150 ldflags_edit->setText(DomUtil::readEntry(dom, prefix + "ldflags"));
00151
00152 QString ccompiler = DomUtil::readEntry(dom, prefix + "ccompiler");
00153 QString cxxcompiler = DomUtil::readEntry(dom, prefix + "cxxcompiler");
00154 QString f77compiler = DomUtil::readEntry(dom, prefix + "f77compiler");
00155
00156 if (ccompiler.isEmpty()) {
00157 kdDebug(9020) << "No c compiler set" << endl;
00158 QValueList<KService::Ptr>::ConstIterator it;
00159 for (it = coffers.begin(); it != coffers.end(); ++it) {
00160 if ((*it)->property("X-KDevelop-Default").toBool()) {
00161 kdDebug(9020) << "Found default " << (*it)->name() << endl;
00162 ccompiler = (*it)->name();
00163 break;
00164 }
00165 }
00166 }
00167 if (cxxcompiler.isEmpty()) {
00168 kdDebug(9020) << "No cxx compiler set" << endl;
00169 QValueList<KService::Ptr>::ConstIterator it;
00170 for (it = cxxoffers.begin(); it != cxxoffers.end(); ++it) {
00171 if ((*it)->property("X-KDevelop-Default").toBool()) {
00172 kdDebug(9020) << "Found default " << (*it)->name() << endl;
00173 cxxcompiler = (*it)->name();
00174 break;
00175 }
00176 }
00177 }
00178 if (f77compiler.isEmpty()) {
00179 kdDebug(9020) << "No c compiler set" << endl;
00180 QValueList<KService::Ptr>::ConstIterator it;
00181 for (it = f77offers.begin(); it != f77offers.end(); ++it) {
00182 if ((*it)->property("X-KDevelop-Default").toBool()) {
00183 kdDebug(9020) << "Found default " << (*it)->name() << endl;
00184 f77compiler = (*it)->name();
00185 break;
00186 }
00187 }
00188 }
00189
00190 ServiceComboBox::setCurrentText(cservice_combo, ccompiler, cservice_names);
00191 ServiceComboBox::setCurrentText(cxxservice_combo, cxxcompiler, cxxservice_names);
00192 ServiceComboBox::setCurrentText(f77service_combo, f77compiler, f77service_names);
00193
00194 cbinary_edit->setText(DomUtil::readEntry(dom, prefix + "ccompilerbinary"));
00195 cxxbinary_edit->setText(DomUtil::readEntry(dom, prefix + "cxxcompilerbinary"));
00196 f77binary_edit->setText(DomUtil::readEntry(dom, prefix + "f77compilerbinary"));
00197
00198 cflags_edit->setText(DomUtil::readEntry(dom, prefix + "cflags"));
00199 cxxflags_edit->setText(DomUtil::readEntry(dom, prefix + "cxxflags"));
00200 f77flags_edit->setText(DomUtil::readEntry(dom, prefix + "f77flags"));
00201
00202 m_environmentVariablesWidget->readEnvironment(dom, prefix + "envvars");
00203 }
00204
00205
00206 void ConfigureOptionsWidget::saveSettings(const QString &config)
00207 {
00208 m_environmentVariablesWidget->accept();
00209 QDomDocument dom = *m_part->projectDom();
00210 QString prefix = "/kdevautoproject/configurations/" + config + "/";
00211 kdDebug(9020) << "Saving config under " << prefix << endl;
00212
00213 DomUtil::writeEntry(dom, prefix + "configargs", configargs_edit->text());
00214 DomUtil::writeEntry(dom, prefix + "builddir", builddir_edit->text());
00215 DomUtil::writeEntry(dom, prefix + "topsourcedir", topsourcedir_edit->text());
00216
00217 DomUtil::writeEntry(dom, prefix + "cppflags", cppflags_edit->text());
00218 DomUtil::writeEntry(dom, prefix + "ldflags", ldflags_edit->text());
00219
00220 QFileInfo fi(m_part->buildDirectory());
00221 QDir dir(fi.dir());
00222 dir.mkdir(fi.fileName());
00223
00224 DomUtil::writeEntry(dom, prefix + "ccompiler",
00225 ServiceComboBox::currentText(cservice_combo, cservice_names));
00226 DomUtil::writeEntry(dom, prefix + "cxxcompiler",
00227 ServiceComboBox::currentText(cxxservice_combo, cxxservice_names));
00228 DomUtil::writeEntry(dom, prefix + "f77compiler",
00229 ServiceComboBox::currentText(f77service_combo, f77service_names));
00230
00231 DomUtil::writeEntry(dom, prefix + "ccompilerbinary", cbinary_edit->text());
00232 DomUtil::writeEntry(dom, prefix + "cxxcompilerbinary", cxxbinary_edit->text());
00233 DomUtil::writeEntry(dom, prefix + "f77compilerbinary", f77binary_edit->text());
00234
00235 DomUtil::writeEntry(dom, prefix + "cflags", cflags_edit->text());
00236 DomUtil::writeEntry(dom, prefix + "cxxflags", cxxflags_edit->text());
00237 DomUtil::writeEntry(dom, prefix + "f77flags", f77flags_edit->text());
00238
00239 if (KMessageBox::questionYesNo(this, i18n("Re-run configure for %1 now?").arg(config)) == KMessageBox::Yes)
00240 QTimer::singleShot(0, m_part, SLOT(slotConfigure()));
00241
00242 }
00243
00244
00245 void ConfigureOptionsWidget::setDirty()
00246 {
00247 kdDebug(9020) << "config dirty" << endl;
00248 dirty = true;
00249 }
00250
00251
00252 void ConfigureOptionsWidget::builddirClicked()
00253 {
00254 QString dir = builddir_edit->text();
00255 dir = KFileDialog::getExistingDirectory(dir, this);
00256 if (!dir.isNull())
00257 builddir_edit->setText(dir);
00258 }
00259
00260 void ConfigureOptionsWidget::topsourcedirClicked()
00261 {
00262 QString dir = topsourcedir_edit->text();
00263 dir = KFileDialog::getExistingDirectory(dir, this);
00264 if (!dir.isNull())
00265 topsourcedir_edit->setText(dir);
00266 }
00267
00268 void ConfigureOptionsWidget::configComboTextChanged(const QString &config)
00269 {
00270 bool canAdd = !allConfigs.contains(config) && !config.contains("/") && !config.isEmpty();
00271 bool canRemove = allConfigs.contains(config) && config != "default";
00272 addconfig_button->setEnabled(canAdd);
00273 removeconfig_button->setEnabled(canRemove);
00274 }
00275
00276
00277 void ConfigureOptionsWidget::configChanged(const QString &config)
00278 {
00279 if (config == currentConfig || !allConfigs.contains(config))
00280 return;
00281
00282 if (!currentConfig.isNull() && dirty)
00283 saveSettings(currentConfig);
00284
00285 currentConfig = config;
00286 readSettings(config);
00287 dirty = false;
00288
00289 config_combo->blockSignals(true);
00290 config_combo->setEditText(config);
00291 config_combo->blockSignals(false);
00292 }
00293
00294
00295 void ConfigureOptionsWidget::configAdded()
00296 {
00297 QString config = config_combo->currentText();
00298
00299 allConfigs.append(config);
00300
00301 config_combo->clear();
00302 config_combo->insertStringList(allConfigs);
00303 configChanged(config);
00304 setDirty();
00305 }
00306
00307
00308 void ConfigureOptionsWidget::configRemoved()
00309 {
00310 QString config = config_combo->currentText();
00311
00312 QDomDocument dom = *m_part->projectDom();
00313 QDomNode node = dom.documentElement().namedItem("kdevautoproject").namedItem("configurations");
00314 node.removeChild(node.namedItem(config));
00315 allConfigs.remove(config);
00316
00317 config_combo->clear();
00318 config_combo->insertStringList(allConfigs);
00319
00320 currentConfig = QString::null;
00321 configChanged("default");
00322 }
00323
00324
00325 void ConfigureOptionsWidget::cserviceChanged()
00326 {
00327 QString exec = ServiceComboBox::currentText(cservice_combo, cservice_execs);
00328 cbinary_edit->setText(exec);
00329 kdDebug(9020) << "exec: " << exec << endl;
00330 }
00331
00332
00333 void ConfigureOptionsWidget::cxxserviceChanged()
00334 {
00335 QString exec = ServiceComboBox::currentText(cxxservice_combo, cxxservice_execs);
00336 cxxbinary_edit->setText(exec);
00337 }
00338
00339
00340 void ConfigureOptionsWidget::f77serviceChanged()
00341 {
00342 QString exec = ServiceComboBox::currentText(f77service_combo, f77service_execs);
00343 f77binary_edit->setText(exec);
00344 kdDebug(9020) << "exec: " << exec << endl;
00345 }
00346
00347
00348 void ConfigureOptionsWidget::cflagsClicked()
00349 {
00350 QString name = ServiceComboBox::currentText(cservice_combo, cservice_names);
00351 KDevCompilerOptions *plugin = createCompilerOptions(name);
00352
00353 if (plugin) {
00354 QString flags = plugin->exec(this, cflags_edit->text());
00355 cflags_edit->setText(flags);
00356 delete plugin;
00357 }
00358 }
00359
00360
00361 void ConfigureOptionsWidget::cxxflagsClicked()
00362 {
00363 QString name = ServiceComboBox::currentText(cxxservice_combo, cxxservice_names);
00364 KDevCompilerOptions *plugin = createCompilerOptions(name);
00365
00366 if (plugin) {
00367 QString flags = plugin->exec(this, cxxflags_edit->text());
00368 cxxflags_edit->setText(flags);
00369 delete plugin;
00370 }
00371 }
00372
00373
00374 void ConfigureOptionsWidget::f77flagsClicked()
00375 {
00376 QString name = ServiceComboBox::currentText(f77service_combo, f77service_names);
00377 KDevCompilerOptions *plugin = createCompilerOptions(name);
00378
00379 if (plugin) {
00380 QString flags = plugin->exec(this, f77flags_edit->text());
00381 f77flags_edit->setText(flags);
00382 delete plugin;
00383 }
00384 }
00385
00386
00387 KDevCompilerOptions *ConfigureOptionsWidget::createCompilerOptions(const QString &name)
00388 {
00389 KService::Ptr service = KService::serviceByDesktopName(name);
00390 if (!service) {
00391 kdDebug(9020) << "Can't find service " << name;
00392 return 0;
00393 }
00394
00395 KLibFactory *factory = KLibLoader::self()->factory(QFile::encodeName(service->library()));
00396 if (!factory) {
00397 QString errorMessage = KLibLoader::self()->lastErrorMessage();
00398 KMessageBox::error(0, i18n("There was an error loading the module %1.\n"
00399 "The diagnostics is:\n%2").arg(service->name()).arg(errorMessage));
00400 exit(1);
00401 }
00402
00403 QStringList args;
00404 QVariant prop = service->property("X-KDevelop-Args");
00405 if (prop.isValid())
00406 args = QStringList::split(" ", prop.toString());
00407
00408 QObject *obj = factory->create(this, service->name().latin1(),
00409 "KDevCompilerOptions", args);
00410
00411 if (!obj->inherits("KDevCompilerOptions")) {
00412 kdDebug(9020) << "Component does not inherit KDevCompilerOptions" << endl;
00413 return 0;
00414 }
00415 KDevCompilerOptions *dlg = (KDevCompilerOptions*) obj;
00416
00417 return dlg;
00418 }
00419
00420
00421 void ConfigureOptionsWidget::accept()
00422 {
00423 DomUtil::writeEntry(*m_part->projectDom(), "/kdevautoproject/general/useconfiguration", currentConfig);
00424 m_environmentVariablesWidget->accept();
00425 if (dirty)
00426 {
00427 saveSettings(currentConfig);
00428 }
00429 }
00430
00431 #include "configureoptionswidget.moc"