summaryrefslogtreecommitdiffstats
path: root/src/progs/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/progs/gui')
-rw-r--r--src/progs/gui/Makefile.am6
-rw-r--r--src/progs/gui/debug_config_center.cpp17
-rw-r--r--src/progs/gui/debug_config_center.h28
-rw-r--r--src/progs/gui/hardware_config_widget.cpp204
-rw-r--r--src/progs/gui/hardware_config_widget.h102
-rw-r--r--src/progs/gui/port_selector.cpp144
-rw-r--r--src/progs/gui/port_selector.h52
-rw-r--r--src/progs/gui/prog_config_center.cpp122
-rw-r--r--src/progs/gui/prog_config_center.h56
-rw-r--r--src/progs/gui/prog_config_widget.cpp46
-rw-r--r--src/progs/gui/prog_config_widget.h45
-rw-r--r--src/progs/gui/prog_group_ui.cpp182
-rw-r--r--src/progs/gui/prog_group_ui.h89
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