diff options
Diffstat (limited to 'src/progs/gui')
-rw-r--r-- | src/progs/gui/Makefile.am | 6 | ||||
-rw-r--r-- | src/progs/gui/debug_config_center.cpp | 17 | ||||
-rw-r--r-- | src/progs/gui/debug_config_center.h | 28 | ||||
-rw-r--r-- | src/progs/gui/hardware_config_widget.cpp | 204 | ||||
-rw-r--r-- | src/progs/gui/hardware_config_widget.h | 102 | ||||
-rw-r--r-- | src/progs/gui/port_selector.cpp | 144 | ||||
-rw-r--r-- | src/progs/gui/port_selector.h | 52 | ||||
-rw-r--r-- | src/progs/gui/prog_config_center.cpp | 122 | ||||
-rw-r--r-- | src/progs/gui/prog_config_center.h | 56 | ||||
-rw-r--r-- | src/progs/gui/prog_config_widget.cpp | 46 | ||||
-rw-r--r-- | src/progs/gui/prog_config_widget.h | 45 | ||||
-rw-r--r-- | src/progs/gui/prog_group_ui.cpp | 182 | ||||
-rw-r--r-- | src/progs/gui/prog_group_ui.h | 89 |
13 files changed, 1093 insertions, 0 deletions
diff --git a/src/progs/gui/Makefile.am b/src/progs/gui/Makefile.am new file mode 100644 index 0000000..7b32635 --- /dev/null +++ b/src/progs/gui/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +libprogui_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libprogui.la +libprogui_la_SOURCES = prog_config_widget.cpp prog_group_ui.cpp \ + hardware_config_widget.cpp prog_config_center.cpp port_selector.cpp debug_config_center.cpp diff --git a/src/progs/gui/debug_config_center.cpp b/src/progs/gui/debug_config_center.cpp new file mode 100644 index 0000000..9286e3e --- /dev/null +++ b/src/progs/gui/debug_config_center.cpp @@ -0,0 +1,17 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "debug_config_center.h" + +#include <kiconloader.h> + +QPixmap Debugger::OptionsConfigWidget::pixmap() const +{ + KIconLoader loader; + return loader.loadIcon("piklab_config_debugger", KIcon::Toolbar, KIcon::SizeMedium); +} diff --git a/src/progs/gui/debug_config_center.h b/src/progs/gui/debug_config_center.h new file mode 100644 index 0000000..a8e496e --- /dev/null +++ b/src/progs/gui/debug_config_center.h @@ -0,0 +1,28 @@ +/*************************************************************************** + * Copyright (C) 2007 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. * + ***************************************************************************/ +#ifndef DEBUG_CONFIG_CENTER_H +#define DEBUG_CONFIG_CENTER_H + +#include <qcheckbox.h> + +#include "common/gui/config_widget.h" +#include "progs/base/debug_config.h" + +namespace Debugger +{ + +BEGIN_DECLARE_CONFIG_WIDGET(Config, OptionsConfigWidget) + virtual QString header() const { return i18n("Debugging Options"); } + virtual QString title() const { return i18n("Debugging Options"); } + virtual QPixmap pixmap() const; +END_DECLARE_CONFIG_WIDGET + +} // namespace + +#endif diff --git a/src/progs/gui/hardware_config_widget.cpp b/src/progs/gui/hardware_config_widget.cpp new file mode 100644 index 0000000..8d82ddb --- /dev/null +++ b/src/progs/gui/hardware_config_widget.cpp @@ -0,0 +1,204 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.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 "hardware_config_widget.h" + +#include <qlabel.h> +#include <kpushbutton.h> + +#include "progs/base/prog_config.h" +#include "devices/base/device_group.h" +#include "common/gui/misc_gui.h" + +//----------------------------------------------------------------------------- +Hardware::HConfigWidget::HConfigWidget(::Programmer::Base &base, QWidget *parent, bool edit) + : QFrame(parent, "hardware_config_widget"), _edit(edit), _connected(false), _base(base) +{ + _hardware = 0; + + QHBoxLayout *top = new QHBoxLayout(this, 0, 10); + _mainVBox = new QVBoxLayout(top); + + if (edit) { + _editVBox = new QVBoxLayout(top); + top->setStretchFactor(_editVBox, 1); + } else _editVBox = 0; +} + +//----------------------------------------------------------------------------- +Hardware::EditDialog::EditDialog(ConfigWidget *cwidget, const QString &name, const Port::Description &pd, Data *data) + : KDialogBase(Plain, i18n("Edit and test hardware"), Ok|Cancel, Cancel, cwidget, "hardware_edit_dialog", true, true), + _cwidget(cwidget), _savedName(name), _oldData(data) +{ + setButtonOK(i18n("Save")); + setButtonCancel(i18n("Close")); + + QGridLayout *grid = new QGridLayout(plainPage(), 1, 1, 0, 10); + grid->setColStretch(2, 1); + + QLabel *label = new QLabel(i18n("Hardware name:"), plainPage()); + grid->addWidget(label, 0, 0); + _name = new QLineEdit(name, plainPage()); + grid->addWidget(_name, 0, 1); + + label = new QLabel(i18n("%1 at %2:").arg(pd.type.label()).arg(pd.device), plainPage()); + grid->addWidget(label, 1, 0); + label = new QLabel(plainPage()); + grid->addWidget(label, 1, 1); + + _hc = cwidget->createHardwareConfigWidget(plainPage(), true); + grid->addMultiCellWidget(_hc, 2,2, 0,2); + + grid->setRowStretch(3, 1); + + bool ok = _hc->set(pd, *data); + label->setText(ok ? i18n("Connected") : i18n("Not Connected")); +} + +void Hardware::EditDialog::slotOk() +{ + if ( _name->text().isEmpty() ) { + MessageBox::sorry(i18n("Could not save configuration: hardware name is empty."), Log::Show); + return; + } + if ( _cwidget->_config->isStandardHardware(_name->text()) ) { + MessageBox::sorry(i18n("The hardware name is already used for a standard hardware."), Log::Show); + return; + } + QStringList names = _cwidget->_config->hardwareNames(PortType::Nb_Types); // all hardwares + if ( names.contains(_name->text()) ) { + if ( !MessageBox::askContinue(i18n("Do you want to overwrite this custom hardware \"%1\"?").arg(_name->text()), + KStdGuiItem::save()) ) return; + } + delete _oldData; + _oldData = _hc->data(); + _cwidget->_config->writeCustomHardware(_name->text(), *_oldData); + _savedName = _name->text(); + KDialogBase::accept(); +} + +void Hardware::EditDialog::slotCancel() +{ + Data *data = _hc->data(); + bool equal = _oldData->isEqual(*data); + delete data; + if ( !equal && !MessageBox::askContinue(i18n("Closing will discard changes you have made. Close anyway?"), KStdGuiItem::close()) ) + return; + KDialogBase::reject(); +} + +//----------------------------------------------------------------------------- +Hardware::ConfigWidget::ConfigWidget(::Programmer::Base *base, Config *config, QWidget *parent) + : ::Programmer::ConfigWidget(base->group(), parent), _base(base), _config(config), _hc(0) +{ +// programmer combo + uint row = numRows(); + _configCombo = new QComboBox(this); + connect(_configCombo, SIGNAL(activated(int)), SLOT(configChanged(int))); + addWidget(_configCombo, row,row, 0,0); + row++; + +// hardware config + QHBoxLayout *hbox = new QHBoxLayout(10); + _hbox = new QHBoxLayout(10); + hbox->addLayout(_hbox); + addLayout(hbox, row,row, 0,1); + row++; + +// comment + _comment = new KTextBrowser(this); + addWidget(_comment, row,row, 0,1); + row++; + +// buttons + QVBoxLayout *vbox = new QVBoxLayout(hbox); + _editButton = new KPushButton(this); + connect(_editButton, SIGNAL(clicked()), SLOT(editClicked())); + vbox->addWidget(_editButton); + _deleteButton = new KPushButton(i18n("Delete"), this); + connect(_deleteButton, SIGNAL(clicked()), SLOT(deleteClicked())); + vbox->addWidget(_deleteButton); + vbox->addStretch(1); +} + +void Hardware::ConfigWidget::saveConfig() +{ + ::Programmer::ConfigWidget::saveConfig(); + _config->writeCurrentHardware(_hc->portDescription().type, _names[_configCombo->currentItem()]); +} + +void Hardware::ConfigWidget::configChanged(int i) +{ + set(_hc->portDescription(), i); +} + +bool Hardware::ConfigWidget::set(const Port::Description &pd, uint i) +{ + Data *hd = _config->hardwareData(_names[i]); + if ( _hc==0 ) { + _hc = createHardwareConfigWidget(this, false); + _hc->show(); + _hbox->addWidget(_hc); + } + bool ok = _hc->set(pd, *hd); + delete hd; + QString s = _config->comment(_names[i]); + if ( s.isEmpty() ) _comment->hide(); + else { + _comment->setText(s); + _comment->show(); + } + bool custom = !_config->isStandardHardware(_names[i]); + _editButton->setText(custom ? i18n("Edit/Test...") : i18n("New/Test...")); + _deleteButton->setEnabled(custom); + return ok; +} + +bool Hardware::ConfigWidget::setPort(const ::Programmer::HardwareDescription &hd) +{ + updateList(hd.port.type); + int i = _names.findIndex(_config->currentHardware(hd.port.type)); + if ( i!=-1 ) _configCombo->setCurrentItem(i); + return set(hd.port, _configCombo->currentItem()); +} + +void Hardware::ConfigWidget::updateList(PortType type) +{ + _configCombo->clear(); + _names = _config->hardwareNames(type); + for (uint i=0; i<_names.count(); i++) { + bool standard = _config->isStandardHardware(_names[i]); + QString s = (standard ? _config->label(_names[i]) : i18n("%1 <custom>").arg(_names[i])); + _configCombo->insertItem(s); + } +} + +void Hardware::ConfigWidget::editClicked() +{ + QString name = _names[_configCombo->currentItem()]; + QString cname = (_config->isStandardHardware(name) ? QString::null : name); + Port::Description pd = _hc->portDescription(); + EditDialog *hcd = new EditDialog(this, cname, pd, _hc->data()); + int res = hcd->exec(); + if ( res==QDialog::Rejected ) return; + updateList(pd.type); + int index = _names.findIndex(hcd->savedName()); + _configCombo->setCurrentItem(index); + configChanged(_configCombo->currentItem()); +} + +void Hardware::ConfigWidget::deleteClicked() +{ + QString name = _names[_configCombo->currentItem()]; + if ( !MessageBox::askContinue(i18n("Do you want to delete custom hardware \"%1\"?").arg(name), + KStdGuiItem::del()) ) return; + _config->deleteCustomHardware(name); + updateList(_hc->portDescription().type); + configChanged(_configCombo->currentItem()); +} diff --git a/src/progs/gui/hardware_config_widget.h b/src/progs/gui/hardware_config_widget.h new file mode 100644 index 0000000..d373990 --- /dev/null +++ b/src/progs/gui/hardware_config_widget.h @@ -0,0 +1,102 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> * + * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.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. * + ***************************************************************************/ +#ifndef HARDWARE_CONFIG_WIDGET +#define HARDWARE_CONFIG_WIDGET + +#include <qlineedit.h> +#include <qcombobox.h> +#include <kdialogbase.h> +#include <ktextbrowser.h> + +#include "progs/base/hardware_config.h" +#include "progs/gui/prog_config_widget.h" +#include "progs/base/generic_prog.h" +#include "progs/base/prog_specific.h" + +namespace Hardware +{ + +//----------------------------------------------------------------------------- +class HConfigWidget : public QFrame +{ +Q_OBJECT +public: + HConfigWidget(::Programmer::Base &base, QWidget *parent, bool edit); + virtual ~HConfigWidget() { delete _hardware; } + virtual bool set(const Port::Description &pd, const Data &data) = 0; + virtual Data *data() const = 0; + Port::Description portDescription() const { return _hardware->portDescription(); } + +protected: + ::Programmer::Hardware *_hardware; + QVBoxLayout *_mainVBox, *_editVBox; + bool _edit, _connected; + ::Programmer::Base &_base; +}; + +//----------------------------------------------------------------------------- +class ConfigWidget; + +class EditDialog : public KDialogBase +{ +Q_OBJECT +public: + EditDialog(ConfigWidget *parent, const QString &name, const Port::Description &pd, Data *data); + QString savedName() const { return _savedName; } + +private slots: + virtual void slotOk(); + virtual void slotCancel(); + +private: + ConfigWidget *_cwidget; + QString _savedName; + Data *_oldData; + HConfigWidget *_hc; + QLineEdit *_name; +}; + +//----------------------------------------------------------------------------- +class ConfigWidget : public ::Programmer::ConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(::Programmer::Base *base, Config *config, QWidget *parent); + virtual ~ConfigWidget() { delete _base; } + virtual void saveConfig(); + virtual bool setPort(const ::Programmer::HardwareDescription &hd); + virtual HConfigWidget *createHardwareConfigWidget(QWidget *parent, bool edit) const = 0; + +private slots: + void editClicked(); + void deleteClicked(); + void configChanged(int i); + +protected: + ::Programmer::Base *_base; + +private: + Config *_config; + QStringList _names; + HConfigWidget *_hc; + QPushButton *_editButton, *_deleteButton; + QComboBox *_configCombo; + KTextBrowser *_comment; + QHBoxLayout *_hbox; + + void updateList(PortType type); + bool set(const Port::Description &pd, uint i); + + friend class EditDialog; +}; + +} // namespace + +#endif diff --git a/src/progs/gui/port_selector.cpp b/src/progs/gui/port_selector.cpp new file mode 100644 index 0000000..2aaaabf --- /dev/null +++ b/src/progs/gui/port_selector.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** + * 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 "port_selector.h" + +#include <qtimer.h> +#include <ktextbrowser.h> + +#include "common/port/serial.h" +#include "common/port/parallel.h" +#include "common/global/about.h" +#include "common/gui/purl_gui.h" +#include "progs/base/prog_config.h" + +const char * const PortSelector::LABELS[PortType::Nb_Types] = { + I18N_NOOP("Serial"), I18N_NOOP("Parallel"), I18N_NOOP("USB") +}; + +PortSelector::PortSelector(QWidget *parent) + : QFrame(parent, "port_selector"), _group(0), _main(0) +{ + _top = new QGridLayout(this, 1, 1, 0, 10); + _top->setRowStretch(1, 1); + + _bgroup = new QButtonGroup; + connect(_bgroup, SIGNAL(clicked(int)), SIGNAL(changed())); +} + +void PortSelector::setGroup(const Programmer::Group &group) +{ + _group = &group; + delete _main; + _main = new QWidget(this); + _top->addWidget(_main, 0, 0); + _grid = new QGridLayout(_main, 1, 1, 0, 10); + _grid->setColStretch(3, 1); + FOR_EACH(PortType, type) { + _combos[type.type()] = 0; + _status[type.type()] = 0; + if ( !group.isPortSupported(type) ) continue; + Port::Description pd(type, Programmer::GroupConfig::portDevice(group, type)); + addPortType(pd); + } + _bgroup->setButton(Programmer::GroupConfig::portType(group).type()); + _main->show(); +} + +void PortSelector::addPortType(const Port::Description &pd) +{ + QString noDeviceMessage, notAvailableMessage; + switch (pd.type.type()) { + case PortType::Serial: + noDeviceMessage = i18n("Your computer might not have any serial port."); + break; + case PortType::Parallel: + noDeviceMessage = i18n("Your computer might not have any parallel port " + "or the /dev/parportX device has not been created.<br>" + "Use \"mknod /dev/parport0 c 99 0\" to create it<br>" + "and \"chmod a+rw /dev/parport0\" to make it RW enabled."); + notAvailableMessage = i18n("Piklab has been compiled without support for parallel port."); + break; + case PortType::USB: + notAvailableMessage = i18n("Piklab has been compiled without support for USB port."); + break; + case PortType::Nb_Types: Q_ASSERT(false); break; + } + + QRadioButton *rb = new QRadioButton(i18n(LABELS[pd.type.type()]), _main); + _bgroup->insert(rb, pd.type.type()); + if ( _bgroup->count()==1 ) _bgroup->setButton(pd.type.type()); + _grid->addWidget(rb, 3*(_bgroup->count()-1), 0); + _status[pd.type.type()] = new QLabel(_main); + _grid->addWidget(_status[pd.type.type()], 3*(_bgroup->count()-1), 2); + + QStringList list = Port::probedDeviceList(pd.type); + bool noDevice = ( list.isEmpty() && pd.type.data().withDevice ); + bool notAvailable = !Port::isAvailable(pd.type); + rb->setEnabled(!notAvailable); + if ( noDevice || notAvailable ) { + KTextBrowser *comment = new KTextBrowser(_main); + QString text = (notAvailable ? notAvailableMessage : noDeviceMessage); + text += "<p>"; + text += i18n("<a href=\"%1\">See Piklab homepage for help</a>.").arg(Piklab::URLS[Piklab::Support]); + comment->setText(text); + _grid->addMultiCellWidget(comment, 3*(_bgroup->count()-1)+1,3*(_bgroup->count()-1)+1, 0,3); + } + + if (pd.type.data().withDevice) { + _combos[pd.type.type()] = new QComboBox(true, _main); + for (uint i=0; i<list.count(); i++) _combos[pd.type.type()]->insertItem(list[i]); + if ( !pd.device.isEmpty() && !list.contains(pd.device) ) _combos[pd.type.type()]->insertItem(pd.device); + _combos[pd.type.type()]->setCurrentText(pd.device); + connect(_combos[pd.type.type()], SIGNAL(activated(int)), SIGNAL(changed())); + connect(_combos[pd.type.type()], SIGNAL(textChanged(const QString &)), SLOT(textChanged())); + _grid->addWidget(_combos[pd.type.type()], 3*(_bgroup->count()-1), 1); + } +} + +void PortSelector::setStatus(PortType ptype, const QString &message) +{ + _pending = false; + FOR_EACH(PortType, type) { + if ( _status[type.type()]==0 ) continue; + if ( type!=ptype ) _status[type.type()]->hide(); + else { + _status[type.type()]->show(); + _status[type.type()]->setText(message); + } + } +} + +QString PortSelector::device(PortType type) const +{ + if ( type==PortType::Nb_Types || _combos[type.type()]==0 || !type.data().withDevice ) return QString::null; + return _combos[type.type()]->currentText(); +} + +void PortSelector::saveConfig() +{ + Programmer::GroupConfig::writePortType(*_group, type()); + FOR_EACH(PortType, type) { + if ( !_group->isPortSupported(type) ) continue; + Programmer::GroupConfig::writePortDevice(*_group, type, device(type)); + } +} + +PortType PortSelector::type() const +{ + if ( _bgroup->count()==0 ) return PortType::Nb_Types; + return PortType::Type(_bgroup->selectedId()); +} + +void PortSelector::textChanged() +{ + if (_pending) return; + _status[type().type()]->hide(); + _pending = true; + QTimer::singleShot(1000, this, SIGNAL(changed())); +} diff --git a/src/progs/gui/port_selector.h b/src/progs/gui/port_selector.h new file mode 100644 index 0000000..6304d1a --- /dev/null +++ b/src/progs/gui/port_selector.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2005 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. * + ***************************************************************************/ +#ifndef PORT_SELECTOR_H +#define PORT_SELECTOR_H + +#include <qradiobutton.h> +#include <qcombobox.h> +#include <qlayout.h> +#include <qbuttongroup.h> +#include <qlabel.h> + +#include "common/port/port.h" +namespace Programmer { class Group; } + +class PortSelector : public QFrame +{ + Q_OBJECT +public: + PortSelector(QWidget *parent); + void setGroup(const Programmer::Group &group); + Port::Description portDescription() const { return Port::Description(type(), device(type())); } + void saveConfig(); + void setStatus(PortType type, const QString &message); + +signals: + void changed(); + +private slots: + void textChanged(); + +private: + const Programmer::Group *_group; + QGridLayout *_top, *_grid; + QWidget *_main; + QButtonGroup *_bgroup; + QComboBox *_combos[PortType::Nb_Types]; + QLabel *_status[PortType::Nb_Types]; + bool _pending; + static const char * const LABELS[PortType::Nb_Types]; + + void addPortType(const Port::Description &pd); + PortType type() const; + QString device(PortType type) const; +}; + +#endif diff --git a/src/progs/gui/prog_config_center.cpp b/src/progs/gui/prog_config_center.cpp new file mode 100644 index 0000000..3210921 --- /dev/null +++ b/src/progs/gui/prog_config_center.cpp @@ -0,0 +1,122 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 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 "prog_config_center.h" + +#include <qlayout.h> +#include <qlabel.h> +#include <qwidgetstack.h> +#include <qcombobox.h> +#include <qcheckbox.h> +#include <qtimer.h> +#include <qtabwidget.h> +#include <kiconloader.h> + +#include "progs/list/prog_list.h" +#include "prog_config_widget.h" +#include "prog_group_ui.h" +#include "libgui/global_config.h" +#include "port_selector.h" +#include "libgui/main_global.h" + +//---------------------------------------------------------------------------- +QPixmap Programmer::OptionsConfigWidget::pixmap() const +{ + KIconLoader loader; + return loader.loadIcon("piklab_config_programmer", KIcon::Toolbar, KIcon::SizeMedium); +} + +//---------------------------------------------------------------------------- +Programmer::SelectConfigWidget::SelectConfigWidget() +{ + uint row = 0; + +// programmer type + QLabel *label = new QLabel(i18n("Programmer in use:"), this); + addWidget(label, row,row, 0,0); + _combo = new KeyComboBox<QString>(this); + connect(_combo->widget(), SIGNAL(activated(int)), SLOT(programmerChanged())); + addWidget(_combo->widget(), row,row, 1,1); + row++; + +// tab widget + _tabWidget = new QTabWidget(this); + addWidget(_tabWidget, row,row, 0,2); + row++; + + // port selector + _portSelectorContainer = new Container; + _portSelectorContainer->setMargin(10); + _portSelector = new PortSelector(_portSelectorContainer); + connect(_portSelector, SIGNAL(changed()), SLOT(portChanged())); + _portSelectorContainer->addWidget(_portSelector, 0,0, 0,0); + + // specific programmer config + _stack = new KeyWidgetStack<QString>(_tabWidget); + static_cast<QFrame *>(_stack->widget())->setMargin(10); + KIconLoader loader; + QPixmap icon = loader.loadIcon("configure", KIcon::Small); + _tabWidget->addTab(_stack->widget(), icon, i18n("Specific")); + ::Programmer::Lister::ConstIterator it; + for (it=::Programmer::lister().begin(); it!=::Programmer::lister().end(); ++it) { + _combo->appendItem(it.key(), it.data()->label()); + ::Programmer::ConfigWidget *pcw = static_cast<const ::Programmer::GroupUI *>(it.data()->gui())->createConfigWidget(_stack->widget()); + pcw->loadConfig(); + _stack->appendItem(it.key(), pcw); + } + + // init + _combo->setCurrentItem(GlobalConfig::programmerGroup().name()); + _stack->setCurrentItem(GlobalConfig::programmerGroup().name()); + QTimer::singleShot(0, this, SLOT(programmerChanged())); +} + +void Programmer::SelectConfigWidget::portChanged() +{ + ::BusyCursor bc; // can take a few seconds to connect programmer... + HardwareDescription hd; + hd.port = _portSelector->portDescription(); + ::Hardware::Config *config = Main::programmerGroup().hardwareConfig(); + if (config) hd.name = config->currentHardware(hd.port.type); + delete config; + QWidget *w = _stack->item(_combo->currentItem()); + bool ok = static_cast< ::Programmer::ConfigWidget *>(w)->setPort(hd); + _portSelector->setStatus(hd.port.type, ok ? i18n("Connection: Ok") : i18n("Connection: Error")); +} + +QPixmap Programmer::SelectConfigWidget::pixmap() const +{ + KIconLoader loader; + return loader.loadIcon("piklab_config_programmer", KIcon::Toolbar, KIcon::SizeMedium); +} + +void Programmer::SelectConfigWidget::saveConfig() +{ + _portSelector->saveConfig(); + QString key = _combo->currentItem(); + static_cast<ConfigWidget *>(_stack->item(key))->saveConfig(); + GlobalConfig::writeProgrammerGroup(*::Programmer::lister().group(key)); +} + +void Programmer::SelectConfigWidget::programmerChanged() +{ + QString key = _combo->currentItem(); + const ::Programmer::Group &group = *::Programmer::lister().group(key); + bool isHardware = !group.isSoftware(); + bool hasTab = ( _tabWidget->indexOf(_portSelectorContainer)!=-1 ); + if (isHardware) { + if ( !hasTab ) { + KIconLoader loader; + QPixmap icon = loader.loadIcon("connect_creating", KIcon::Small); + _tabWidget->insertTab(_portSelectorContainer, icon, i18n("Port Selection"), 0); + } + } else if (hasTab) _tabWidget->removePage(_portSelectorContainer); + _portSelector->setGroup(group); + _stack->setCurrentItem(key); + if (isHardware) QTimer::singleShot(0, this, SLOT(portChanged())); +} diff --git a/src/progs/gui/prog_config_center.h b/src/progs/gui/prog_config_center.h new file mode 100644 index 0000000..ea5ee6d --- /dev/null +++ b/src/progs/gui/prog_config_center.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2005 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. * + ***************************************************************************/ +#ifndef PROG_CONFIG_CENTER_H +#define PROG_CONFIG_CENTER_H + +#include <qcheckbox.h> + +#include "common/gui/config_widget.h" +#include "common/gui/key_gui.h" +#include "progs/base/prog_config.h" +class Container; +class PortSelector; + +namespace Programmer +{ +BEGIN_DECLARE_CONFIG_WIDGET(Config, OptionsConfigWidget) + virtual QString header() const { return i18n("Programmer Options"); } + virtual QString title() const { return i18n("Programmer Options"); } + virtual QPixmap pixmap() const; +END_DECLARE_CONFIG_WIDGET + +//---------------------------------------------------------------------------- +class SelectConfigWidget : public ::ConfigWidget +{ +Q_OBJECT +public: + SelectConfigWidget(); + virtual void loadConfig() {} + virtual QString header() const { return i18n("Programmer Selection"); } + virtual QString title() const { return i18n("Programmer Selection"); } + virtual QPixmap pixmap() const; + +public slots: + virtual void saveConfig(); + +private slots: + void programmerChanged(); + void portChanged(); + +private: + KeyComboBox<QString> *_combo; + PortSelector *_portSelector; + KeyWidgetStack<QString> *_stack; + Container *_portSelectorContainer; + QTabWidget *_tabWidget; +}; + +} // namespace + +#endif diff --git a/src/progs/gui/prog_config_widget.cpp b/src/progs/gui/prog_config_widget.cpp new file mode 100644 index 0000000..be767c2 --- /dev/null +++ b/src/progs/gui/prog_config_widget.cpp @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2005 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 "prog_config_widget.h" + +#include <qlayout.h> +#include <qlabel.h> +#include <qcombobox.h> +#include <qcheckbox.h> +#include <kurlrequester.h> + +#include "progs/base/prog_config.h" +#include "progs/base/prog_group.h" + +Programmer::ConfigWidget::ConfigWidget(const Group &group, QWidget *parent) + : ::ConfigWidget(parent), _group(group) +{ + if ( group.properties() & NeedDeviceSpecificFirmware ) { + uint row = numRows(); + QLabel *label = new QLabel(i18n("Firmware directory:"), this); + addWidget(label, row,row, 0,0); + _firmwareDir = new KURLRequester(this); + _firmwareDir->setMode(KFile::Directory | KFile::ExistingOnly); + addWidget(_firmwareDir, row,row, 1,1); + } else _firmwareDir = 0; +} + +void Programmer::ConfigWidget::loadConfig() +{ + if (_firmwareDir) _firmwareDir->setURL(GroupConfig::firmwareDirectory(_group)); +} + +void Programmer::ConfigWidget::saveConfig() +{ + if (_firmwareDir) GroupConfig::writeFirmwareDirectory(_group, _firmwareDir->url()); +} + +bool Programmer::ConfigWidget::setPort(const HardwareDescription &hd) +{ + return _group.checkConnection(hd); +} diff --git a/src/progs/gui/prog_config_widget.h b/src/progs/gui/prog_config_widget.h new file mode 100644 index 0000000..d201cea --- /dev/null +++ b/src/progs/gui/prog_config_widget.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2005 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. * + ***************************************************************************/ +#ifndef PROG_CONFIG_WIDGET +#define PROG_CONFIG_WIDGET + +class QCheckBox; +class KURLRequester; + +#include "common/gui/config_widget.h" +#include "common/port/port.h" + +namespace Programmer +{ +class Group; +class HardwareDescription; + +class ConfigWidget: public ::ConfigWidget +{ +Q_OBJECT +public: + ConfigWidget(const Group &group, QWidget *parent); + virtual void loadConfig(); + const Group &group() const { return _group; } + virtual void saveConfig(); + virtual bool setPort(const HardwareDescription &hd); + +signals: + void updatePortStatus(bool ok); + +protected: + const Group &_group; + +private: + KURLRequester *_firmwareDir; +}; + +} // namespace + +#endif diff --git a/src/progs/gui/prog_group_ui.cpp b/src/progs/gui/prog_group_ui.cpp new file mode 100644 index 0000000..14cf7b0 --- /dev/null +++ b/src/progs/gui/prog_group_ui.cpp @@ -0,0 +1,182 @@ +/*************************************************************************** + * Copyright (C) 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 "prog_group_ui.h" + +#include <klocale.h> +#include <kaction.h> +#include <kiconloader.h> + +#include "common/common/misc.h" +#include "common/global/purl.h" +#include "common/gui/purl_gui.h" +#include "progs/base/generic_prog.h" +#include "progs/base/prog_group.h" +#include "progs/base/prog_config.h" +#include "libgui/main_global.h" +#include "libgui/toplevel.h" +#include "devices/base/device_group.h" +#include "devices/pic/prog/pic_prog.h" + +//---------------------------------------------------------------------------- +Programmer::StandaloneMemoryCalibrationEditor::StandaloneMemoryCalibrationEditor(const Pic::Memory &memory, QWidget *parent) + : Pic::MemoryCalibrationEditor(0, const_cast<Pic::Memory &>(memory), parent) +{} + +void Programmer::StandaloneMemoryCalibrationEditor::init(bool first) +{ + Pic::MemoryCalibrationEditor::init(first); + KAction *action = new KAction(i18n("Read"), "reload", 0, this, SIGNAL(updateCalibration()), Main::toplevel().actionCollection()); + addAction(action); + action = new KAction(i18n("Regenerating..."), 0, 0, this, SIGNAL(regenerate()), Main::toplevel().actionCollection()); + addAction(action); +} + +//---------------------------------------------------------------------------- +Programmer::ButtonContainer::ButtonContainer(const QString &title, + QObject *receiver, const char *updateSlot, QWidget *parent) + : ::ButtonContainer(title, parent) +{ + if (receiver) button().appendAction(i18n("Read"), "reload", receiver, updateSlot); +} + +//---------------------------------------------------------------------------- +Programmer::AdvancedDialog::AdvancedDialog(Base &base, QWidget *parent, const char *name) + : Dialog(IconList, i18n("Advanced Dialog"), Close, Close, parent, name, true, false), + _base(base), _calEditor(0) +{ + // programmer + KIconLoader loader; + QPixmap pixmap = loader.loadIcon("piklab_burnchip", KIcon::Toolbar, KIcon::SizeMedium); + QFrame *page = addPage(i18n("Programmer"), _base.group().label(), pixmap); + QVBoxLayout *vbox = new QVBoxLayout(page); + _programmerContainer = new Container(page); + vbox->addWidget(_programmerContainer); + + Properties properties = _base.group().properties(); + uint row = _programmerContainer->numRows(); + if ( properties & HasFirmware ) { + _firmwareContainer = new ButtonContainer(i18n("Firmware"), this, SLOT(updateFirmware()), _programmerContainer); + _programmerContainer->addWidget(_firmwareContainer, row,row, 0,1); + if ( _base.group().properties() & CanUploadFirmware ) + _firmwareContainer->button().appendAction(i18n("Uploading..."), "piklab_burnchip", this, SLOT(uploadFirmware())); + QLabel *label = new QLabel(i18n("Version:"), _firmwareContainer); + _firmwareContainer->addWidget(label, 1,1, 0,0); + _firmwareLabel = new QLabel(_firmwareContainer); + _firmwareContainer->addWidget(_firmwareLabel, 1,1, 1,1); + row++; + } else { + _firmwareContainer = 0; + _firmwareLabel = 0; + } + + if ( _base.group().canReadVoltages() ) { + _voltagesContainer = new ButtonContainer(i18n("Voltages"), this, SLOT(updateVoltages()), _programmerContainer); + _programmerContainer->addWidget(_voltagesContainer, row,row, 0,1); + row++; + } else _voltagesContainer = 0; + + if ( properties & HasSelfTest ) { + _selfTestContainer = new ButtonContainer(i18n("Self-test"), this, SLOT(updateSelfTest()), _programmerContainer); + _programmerContainer->addWidget(_selfTestContainer, row,row, 0,1); + row++; + } else _selfTestContainer = 0; + + // calibration + pixmap = loader.loadIcon("configure", KIcon::Toolbar, KIcon::SizeMedium); + page = addPage(i18n("Calibration"), i18n("Calibration"), pixmap); + vbox = new QVBoxLayout(page); + _calibrationContainer = new Container(page); + vbox->addWidget(_calibrationContainer); + const Device::Data *data = Main::deviceData(); + QString s; + if ( data==0 ) s = i18n("No device selected."); + else if ( data->group().name()!="pic" || !static_cast<const Pic::Data *>(data)->isReadable(Pic::MemoryRangeType::Cal) ) + s = i18n("This device has no calibration information."); + else if ( !_base.group().isSupported(data->name()) ) s = i18n("The selected device is not supported by this programmer."); + else { + const ::Programmer::PicBase &pbase = static_cast<const ::Programmer::PicBase &>(_base); + _calEditor = new StandaloneMemoryCalibrationEditor(pbase.deviceMemory(), _calibrationContainer); + connect(_calEditor, SIGNAL(updateCalibration()), SLOT(updateCalibration())); + connect(_calEditor, SIGNAL(regenerate()), SLOT(regenerateCalibration())); + _calEditor->init(true); + _calEditor->setReadOnly(true); + _calibrationContainer->addWidget(_calEditor, 0,0, 0,0); + } + if ( !s.isEmpty() ) { + QLabel *label = new QLabel(s, _calibrationContainer); + _calibrationContainer->addWidget(label, 0,0, 0,0); + } +} + +bool Programmer::AdvancedDialog::connectProgrammer() +{ + _base.disconnectHardware(); + if ( !_base.connectHardware() ) { + MessageBox::sorry(i18n("Could not connect programmer."), Log::Show); + return false; + } + return true; +} + +bool Programmer::AdvancedDialog::ensureConnected() +{ + if ( (_base.state()==NotConnected || _base.state()==Running) && !connectProgrammer() ) return false; + return _base.setTargetPowerOn(!readConfigEntry(Config::TargetSelfPowered).toBool()); +} + +void Programmer::AdvancedDialog::updateFirmware() +{ + ::BusyCursor bc; + if ( ensureConnected() ) _base.readFirmwareVersion(); + updateDisplay(); +} + +void Programmer::AdvancedDialog::uploadFirmware() +{ + PURL::Url url = PURL::getOpenUrl(":open_firmware", PURL::filter(PURL::Hex), this ,i18n("Open Firmware")); + if ( url.isEmpty() ) return; + ::BusyCursor bc; + if ( !connectProgrammer() ) return; + if ( _base.uploadFirmware(url) ) + MessageBox::information(i18n("Firmware uploaded successfully."), Log::Show); + else MessageBox::sorry(i18n("Error uploading firmware."), Log::Show); + updateFirmware(); +} + +void Programmer::AdvancedDialog::updateVoltages() +{ + ::BusyCursor bc; + if ( ensureConnected() ) _base.readVoltages(); + updateDisplay(); +} + +void Programmer::AdvancedDialog::updateSelfTest() +{ + ::BusyCursor bc; + if ( ensureConnected() ) _base.selfTest(false); + updateDisplay(); +} + +void Programmer::AdvancedDialog::updateCalibration() +{ + ::BusyCursor bc; + if ( ensureConnected() ) static_cast< ::Programmer::PicBase &>(_base).readCalibration(); + updateDisplay(); +} + +void Programmer::AdvancedDialog::regenerateCalibration() +{ + MessageBox::sorry(i18n("Oscillator calibration regeneration is not available with the selected programmer."), Log::Show); +} + +void Programmer::AdvancedDialog::updateDisplay() +{ + if (_firmwareLabel) _firmwareLabel->setText(_base.firmwareVersion().pretty()); + if (_calEditor) _calEditor->updateDisplay(); +} diff --git a/src/progs/gui/prog_group_ui.h b/src/progs/gui/prog_group_ui.h new file mode 100644 index 0000000..cd97834 --- /dev/null +++ b/src/progs/gui/prog_group_ui.h @@ -0,0 +1,89 @@ +/*************************************************************************** + * 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. * + ***************************************************************************/ +#ifndef PROG_GROUP_UI_H +#define PROG_GROUP_UI_H + +#include "common/gui/container.h" +#include "common/gui/dialog.h" +#include "progs/base/prog_group.h" +#include "progs/base/generic_prog.h" +#include "devices/pic/gui/pic_memory_editor.h" +class Container; +class PopupButton; + +namespace Programmer +{ +class ConfigWidget; +class Base; +class Group; + +//---------------------------------------------------------------------------- +class StandaloneMemoryCalibrationEditor : public Pic::MemoryCalibrationEditor +{ +Q_OBJECT +public: + StandaloneMemoryCalibrationEditor(const Pic::Memory &memory, QWidget *parent); + virtual void init(bool first); + virtual bool hasAction(Device::Action) const { return false; } + +signals: + void updateCalibration(); + void regenerate(); +}; + +//---------------------------------------------------------------------------- +class ButtonContainer : public ::ButtonContainer +{ +Q_OBJECT +public: + ButtonContainer(const QString &title, QObject *receiver, const char *updateSlot, QWidget *parent); +}; + +//---------------------------------------------------------------------------- +class AdvancedDialog : public Dialog +{ +Q_OBJECT +public: + AdvancedDialog(Base &base, QWidget *parent, const char *name); + virtual void updateDisplay(); + +protected: + Base &_base; + Container *_programmerContainer, *_calibrationContainer; + ButtonContainer *_firmwareContainer, *_voltagesContainer, *_selfTestContainer; + Pic::MemoryCalibrationEditor *_calEditor; + bool connectProgrammer(); + bool ensureConnected(); + +protected slots: + void updateFirmware(); + void uploadFirmware(); + void updateVoltages(); + void updateSelfTest(); + void updateCalibration(); + virtual void regenerateCalibration(); + +private: + QLabel *_firmwareLabel; +}; + +//---------------------------------------------------------------------------- +class GroupUI : public ::Group::BaseGui +{ +public: + virtual ::Programmer::ConfigWidget *createConfigWidget(QWidget *parent) const = 0; + virtual bool hasAdvancedDialog() const = 0; + virtual AdvancedDialog *createAdvancedDialog(Base &base, QWidget *parent) const = 0; +}; + +inline const ::Programmer::GroupUI &groupui(const ::Programmer::Base &base) { return static_cast<const ::Programmer::GroupUI &>(*base.group().gui()); } + +} // namespace + +#endif |