/*************************************************************************** * Copyright (C) 2005-2006 Nicolas Hadacek * * Copyright (C) 2003-2004 Alain Gibaud * * * * 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 "memory_editor.h" #include #include #include #include #include #include #include #include #include #include "common/common/misc.h" #include "hex_word_editor.h" #include "device_group_ui.h" #include "libgui/toplevel.h" #include "libgui/main_global.h" #include "hex_view.h" #include "libgui/gui_prog_manager.h" //----------------------------------------------------------------------------- Device::MemoryEditor::MemoryEditor(Device::Memory *memory, TQWidget *parent, const char *name) : TQFrame(parent, name), _memory(memory) { _top = new TQVBoxLayout(this, 5, 10); } //----------------------------------------------------------------------------- Device::MemoryRangeEditor::MemoryRangeEditor(Device::Memory &memory, uint nbLines, uint nbCols, uint offset, int nb, TQWidget *parent, const char *name) : MemoryEditor(&memory, parent, name), _nbLines(nbLines), _nbCols(nbCols), _offset(offset), _nb(nb) {} void Device::MemoryRangeEditor::init() { if ( _nb==-1 ) _nb = nbWords(); uint totalNbLines = _nb / _nbCols; if ( (_nb % _nbCols)!=0 ) totalNbLines++; TQHBoxLayout *hbox = new TQHBoxLayout(_top); TQVBoxLayout *vbox = new TQVBoxLayout(hbox); TQFrame *frame = new TQFrame(this); frame->setFrameStyle(TQFrame::Panel | TQFrame::Raised); frame->setMargin(5); vbox->addWidget(frame); vbox->addStretch(1); TQHBoxLayout *fbox = new TQHBoxLayout(frame, 5, 5); TQGrid *grid = new TQGrid(3+_nbCols, TQt::Horizontal, frame, "memory_range_editor_grid"); fbox->addWidget(grid); grid->setSpacing(0); grid->setMargin(3); TQFont f("courier", font().pointSize()); grid->setFont(f); for (uint k=0; k<_nbLines; ++k) { // addresses TQWidget *w = new TQWidget(grid); w->setFixedWidth(10); _blocks.append(w); TQLabel *label = new TQLabel(toHex(0, 2*_memory->device().nbBytesAddress()), grid, "address_label"); _addresses.append(label); label = new TQLabel(":", grid); // memory for (uint i = 0; i<_nbCols; ++i) { HexWordEditor *h = createHexWordEditor(grid); _editors.append(h); connect(h, TQT_SIGNAL(modified()), TQT_SIGNAL(modified())); connect(h, TQT_SIGNAL(moveNext()), TQT_SLOT(moveNext())); connect(h, TQT_SIGNAL(movePrev()), TQT_SLOT(movePrev())); connect(h, TQT_SIGNAL(moveFirst()), TQT_SLOT(moveFirst())); connect(h, TQT_SIGNAL(moveLast()), TQT_SLOT(moveLast())); connect(h, TQT_SIGNAL(moveUp()), TQT_SLOT(moveUp())); connect(h, TQT_SIGNAL(moveDown()), TQT_SLOT(moveDown())); connect(h, TQT_SIGNAL(moveNextPage()), TQT_SLOT(moveNextPage())); connect(h, TQT_SIGNAL(movePrevPage()), TQT_SLOT(movePrevPage())); } } // scrollbar if there are more lines to display than visible _scrollbar = new TQScrollBar(0, TQMAX(_nbLines, totalNbLines)-_nbLines, 1, _nbLines, 0, TQt::Vertical, frame, "memory_range_editor_scrollbar"); connect(_scrollbar, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(setIndex(int))) ; if ( totalNbLines<=_nbLines ) _scrollbar->hide(); fbox->addWidget(_scrollbar); fbox->addStretch(1); vbox->addStretch(1); TQVBoxLayout *vboxc = new TQVBoxLayout(hbox); vboxc->setSpacing(0); _comment = new TQLabel(this); _comment->hide(); vboxc->addWidget(_comment); _spacer = new TQLabel(this); _spacer->setFixedHeight(10); _spacer->hide(); vboxc->addWidget(_spacer); addLegend(vboxc); vboxc->addStretch(1); hbox->addStretch(1); setReadOnly(false); setIndex(0); } void Device::MemoryRangeEditor::setComment(const TQString &text) { _comment->setText(text); _comment->show(); _spacer->show(); } void Device::MemoryRangeEditor::setReadOnly(bool readOnly) { for (uint i=0; i<_editors.count(); i++) _editors[i]->setReadOnly(readOnly || isRangeReadOnly()); } void Device::MemoryRangeEditor::updateDisplay() { setIndex(_scrollbar->value()); } void Device::MemoryRangeEditor::setStartWord(int index) { setIndex(index / _nbCols / addressIncrement()); } void Device::MemoryRangeEditor::setEndWord(int index) { uint i = index / _nbCols / addressIncrement(); i = (i<_nbLines ? 0 : i - _nbLines + 1); setIndex(i); } void Device::MemoryRangeEditor::setIndex(int index) { _scrollbar->blockSignals(true); _scrollbar->setValue(index); _scrollbar->blockSignals(false); // memory for (uint i=0; i<_editors.count(); i++) { int offset = wordOffset() + i; _editors[i]->setOffset(offsetsetText(toHex(address, 2*_memory->device().nbBytesAddress())); updateAddressColor(i, address); address += inc * _nbCols; } } void Device::MemoryRangeEditor::moveNext() { TQValueList::iterator it = _editors.find((HexWordEditor *)sender()); ++it; if ( it==_editors.end() || (*it)->offset()==-1 ) { if ( current()==uint(_scrollbar->maxValue()) ) return; // at end setIndex(current()+1); _editors[_editors.count()-_nbCols]->setFocus(); } else (*it)->setFocus(); } void Device::MemoryRangeEditor::movePrev() { TQValueList::iterator it = _editors.find((HexWordEditor *)sender()); if ( it==_editors.begin() ) { if ( current()==0 ) return; // at beginning setIndex(current()-1); _editors[_nbCols-1]->setFocus(); } else { --it; (*it)->setFocus(); } } void Device::MemoryRangeEditor::moveFirst() { if ( _editors[0]==0 ) return; setIndex(0); _editors[0]->setFocus(); } void Device::MemoryRangeEditor::moveLast() { if ( _editors.count()==0 ) return; setIndex(_scrollbar->maxValue()); for (uint i=1; i<=_nbCols; i++) { if ( _editors[_editors.count()-i]->offset()==-1 ) continue; _editors[_editors.count()-i]->setFocus(); break; } } void Device::MemoryRangeEditor::moveUp() { int i = _editors.findIndex((HexWordEditor *)sender()); uint line = i / _nbCols; if ( line==0 ) { if ( current()==0 ) return; // on first line setIndex(current()-1); _editors[i]->setFocus(); } else _editors[i-_nbCols]->setFocus(); } void Device::MemoryRangeEditor::moveDown() { int i = _editors.findIndex((HexWordEditor *)sender()); uint line = i / _nbCols; if ( line+1==_nbLines ) { if ( current()==uint(_scrollbar->maxValue()) ) return; // on last line setIndex(current()+1); if ( _editors[i]->offset()==-1 ) _editors[i-_nbCols]->setFocus(); else _editors[i]->setFocus(); } else _editors[i+_nbCols]->setFocus(); } void Device::MemoryRangeEditor::moveNextPage() { int i = _editors.findIndex((HexWordEditor *)sender()); if ( _nbLines>(uint(_scrollbar->maxValue()) - current()) ) i = (_nbLines-1) * _nbCols + (i % _nbCols); else setIndex(current()+_nbLines); if ( _editors[i]->offset()==-1 ) _editors[i-_nbCols]->setFocus(); else _editors[i]->setFocus(); } void Device::MemoryRangeEditor::movePrevPage() { int i = _editors.findIndex((HexWordEditor *)sender()); if ( current()<_nbLines ) i = (i % _nbCols); else setIndex(current()-_nbLines); _editors[i]->setFocus(); } //----------------------------------------------------------------------------- Device::MemoryEditorGroup::MemoryEditorGroup(Device::Memory *memory, TQWidget *parent, const char *name) : MemoryEditor(memory, parent, name) {} void Device::MemoryEditorGroup::addEditor(MemoryEditor *editor) { connect(editor, TQT_SIGNAL(modified()), TQT_SIGNAL(modified())); _editors.append(editor); } void Device::MemoryEditorGroup::setReadOnly(bool readOnly) { for (uint i=0; i<_editors.count(); i++) _editors[i]->setReadOnly(readOnly); } void Device::MemoryEditorGroup::updateDisplay() { for (uint i=0; i<_editors.count(); i++) _editors[i]->updateDisplay(); } //----------------------------------------------------------------------------- const Device::ActionData Device::ACTION_DATA[Nb_Actions] = { { I18N_NOOP("&Clear"), "window-close", NeedWrite }, { I18N_NOOP("&Zero"), 0, NeedWrite }, { I18N_NOOP("For checksum check"), 0, NeedWrite }, { I18N_NOOP("Re&load"), "reload", SeparatorAfter | NeedModified }, { I18N_NOOP("&Program"), "piklab_burnchip", NeedProgrammer }, { I18N_NOOP("&Verify"), "piklab_verifychip", NeedProgrammer }, { I18N_NOOP("&Read"), "piklab_readchip", NeedProgrammer | NeedWrite }, { I18N_NOOP("&Erase"), "piklab_erasechip", NeedProgrammer }, { I18N_NOOP("&Blank Check"), "piklab_blankcheck", NeedProgrammer } }; Device::MemoryTypeEditor::MemoryTypeEditor(const HexView *hexview, Device::Memory &memory, TQWidget *parent, const char *name) : MemoryEditorGroup(&memory, parent, name), _title(0), _comment(0), _hexview(hexview) { for (uint i=0; iaddWidget(new SeparatorWidget(this)); TQHBoxLayout *hbox = new TQHBoxLayout(_top); _title = new PopupButton(this); for (uint i=0; iappendSeparator(); } _title->appendSeparator(); hbox->addWidget(_title); _comment = new TQLabel(this); hbox->addWidget(_comment); hbox->addStretch(1); connect(&Main::toplevel(), TQT_SIGNAL(stateChanged()), TQT_SLOT(stateChanged())); } void Device::MemoryTypeEditor::addAction(TDEAction *action) { _title->appendAction(action); } void Device::MemoryTypeEditor::doAction() { for (uint i=0; iinitProgramming(false) ) return; bool ok = internalDoAction(action); if ( ACTION_DATA[action].properties & NeedProgrammer ) Programmer::manager->endProgramming(); if (ok) { updateDisplay(); modified(); } } void Device::MemoryTypeEditor::stateChanged() { bool idle = ( Main::state()==Main::Idle ); for (uint i=0; iisModified()) ) on = false; _actions[i]->setEnabled(on); } } void Device::MemoryTypeEditor::setReadOnly(bool readOnly) { _readOnly = readOnly; MemoryEditorGroup::setReadOnly(readOnly); stateChanged(); } const Device::Memory *Device::MemoryTypeEditor::originalMemory() const { return (_hexview ? _hexview->originalMemory() : 0); }