1 #include "RegistersWidget.h"
2 #include "ui_RegistersWidget.h"
3 #include "common/JsonModel.h"
4 
5 #include "core/MainWindow.h"
6 
7 #include <QCollator>
8 #include <QLabel>
9 #include <QLineEdit>
10 
RegistersWidget(MainWindow * main)11 RegistersWidget::RegistersWidget(MainWindow *main) :
12     CutterDockWidget(main),
13     ui(new Ui::RegistersWidget),
14     addressContextMenu(this, main)
15 {
16     ui->setupUi(this);
17 
18     // setup register layout
19     registerLayout->setVerticalSpacing(0);
20     registerLayout->setAlignment(Qt::AlignLeft |  Qt::AlignTop) ;
21     ui->verticalLayout->addLayout(registerLayout);
22 
23     refreshDeferrer = createRefreshDeferrer([this]() {
24         updateContents();
25     });
26 
27     connect(Core(), &CutterCore::refreshAll, this, &RegistersWidget::updateContents);
28     connect(Core(), &CutterCore::registersChanged, this, &RegistersWidget::updateContents);
29 
30     // Hide shortcuts because there is no way of selecting an item and triger them
31     for (auto &action : addressContextMenu.actions()) {
32         action->setShortcut(QKeySequence());
33         // setShortcutVisibleInContextMenu(false) doesn't work
34     }
35 }
36 
37 RegistersWidget::~RegistersWidget() = default;
38 
updateContents()39 void RegistersWidget::updateContents()
40 {
41     if (!refreshDeferrer->attemptRefresh(nullptr)) {
42         return;
43     }
44     setRegisterGrid();
45 }
46 
setRegisterGrid()47 void RegistersWidget::setRegisterGrid()
48 {
49     int i = 0;
50     int col = 0;
51     QString regValue;
52     QLabel *registerLabel;
53     QLineEdit *registerEditValue;
54     const auto registerRefs = Core()->getRegisterRefValues();
55 
56     registerLen = registerRefs.size();
57     for (auto &reg : registerRefs) {
58         regValue = "0x" + reg.value;
59         // check if we already filled this grid space with label/value
60         if (!registerLayout->itemAtPosition(i, col)) {
61             registerLabel = new QLabel;
62             registerLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
63             registerLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
64             registerLabel->setMaximumWidth(60);
65             registerLabel->setStyleSheet("font-weight: bold; font-family: mono;");
66             registerEditValue = new QLineEdit;
67             registerEditValue->setMaximumWidth(140);
68             registerEditValue->setFont(Config()->getFont());
69             registerLabel->setContextMenuPolicy(Qt::CustomContextMenu);
70             connect(registerLabel, &QWidget::customContextMenuRequested, this, [this, registerEditValue, registerLabel](QPoint p){
71                 openContextMenu(registerLabel->mapToGlobal(p), registerEditValue->text());
72             });
73             registerEditValue->setContextMenuPolicy(Qt::CustomContextMenu);
74             connect(registerEditValue, &QWidget::customContextMenuRequested, this, [this, registerEditValue](QPoint p){
75                 openContextMenu(registerEditValue->mapToGlobal(p), registerEditValue->text());
76             });
77             // add label and register value to grid
78             registerLayout->addWidget(registerLabel, i, col);
79             registerLayout->addWidget(registerEditValue, i, col + 1);
80             connect(registerEditValue, &QLineEdit::editingFinished, [ = ]() {
81                 QString regNameString = registerLabel->text();
82                 QString regValueString = registerEditValue->text();
83                 Core()->setRegister(regNameString, regValueString);
84             });
85         } else {
86             QWidget *regNameWidget = registerLayout->itemAtPosition(i, col)->widget();
87             QWidget *regValueWidget = registerLayout->itemAtPosition(i, col + 1)->widget();
88             registerLabel = qobject_cast<QLabel *>(regNameWidget);
89             registerEditValue = qobject_cast<QLineEdit *>(regValueWidget);
90         }
91         // decide to highlight QLine Box in case of change of register value
92         if (regValue != registerEditValue->text() && registerEditValue->text() != 0) {
93             registerEditValue->setStyleSheet("border: 1px solid green;");
94         } else {
95             // reset stylesheet
96             registerEditValue->setStyleSheet("");
97         }
98         // define register label and value
99         registerLabel->setText(reg.name);
100 
101         registerLabel->setToolTip(reg.ref);
102         registerEditValue->setToolTip(reg.ref);
103 
104         registerEditValue->setPlaceholderText(regValue);
105         registerEditValue->setText(regValue);
106         i++;
107         // decide if we should change column
108         if (i >= (registerLen + numCols - 1) / numCols) {
109             i = 0;
110             col += 2;
111         }
112     }
113 }
114 
openContextMenu(QPoint point,QString address)115 void RegistersWidget::openContextMenu(QPoint point, QString address)
116 {
117     addressContextMenu.setTarget(address.toULongLong(nullptr, 16));
118     addressContextMenu.exec(point);
119 }
120