You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
piklab/src/tools/gui/toolchain_config_widget.cpp

302 lines
11 KiB

/***************************************************************************
* Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> *
* *
* 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 "toolchain_config_widget.h"
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqtooltip.h>
#include <tqgroupbox.h>
#include <tqtabwidget.h>
#include <kiconloader.h>
#include <ktextedit.h>
#include "tools/list/compile_config.h"
#include "common/gui/purl_gui.h"
#include "common/global/process.h"
#include "common/gui/container.h"
//----------------------------------------------------------------------------
ToolchainConfigWidget::ToolchainConfigWidget(const Tool::Group &group, TQWidget *parent)
: ::ConfigWidget(parent),
_group(group), _dirty(false), _outputType(0), _devicesData(group.nbCheckDevices())
{
_config = group.createConfig(0);
}
ToolchainConfigWidget::~ToolchainConfigWidget()
{
delete _config;
}
void ToolchainConfigWidget::init()
{
Container *container = new Container(this, Container::Sunken);
addWidget(container, 0,0, 0,3);
container->setColStretch(3, 1);
uint row = 0;
TQLabel *label = new TQLabel(Compile::DirectoryType(Compile::DirectoryType::Executable).label() + ":", container);
container->addWidget(label, row,row, 0,0);
_dirs[Compile::DirectoryType::Executable] = new PURL::DirectoryWidget(container);
connect(_dirs[Compile::DirectoryType::Executable], TQ_SIGNAL(changed()), TQ_SLOT(forceDetect()));
container->addWidget(_dirs[Compile::DirectoryType::Executable], row,row, 1,3);
row++;
label = new TQLabel(i18n("Executable Type:"), container);
container->addWidget(label, row,row, 0,0);
_execType = new TQComboBox(container);
FOR_EACH(Tool::ExecutableType, type) _execType->insertItem(type.label());
connect(_execType, TQ_SIGNAL(activated(int)), TQ_SLOT(forceDetect()));
container->addWidget(_execType, row,row, 1,2);
row++;
uint nbOutputTypes = 0;
FOR_EACH(Tool::OutputExecutableType, type)
if ( _group.hasOutputExecutableType(type) ) nbOutputTypes++;
if ( nbOutputTypes>1 ) {
label = new TQLabel(i18n("Output Executable Type:"), container);
container->addWidget(label, row,row, 0,0);
_outputType = new KeyComboBox<Tool::OutputExecutableType>(container);
FOR_EACH(Tool::OutputExecutableType, type)
if ( _group.hasOutputExecutableType(type) ) _outputType->appendItem(type, type.label());
connect(_outputType->widget(), TQ_SIGNAL(activated(int)), TQ_SLOT(forceDetect()));
container->addWidget(_outputType->widget(), row,row, 1,1);
row++;
}
addCustomExecutableOptions(container);
FOR_EACH(Tool::Category, k) {
const Tool::Base *base = _group.base(k);
if ( base==0 ) continue;
label = new TQLabel(k.label(), container);
container->addWidget(label, row,row, 0,0);
_data[k].label = new TQLabel(container);
container->addWidget(_data[k].label, row,row, 1,1);
_data[k].button = new KPushButton(KGuiItem(TQString(), "viewmag"), container);
connect(_data[k].button, TQ_SIGNAL(clicked()), TQ_SLOT(showDetails()));
container->addWidget(_data[k].button, row,row, 2,2);
row++;
}
label = new TQLabel(i18n("Device detection:"), container);
container->addWidget(label, row,row, 0,0);
_devicesLabel = new TQLabel(container);
container->addWidget(_devicesLabel, row,row, 1,1);
KPushButton *button = new KPushButton(KGuiItem(TQString(), "viewmag"), container);
connect(button, TQ_SIGNAL(clicked()), TQ_SLOT(showDeviceDetails()));
container->addWidget(button, row,row, 2,2);
row++;
row = numRows();
FOR_EACH(Compile::DirectoryType, type) {
if ( type==Compile::DirectoryType::Executable ) continue;
if ( !_group.hasDirectory(type) ) _dirs[type] = 0;
else {
label = new TQLabel(type.label() + ":", this);
addWidget(label, row,row, 0,0);
_dirs[type] = new PURL::DirectoryWidget(this);
addWidget(_dirs[type], row,row, 1,3);
row++;
}
}
if ( !_group.comment().isEmpty() ) {
KTextEdit *w = new KTextEdit(_group.comment(), TQString(), this);
w->setReadOnly(true);
w->setWordWrap(TQTextEdit::WidgetWidth);
addWidget(w, row,row, 0,3);
row++;
}
setColStretch(3, 1);
}
void ToolchainConfigWidget::loadConfig()
{
_execType->blockSignals(true);
_execType->setCurrentItem(Compile::Config::withWine(_group) ? Tool::ExecutableType::Windows : Tool::ExecutableType::Unix);
_execType->blockSignals(false);
if (_outputType) {
_outputType->widget()->blockSignals(true);
_outputType->setCurrentItem(Compile::Config::outputExecutableType(_group));
_outputType->widget()->blockSignals(false);
}
FOR_EACH(Compile::DirectoryType, type) {
if ( _dirs[type]==0 ) continue;
_dirs[type]->blockSignals(true);
_dirs[type]->setDirectory(Compile::Config::directory(_group, type));
_dirs[type]->blockSignals(false);
}
_dirty = true;
}
void ToolchainConfigWidget::saveConfig()
{
Compile::Config::setWithWine(_group, withWine());
if (_outputType) Compile::Config::setOutputExecutableType(_group, outputType());
FOR_EACH(Compile::DirectoryType, type)
if ( _dirs[type] ) Compile::Config::setDirectory(_group, type, _dirs[type]->directory());
}
void ToolchainConfigWidget::forceDetect()
{
_dirty = true;
detect();
}
void ToolchainConfigWidget::checkExecutableDone()
{
FOR_EACH(Tool::Category, i) {
if ( _data[i].process!=sender() ) continue;
if ( _data[i].process->state()==::Process::Timedout ) {
_data[i].label->setText(i18n("Timeout"));
return;
}
_data[i].checkLines = _data[i].process->sout() + _data[i].process->serr();
const Tool::Base *base = _group.base(i);
TQString exec = base->baseExecutable(withWine(), outputType());
if ( base->checkExecutableResult(withWine(), _data[i].checkLines) ) _data[i].label->setText(i18n("\"%1\" found").arg(exec));
else _data[i].label->setText(i18n("\"%1\" not recognized").arg(exec));
break;
}
}
void ToolchainConfigWidget::checkDevicesDone()
{
for(uint i=0; i<_devicesData.count(); i++) {
if ( _devicesData[i].process!=sender() ) continue;
if ( _devicesData[i].process->state()==::Process::Timedout ) {
_devicesLabel->setText(i18n("Timeout"));
return;
}
_devicesData[i].checkLines = _devicesData[i].process->sout() + _devicesData[i].process->serr();
_devicesData[i].done = true;
break;
}
TQValueList<const Device::Data *> list;
for(uint i=0; i<_devicesData.count(); i++) {
if ( !_devicesData[i].done ) return;
list += _group.getSupportedDevices(_devicesData[i].checkLines.join("\n"));
}
_devicesLabel->setText(i18n("Detected (%1)").arg(list.count()));
}
bool ToolchainConfigWidget::withWine() const
{
return ( _execType->currentItem()==Tool::ExecutableType::Windows );
}
Tool::OutputExecutableType ToolchainConfigWidget::outputType() const
{
return (_outputType==0 ? Compile::Config::outputExecutableType(_group) : _outputType->currentItem());
}
TQString ToolchainConfigWidget::baseExecutable(Tool::Category category) const
{
return _group.base(category)->baseExecutable(withWine(), outputType());
}
::Process::LineOutput *ToolchainConfigWidget::checkExecutableProcess(Tool::Category category) const
{
PURL::Directory execDir = _dirs[Compile::DirectoryType::Executable]->directory();
return _group.base(category)->checkExecutableProcess(execDir, withWine(), outputType());
}
::Process::LineOutput *ToolchainConfigWidget::checkDevicesProcess(uint i) const
{
PURL::Directory execDir = _dirs[Compile::DirectoryType::Executable]->directory();
return _group.checkDevicesProcess(i, execDir, withWine());
}
void ToolchainConfigWidget::detect()
{
if ( !_dirty ) return;
FOR_EACH(Tool::Category, k) {
if ( _data[k].label==0 ) continue;
if ( !_group.base(k)->checkExecutable() ) _data[k].label->setText(i18n("Unknown"));
else {
delete _data[k].process;
_data[k].checkLines.clear();
_data[k].process = checkExecutableProcess(k);
_data[k].command = _data[k].process->prettyCommand();
connect(_data[k].process, TQ_SIGNAL(done(int)), TQ_SLOT(checkExecutableDone()));
connect(_data[k].process, TQ_SIGNAL(timeout()), TQ_SLOT(checkExecutableDone()));
TQString exec = baseExecutable(k);
if ( !_data[k].process->start(10000) ) _data[k].label->setText(i18n("\"%1\" not found").arg(exec));
else _data[k].label->setText(i18n("Detecting \"%1\"...").arg(exec));
}
}
if ( _group.checkDevicesCategory()==Tool::Category::Nb_Types ) {
TQValueVector<TQString> supported = _group.supportedDevices();
_devicesLabel->setText(i18n("Hardcoded (%1)").arg(supported.count()));
} else {
for (uint i=0; i<_devicesData.count(); i++) {
delete _devicesData[i].process;
_devicesData[i].process = checkDevicesProcess(i);
_devicesData[i].command = _devicesData[i].process->prettyCommand();
connect(_devicesData[i].process, TQ_SIGNAL(done(int)), TQ_SLOT(checkDevicesDone()));
connect(_devicesData[i].process, TQ_SIGNAL(timeout()), TQ_SLOT(checkDevicesDone()));
_devicesData[i].done = false;
_devicesData[i].checkLines.clear();
if ( !_devicesData[i].process->start(10000) ) _devicesLabel->setText(i18n("Failed"));
else _devicesLabel->setText(i18n("Detecting ..."));
}
}
FOR_EACH(Compile::DirectoryType, type) {
if ( _dirs[type]==0 || type==Compile::DirectoryType::Executable ) continue;
PURL::Directory execDir = _dirs[Compile::DirectoryType::Executable]->directory();
PURL::Directory dir = _group.autodetectDirectory(type, execDir, withWine());
if ( !dir.isEmpty() ) _dirs[type]->setDirectory(dir);
}
_dirty = false;
}
void ToolchainConfigWidget::showDetails()
{
FOR_EACH(Tool::Category, k) {
if ( sender()!=_data[k].button ) continue;
TQString s;
const Tool::Base *base = _group.base(k);
if ( base->checkExecutable() ) {
s += i18n("<qt><b>Command for executable detection:</b><br>%1<br>").arg(_data[k].command);
s += i18n("<b>Version string:</b><br>%1<br></qt>").arg(_data[k].checkLines.join("<br>"));
} else s += i18n("This tool cannot be automatically detected.");
MessageBox::text(s, Log::Show);
break;
}
}
void ToolchainConfigWidget::showDeviceDetails()
{
TQString s;
if ( _group.checkDevicesCategory()==Tool::Category::Nb_Types ) {
s += "<qt>";
TQValueVector<TQString> supported = _group.supportedDevices();
for (uint i=0; i<supported.count(); i++) {
if ( i!=0 ) {
if ( (i%10)==0 ) s += "<br>";
s += " ";
}
s += supported[i];
}
s += "</qt>";
} else {
uint nb = _group.nbCheckDevices();
for (uint i=0; i<nb; i++) {
if ( nb==1 ) s += i18n("<qt><b>Command for devices detection:</b><br>%1<br>").arg(_devicesData[i].command);
else s += i18n("<qt><b>Command #%1 for devices detection:</b><br>%2<br>").arg(i+1).arg(_devicesData[i].command);
TQString ss = _devicesData[i].checkLines.join("<br>");
if ( nb==1 ) s += i18n("<b>Device string:</b><br>%1<br>").arg(ss);
else s += i18n("<b>Device string #%1:</b><br>%2<br>").arg(i+1).arg(ss);
}
}
MessageBox::text(s, Log::Show);
}