File indexing completed on 2024-04-21 05:43:43

0001 /***************************************************************************
0002  *   Copyright (C) 2005 by David Saxton                                    *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #include "config.h"
0012 #ifndef NO_GPSIM
0013 
0014 #include "gpsimprocessor.h"
0015 #include "katemdi.h"
0016 #include "symbolviewer.h"
0017 
0018 #include <KComboBox>
0019 #include <KConfig>
0020 #include <KConfigGroup>
0021 #include <KLocalizedString>
0022 
0023 #include <QGridLayout>
0024 #include <QHeaderView>
0025 #include <QLabel>
0026 
0027 #include <cassert>
0028 
0029 #include <ktechlab_debug.h>
0030 
0031 static const int NAME_COLUMN = 0;
0032 static const int VALUE_COLUMN = 1;
0033 
0034 // BEGIN class SymbolViewerItem
0035 SymbolViewerItem::SymbolViewerItem(SymbolViewer *symbolViewer, const RegisterInfo *registerInfo, int intendedColumn)
0036     : QObject()
0037     , QTableWidgetItem()
0038     , m_pRegisterInfo(registerInfo)
0039     , m_pSymbolViewer(symbolViewer)
0040 {
0041     qCDebug(KTL_LOG) << " reg info name " << m_pRegisterInfo->name();
0042     qCDebug(KTL_LOG) << " row " << row() << " column " << column();
0043 
0044     assert(registerInfo);
0045     m_pRegisterInfo = registerInfo;
0046     m_pSymbolViewer = symbolViewer;
0047 
0048     // note: at initial update the column is set to -1, so don't rely on that
0049     if (intendedColumn == NAME_COLUMN) {
0050         setText(m_pRegisterInfo->name());
0051     } else { // VALUE_COLUMN...
0052         setText(m_pSymbolViewer->toDisplayString(m_pRegisterInfo->value()));
0053     }
0054 
0055     connect(m_pRegisterInfo, &RegisterInfo::valueChanged, this, &SymbolViewerItem::valueChanged);
0056     connect(m_pSymbolViewer, &SymbolViewer::valueRadixChanged, this, &SymbolViewerItem::radixChanged);
0057 }
0058 
0059 void SymbolViewerItem::valueChanged(unsigned newValue)
0060 {
0061     if (column() == VALUE_COLUMN) {
0062         setText(m_pSymbolViewer->toDisplayString(newValue));
0063     }
0064 }
0065 
0066 void SymbolViewerItem::radixChanged()
0067 {
0068     if (column() == VALUE_COLUMN) {
0069         valueChanged(m_pRegisterInfo->value());
0070     }
0071 }
0072 // END class SymbolViewerItem
0073 
0074 // BEGIN class SymbolView
0075 SymbolViewer *SymbolViewer::m_pSelf = nullptr;
0076 SymbolViewer *SymbolViewer::self(KateMDI::ToolView *parent)
0077 {
0078     if (!m_pSelf) {
0079         assert(parent);
0080         m_pSelf = new SymbolViewer(parent);
0081     }
0082     return m_pSelf;
0083 }
0084 
0085 SymbolViewer::SymbolViewer(KateMDI::ToolView *parent)
0086     : QWidget(static_cast<QWidget *>(parent))
0087 {
0088     if (parent->layout()) {
0089         parent->layout()->addWidget(this);
0090         qCDebug(KTL_LOG) << " added item selector to parent's layout " << parent;
0091     } else {
0092         qCWarning(KTL_LOG) << " unexpected null layout on parent " << parent;
0093     }
0094 
0095     QGridLayout *grid = new QGridLayout(this /*, 1, 1, 0, 6 */);
0096     grid->setMargin(0);
0097     grid->setSpacing(6);
0098 
0099     m_pSymbolList = new QTableWidget(this);
0100     m_pSymbolList->setFocusPolicy(Qt::NoFocus);
0101     // grid->addMultiCellWidget( m_pSymbolList, 0, 0, 0, 1 ); // 2018.12.02
0102     grid->addWidget(m_pSymbolList, 0, 0, 1, 2);
0103 
0104     grid->addWidget(new QLabel(i18n("Value radix:"), this), 1, 0);
0105 
0106     m_pRadixCombo = new KComboBox(false, this);
0107     grid->addWidget(m_pRadixCombo, 1, 1);
0108     m_pRadixCombo->insertItem(m_pRadixCombo->count(), i18n("Binary"));
0109     m_pRadixCombo->insertItem(m_pRadixCombo->count(), i18n("Octal"));
0110     m_pRadixCombo->insertItem(m_pRadixCombo->count(), i18n("Decimal"));
0111     m_pRadixCombo->insertItem(m_pRadixCombo->count(), i18n("Hexadecimal"));
0112     m_valueRadix = Decimal;
0113     m_pRadixCombo->setCurrentIndex(2);
0114     connect(m_pRadixCombo, qOverload<int>(&KComboBox::activated), this, &SymbolViewer::selectRadix);
0115 
0116     m_pGpsim = nullptr;
0117     m_pCurrentContext = nullptr;
0118 
0119     m_pSymbolList->verticalHeader()->setVisible(false);
0120     m_pSymbolList->horizontalHeader()->setVisible(true);
0121     // m_pSymbolList->addColumn( i18n("Name") ); // 2018.06.02 - use QTableWidget
0122     // m_pSymbolList->addColumn( i18n("Value") ); // 2018.06.02 - use QTableWidget
0123     m_pSymbolList->setColumnCount(2);
0124     m_pSymbolList->setHorizontalHeaderItem(0, new QTableWidgetItem(i18n("Name")));
0125     m_pSymbolList->setHorizontalHeaderItem(1, new QTableWidgetItem(i18n("Value")));
0126     m_pSymbolList->horizontalHeaderItem(0)->setText(i18n("Name"));
0127     m_pSymbolList->horizontalHeaderItem(1)->setText(i18n("Value"));
0128     // m_pSymbolList->setFullWidth(true);
0129     // m_pSymbolList->setColumnWidthMode(1, Q3ListView::Maximum);    // 2018.06.02 - use QTableWidget
0130     m_pSymbolList->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
0131     // m_pSymbolList->setAllColumnsShowFocus( true );    // 2018.06.02 - use QTableWidget
0132     m_pSymbolList->setEditTriggers(QAbstractItemView::NoEditTriggers);
0133     QHeaderView *symbolListHeader = m_pSymbolList->horizontalHeader();
0134     symbolListHeader->setSectionResizeMode(0, QHeaderView::Stretch);
0135     symbolListHeader->setSectionResizeMode(1, QHeaderView::Stretch);
0136 }
0137 
0138 SymbolViewer::~SymbolViewer()
0139 {
0140 }
0141 
0142 void SymbolViewer::saveProperties(KConfig *config)
0143 {
0144     // QString oldGroup = config->group();
0145 
0146     KConfigGroup grSym = config->group("SymbolEditor");
0147     grSym.writeEntry("Radix", static_cast<int>(m_valueRadix));
0148 
0149     // config->setGroup( oldGroup );
0150 }
0151 
0152 void SymbolViewer::readProperties(KConfig *config)
0153 {
0154     // QString oldGroup = config->group();
0155 
0156     KConfigGroup grSym = config->group("SymbolEditor");
0157 
0158     m_valueRadix = static_cast<SymbolViewer::Radix>(grSym.readEntry("Radix", static_cast<int>(Decimal)));
0159 
0160     int pos = 4;
0161     switch (m_valueRadix) {
0162     case Binary:
0163         pos = 0;
0164         break;
0165     case Octal:
0166         pos = 1;
0167         break;
0168     case Decimal:
0169         pos = 2;
0170         break;
0171     case Hexadecimal:
0172         pos = 3;
0173         break;
0174     }
0175     m_pRadixCombo->setCurrentIndex(pos);
0176 
0177     // config->setGroup( oldGroup );
0178 }
0179 
0180 void SymbolViewer::setContext(GpsimProcessor *gpsim)
0181 {
0182     RegisterSet *registerSet = gpsim ? gpsim->registerMemory() : nullptr;
0183 
0184     if (registerSet == m_pCurrentContext)
0185         return;
0186 
0187     m_pSymbolList->clear();
0188     m_pSymbolList->setColumnCount(2);
0189     m_pSymbolList->setRowCount(0);
0190 
0191     m_pSymbolList->setHorizontalHeaderItem(0, new QTableWidgetItem(i18n("Name")));
0192     m_pSymbolList->setHorizontalHeaderItem(1, new QTableWidgetItem(i18n("Value")));
0193     m_pSymbolList->horizontalHeaderItem(0)->setText(i18n("Name"));
0194     m_pSymbolList->horizontalHeaderItem(1)->setText(i18n("Value"));
0195 
0196     m_pGpsim = gpsim;
0197     m_pCurrentContext = registerSet;
0198 
0199     if (!m_pCurrentContext)
0200         return;
0201 
0202     connect(gpsim, &GpsimProcessor::destroyed, m_pSymbolList, &QTableWidget::clearContents);
0203 
0204     unsigned count = m_pCurrentContext->size();
0205     for (unsigned i = 0; i < count; ++i) {
0206         RegisterInfo *reg = m_pCurrentContext->fromAddress(i);
0207 
0208         if (!reg) {
0209             qCDebug(KTL_LOG) << " skip null register at " << i;
0210             continue;
0211         }
0212 
0213         if ((reg->type() == RegisterInfo::Generic) || (reg->type() == RegisterInfo::Invalid)) {
0214             continue;
0215         }
0216 
0217         qCDebug(KTL_LOG) << " add reg at " << i << " info " << reg;
0218 
0219         m_pSymbolList->insertRow(i);
0220 
0221         SymbolViewerItem *itemName = new SymbolViewerItem(this, reg, 0);
0222         m_pSymbolList->setItem(i, 0, itemName);
0223         SymbolViewerItem *itemVal = new SymbolViewerItem(this, reg, 1);
0224         m_pSymbolList->setItem(i, 1, itemVal);
0225     }
0226 }
0227 
0228 void SymbolViewer::selectRadix(int selectIndex)
0229 {
0230     if ((selectIndex < 0) || (selectIndex > 3)) {
0231         qCWarning(KTL_LOG) << "Invalid select position for radix: " << selectIndex;
0232         return;
0233     }
0234 
0235     Radix radii[] = {Binary, Octal, Decimal, Hexadecimal};
0236     Radix newRadix = radii[selectIndex];
0237 
0238     if (newRadix == m_valueRadix)
0239         return;
0240 
0241     m_valueRadix = newRadix;
0242 
0243     emit valueRadixChanged(m_valueRadix);
0244 }
0245 
0246 QString SymbolViewer::toDisplayString(unsigned value) const
0247 {
0248     switch (m_valueRadix) {
0249     case Binary:
0250         return QString::number(value, 2).rightJustified(8, '0', false);
0251 
0252     case Octal:
0253         return "0" + QString::number(value, 8);
0254 
0255     case Decimal:
0256         return QString::number(value, 10);
0257 
0258     case Hexadecimal:
0259         return "0x" + QString::number(value, 16);
0260     }
0261 
0262     return "?";
0263 }
0264 // END class SymbolView
0265 
0266 #include "moc_symbolviewer.cpp"
0267 
0268 #endif