/************************************************************************** ** ** This file is part of Qt Creator ** ** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** Commercial Usage ** ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at http://qt.nokia.com/contact. ** **************************************************************************/ #include "registerwindow.h" #include "debuggeractions.h" #include "debuggerconstants.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Debugger { namespace Internal { /////////////////////////////////////////////////////////////////////// // // RegisterDelegate // /////////////////////////////////////////////////////////////////////// class RegisterDelegate : public QItemDelegate { public: RegisterDelegate(RegisterWindow *owner, QObject *parent) : QItemDelegate(parent), m_owner(owner) {} QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const { QLineEdit *lineEdit = new QLineEdit(parent); lineEdit->setAlignment(Qt::AlignRight); return lineEdit; } void setEditorData(QWidget *editor, const QModelIndex &index) const { QLineEdit *lineEdit = qobject_cast(editor); QTC_ASSERT(lineEdit, return); lineEdit->setText(index.data(Qt::DisplayRole).toString()); } void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { Q_UNUSED(model); //qDebug() << "SET MODEL DATA"; QLineEdit *lineEdit = qobject_cast(editor); QTC_ASSERT(lineEdit, return); QString value = lineEdit->text(); //model->setData(index, value, Qt::EditRole); if (index.column() == 1) m_owner->model()->setData(index, value, RequestSetRegisterRole); } void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const { editor->setGeometry(option.rect); } void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (index.column() == 1) { bool paintRed = index.data(RegisterChangedRole).toBool(); QPen oldPen = painter->pen(); if (paintRed) painter->setPen(QColor(200, 0, 0)); // FIXME: performance? this changes only on real font changes. QFontMetrics fm(option.font); int charWidth = fm.width(QLatin1Char('x')); for (int i = '1'; i <= '9'; ++i) charWidth = qMax(charWidth, fm.width(QLatin1Char(i))); for (int i = 'a'; i <= 'f'; ++i) charWidth = qMax(charWidth, fm.width(QLatin1Char(i))); QString str = index.data(Qt::DisplayRole).toString(); int x = option.rect.x(); for (int i = 0; i < str.size(); ++i) { QRect r = option.rect; r.setX(x); r.setWidth(charWidth); x += charWidth; painter->drawText(r, Qt::AlignHCenter, QString(str.at(i))); } if (paintRed) painter->setPen(oldPen); } else { QItemDelegate::paint(painter, option, index); } } private: RegisterWindow *m_owner; }; /////////////////////////////////////////////////////////////////////// // // RegisterWindow // /////////////////////////////////////////////////////////////////////// RegisterWindow::RegisterWindow(QWidget *parent) : QTreeView(parent), m_alwaysResizeColumnsToContents(true) { QAction *act = theDebuggerAction(UseAlternatingRowColors); setFrameStyle(QFrame::NoFrame); setWindowTitle(tr("Registers")); setAttribute(Qt::WA_MacShowFocusRect, false); setAlternatingRowColors(act->isChecked()); setRootIsDecorated(false); setItemDelegate(new RegisterDelegate(this, this)); connect(act, SIGNAL(toggled(bool)), this, SLOT(setAlternatingRowColorsHelper(bool))); } void RegisterWindow::resizeEvent(QResizeEvent *ev) { QTreeView::resizeEvent(ev); } void RegisterWindow::contextMenuEvent(QContextMenuEvent *ev) { QMenu menu; const unsigned engineCapabilities = modelData(EngineCapabilitiesRole).toUInt(); const bool actionsEnabled = modelData(EngineActionsEnabledRole).toInt(); const int state = modelData(EngineStateRole).toInt(); QAction *actReload = menu.addAction(tr("Reload Register Listing")); actReload->setEnabled((engineCapabilities & RegisterCapability) && (state == InferiorStopOk || state == InferiorUnrunnable)); menu.addSeparator(); QModelIndex idx = indexAt(ev->pos()); QString address = modelData(RegisterAddressRole, idx).toString(); QAction *actShowMemory = menu.addAction(QString()); if (address.isEmpty()) { actShowMemory->setText(tr("Open Memory Editor")); actShowMemory->setEnabled(false); } else { actShowMemory->setText(tr("Open Memory Editor at %1").arg(address)); actShowMemory->setEnabled(actionsEnabled && (engineCapabilities & ShowMemoryCapability)); } menu.addSeparator(); int base = modelData(RegisterNumberBaseRole).toInt(); QAction *act16 = menu.addAction(tr("Hexadecimal")); act16->setCheckable(true); act16->setChecked(base == 16); QAction *act10 = menu.addAction(tr("Decimal")); act10->setCheckable(true); act10->setChecked(base == 10); QAction *act8 = menu.addAction(tr("Octal")); act8->setCheckable(true); act8->setChecked(base == 8); QAction *act2 = menu.addAction(tr("Binary")); act2->setCheckable(true); act2->setChecked(base == 2); menu.addSeparator(); QAction *actAdjust = menu.addAction(tr("Adjust Column Widths to Contents")); QAction *actAlwaysAdjust = menu.addAction(tr("Always Adjust Column Widths to Contents")); actAlwaysAdjust->setCheckable(true); actAlwaysAdjust->setChecked(m_alwaysResizeColumnsToContents); menu.addSeparator(); menu.addAction(theDebuggerAction(SettingsDialog)); QAction *act = menu.exec(ev->globalPos()); if (act == actAdjust) resizeColumnsToContents(); else if (act == actAlwaysAdjust) setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents); else if (act == actReload) setModelData(RequestReloadRegistersRole); else if (act == actShowMemory) setModelData(RequestShowMemoryRole, address); else if (act) { base = (act == act10 ? 10 : act == act8 ? 8 : act == act2 ? 2 : 16); QMetaObject::invokeMethod(model(), "setNumberBase", Q_ARG(int, base)); } } void RegisterWindow::resizeColumnsToContents() { resizeColumnToContents(0); resizeColumnToContents(1); } void RegisterWindow::setAlwaysResizeColumnsToContents(bool on) { m_alwaysResizeColumnsToContents = on; QHeaderView::ResizeMode mode = on ? QHeaderView::ResizeToContents : QHeaderView::Interactive; header()->setResizeMode(0, mode); header()->setResizeMode(1, mode); } void RegisterWindow::setModel(QAbstractItemModel *model) { QTreeView::setModel(model); setAlwaysResizeColumnsToContents(true); } void RegisterWindow::reloadRegisters() { // FIXME: Only trigger when becoming visible? setModelData(RequestReloadRegistersRole); } void RegisterWindow::setModelData (int role, const QVariant &value, const QModelIndex &index) { QTC_ASSERT(model(), return); model()->setData(index, value, role); } QVariant RegisterWindow::modelData(int role, const QModelIndex &index) { QTC_ASSERT(model(), return QVariant()); return model()->data(index, role); } } // namespace Internal } // namespace Debugger