/*************************************************************************** * Copyright (C) 2005-2006 Nicolas Hadacek * * * * 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 "device_gui.h" #include #include #include #include #include #include #include #include #include #include #include "devices/list/device_list.h" #include "devices/base/device_group.h" #include "devices/gui/device_group_ui.h" #include "progs/list/prog_list.h" #include "tools/list/device_info.h" #include "tools/list/tool_list.h" namespace DeviceChooser { //----------------------------------------------------------------------------- void DeviceChooser::Config::writeProgrammerGroup(const Programmer::Group *group) { writeEntry("programmer", group ? group->name() : TQString()); } const Programmer::Group *DeviceChooser::Config::programmerGroup() { TQString name = readEntry("programmer", TQString()); return Programmer::lister().group(name); } void DeviceChooser::Config::writeToolGroup(const Tool::Group *group) { writeEntry("tool", group ? group->name() : TQString()); } const Tool::Group *DeviceChooser::Config::toolGroup() { TQString name = readEntry("tool", TQString()); return Tool::lister().group(name); } //----------------------------------------------------------------------------- class ListItem : public KListViewItem { public: ListItem(KListView *list, const TQString &name, bool selectable, bool isDevice) : KListViewItem(list, name), _device(isDevice) { setSelectable(selectable); } ListItem(KListViewItem *item, const TQString &name) : KListViewItem(item, name), _device(true) {} bool isDevice() const { return _device; } virtual void paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int align) { TQColorGroup ncg = cg; if (_device) { const Device::Data *device = Device::lister().data(text(0)); Q_ASSERT(device); ncg.setColor(TQColorGroup::Text, Device::statusColor(device->status())); } KListViewItem::paintCell(p, ncg, column, width, align); } private: bool _device; }; } // namespace //----------------------------------------------------------------------------- const DeviceChooser::ListType::Data DeviceChooser::ListType::DATA[Nb_Types] = { { "family_tree", I18N_NOOP("Family Tree") }, { "flat", I18N_NOOP("Flat List") } }; DeviceChooser::Dialog::Dialog(const TQString &device, Type type, TQWidget *tqparent) : ::Dialog(tqparent, "device_chooser_dialog", true, i18n("Select a device"), Ok|Close, Close, false, TQSize(400, 300)), _withAuto(type==ChooseWithAuto) { setButtonOK(KGuiItem(i18n( "&Select"), "button_ok")); TQVBoxLayout *top = new TQVBoxLayout(mainWidget(), 0, 10); // view TQHBoxLayout *hbox = new TQHBoxLayout(top, 10); TQVBoxLayout *vbox = new TQVBoxLayout(hbox); _listTypeCombo = new EnumComboBox("list_type", mainWidget()); connect(_listTypeCombo->combo(), TQT_SIGNAL(activated(int)), TQT_SLOT(updateList())); vbox->addWidget(_listTypeCombo->combo()); TQPushButton *button = new KPushButton(KGuiItem(i18n("Reset Filters"), "reload"), mainWidget()); connect(button, TQT_SIGNAL(clicked()), TQT_SLOT(resetFilters())); vbox->addWidget(button); vbox->addStretch(1); // filters TQFrame *frame = new TQFrame(mainWidget()); frame->setFrameStyle(TQFrame::Panel | TQFrame::Raised); frame->setMargin(5); hbox->addWidget(frame); hbox = new TQHBoxLayout(frame, 10, 10); TQLabel *label = new TQLabel(i18n("Filters:"), frame); hbox->addWidget(label); vbox = new TQVBoxLayout(hbox); TQHBoxLayout *shbox = new TQHBoxLayout(vbox); // programmer filter _programmerCombo = new KeyComboBox(frame); _programmerCombo->appendItem("", i18n("")); Programmer::Lister::ConstIterator pit; for (pit=Programmer::lister().begin(); pit!=Programmer::lister().end(); ++pit) _programmerCombo->appendItem(pit.key(), pit.data()->label()); Config config; const Programmer::Group *pgroup = config.programmerGroup(); if (pgroup) _programmerCombo->setCurrentItem(pgroup->name()); connect(_programmerCombo->widget(), TQT_SIGNAL(activated(int)), TQT_SLOT(updateList())); shbox->addWidget(_programmerCombo->widget()); // tool filter _toolCombo = new KeyComboBox(frame); _toolCombo->appendItem("", i18n("")); Tool::Lister::ConstIterator tit; for (tit=Tool::lister().begin(); tit!=Tool::lister().end(); ++tit) { if ( tit.data()->isCustom() ) continue; _toolCombo->appendItem(tit.key(), tit.data()->label()); } const Tool::Group *tgroup = config.toolGroup(); if (tgroup) _toolCombo->setCurrentItem(tgroup->name()); connect(_toolCombo->widget(), TQT_SIGNAL(activated(int)), TQT_SLOT(updateList())); shbox->addWidget(_toolCombo->widget()); // memory filter _memoryCombo = new EnumComboBox(i18n(""), "memory_technology", frame); connect(_memoryCombo->combo(), TQT_SIGNAL(activated(int)), TQT_SLOT(updateList())); shbox->addWidget(_memoryCombo->combo()); shbox->addStretch(1); shbox = new TQHBoxLayout(vbox); // status filter _statusCombo = new EnumComboBox(i18n(""), "status", frame); connect(_statusCombo->combo(), TQT_SIGNAL(activated(int)), TQT_SLOT(updateList())); shbox->addWidget(_statusCombo->combo()); // features filter _featureCombo = new EnumComboBox(i18n(""), "feature", frame); connect(_featureCombo->combo(), TQT_SIGNAL(activated(int)), TQT_SLOT(updateList())); shbox->addWidget(_featureCombo->combo()); shbox->addStretch(1); // list view TQValueList widths; widths += 80; widths += 500; Splitter *splitter = new Splitter(widths,Qt::Horizontal, mainWidget(), "device_shooser_splitter"); top->addWidget(splitter, 1); _listView = new KListView(splitter); connect(_listView, TQT_SIGNAL(currentChanged(TQListViewItem *)), TQT_SLOT(currentChanged(TQListViewItem *))); connect(_listView, TQT_SIGNAL(doubleClicked(TQListViewItem *, const TQPoint &, int)), TQT_SLOT(listDoubleClicked(TQListViewItem *))); _listView->setAllColumnsShowFocus(true); _listView->setRootIsDecorated(true); _listView->setSorting(-1); _listView->addColumn(i18n("Device")); _listView->setResizeMode(TQListView::LastColumn); // device view _deviceView = new View(splitter); connect(_deviceView, TQT_SIGNAL(deviceChanged(const TQString &)), TQT_SLOT(deviceChange(const TQString &))); updateList(device); } DeviceChooser::Dialog::~Dialog() { Config config; config.writeProgrammerGroup(programmerGroup()); config.writeToolGroup(toolGroup()); _listTypeCombo->writeConfig(); _memoryCombo->writeConfig(); _statusCombo->writeConfig(); _featureCombo->writeConfig(); } TQString DeviceChooser::Dialog::device() const { TQListViewItem *item = _listView->selectedItem(); if ( item==0 || !static_cast(item)->isDevice() ) return Device::AUTO_DATA.name; return item->text(0); } void DeviceChooser::Dialog::listDoubleClicked(TQListViewItem *item) { if ( item==0 ) return; if ( !static_cast(item)->isDevice() ) item->setOpen(!item->isOpen()); else accept(); } void DeviceChooser::Dialog::currentChanged(TQListViewItem *item) { if ( item==0 || !static_cast(item)->isDevice() ) _deviceView->clear(); else _deviceView->setDevice(item->text(0), false); } void DeviceChooser::Dialog::deviceChange(const TQString &name) { TQListViewItemIterator it(_listView); for (; it.current(); ++it) if ( it.current()->text(0)==name ) { _listView->setSelected(it.current(), true); _listView->ensureItemVisible(it.current()); break; } } void DeviceChooser::Dialog::resetFilters() { _programmerCombo->setCurrentItem(""); _toolCombo->setCurrentItem(""); _memoryCombo->reset(); _statusCombo->reset(); _featureCombo->reset(); updateList(); } void DeviceChooser::Dialog::updateList() { TQListViewItem *item = _listView->selectedItem(); TQString device = (item ? item->text(0) : TQString()); _listView->clear(); updateList(device); } const Programmer::Group *DeviceChooser::Dialog::programmerGroup() const { return Programmer::lister().group(_programmerCombo->currentItem()); } const Tool::Group *DeviceChooser::Dialog::toolGroup() const { return Tool::lister().group(_toolCombo->currentItem()); } void DeviceChooser::Dialog::updateList(const TQString &device) { TQValueVector list = Device::lister().supportedDevices(); TQMap groups; TQListViewItem *selected = 0; const Programmer::Group *pgroup = programmerGroup(); if ( pgroup && pgroup->supportedDevices().isEmpty() && pgroup->isSoftware() ) { _deviceView->setText(i18n("Could not detect supported devices for \"%1\". Please check installation.").tqarg(pgroup->label())); return; } const Tool::Group *tgroup = toolGroup(); if ( tgroup && tgroup->supportedDevices().isEmpty() ) { _deviceView->setText(i18n("Could not detect supported devices for toolchain \"%1\". Please check installation.").tqarg(tgroup->label())); return; } for (int i=list.count()-1; i>=0; i--) { if ( pgroup && !pgroup->isSupported(list[i]) ) continue; if ( tgroup && !tgroup->isSupported(list[i]) ) continue; const Device::Data *data = Device::lister().data(list[i]); Q_ASSERT(data); if ( _memoryCombo->value()!=Device::MemoryTechnology::Nb_Types && data->memoryTechnology()!=_memoryCombo->value() ) continue; if ( _statusCombo->value()!=Device::tqStatus::Nb_Types && data->status()!=_statusCombo->value() ) continue; if ( _featureCombo->value()!=Pic::Feature::Nb_Types ) { if ( data->group().name()!="pic" ) continue; if ( !static_cast(data)->hasFeature(_featureCombo->value()) ) continue; } KListViewItem *item = 0; switch (_listTypeCombo->value().type()) { case ListType::FamilyTree: { TQString gname = data->listViewGroup(); if ( !groups.tqcontains(gname) ) groups[gname] = new ListItem(_listView, gname, false, false); item = new ListItem(groups[gname], list[i]); break; } case ListType::Flat: item = new ListItem(_listView, list[i], true, true); break; case ListType::Nb_Types: Q_ASSERT(false); break; } if ( device==list[i] ) selected = item; } if (_withAuto) (void)new ListItem(_listView, i18n(Device::AUTO_DATA.label), true, false); if ( selected==0 ) selected = _listView->firstChild(); if (selected) { _listView->setSelected(selected, true); _listView->ensureItemVisible(selected); currentChanged(selected); } } //----------------------------------------------------------------------------- DeviceChooser::ComboBox::ComboBox(bool withAuto, TQWidget *tqparent) : TQComboBox(tqparent, "device_chooser_combo"), _withAuto(withAuto) { if (withAuto) insertItem(i18n(Device::AUTO_DATA.label)); Device::Lister::ConstIterator it; for (it=Device::lister().begin(); it!=Device::lister().end(); ++it) { TQValueVector devices = it.data()->supportedDevices(); qHeapSort(devices); for (uint k=0; kname() + " " + i18n(Device::AUTO_DATA.label), 0); else changeItem(i18n(Device::AUTO_DATA.label), 0); setCurrentItem(0); } else setCurrentText(text); } TQString DeviceChooser::ComboBox::device() const { if ( _withAuto && currentItem()==0 ) return Device::AUTO_DATA.name; return currentText(); } //----------------------------------------------------------------------------- DeviceChooser::Button::Button(bool withAuto, TQWidget *tqparent) : TQWidget(tqparent, "device_chooser_button") { TQHBoxLayout *hbox = new TQHBoxLayout(this, 0, 10); _combo = new ComboBox(withAuto, this); connect(_combo, TQT_SIGNAL(activated(int)), TQT_SIGNAL(changed())); hbox->addWidget(_combo); KIconLoader loader; TQIconSet iconset = loader.loadIcon("fileopen", KIcon::Toolbar); KPushButton *button = new KPushButton(iconset, TQString(), this); connect(button, TQT_SIGNAL(clicked()), TQT_SLOT(chooseDevice())); hbox->addWidget(button); } void DeviceChooser::Button::chooseDevice() { Dialog dialog(_combo->device(), (_combo->withAuto() ? ChooseWithAuto : Choose), this); if ( !dialog.exec() || dialog.device().isEmpty() ) return; _combo->setDevice(dialog.device()); emit changed(); } //----------------------------------------------------------------------------- DeviceChooser::Browser::Browser(TQWidget *tqparent) : KTextBrowser(tqparent, "device_browser") {} PURL::Url findDocumentUrl(const TQString &prefix, const TQString &baseName) { PURL::Url previous = KURL::fromPathOrURL(prefix + baseName + ".pdf"); bool previousExists = previous.exists(); for (uint i=0; i<26; i++) { PURL::Url url = KURL::fromPathOrURL(prefix + baseName + TQChar('a' + i) + ".pdf"); bool exists = url.exists(); if ( !exists && previousExists ) return previous; previous = url; previousExists = exists; } return previous; } void DeviceChooser::Browser::setSource(const TQString &name) { ::PBusyCursor bc; if ( name.startsWith("device://") ) emit deviceChanged(name.mid(9)); else if ( name.startsWith("document://") ) { TQString prefix = "http://ww1.microchip.com/downloads/en/DeviceDoc/"; PURL::Url url = findDocumentUrl(prefix, name.mid(11, name.length()-11-1)); KTextBrowser::setSource(url.kurl().htmlURL()); } else KTextBrowser::setSource(name); } //----------------------------------------------------------------------------- DeviceChooser::View::View(TQWidget *tqparent) : TabWidget(tqparent, "device_view") { // Information _info = new Browser(this); _info->setMimeSourceFactory(&_msf); insertTab(_info, i18n("Information")); connect(_info, TQT_SIGNAL(deviceChanged(const TQString &)), TQT_SIGNAL(deviceChanged(const TQString &))); // Memory Map _memory = new Browser(this); _memory->setMimeSourceFactory(&_msf); insertTab(_memory, i18n("Memory Map")); // Voltage-Frequency Graphs _vfg = new Browser(this); _vfg->setMimeSourceFactory(&_msf); insertTab(_vfg, i18n("Voltage-Frequency Graphs")); // Pin Diagrams _pins = new Browser(this); _pins->setMimeSourceFactory(&_msf); insertTab(_pins, i18n("Pin Diagrams")); } void DeviceChooser::View::setDevice(const TQString &name, bool cannotChangeDevice) { const Device::Data *data = Device::lister().data(name); if ( data==0 ) return; TQString doc = htmlInfo(*data, (cannotChangeDevice ? TQString() : "device:%1"), Device::documentHtml(*data)); doc += Device::supportedHtmlInfo(*data); _info->setText("" + doc + ""); doc = htmlVoltageFrequencyGraphs(*data, TQString(), &_msf); TQPixmap pix = data->group().memoryGraph(*data); TQString label = data->name() + "_memory_map.png"; _msf.setPixmap(label, pix); _memory->setText(""); _vfg->setText("" + doc + ""); doc = htmlPinDiagrams(*data, TQString(), &_msf); _pins->setText("" + doc + ""); } void DeviceChooser::View::setText(const TQString &text) { _info->setText(text); _vfg->setText(text); _pins->setText(text); } void DeviceChooser::View::clear() { _info->clear(); _vfg->clear(); _pins->clear(); } //----------------------------------------------------------------------------- DeviceChooser::Editor::Editor(const TQString &title, const TQString &tag, TQWidget *widget) : DeviceEditor(title, tag, widget, "device_view_editor") {} TQWidget *DeviceChooser::Editor::createView(const Device::Data *, TQWidget *tqparent) { DeviceChooser::View *view = new DeviceChooser::View(tqparent); connect(view, TQT_SIGNAL(deviceChanged(const TQString &)), TQT_SIGNAL(deviceChanged(const TQString &))); view->setDevice(_device, true); return view; }