diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2016-02-06 15:08:43 +0000 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2016-02-06 15:20:48 +0000 |
commit | 6b9610fb908b27d1e0383c8d9bde3a88f35ed30c (patch) | |
tree | 1b0f5e2821b44d20f3704c584e309f5911357040 /utils/regtools/qeditor/regedit.cpp | |
parent | 0f701a64bee43e79f95970ae9c0ec43ea7fcdf17 (diff) | |
download | rockbox-6b9610fb908b27d1e0383c8d9bde3a88f35ed30c.tar.gz rockbox-6b9610fb908b27d1e0383c8d9bde3a88f35ed30c.zip |
regtoosl/qeditor: port to the new description format
This big commit port qeditor from v1 to v2 register file format. Although
the display code was much simplified, the edit code had to be rewritten.
The new code also brings many improvement to the register display widget.
The new code also compiles with both Qt4 and Qt5, although it is recommended
to use Qt5 to get some improvements, especially in the layout of editor.
Change-Id: I24633ac37a144f25d9e705b565654269ec9cfbd3
Diffstat (limited to 'utils/regtools/qeditor/regedit.cpp')
-rw-r--r-- | utils/regtools/qeditor/regedit.cpp | 2222 |
1 files changed, 1317 insertions, 905 deletions
diff --git a/utils/regtools/qeditor/regedit.cpp b/utils/regtools/qeditor/regedit.cpp index 8b4bfb7c49..826452fdbd 100644 --- a/utils/regtools/qeditor/regedit.cpp +++ b/utils/regtools/qeditor/regedit.cpp | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <QHeaderView> | 24 | #include <QHeaderView> |
25 | #include <QMessageBox> | 25 | #include <QMessageBox> |
26 | #include <QInputDialog> | 26 | #include <QInputDialog> |
27 | #include <QStandardItemModel> | ||
27 | 28 | ||
28 | /** | 29 | /** |
29 | * EmptyEditPanel | 30 | * EmptyEditPanel |
@@ -36,863 +37,1300 @@ EmptyEditPanel::EmptyEditPanel(QWidget *parent) | |||
36 | /** | 37 | /** |
37 | * SocEditPanel | 38 | * SocEditPanel |
38 | */ | 39 | */ |
39 | SocEditPanel::SocEditPanel(SocRef ref, QWidget *parent) | 40 | |
41 | namespace | ||
42 | { | ||
43 | |||
44 | template< typename T > | ||
45 | void my_remove_at(std::vector< T >& v, size_t at) | ||
46 | { | ||
47 | v.erase(v.begin() + at); | ||
48 | } | ||
49 | |||
50 | enum | ||
51 | { | ||
52 | SocEditPanelDelType = QTableWidgetItem::UserType, | ||
53 | SocEditPanelAddType, | ||
54 | }; | ||
55 | |||
56 | } | ||
57 | |||
58 | SocEditPanel::SocEditPanel(const soc_desc::soc_ref_t& ref, QWidget *parent) | ||
40 | :QWidget(parent), m_ref(ref) | 59 | :QWidget(parent), m_ref(ref) |
41 | { | 60 | { |
42 | m_name_group = new QGroupBox("Name", this); | 61 | QLineEdit *name_edit = new QLineEdit(this); |
43 | m_name_edit = new QLineEdit(this); | 62 | QLineEdit *title_edit = new QLineEdit(this); |
44 | m_name_edit->setText(QString::fromStdString(ref.GetSoc().name)); | 63 | QLineEdit *isa_edit = new QLineEdit(this); |
45 | QVBoxLayout *name_group_layout = new QVBoxLayout; | 64 | QLineEdit *version_edit = new QLineEdit(this); |
46 | name_group_layout->addWidget(m_name_edit); | 65 | |
47 | m_name_group->setLayout(name_group_layout); | 66 | m_authors_list = new QTableWidget(this); |
67 | QGroupBox *authors_group = Misc::EncloseInBox("Authors", m_authors_list); | ||
48 | 68 | ||
49 | m_desc_group = new QGroupBox("Description", this); | ||
50 | QHBoxLayout *group_layout = new QHBoxLayout; | ||
51 | m_desc_edit = new MyTextEditor(this); | 69 | m_desc_edit = new MyTextEditor(this); |
52 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.GetSoc().desc)); | 70 | |
53 | group_layout->addWidget(m_desc_edit); | 71 | QGroupBox *desc_group = Misc::EncloseInBox("Description", m_desc_edit); |
54 | m_desc_group->setLayout(group_layout); | 72 | |
73 | QFormLayout *banner_left_layout = new QFormLayout; | ||
74 | banner_left_layout->addRow("Name:", name_edit); | ||
75 | banner_left_layout->addRow("Title:", title_edit); | ||
76 | banner_left_layout->addRow("Instruction Set:", isa_edit); | ||
77 | banner_left_layout->addRow("Version:", version_edit); | ||
78 | |||
79 | QGroupBox *banner_left_group = new QGroupBox("Information"); | ||
80 | banner_left_group->setLayout(banner_left_layout); | ||
81 | |||
82 | QHBoxLayout *banner_layout = new QHBoxLayout; | ||
83 | banner_layout->addWidget(banner_left_group); | ||
84 | banner_layout->addWidget(authors_group); | ||
85 | banner_layout->addStretch(0); | ||
55 | 86 | ||
56 | QVBoxLayout *layout = new QVBoxLayout; | 87 | QVBoxLayout *layout = new QVBoxLayout; |
57 | layout->addWidget(m_name_group); | 88 | layout->addLayout(banner_layout); |
58 | layout->addWidget(m_desc_group); | 89 | layout->addWidget(desc_group); |
59 | layout->addStretch(1); | 90 | layout->addStretch(1); |
60 | 91 | ||
61 | connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameEdited(const QString&))); | 92 | /* fill data */ |
93 | name_edit->setText(QString::fromStdString(ref.get()->name)); | ||
94 | title_edit->setText(QString::fromStdString(ref.get()->title)); | ||
95 | isa_edit->setText(QString::fromStdString(ref.get()->isa)); | ||
96 | version_edit->setText(QString::fromStdString(ref.get()->version)); | ||
97 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.get()->desc)); | ||
98 | |||
99 | m_authors_list->setColumnCount(2); | ||
100 | m_authors_list->setHorizontalHeaderItem(0, new QTableWidgetItem("")); | ||
101 | m_authors_list->setHorizontalHeaderItem(1, new QTableWidgetItem("Name")); | ||
102 | m_authors_list->horizontalHeader()->setVisible(false); | ||
103 | m_authors_list->verticalHeader()->setVisible(false); | ||
104 | m_authors_list->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | ||
105 | std::vector< std::string >& authors = ref.get()->author; | ||
106 | m_authors_list->setRowCount(authors.size() + 1); | ||
107 | for(size_t i = 0; i < authors.size(); i++) | ||
108 | { | ||
109 | QTableWidgetItem *item = new QTableWidgetItem( | ||
110 | QIcon::fromTheme("list-remove"), "", SocEditPanelDelType); | ||
111 | item->setFlags(Qt::ItemIsEnabled); | ||
112 | m_authors_list->setItem(i, 0, item); | ||
113 | item = new QTableWidgetItem(QString::fromStdString(authors[i])); | ||
114 | m_authors_list->setItem(i, 1, item); | ||
115 | } | ||
116 | QTableWidgetItem *new_item = new QTableWidgetItem( | ||
117 | QIcon::fromTheme("list-add"), "", SocEditPanelAddType); | ||
118 | new_item->setFlags(Qt::ItemIsEnabled); | ||
119 | m_authors_list->setItem(authors.size(), 0, new_item); | ||
120 | new_item = new QTableWidgetItem("New author...", QTableWidgetItem::UserType); | ||
121 | new_item->setFlags(Qt::ItemIsEnabled); | ||
122 | QFont font = new_item->font(); | ||
123 | font.setItalic(true); | ||
124 | new_item->setFont(font); | ||
125 | m_authors_list->setItem(authors.size(), 1, new_item); | ||
126 | m_authors_list->resizeColumnsToContents(); | ||
127 | m_authors_list->horizontalHeader()->setStretchLastSection(true); | ||
128 | |||
129 | connect(name_edit, SIGNAL(textChanged(const QString&)), this, | ||
130 | SLOT(OnNameEdited(const QString&))); | ||
62 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnTextEdited())); | 131 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnTextEdited())); |
132 | connect(title_edit, SIGNAL(textChanged(const QString&)), this, | ||
133 | SLOT(OnTitleEdited(const QString&))); | ||
134 | connect(version_edit, SIGNAL(textChanged(const QString&)), this, | ||
135 | SLOT(OnVersionEdited(const QString&))); | ||
136 | connect(isa_edit, SIGNAL(textChanged(const QString&)), this, | ||
137 | SLOT(OnIsaEdited(const QString&))); | ||
138 | connect(m_authors_list, SIGNAL(itemActivated(QTableWidgetItem *)), this, | ||
139 | SLOT(OnAuthorActivated(QTableWidgetItem *))); | ||
140 | connect(m_authors_list, SIGNAL(itemChanged(QTableWidgetItem *)), this, | ||
141 | SLOT(OnAuthorChanged(QTableWidgetItem *))); | ||
63 | 142 | ||
64 | setLayout(layout); | 143 | setLayout(layout); |
65 | } | 144 | } |
66 | 145 | ||
67 | void SocEditPanel::OnNameEdited(const QString& text) | 146 | void SocEditPanel::OnNameEdited(const QString& text) |
68 | { | 147 | { |
69 | m_ref.GetSoc().name = text.toStdString(); | 148 | m_ref.get()->name = text.toStdString(); |
70 | OnModified(m_name_edit->isModified()); | 149 | OnModified(); |
71 | } | 150 | } |
72 | 151 | ||
73 | void SocEditPanel::OnTextEdited() | 152 | void SocEditPanel::OnTitleEdited(const QString& text) |
74 | { | 153 | { |
75 | m_ref.GetSoc().desc = m_desc_edit->GetTextHtml().toStdString(); | 154 | m_ref.get()->title = text.toStdString(); |
76 | OnModified(m_desc_edit->IsModified()); | 155 | OnModified(); |
77 | } | 156 | } |
78 | 157 | ||
79 | /** | 158 | void SocEditPanel::OnVersionEdited(const QString& text) |
80 | * DevEditPanel | ||
81 | */ | ||
82 | DevEditPanel::DevEditPanel(SocDevRef ref, QWidget *parent) | ||
83 | :QWidget(parent), m_ref(ref) | ||
84 | { | 159 | { |
85 | m_name_group = new QGroupBox("Name", this); | 160 | m_ref.get()->version = text.toStdString(); |
86 | m_name_edit = new QLineEdit(this); | 161 | OnModified(); |
87 | m_name_edit->setText(QString::fromStdString(ref.GetDev().name)); | 162 | } |
88 | QVBoxLayout *name_group_layout = new QVBoxLayout; | ||
89 | name_group_layout->addWidget(m_name_edit); | ||
90 | m_name_group->setLayout(name_group_layout); | ||
91 | |||
92 | m_long_name_group = new QGroupBox("Long Name", this); | ||
93 | m_long_name_edit = new QLineEdit(this); | ||
94 | m_long_name_edit->setText(QString::fromStdString(ref.GetDev().long_name)); | ||
95 | QVBoxLayout *long_name_group_layout = new QVBoxLayout; | ||
96 | long_name_group_layout->addWidget(m_long_name_edit); | ||
97 | m_long_name_group->setLayout(long_name_group_layout); | ||
98 | |||
99 | m_version_group = new QGroupBox("Version", this); | ||
100 | m_version_edit = new QLineEdit(this); | ||
101 | m_version_edit->setText(QString::fromStdString(ref.GetDev().version)); | ||
102 | QVBoxLayout *version_group_layout = new QVBoxLayout; | ||
103 | version_group_layout->addWidget(m_version_edit); | ||
104 | m_version_group->setLayout(version_group_layout); | ||
105 | |||
106 | QVBoxLayout *name_ver_layout = new QVBoxLayout; | ||
107 | name_ver_layout->addWidget(m_name_group); | ||
108 | name_ver_layout->addWidget(m_long_name_group); | ||
109 | name_ver_layout->addWidget(m_version_group); | ||
110 | name_ver_layout->addStretch(); | ||
111 | |||
112 | m_instances_table = new QTableWidget(this); | ||
113 | m_instances_table->setRowCount(ref.GetDev().addr.size() + 1); | ||
114 | m_instances_table->setColumnCount(3); | ||
115 | for(size_t row = 0; row < ref.GetDev().addr.size(); row++) | ||
116 | FillRow(row, ref.GetDev().addr[row]); | ||
117 | CreateNewRow(ref.GetDev().addr.size()); | ||
118 | m_instances_table->setHorizontalHeaderItem(0, new QTableWidgetItem("")); | ||
119 | m_instances_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Name")); | ||
120 | m_instances_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Address")); | ||
121 | m_instances_table->verticalHeader()->setVisible(false); | ||
122 | m_instances_table->resizeColumnsToContents(); | ||
123 | m_instances_table->horizontalHeader()->setStretchLastSection(true); | ||
124 | m_instances_table->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); | ||
125 | m_instances_group = new QGroupBox("Instances", this); | ||
126 | QHBoxLayout *instances_group_layout = new QHBoxLayout; | ||
127 | instances_group_layout->addWidget(m_instances_table); | ||
128 | m_instances_group->setLayout(instances_group_layout); | ||
129 | |||
130 | QHBoxLayout *top_layout = new QHBoxLayout; | ||
131 | top_layout->addWidget(m_instances_group); | ||
132 | top_layout->addLayout(name_ver_layout); | ||
133 | top_layout->addStretch(); | ||
134 | |||
135 | m_desc_group = new QGroupBox("Description", this); | ||
136 | QHBoxLayout *group_layout = new QHBoxLayout; | ||
137 | m_desc_edit = new MyTextEditor(this); | ||
138 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.GetDev().desc)); | ||
139 | group_layout->addWidget(m_desc_edit); | ||
140 | m_desc_group->setLayout(group_layout); | ||
141 | |||
142 | QVBoxLayout *layout = new QVBoxLayout; | ||
143 | layout->addLayout(top_layout, 0); | ||
144 | layout->addWidget(m_desc_group, 1); | ||
145 | |||
146 | setLayout(layout); | ||
147 | 163 | ||
148 | SocFieldItemDelegate *m_table_delegate = new SocFieldItemDelegate(this); | 164 | void SocEditPanel::OnIsaEdited(const QString& text) |
149 | QItemEditorFactory *m_table_edit_factory = new QItemEditorFactory(); | 165 | { |
150 | SocFieldEditorCreator *m_table_edit_creator = new SocFieldEditorCreator(); | 166 | m_ref.get()->isa = text.toStdString(); |
151 | m_table_edit_factory->registerEditor(QVariant::UInt, m_table_edit_creator); | 167 | OnModified(); |
152 | m_table_delegate->setItemEditorFactory(m_table_edit_factory); | ||
153 | m_instances_table->setItemDelegate(m_table_delegate); | ||
154 | |||
155 | connect(m_instances_table, SIGNAL(cellActivated(int,int)), this, SLOT(OnInstActivated(int,int))); | ||
156 | connect(m_instances_table, SIGNAL(cellChanged(int,int)), this, SLOT(OnInstChanged(int,int))); | ||
157 | connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameEdited(const QString&))); | ||
158 | connect(m_long_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnLongNameEdited(const QString&))); | ||
159 | connect(m_version_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnVersionEdited(const QString&))); | ||
160 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited())); | ||
161 | } | 168 | } |
162 | 169 | ||
163 | void DevEditPanel::OnNameEdited(const QString& text) | 170 | void SocEditPanel::OnTextEdited() |
164 | { | 171 | { |
165 | m_ref.GetDev().name = text.toStdString(); | 172 | m_ref.get()->desc = m_desc_edit->GetTextHtml().toStdString(); |
166 | OnModified(m_name_edit->isModified()); | 173 | OnModified(); |
167 | } | 174 | } |
168 | 175 | ||
169 | void DevEditPanel::OnLongNameEdited(const QString& text) | 176 | void SocEditPanel::OnAuthorActivated(QTableWidgetItem *item) |
170 | { | 177 | { |
171 | m_ref.GetDev().long_name = text.toStdString(); | 178 | if(item->type() == SocEditPanelDelType) |
172 | OnModified(m_long_name_edit->isModified()); | 179 | { |
180 | int row = item->row(); | ||
181 | my_remove_at(m_ref.get()->author, row); | ||
182 | m_authors_list->removeRow(row); | ||
183 | OnModified(); | ||
184 | } | ||
185 | else if(item->type() == SocEditPanelAddType) | ||
186 | { | ||
187 | int row = m_ref.get()->author.size(); | ||
188 | m_ref.get()->author.push_back("Anonymous"); | ||
189 | m_authors_list->insertRow(row); | ||
190 | QTableWidgetItem *item = new QTableWidgetItem( | ||
191 | QIcon::fromTheme("list-remove"), "", SocEditPanelDelType); | ||
192 | item->setFlags(Qt::ItemIsEnabled); | ||
193 | m_authors_list->setItem(row, 0, item); | ||
194 | item = new QTableWidgetItem(QString::fromStdString(m_ref.get()->author.back())); | ||
195 | m_authors_list->setItem(row, 1, item); | ||
196 | OnModified(); | ||
197 | } | ||
173 | } | 198 | } |
174 | 199 | ||
175 | void DevEditPanel::OnVersionEdited(const QString& text) | 200 | void SocEditPanel::OnAuthorChanged(QTableWidgetItem *item) |
176 | { | 201 | { |
177 | m_ref.GetDev().version = text.toStdString(); | 202 | if((size_t)item->row() >= m_ref.get()->author.size()) |
178 | OnModified(m_version_edit->isModified()); | 203 | return; |
204 | if(item->column() == 1) | ||
205 | m_ref.get()->author[item->row()] = item->text().toStdString(); | ||
206 | OnModified(); | ||
179 | } | 207 | } |
180 | 208 | ||
181 | void DevEditPanel::OnDescEdited() | 209 | /** |
210 | * NodeInstanceEditPanel | ||
211 | */ | ||
212 | |||
213 | namespace | ||
182 | { | 214 | { |
183 | m_ref.GetDev().desc = m_desc_edit->GetTextHtml().toStdString(); | 215 | |
184 | OnModified(m_desc_edit->IsModified()); | 216 | template< typename T > |
217 | soc_id_t GetFreshId(const std::vector< T >& list) | ||
218 | { | ||
219 | soc_id_t id = 0; | ||
220 | for(size_t i = 0; i < list.size(); i++) | ||
221 | id = std::max(id, list[i].id); | ||
222 | return id + 1; | ||
185 | } | 223 | } |
186 | 224 | ||
187 | void DevEditPanel::CreateNewRow(int row) | 225 | template< typename T > |
226 | int GetIndexById(const std::vector< T >& list, soc_id_t id) | ||
188 | { | 227 | { |
189 | QTableWidgetItem *item = new QTableWidgetItem(QIcon::fromTheme("list-add"), "", DevInstNewType); | 228 | for(size_t i = 0; i < list.size(); i++) |
190 | item->setToolTip("New?"); | 229 | if(list[i].id == id) |
191 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | 230 | return i; |
192 | m_instances_table->setItem(row, DevInstIconColumn, item); | 231 | return -1; |
193 | item = new QTableWidgetItem("New instance..."); | ||
194 | QFont font = item->font(); | ||
195 | font.setItalic(true); | ||
196 | item->setFont(font); | ||
197 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
198 | m_instances_table->setItem(row, DevInstNameColumn, item); | ||
199 | item = new QTableWidgetItem(""); | ||
200 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
201 | m_instances_table->setItem(row, DevInstAddrColumn, item); | ||
202 | } | 232 | } |
203 | 233 | ||
204 | void DevEditPanel::FillRow(int row, const soc_dev_addr_t& addr) | 234 | soc_desc::instance_t *GetInstanceById(const soc_desc::node_ref_t& node, soc_id_t id) |
205 | { | 235 | { |
206 | QTableWidgetItem *item = new QTableWidgetItem(QString::fromStdString(addr.name)); | 236 | std::vector< soc_desc::instance_t >& inst_list = node.get()->instance; |
207 | item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); | 237 | for(size_t i = 0; i < inst_list.size(); i++) |
208 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | 238 | if(inst_list[i].id == id) |
209 | m_instances_table->setItem(row, DevInstNameColumn, item); | 239 | return &inst_list[i]; |
210 | item = new QTableWidgetItem(); | 240 | return 0; |
211 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | ||
212 | item->setData(Qt::DisplayRole, QVariant(addr.addr)); | ||
213 | m_instances_table->setItem(row, DevInstAddrColumn, item); | ||
214 | item = new QTableWidgetItem(QIcon::fromTheme("list-remove"), "", DevInstDeleteType); | ||
215 | item->setToolTip("Remove?"); | ||
216 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
217 | m_instances_table->setItem(row, DevInstIconColumn, item); | ||
218 | } | 241 | } |
219 | 242 | ||
220 | void DevEditPanel::OnInstActivated(int row, int column) | 243 | bool RemoveInstanceById(const soc_desc::node_ref_t& node, soc_id_t id) |
221 | { | 244 | { |
222 | if(column != 0) | 245 | std::vector< soc_desc::instance_t >& inst_list = node.get()->instance; |
223 | return; | 246 | for(size_t i = 0; i < inst_list.size(); i++) |
224 | int type = m_instances_table->item(row, column)->type(); | 247 | if(inst_list[i].id == id) |
225 | if(type == DevInstDeleteType) | 248 | { |
226 | { | 249 | my_remove_at(inst_list, i); |
227 | m_ref.GetDev().addr.erase(m_ref.GetDev().addr.begin() + row); | 250 | return true; |
228 | m_instances_table->removeRow(row); | 251 | } |
229 | OnModified(true); | 252 | return false; |
230 | } | ||
231 | else if(type == DevInstNewType) | ||
232 | { | ||
233 | m_instances_table->insertRow(row); | ||
234 | soc_dev_addr_t addr; | ||
235 | addr.name = QString("UNNAMED_%1").arg(row).toStdString(); | ||
236 | addr.addr = 0; | ||
237 | m_ref.GetDev().addr.push_back(addr); | ||
238 | FillRow(row, addr); | ||
239 | } | ||
240 | } | 253 | } |
241 | 254 | ||
242 | void DevEditPanel::OnInstChanged(int row, int column) | 255 | enum |
243 | { | 256 | { |
244 | /* ignore extra row for addition */ | 257 | InstTypeSingle, |
245 | if(row >= (int)m_ref.GetDev().addr.size()) | 258 | InstTypeRangeStride, |
246 | return; | 259 | InstTypeRangeFormula, |
247 | QTableWidgetItem *item = m_instances_table->item(row, column); | 260 | InstTypeRangeList |
248 | if(column == DevInstNameColumn) | 261 | }; |
262 | |||
263 | enum | ||
264 | { | ||
265 | NodeInstEditPanelDelType = QTableWidgetItem::UserType, | ||
266 | NodeInstEditPanelAddType | ||
267 | }; | ||
268 | |||
269 | } | ||
270 | |||
271 | NodeInstanceEditPanel::NodeInstanceEditPanel(const soc_desc::node_ref_t& ref, | ||
272 | soc_id_t inst_id, QWidget *parent) | ||
273 | :QWidget(parent), m_ref(ref), m_id(inst_id) | ||
274 | { | ||
275 | QLineEdit *name_edit = new QLineEdit(this); | ||
276 | QLineEdit *title_edit = new QLineEdit(this); | ||
277 | m_type_combo = new QComboBox(this); | ||
278 | QLabel *type_label = new QLabel("Type:", this); | ||
279 | QFont f = type_label->font(); | ||
280 | f.setBold(true); | ||
281 | type_label->setFont(f); | ||
282 | |||
283 | QHBoxLayout *type_layout = new QHBoxLayout; | ||
284 | type_layout->addWidget(type_label); | ||
285 | type_layout->addWidget(m_type_combo); | ||
286 | type_layout->addStretch(0); | ||
287 | |||
288 | soc_desc::field_t fake_field; | ||
289 | fake_field.pos = 0; | ||
290 | fake_field.width = 32; | ||
291 | |||
292 | m_single_group = new QWidget(this); | ||
293 | QHBoxLayout *sg_layout = new QHBoxLayout; | ||
294 | sg_layout->addWidget(new QLabel("Address:", m_single_group)); | ||
295 | SocFieldEditor *addr_edit = new SocFieldEditor(fake_field, m_single_group); | ||
296 | sg_layout->addWidget(addr_edit); | ||
297 | m_single_group->setLayout(sg_layout); | ||
298 | |||
299 | m_range_group = new QWidget(this); | ||
300 | QGridLayout *rg_layout = new QGridLayout; | ||
301 | rg_layout->addWidget(new QLabel("First:", m_range_group), 0, 0); | ||
302 | QSpinBox *first_spin = new QSpinBox(m_range_group); | ||
303 | rg_layout->addWidget(first_spin, 0, 1); | ||
304 | rg_layout->addWidget(new QLabel("Count:", m_range_group), 1, 0); | ||
305 | QSpinBox *count_spin = new QSpinBox(m_range_group); | ||
306 | rg_layout->addWidget(count_spin, 1, 1); | ||
307 | m_range_group->setLayout(rg_layout); | ||
308 | |||
309 | m_stride_group = new QWidget(m_range_group); | ||
310 | QGridLayout *rsg_layout = new QGridLayout; | ||
311 | rsg_layout->addWidget(new QLabel("Base:", m_stride_group), 0, 0); | ||
312 | SocFieldEditor *base_edit = new SocFieldEditor(fake_field, m_stride_group); | ||
313 | rsg_layout->addWidget(base_edit, 0, 1); | ||
314 | rsg_layout->addWidget(new QLabel("Stride:", m_stride_group), 1, 0); | ||
315 | SocFieldEditor *stride_edit = new SocFieldEditor(fake_field, m_stride_group); | ||
316 | rsg_layout->addWidget(stride_edit, 1, 1); | ||
317 | m_stride_group->setLayout(rsg_layout); | ||
318 | |||
319 | m_formula_group = new QWidget(m_range_group); | ||
320 | QGridLayout *fsg_layout = new QGridLayout; | ||
321 | fsg_layout->addWidget(new QLabel("Variable:", m_formula_group), 0, 0); | ||
322 | QLineEdit *variable_edit = new QLineEdit(m_formula_group); | ||
323 | fsg_layout->addWidget(variable_edit, 0, 1); | ||
324 | fsg_layout->addWidget(new QLabel("Formula:", m_formula_group), 1, 0); | ||
325 | QLineEdit *formula_edit = new QLineEdit(m_formula_group); | ||
326 | fsg_layout->addWidget(formula_edit, 1, 1); | ||
327 | m_formula_group->setLayout(fsg_layout); | ||
328 | |||
329 | QTableWidget *addr_list = new QTableWidget(m_range_group); | ||
330 | m_list_group = addr_list; | ||
331 | |||
332 | QHBoxLayout *inst_layout = new QHBoxLayout; | ||
333 | inst_layout->addWidget(m_single_group); | ||
334 | inst_layout->addWidget(m_range_group); | ||
335 | inst_layout->addWidget(m_stride_group); | ||
336 | inst_layout->addWidget(m_formula_group); | ||
337 | inst_layout->addWidget(m_list_group); | ||
338 | inst_layout->addStretch(0); | ||
339 | |||
340 | QGroupBox *inst_groupbox = new QGroupBox(this); | ||
341 | inst_groupbox->setLayout(inst_layout); | ||
342 | |||
343 | MyTextEditor *desc_edit = new MyTextEditor(this); | ||
344 | QVBoxLayout *ii_layout = new QVBoxLayout; | ||
345 | |||
346 | QFormLayout *info_layout = new QFormLayout(); | ||
347 | info_layout->addRow("Name", name_edit); | ||
348 | info_layout->addRow("Title", title_edit); | ||
349 | |||
350 | QGroupBox *info_group = Misc::EncloseInBox("Information", info_layout); | ||
351 | QGroupBox *desc_group = Misc::EncloseInBox("Description", desc_edit); | ||
352 | QHBoxLayout *name_title_desc_layout = new QHBoxLayout; | ||
353 | name_title_desc_layout->addWidget(info_group, 1); | ||
354 | name_title_desc_layout->addWidget(desc_group, 2); | ||
355 | |||
356 | ii_layout->addLayout(name_title_desc_layout); | ||
357 | ii_layout->addLayout(type_layout); | ||
358 | ii_layout->addWidget(inst_groupbox); | ||
359 | ii_layout->addStretch(1); | ||
360 | |||
361 | m_type_combo->addItem("Single", QVariant(InstTypeSingle)); | ||
362 | m_type_combo->addItem("Range > Stride", QVariant(InstTypeRangeStride)); | ||
363 | m_type_combo->addItem("Range > Formula", QVariant(InstTypeRangeFormula)); | ||
364 | m_type_combo->addItem("Range > List", QVariant(InstTypeRangeList)); | ||
365 | |||
366 | /* fill info */ | ||
367 | soc_desc::instance_t& inst = GetInstance(); | ||
368 | name_edit->setText(QString::fromStdString(inst.name)); | ||
369 | title_edit->setText(QString::fromStdString(inst.title)); | ||
370 | desc_edit->SetTextHtml(QString::fromStdString(inst.desc)); | ||
371 | addr_edit->setField(inst.addr); | ||
372 | base_edit->setField(inst.range.base); | ||
373 | stride_edit->setField(inst.range.stride); | ||
374 | first_spin->setValue(inst.range.first); | ||
375 | count_spin->setValue(inst.range.count); | ||
376 | formula_edit->setText(QString::fromStdString(inst.range.formula)); | ||
377 | variable_edit->setText(QString::fromStdString(inst.range.variable)); | ||
378 | addr_list->setColumnCount(2); | ||
379 | addr_list->setHorizontalHeaderItem(0, new QTableWidgetItem("")); | ||
380 | addr_list->setHorizontalHeaderItem(1, new QTableWidgetItem("Address")); | ||
381 | addr_list->horizontalHeader()->setVisible(false); | ||
382 | addr_list->verticalHeader()->setVisible(false); | ||
383 | addr_list->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | ||
384 | std::vector< soc_word_t >& addrs = inst.range.list; | ||
385 | addr_list->setRowCount(addrs.size() + 1); | ||
386 | for(size_t i = 0; i < addrs.size(); i++) | ||
249 | { | 387 | { |
250 | m_ref.GetDev().addr[row].name = item->text().toStdString(); | 388 | QTableWidgetItem *item = new QTableWidgetItem( |
251 | OnModified(true); | 389 | QIcon::fromTheme("list-remove"), "", NodeInstEditPanelDelType); |
390 | item->setFlags(Qt::ItemIsEnabled); | ||
391 | addr_list->setItem(i, 0, item); | ||
392 | item = new QTableWidgetItem(); | ||
393 | item->setData(Qt::EditRole, QVariant::fromValue(addrs[i])); | ||
394 | addr_list->setItem(i, 1, item); | ||
252 | } | 395 | } |
253 | else if(column == DevInstAddrColumn) | 396 | QTableWidgetItem *new_item = new QTableWidgetItem( |
397 | QIcon::fromTheme("list-add"), "", NodeInstEditPanelAddType); | ||
398 | new_item->setFlags(Qt::ItemIsEnabled); | ||
399 | addr_list->setItem(addrs.size(), 0, new_item); | ||
400 | new_item = new QTableWidgetItem("New address...", QTableWidgetItem::UserType); | ||
401 | new_item->setFlags(Qt::ItemIsEnabled); | ||
402 | QFont font = new_item->font(); | ||
403 | font.setItalic(true); | ||
404 | new_item->setFont(font); | ||
405 | addr_list->setItem(addrs.size(), 1, new_item); | ||
406 | addr_list->resizeColumnsToContents(); | ||
407 | addr_list->horizontalHeader()->setStretchLastSection(true); | ||
408 | m_table_delegate = new SocFieldItemDelegate(this); | ||
409 | m_table_delegate->setItemEditorFactory(new QItemEditorFactory); | ||
410 | m_table_edit_factory = new SocFieldEditorCreator; | ||
411 | m_table_delegate->itemEditorFactory()->registerEditor(QVariant::UInt, m_table_edit_factory); | ||
412 | addr_list->setItemDelegate(m_table_delegate); | ||
413 | |||
414 | setLayout(ii_layout); | ||
415 | |||
416 | connect(name_edit, SIGNAL(textChanged(const QString&)), this, | ||
417 | SLOT(OnNameEdited(const QString&))); | ||
418 | connect(desc_edit, SIGNAL(OnTextChanged(const QString&)), this, | ||
419 | SLOT(OnDescEdited(const QString&))); | ||
420 | connect(title_edit, SIGNAL(textChanged(const QString&)), this, | ||
421 | SLOT(OnTitleEdited(const QString&))); | ||
422 | connect(addr_edit, SIGNAL(editingFinished(uint)), this, SLOT(OnAddrChanged(uint))); | ||
423 | connect(base_edit, SIGNAL(editingFinished(uint)), this, SLOT(OnBaseChanged(uint))); | ||
424 | connect(stride_edit, SIGNAL(editingFinished(uint)), this, SLOT(OnStrideChanged(uint))); | ||
425 | connect(first_spin, SIGNAL(valueChanged(int)), this, SLOT(OnFirstChanged(int))); | ||
426 | connect(count_spin, SIGNAL(valueChanged(int)), this, SLOT(OnCountChanged(int))); | ||
427 | connect(formula_edit, SIGNAL(textChanged(const QString&)), this, | ||
428 | SLOT(OnFormulaChanged(const QString&))); | ||
429 | connect(variable_edit, SIGNAL(textChanged(const QString&)), this, | ||
430 | SLOT(OnVariableChanged(const QString&))); | ||
431 | connect(m_type_combo, SIGNAL(currentIndexChanged(int)), | ||
432 | this, SLOT(OnTypeChanged(int))); | ||
433 | connect(addr_list, SIGNAL(itemActivated(QTableWidgetItem *)), this, | ||
434 | SLOT(OnAddressActivated(QTableWidgetItem *))); | ||
435 | connect(addr_list, SIGNAL(itemChanged(QTableWidgetItem *)), this, | ||
436 | SLOT(OnAddressChanged(QTableWidgetItem *))); | ||
437 | |||
438 | /* fill info */ | ||
439 | int combo_type; | ||
440 | if(inst.type == soc_desc::instance_t::RANGE) | ||
254 | { | 441 | { |
255 | m_ref.GetDev().addr[row].addr = item->data(Qt::DisplayRole).toUInt(); | 442 | if(inst.range.type == soc_desc::range_t::STRIDE) |
256 | OnModified(true); | 443 | combo_type = InstTypeRangeStride; |
444 | else if(inst.range.type == soc_desc::range_t::FORMULA) | ||
445 | combo_type = InstTypeRangeFormula; | ||
446 | else /* LIST */ | ||
447 | combo_type = InstTypeRangeList; | ||
257 | } | 448 | } |
449 | else | ||
450 | combo_type = InstTypeSingle; | ||
451 | m_type_combo->setCurrentIndex(m_type_combo->findData(QVariant(combo_type))); | ||
452 | UpdateType(combo_type); | ||
258 | } | 453 | } |
259 | 454 | ||
260 | /** | 455 | soc_desc::instance_t& NodeInstanceEditPanel::GetInstance() |
261 | * RegEditPanel | 456 | { |
262 | */ | 457 | return *GetInstanceById(m_ref, m_id); |
458 | } | ||
263 | 459 | ||
264 | RegEditPanel::RegEditPanel(SocRegRef ref, QWidget *parent) | 460 | void NodeInstanceEditPanel::OnNameEdited(const QString& text) |
265 | :QWidget(parent), m_ref(ref), m_reg_font(font()) | ||
266 | { | 461 | { |
267 | m_reg_font.setWeight(100); | 462 | GetInstance().name = text.toStdString(); |
268 | m_reg_font.setKerning(false); | 463 | OnModified(); |
464 | } | ||
269 | 465 | ||
270 | m_name_group = new QGroupBox("Name", this); | 466 | void NodeInstanceEditPanel::OnTitleEdited(const QString& text) |
271 | m_name_edit = new QLineEdit(this); | 467 | { |
272 | m_name_edit->setText(QString::fromStdString(ref.GetReg().name)); | 468 | GetInstance().title = text.toStdString(); |
273 | QVBoxLayout *name_group_layout = new QVBoxLayout; | 469 | OnModified(); |
274 | name_group_layout->addWidget(m_name_edit); | 470 | } |
275 | m_name_group->setLayout(name_group_layout); | ||
276 | |||
277 | m_instances_table = new QTableWidget(this); | ||
278 | m_instances_table->setRowCount(ref.GetReg().addr.size() + 1); | ||
279 | m_instances_table->setColumnCount(RegInstNrColumns); | ||
280 | for(size_t row = 0; row < ref.GetReg().addr.size(); row++) | ||
281 | FillRow(row, ref.GetReg().addr[row]); | ||
282 | CreateNewAddrRow(ref.GetReg().addr.size()); | ||
283 | m_instances_table->setHorizontalHeaderItem(RegInstIconColumn, new QTableWidgetItem("")); | ||
284 | m_instances_table->setHorizontalHeaderItem(RegInstNameColumn, new QTableWidgetItem("Name")); | ||
285 | m_instances_table->setHorizontalHeaderItem(RegInstAddrColumn, new QTableWidgetItem("Address")); | ||
286 | m_instances_table->verticalHeader()->setVisible(false); | ||
287 | m_instances_table->resizeColumnsToContents(); | ||
288 | m_instances_table->horizontalHeader()->setStretchLastSection(true); | ||
289 | m_instances_table->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); | ||
290 | m_instances_group = new QGroupBox("Instances", this); | ||
291 | QHBoxLayout *instances_group_layout = new QHBoxLayout; | ||
292 | instances_group_layout->addWidget(m_instances_table); | ||
293 | m_instances_group->setLayout(instances_group_layout); | ||
294 | |||
295 | m_desc_group = new QGroupBox("Description", this); | ||
296 | QHBoxLayout *group_layout = new QHBoxLayout; | ||
297 | m_desc_edit = new MyTextEditor(this); | ||
298 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.GetReg().desc)); | ||
299 | group_layout->addWidget(m_desc_edit); | ||
300 | m_desc_group->setLayout(group_layout); | ||
301 | |||
302 | bool has_sct = m_ref.GetReg().flags & REG_HAS_SCT; | ||
303 | m_sct_check = new QCheckBox("Set/Clear/Toggle", this); | ||
304 | m_sct_check->setCheckState(has_sct ? Qt::Checked : Qt::Unchecked); | ||
305 | QHBoxLayout *flags_layout = new QHBoxLayout; | ||
306 | flags_layout->addWidget(m_sct_check); | ||
307 | flags_layout->addStretch(); | ||
308 | m_flags_group = new QGroupBox("Flags", this); | ||
309 | m_flags_group->setLayout(flags_layout); | ||
310 | |||
311 | m_formula_combo = new QComboBox(this); | ||
312 | m_formula_combo->addItem("None", QVariant(REG_FORMULA_NONE)); | ||
313 | m_formula_combo->addItem("String", QVariant(REG_FORMULA_STRING)); | ||
314 | m_formula_combo->setCurrentIndex(m_formula_combo->findData(QVariant(m_ref.GetReg().formula.type))); | ||
315 | m_formula_type_label = new QLabel("Type:", this); | ||
316 | QHBoxLayout *formula_top_layout = new QHBoxLayout; | ||
317 | formula_top_layout->addWidget(m_formula_type_label); | ||
318 | formula_top_layout->addWidget(m_formula_combo); | ||
319 | m_formula_string_edit = new QLineEdit(QString::fromStdString(ref.GetReg().formula.string), this); | ||
320 | QVBoxLayout *formula_layout = new QVBoxLayout; | ||
321 | formula_layout->addLayout(formula_top_layout); | ||
322 | formula_layout->addWidget(m_formula_string_edit); | ||
323 | m_formula_string_gen = new QPushButton("Generate", this); | ||
324 | formula_layout->addWidget(m_formula_string_gen); | ||
325 | m_formula_group = new QGroupBox("Formula", this); | ||
326 | m_formula_group->setLayout(formula_layout); | ||
327 | |||
328 | QVBoxLayout *name_layout = new QVBoxLayout; | ||
329 | name_layout->addWidget(m_name_group); | ||
330 | name_layout->addWidget(m_flags_group); | ||
331 | name_layout->addWidget(m_formula_group); | ||
332 | name_layout->addStretch(); | ||
333 | |||
334 | QHBoxLayout *top_layout = new QHBoxLayout; | ||
335 | top_layout->addWidget(m_instances_group); | ||
336 | top_layout->addLayout(name_layout); | ||
337 | top_layout->addWidget(m_desc_group, 1); | ||
338 | |||
339 | m_value_table = new QTableView(this); | ||
340 | m_value_model = new RegFieldTableModel(m_value_table); // view takes ownership | ||
341 | m_value_model->SetRegister(m_ref.GetReg()); | ||
342 | m_value_model->SetReadOnly(true); | ||
343 | m_value_table->setModel(m_value_model); | ||
344 | m_value_table->verticalHeader()->setVisible(false); | ||
345 | m_value_table->horizontalHeader()->setStretchLastSection(true); | ||
346 | m_value_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | ||
347 | // FIXME we cannot use setAlternatingRowColors() because we override the | ||
348 | // background color, should it be part of the model ? | ||
349 | m_table_delegate = new SocFieldCachedItemDelegate(this); | ||
350 | m_value_table->setItemDelegate(m_table_delegate); | ||
351 | m_value_table->resizeColumnsToContents(); | ||
352 | |||
353 | m_sexy_display2 = new Unscroll<RegSexyDisplay2>(this); | ||
354 | m_sexy_display2->setFont(m_reg_font); | ||
355 | m_sexy_display2->setModel(m_value_model); | ||
356 | m_sexy_display2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | ||
357 | 471 | ||
358 | QHBoxLayout *field_layout = new QHBoxLayout; | 472 | void NodeInstanceEditPanel::OnDescEdited(const QString& text) |
359 | field_layout->addWidget(m_value_table); | 473 | { |
360 | m_field_group = new QGroupBox("Flags", this); | 474 | GetInstance().desc = text.toStdString(); |
361 | m_field_group->setLayout(field_layout); | 475 | OnModified(); |
476 | } | ||
362 | 477 | ||
363 | QVBoxLayout *layout = new QVBoxLayout; | 478 | void NodeInstanceEditPanel::OnAddrChanged(uint addr) |
364 | layout->addLayout(top_layout, 0); | 479 | { |
365 | layout->addWidget(m_sexy_display2, 0); | 480 | GetInstance().addr = addr; |
366 | layout->addWidget(m_field_group); | 481 | OnModified(); |
482 | } | ||
367 | 483 | ||
368 | UpdateFormula(); | 484 | void NodeInstanceEditPanel::OnBaseChanged(uint base) |
485 | { | ||
486 | GetInstance().range.base = base; | ||
487 | OnModified(); | ||
488 | } | ||
369 | 489 | ||
370 | setLayout(layout); | 490 | void NodeInstanceEditPanel::OnStrideChanged(uint stride) |
491 | { | ||
492 | GetInstance().range.stride = stride; | ||
493 | OnModified(); | ||
494 | } | ||
371 | 495 | ||
372 | SocFieldItemDelegate *m_table_delegate = new SocFieldItemDelegate(this); | 496 | void NodeInstanceEditPanel::OnFirstChanged(int first) |
373 | QItemEditorFactory *m_table_edit_factory = new QItemEditorFactory(); | 497 | { |
374 | SocFieldEditorCreator *m_table_edit_creator = new SocFieldEditorCreator(); | 498 | GetInstance().range.first = first; |
375 | m_table_edit_factory->registerEditor(QVariant::UInt, m_table_edit_creator); | 499 | OnModified(); |
376 | m_table_delegate->setItemEditorFactory(m_table_edit_factory); | 500 | } |
377 | m_instances_table->setItemDelegate(m_table_delegate); | ||
378 | 501 | ||
379 | connect(m_instances_table, SIGNAL(cellActivated(int,int)), this, SLOT(OnInstActivated(int,int))); | 502 | void NodeInstanceEditPanel::OnCountChanged(int count) |
380 | connect(m_instances_table, SIGNAL(cellChanged(int,int)), this, SLOT(OnInstChanged(int,int))); | 503 | { |
381 | connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameEdited(const QString&))); | 504 | GetInstance().range.count = count; |
382 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited())); | 505 | OnModified(); |
383 | connect(m_sct_check, SIGNAL(stateChanged(int)), this, SLOT(OnSctEdited(int))); | ||
384 | connect(m_formula_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(OnFormulaChanged(int))); | ||
385 | connect(m_formula_string_edit, SIGNAL(textChanged(const QString&)), this, | ||
386 | SLOT(OnFormulaStringChanged(const QString&))); | ||
387 | connect(m_formula_string_gen, SIGNAL(clicked(bool)), this, SLOT(OnFormulaGenerate(bool))); | ||
388 | } | 506 | } |
389 | 507 | ||
390 | void RegEditPanel::UpdateWarning(int row) | 508 | void NodeInstanceEditPanel::OnFormulaChanged(const QString& formula) |
391 | { | 509 | { |
392 | Q_UNUSED(row); | 510 | GetInstance().range.formula = formula.toStdString(); |
511 | OnModified(); | ||
393 | } | 512 | } |
394 | 513 | ||
395 | void RegEditPanel::OnFormulaStringChanged(const QString& text) | 514 | void NodeInstanceEditPanel::OnVariableChanged(const QString& variable) |
396 | { | 515 | { |
397 | m_ref.GetReg().formula.string = text.toStdString(); | 516 | GetInstance().range.variable = variable.toStdString(); |
398 | OnModified(true); | 517 | OnModified(); |
399 | } | 518 | } |
400 | 519 | ||
401 | void RegEditPanel::OnFormulaGenerate(bool checked) | 520 | void NodeInstanceEditPanel::OnAddressActivated(QTableWidgetItem *item) |
402 | { | 521 | { |
403 | Q_UNUSED(checked); | 522 | QTableWidget *table = item->tableWidget(); |
404 | bool ok; | 523 | soc_desc::instance_t& inst = GetInstance(); |
405 | int count = QInputDialog::getInt(this, "Instance generator", "Number of instances", | 524 | if(item->type() == NodeInstEditPanelDelType) |
406 | 0, 0, 100, 1, &ok); | ||
407 | if(!ok) | ||
408 | return; | ||
409 | std::string name(m_ref.GetReg().name); | ||
410 | size_t pos = name.find('n'); | ||
411 | if(pos == std::string::npos) | ||
412 | { | ||
413 | name.push_back('n'); | ||
414 | pos = name.size() - 1; | ||
415 | } | ||
416 | std::map< std::string, soc_word_t > map; | ||
417 | std::vector< std::pair< std::string, soc_word_t > > list; | ||
418 | std::string formula = m_ref.GetReg().formula.string; | ||
419 | for(int n = 0; n < count; n++) | ||
420 | { | 525 | { |
421 | map["n"] = n; | 526 | int row = item->row(); |
422 | std::string err; | 527 | my_remove_at(inst.range.list, row); |
423 | soc_word_t res; | 528 | table->removeRow(row); |
424 | if(!evaluate_formula(formula, map, res, err)) | 529 | OnModified(); |
425 | { | ||
426 | qDebug() << "Cannot evaluator " << QString::fromStdString(formula) | ||
427 | << "for n=" << n << ": " << QString::fromStdString(err); | ||
428 | return; | ||
429 | } | ||
430 | std::string regname = name; | ||
431 | std::string strn = QString("%1").arg(n).toStdString(); | ||
432 | regname.replace(pos, 1, strn); | ||
433 | list.push_back(std::make_pair(regname, res)); | ||
434 | } | 530 | } |
435 | // everything went good, commit result | 531 | else if(item->type() == NodeInstEditPanelAddType) |
436 | while(m_instances_table->rowCount() > 1) | ||
437 | m_instances_table->removeRow(0); | ||
438 | m_ref.GetReg().addr.resize(list.size()); | ||
439 | for(size_t i = 0; i < list.size(); i++) | ||
440 | { | 532 | { |
441 | m_instances_table->insertRow(i); | 533 | int row = inst.range.list.size(); |
442 | m_ref.GetReg().addr[i].name = list[i].first; | 534 | soc_word_t new_addr = 0; |
443 | m_ref.GetReg().addr[i].addr = list[i].second; | 535 | GetInstance().range.list.push_back(new_addr); |
444 | FillRow(i, m_ref.GetReg().addr[i]); | 536 | table->insertRow(row); |
537 | QTableWidgetItem *item = new QTableWidgetItem( | ||
538 | QIcon::fromTheme("list-remove"), "", NodeInstEditPanelDelType); | ||
539 | item->setFlags(Qt::ItemIsEnabled); | ||
540 | table->setItem(row, 0, item); | ||
541 | item = new QTableWidgetItem(); | ||
542 | item->setData(Qt::EditRole, QVariant(new_addr)); | ||
543 | table->setItem(row, 1, item); | ||
544 | OnModified(); | ||
445 | } | 545 | } |
446 | } | 546 | } |
447 | 547 | ||
448 | void RegEditPanel::OnFormulaChanged(int index) | 548 | void NodeInstanceEditPanel::OnAddressChanged(QTableWidgetItem *item) |
449 | { | 549 | { |
450 | if(index == -1) | 550 | soc_desc::instance_t& inst = GetInstance(); |
551 | if((size_t)item->row() >= inst.range.list.size()) | ||
451 | return; | 552 | return; |
452 | m_ref.GetReg().formula.type = static_cast< soc_reg_formula_type_t >(m_formula_combo->itemData(index).toInt()); | 553 | soc_word_t& addr = inst.range.list[item->row()]; |
453 | UpdateFormula(); | 554 | if(item->column() == 1) |
454 | OnModified(true); | 555 | addr = item->data(Qt::EditRole).value< soc_word_t >(); |
556 | OnModified(); | ||
455 | } | 557 | } |
456 | 558 | ||
457 | void RegEditPanel::UpdateFormula() | 559 | void NodeInstanceEditPanel::UpdateType(int type) |
458 | { | 560 | { |
459 | m_formula_string_edit->hide(); | 561 | m_single_group->hide(); |
460 | m_formula_string_gen->hide(); | 562 | m_range_group->hide(); |
461 | switch(m_ref.GetReg().formula.type) | 563 | m_stride_group->hide(); |
564 | m_formula_group->hide(); | ||
565 | m_list_group->hide(); | ||
566 | |||
567 | switch(type) | ||
462 | { | 568 | { |
463 | case REG_FORMULA_STRING: | 569 | case InstTypeSingle: |
464 | m_formula_string_edit->show(); | 570 | m_single_group->show(); |
465 | m_formula_string_gen->show(); | 571 | GetInstance().type = soc_desc::instance_t::SINGLE; |
572 | break; | ||
573 | case InstTypeRangeStride: | ||
574 | m_range_group->show(); | ||
575 | m_stride_group->show(); | ||
576 | GetInstance().type = soc_desc::instance_t::RANGE; | ||
577 | GetInstance().range.type = soc_desc::range_t::STRIDE; | ||
578 | break; | ||
579 | case InstTypeRangeFormula: | ||
580 | m_range_group->show(); | ||
581 | m_formula_group->show(); | ||
582 | GetInstance().type = soc_desc::instance_t::RANGE; | ||
583 | GetInstance().range.type = soc_desc::range_t::FORMULA; | ||
584 | break; | ||
585 | case InstTypeRangeList: | ||
586 | m_range_group->show(); | ||
587 | m_formula_group->hide(); | ||
588 | m_list_group->show(); | ||
589 | GetInstance().type = soc_desc::instance_t::RANGE; | ||
590 | GetInstance().range.type = soc_desc::range_t::LIST; | ||
466 | break; | 591 | break; |
467 | case REG_FORMULA_NONE: | ||
468 | default: | 592 | default: |
469 | break; | 593 | break; |
470 | } | 594 | } |
471 | } | 595 | } |
472 | 596 | ||
473 | void RegEditPanel::OnSctEdited(int state) | 597 | void NodeInstanceEditPanel::OnTypeChanged(int index) |
474 | { | 598 | { |
475 | if(state == Qt::Checked) | 599 | if(index == -1) |
476 | m_ref.GetReg().flags |= REG_HAS_SCT; | 600 | return; |
477 | else | 601 | UpdateType(m_type_combo->itemData(index).toInt()); |
478 | m_ref.GetReg().flags &= ~REG_HAS_SCT; | 602 | OnModified(); |
479 | OnModified(true); | ||
480 | } | ||
481 | |||
482 | void RegEditPanel::FillRow(int row, const soc_reg_addr_t& addr) | ||
483 | { | ||
484 | QTableWidgetItem *item = new QTableWidgetItem(QString::fromStdString(addr.name)); | ||
485 | item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); | ||
486 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | ||
487 | m_instances_table->setItem(row, RegInstNameColumn, item); | ||
488 | item = new QTableWidgetItem(); | ||
489 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | ||
490 | item->setData(Qt::DisplayRole, QVariant(addr.addr)); | ||
491 | m_instances_table->setItem(row, RegInstAddrColumn, item); | ||
492 | item = new QTableWidgetItem(QIcon::fromTheme("list-remove"), "", RegInstDeleteType); | ||
493 | item->setToolTip("Remove?"); | ||
494 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
495 | m_instances_table->setItem(row, RegInstIconColumn, item); | ||
496 | } | ||
497 | |||
498 | void RegEditPanel::CreateNewAddrRow(int row) | ||
499 | { | ||
500 | QTableWidgetItem *item = new QTableWidgetItem(QIcon::fromTheme("list-add"), "", RegInstNewType); | ||
501 | item->setToolTip("New?"); | ||
502 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
503 | m_instances_table->setItem(row, RegInstIconColumn, item); | ||
504 | item = new QTableWidgetItem("New instance..."); | ||
505 | QFont font = item->font(); | ||
506 | font.setItalic(true); | ||
507 | item->setFont(font); | ||
508 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
509 | m_instances_table->setItem(row, RegInstNameColumn, item); | ||
510 | item = new QTableWidgetItem(""); | ||
511 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
512 | m_instances_table->setItem(row, RegInstAddrColumn, item); | ||
513 | } | 603 | } |
514 | 604 | ||
515 | void RegEditPanel::OnNameEdited(const QString& text) | 605 | soc_id_t NodeInstanceEditPanel::GetId() |
516 | { | 606 | { |
517 | m_ref.GetReg().name = text.toStdString(); | 607 | return m_id; |
518 | OnModified(m_name_edit->isModified()); | ||
519 | } | 608 | } |
520 | 609 | ||
521 | void RegEditPanel::OnDescEdited() | 610 | /** |
522 | { | 611 | * NodeEditPanel |
523 | m_ref.GetReg().desc = m_desc_edit->GetTextHtml().toStdString(); | 612 | */ |
524 | OnModified(m_desc_edit->IsModified()); | ||
525 | } | ||
526 | 613 | ||
527 | void RegEditPanel::OnInstActivated(int row, int column) | 614 | NodeEditPanel::NodeEditPanel(const soc_desc::node_ref_t& ref, QWidget *parent) |
615 | :QWidget(parent), m_ref(ref) | ||
528 | { | 616 | { |
529 | if(column != 0) | 617 | /* top layout: name, title then desc */ |
530 | return; | 618 | QLineEdit *name_edit = new QLineEdit(this); |
531 | int type = m_instances_table->item(row, column)->type(); | 619 | name_edit->setText(QString::fromStdString(ref.get()->name)); |
532 | if(type == RegInstDeleteType) | 620 | |
533 | { | 621 | QLineEdit *title_edit = new QLineEdit(this); |
534 | m_ref.GetReg().addr.erase(m_ref.GetReg().addr.begin() + row); | 622 | title_edit->setText(QString::fromStdString(ref.get()->title)); |
535 | m_instances_table->removeRow(row); | 623 | |
536 | OnModified(true); | 624 | QFormLayout *info_layout = new QFormLayout(); |
537 | } | 625 | info_layout->addRow("Name", name_edit); |
538 | else if(type == RegInstNewType) | 626 | info_layout->addRow("Title", title_edit); |
627 | |||
628 | QGroupBox *info_group = Misc::EncloseInBox("Information", info_layout); | ||
629 | |||
630 | m_desc_edit = new MyTextEditor(this); | ||
631 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.get()->desc)); | ||
632 | QGroupBox *desc_group = Misc::EncloseInBox("Description", m_desc_edit); | ||
633 | |||
634 | QHBoxLayout *name_title_desc_layout = new QHBoxLayout; | ||
635 | name_title_desc_layout->addWidget(info_group, 1); | ||
636 | name_title_desc_layout->addWidget(desc_group, 2); | ||
637 | |||
638 | /* instance tab */ | ||
639 | m_instances_tab = new YTabWidget(0, this); | ||
640 | m_instances_tab->setTabOpenable(true); | ||
641 | std::vector< soc_desc::instance_t >& inst_list = m_ref.get()->instance; | ||
642 | m_instances_tab->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); | ||
643 | m_instances_tab->setTabsClosable(true); | ||
644 | QGroupBox *instance_tab_group = Misc::EncloseInBox("Instances", m_instances_tab); | ||
645 | for(size_t i = 0; i < inst_list.size(); i++) | ||
539 | { | 646 | { |
540 | m_instances_table->insertRow(row); | 647 | NodeInstanceEditPanel *p = new NodeInstanceEditPanel(m_ref, inst_list[i].id, this); |
541 | soc_reg_addr_t addr; | 648 | connect(p, SIGNAL(OnModified()), this, SLOT(OnInstModified())); |
542 | addr.name = QString("UNNAMED_%1").arg(row).toStdString(); | 649 | m_instances_tab->addTab(p, QString::fromStdString(inst_list[i].name)); |
543 | addr.addr = 0; | ||
544 | m_ref.GetReg().addr.push_back(addr); | ||
545 | FillRow(row, addr); | ||
546 | } | 650 | } |
651 | |||
652 | /* boring */ | ||
653 | QVBoxLayout *layout = new QVBoxLayout; | ||
654 | layout->addLayout(name_title_desc_layout); | ||
655 | layout->addWidget(instance_tab_group); | ||
656 | layout->addStretch(1); | ||
657 | |||
658 | setLayout(layout); | ||
659 | |||
660 | connect(name_edit, SIGNAL(textChanged(const QString&)), this, | ||
661 | SLOT(OnNameEdited(const QString&))); | ||
662 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited())); | ||
663 | connect(title_edit, SIGNAL(textChanged(const QString&)), this, | ||
664 | SLOT(OnTitleEdited(const QString&))); | ||
665 | connect(m_instances_tab, SIGNAL(tabCloseRequested(int)), this, | ||
666 | SLOT(OnInstRemove(int))); | ||
667 | connect(m_instances_tab, SIGNAL(tabOpenRequested()), this, SLOT(OnInstCreate())); | ||
547 | } | 668 | } |
548 | 669 | ||
549 | void RegEditPanel::OnInstChanged(int row, int column) | 670 | void NodeEditPanel::OnNameEdited(const QString& text) |
550 | { | 671 | { |
551 | /* ignore extra row for addition */ | 672 | m_ref.get()->name = text.toStdString(); |
552 | if(row >= (int)m_ref.GetReg().addr.size()) | 673 | OnModified(); |
553 | return; | 674 | } |
554 | QTableWidgetItem *item = m_instances_table->item(row, column); | 675 | |
555 | if(column == RegInstNameColumn) | 676 | void NodeEditPanel::OnTitleEdited(const QString& text) |
556 | { | 677 | { |
557 | m_ref.GetReg().addr[row].name = item->text().toStdString(); | 678 | m_ref.get()->title = text.toStdString(); |
558 | OnModified(true); | 679 | OnModified(); |
559 | } | 680 | } |
560 | else if(column == RegInstAddrColumn) | 681 | |
682 | void NodeEditPanel::OnDescEdited() | ||
683 | { | ||
684 | m_ref.get()->desc = m_desc_edit->GetTextHtml().toStdString(); | ||
685 | OnModified(); | ||
686 | } | ||
687 | |||
688 | void NodeEditPanel::OnInstRemove(int index) | ||
689 | { | ||
690 | NodeInstanceEditPanel *panel = | ||
691 | dynamic_cast< NodeInstanceEditPanel * >(m_instances_tab->widget(index)); | ||
692 | RemoveInstanceById(m_ref, panel->GetId()); | ||
693 | m_instances_tab->removeTab(index); | ||
694 | delete panel; | ||
695 | OnModified(); | ||
696 | } | ||
697 | |||
698 | void NodeEditPanel::OnInstModified() | ||
699 | { | ||
700 | int index = m_instances_tab->currentIndex(); | ||
701 | NodeInstanceEditPanel *panel = | ||
702 | dynamic_cast< NodeInstanceEditPanel * >(m_instances_tab->widget(index)); | ||
703 | m_instances_tab->setTabText(index, QString::fromStdString(panel->GetInstance().name)); | ||
704 | OnModified(); | ||
705 | } | ||
706 | |||
707 | QString NodeEditPanel::GuessName() | ||
708 | { | ||
709 | /* try to find instances named Xddd where X is the node name (case insensitive) | ||
710 | * and d are digits. */ | ||
711 | int max_nr_digits = -1; | ||
712 | int max_value = -1; | ||
713 | QString node_name = QString::fromStdString(m_ref.get()->name); | ||
714 | std::vector< soc_desc::instance_t >& inst_list = m_ref.get()->instance; | ||
715 | for(size_t i = 0; i < inst_list.size(); i++) | ||
561 | { | 716 | { |
562 | m_ref.GetReg().addr[row].addr = item->data(Qt::DisplayRole).toUInt(); | 717 | QString inst_name = QString::fromStdString(inst_list[i].name); |
563 | OnModified(true); | 718 | /* ignore name if it doesn't start like the node name */ |
719 | if(!inst_name.startsWith(node_name, Qt::CaseInsensitive)) | ||
720 | continue; | ||
721 | /* check if the suffix is a digit */ | ||
722 | QString suffix = inst_name.mid(node_name.size()); | ||
723 | if(suffix.size() == 0) | ||
724 | { | ||
725 | max_nr_digits = qMax(max_nr_digits, 0); | ||
726 | continue; | ||
727 | } | ||
728 | bool ok; | ||
729 | int value = suffix.toUInt(&ok); | ||
730 | if(!ok) | ||
731 | continue; | ||
732 | max_value = qMax(max_value, value); | ||
733 | max_nr_digits = qMax(max_nr_digits, suffix.size()); | ||
564 | } | 734 | } |
735 | /* if no match, use node name */ | ||
736 | if(max_nr_digits == -1) | ||
737 | return node_name; | ||
738 | /* match of size 0, add "1" at the end */ | ||
739 | if(max_nr_digits == 0) | ||
740 | return node_name + "1"; | ||
741 | /* otherwise, pick next value */ | ||
742 | return QString("%1%2").arg(node_name) | ||
743 | .arg(max_value + 1, max_nr_digits, 10, QChar('0')); | ||
744 | } | ||
745 | |||
746 | void NodeEditPanel::OnInstCreate() | ||
747 | { | ||
748 | std::vector< soc_desc::instance_t >& inst_list = m_ref.get()->instance; | ||
749 | soc_desc::instance_t inst; | ||
750 | inst.id = GetFreshId(inst_list); | ||
751 | inst.name = GuessName().toStdString(); | ||
752 | inst.type = soc_desc::instance_t::SINGLE; | ||
753 | inst.addr = 0; | ||
754 | inst.range.type = soc_desc::range_t::STRIDE; | ||
755 | inst.range.first = 0; | ||
756 | inst.range.count = 0; | ||
757 | inst.range.stride = 0; | ||
758 | inst_list.push_back(inst); | ||
759 | NodeInstanceEditPanel *p = new NodeInstanceEditPanel(m_ref, inst.id, this); | ||
760 | connect(p, SIGNAL(OnModified()), this, SLOT(OnInstModified())); | ||
761 | int idx = m_instances_tab->addTab(p, QString::fromStdString(inst.name)); | ||
762 | m_instances_tab->setCurrentIndex(idx); | ||
763 | OnModified(); | ||
565 | } | 764 | } |
566 | 765 | ||
567 | /** | 766 | /** |
568 | * FieldEditPanel | 767 | * RegFieldEditPanel |
569 | */ | 768 | */ |
570 | FieldEditPanel::FieldEditPanel(SocFieldRef ref, QWidget *parent) | 769 | |
770 | namespace | ||
771 | { | ||
772 | |||
773 | enum | ||
774 | { | ||
775 | RegFieldEditPanelDelType = QTableWidgetItem::UserType, | ||
776 | RegFieldEditPanelAddType, | ||
777 | }; | ||
778 | |||
779 | } | ||
780 | |||
781 | RegFieldEditPanel::RegFieldEditPanel(const soc_desc::field_ref_t& ref, QWidget *parent) | ||
571 | :QWidget(parent), m_ref(ref) | 782 | :QWidget(parent), m_ref(ref) |
572 | { | 783 | { |
573 | m_name_group = new QGroupBox("Name", this); | ||
574 | m_name_edit = new QLineEdit(this); | 784 | m_name_edit = new QLineEdit(this); |
575 | m_name_edit->setText(QString::fromStdString(ref.GetField().name)); | 785 | m_range_edit = new QLineEdit(this); |
576 | QVBoxLayout *name_group_layout = new QVBoxLayout; | 786 | m_range_validator = new SocBitRangeValidator(this); |
577 | name_group_layout->addWidget(m_name_edit); | 787 | m_range_validator->setWidth(m_ref.reg().get()->width); |
578 | m_name_group->setLayout(name_group_layout); | 788 | m_range_edit->setValidator(m_range_validator); |
579 | |||
580 | m_bitrange_group = new QGroupBox("Bit Range", this); | ||
581 | m_bitrange_edit = new QLineEdit(this); | ||
582 | const soc_reg_field_t& field = ref.GetField(); | ||
583 | QString bits_str; | ||
584 | if(field.first_bit == field.last_bit) | ||
585 | bits_str.sprintf("%d", field.first_bit); | ||
586 | else | ||
587 | bits_str.sprintf("%d:%d", field.last_bit, field.first_bit); | ||
588 | m_bitrange_edit->setText(bits_str); | ||
589 | m_bitrange_edit->setValidator(new SocBitRangeValidator(m_bitrange_edit)); | ||
590 | QVBoxLayout *bitrange_group_layout = new QVBoxLayout; | ||
591 | bitrange_group_layout->addWidget(m_bitrange_edit); | ||
592 | m_bitrange_group->setLayout(bitrange_group_layout); | ||
593 | |||
594 | m_desc_group = new QGroupBox("Description", this); | ||
595 | QHBoxLayout *group_layout = new QHBoxLayout; | ||
596 | m_desc_edit = new MyTextEditor(this); | 789 | m_desc_edit = new MyTextEditor(this); |
597 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.GetField().desc)); | 790 | QHBoxLayout *namepos_layout = new QHBoxLayout; |
598 | group_layout->addWidget(m_desc_edit); | 791 | namepos_layout->addWidget(new QLabel("Name:")); |
599 | m_desc_group->setLayout(group_layout); | 792 | namepos_layout->addWidget(m_name_edit); |
600 | 793 | namepos_layout->addWidget(new QLabel("Range:")); | |
601 | m_value_group = new QGroupBox("Values", this); | 794 | namepos_layout->addWidget(m_range_edit); |
602 | QHBoxLayout *value_layout = new QHBoxLayout; | 795 | QVBoxLayout *nameposdesc_layout = new QVBoxLayout; |
603 | m_value_table = new QTableWidget(this); | 796 | nameposdesc_layout->addWidget(Misc::EncloseInBox("Information", namepos_layout)); |
604 | m_value_table->setRowCount(ref.GetField().value.size() + 1); | 797 | nameposdesc_layout->addWidget(Misc::EncloseInBox("Description", m_desc_edit)); |
605 | m_value_table->setColumnCount(FieldValueNrColumns); | 798 | nameposdesc_layout->addStretch(0); |
606 | for(size_t row = 0; row < ref.GetField().value.size(); row++) | 799 | |
607 | FillRow(row, ref.GetField().value[row]); | 800 | m_enum_table = new QTableWidget(this); |
608 | CreateNewRow(ref.GetField().value.size()); | 801 | m_enum_table->setColumnCount(4); |
609 | m_value_table->setHorizontalHeaderItem(FieldValueIconColumn, new QTableWidgetItem("")); | 802 | m_enum_table->setHorizontalHeaderItem(0, new QTableWidgetItem("")); |
610 | m_value_table->setHorizontalHeaderItem(FieldValueNameColumn, new QTableWidgetItem("Name")); | 803 | m_enum_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Name")); |
611 | m_value_table->setHorizontalHeaderItem(FieldValueValueColumn, new QTableWidgetItem("Value")); | 804 | m_enum_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Value")); |
612 | m_value_table->setHorizontalHeaderItem(FieldValueDescColumn, new QTableWidgetItem("Description")); | 805 | m_enum_table->setHorizontalHeaderItem(3, new QTableWidgetItem("Description")); |
613 | m_value_table->verticalHeader()->setVisible(false); | 806 | m_enum_table->verticalHeader()->setVisible(false); |
614 | m_value_table->horizontalHeader()->setStretchLastSection(true); | 807 | m_enum_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
615 | value_layout->addWidget(m_value_table); | 808 | m_enum_delegate = new SocFieldItemDelegate(this); |
616 | m_value_group->setLayout(value_layout); | 809 | m_enum_delegate->setItemEditorFactory(new QItemEditorFactory); |
617 | 810 | m_enum_editor = new SocFieldEditorCreator; | |
618 | QHBoxLayout *line_layout = new QHBoxLayout; | 811 | m_enum_delegate->itemEditorFactory()->registerEditor(QVariant::UInt, m_enum_editor); |
619 | line_layout->addWidget(m_name_group); | 812 | m_enum_table->setItemDelegate(m_enum_delegate); |
620 | line_layout->addWidget(m_bitrange_group); | ||
621 | line_layout->addStretch(); | ||
622 | |||
623 | QVBoxLayout *left_layout = new QVBoxLayout; | ||
624 | left_layout->addLayout(line_layout); | ||
625 | left_layout->addWidget(m_desc_group); | ||
626 | left_layout->addWidget(m_value_group, 1); | ||
627 | |||
628 | UpdateDelegates(); | ||
629 | |||
630 | connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameEdited(const QString&))); | ||
631 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited())); | ||
632 | connect(m_value_table, SIGNAL(cellActivated(int,int)), this, SLOT(OnValueActivated(int,int))); | ||
633 | connect(m_value_table, SIGNAL(cellChanged(int,int)), this, SLOT(OnValueChanged(int,int))); | ||
634 | connect(m_bitrange_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnBitRangeEdited(const QString&))); | ||
635 | 813 | ||
636 | setLayout(left_layout); | 814 | QHBoxLayout *field_layout = new QHBoxLayout; |
815 | field_layout->addLayout(nameposdesc_layout); | ||
816 | field_layout->addWidget(Misc::EncloseInBox("Special Values", m_enum_table), 1); | ||
817 | |||
818 | setLayout(field_layout); | ||
819 | |||
820 | const soc_desc::field_t& field = *m_ref.get(); | ||
821 | m_name_edit->setText(QString::fromStdString(field.name)); | ||
822 | m_range_edit->setText(m_range_validator->generate( | ||
823 | field.pos + field.width - 1, field.pos)); | ||
824 | m_desc_edit->SetTextHtml(QString::fromStdString(field.desc)); | ||
825 | m_enum_delegate->setWidth(field.width); | ||
826 | m_enum_editor->setWidth(field.width); | ||
827 | m_enum_table->setRowCount(field.enum_.size() + 1); | ||
828 | for(size_t i = 0; i < field.enum_.size(); i++) | ||
829 | { | ||
830 | QTableWidgetItem *item = new QTableWidgetItem( | ||
831 | QIcon::fromTheme("list-remove"), "", RegFieldEditPanelDelType); | ||
832 | item->setFlags(Qt::ItemIsEnabled); | ||
833 | m_enum_table->setItem(i, 0, item); | ||
834 | item = new QTableWidgetItem(QString::fromStdString(field.enum_[i].name)); | ||
835 | m_enum_table->setItem(i, 1, item); | ||
836 | item = new QTableWidgetItem(); | ||
837 | item->setData(Qt::EditRole, QVariant(field.enum_[i].value)); | ||
838 | m_enum_table->setItem(i, 2, item); | ||
839 | item = new QTableWidgetItem(QString::fromStdString(field.enum_[i].desc)); | ||
840 | m_enum_table->setItem(i, 3, item); | ||
841 | } | ||
842 | QTableWidgetItem *new_item = new QTableWidgetItem( | ||
843 | QIcon::fromTheme("list-add"), "", RegFieldEditPanelAddType); | ||
844 | new_item->setFlags(Qt::ItemIsEnabled); | ||
845 | m_enum_table->setItem(field.enum_.size(), 0, new_item); | ||
846 | new_item = new QTableWidgetItem("New field..."); | ||
847 | new_item->setFlags(Qt::ItemIsEnabled); | ||
848 | QFont font = new_item->font(); | ||
849 | font.setItalic(true); | ||
850 | new_item->setFont(font); | ||
851 | m_enum_table->setItem(field.enum_.size(), 1, new_item); | ||
852 | new_item = new QTableWidgetItem(); | ||
853 | new_item->setFlags(Qt::ItemIsEnabled); | ||
854 | m_enum_table->setItem(field.enum_.size(), 2, new_item); | ||
855 | new_item = new QTableWidgetItem(); | ||
856 | new_item->setFlags(Qt::ItemIsEnabled); | ||
857 | m_enum_table->setItem(field.enum_.size(), 3, new_item); | ||
858 | m_enum_table->resizeColumnsToContents(); | ||
859 | m_enum_table->horizontalHeader()->setStretchLastSection(true); | ||
860 | |||
861 | connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, | ||
862 | SLOT(OnFieldNameChanged(const QString&))); | ||
863 | connect(m_range_edit, SIGNAL(textChanged(const QString&)), this, | ||
864 | SLOT(OnFieldRangeChanged(const QString&))); | ||
865 | connect(m_desc_edit, SIGNAL(OnTextChanged(const QString&)), this, | ||
866 | SLOT(OnFieldDescChanged(const QString&))); | ||
867 | connect(m_enum_table, SIGNAL(itemActivated(QTableWidgetItem *)), this, | ||
868 | SLOT(OnFieldValueActivated(QTableWidgetItem *))); | ||
869 | connect(m_enum_table, SIGNAL(itemChanged(QTableWidgetItem *)), this, | ||
870 | SLOT(OnFieldValueChanged(QTableWidgetItem *))); | ||
637 | } | 871 | } |
638 | 872 | ||
639 | void FieldEditPanel::UpdateDelegates() | 873 | void RegFieldEditPanel::UpdateWidth() |
640 | { | 874 | { |
641 | SocFieldItemDelegate *m_table_delegate = new SocFieldItemDelegate(m_ref.GetField(), this); | 875 | m_range_validator->setWidth(m_ref.reg().get()->width); |
642 | QItemEditorFactory *m_table_edit_factory = new QItemEditorFactory(); | ||
643 | SocFieldEditorCreator *m_table_edit_creator = new SocFieldEditorCreator(m_ref.GetField()); | ||
644 | m_table_edit_factory->registerEditor(QVariant::UInt, m_table_edit_creator); | ||
645 | m_table_delegate->setItemEditorFactory(m_table_edit_factory); | ||
646 | m_value_table->setItemDelegate(m_table_delegate); | ||
647 | m_value_table->resizeColumnsToContents(); | ||
648 | } | 876 | } |
649 | 877 | ||
650 | void FieldEditPanel::UpdateWarning(int row) | 878 | void RegFieldEditPanel::OnFieldValueActivated(QTableWidgetItem *item) |
651 | { | 879 | { |
652 | soc_word_t val = m_ref.GetField().value[row].value; | 880 | if(item->type() == RegFieldEditPanelDelType) |
653 | soc_word_t max = m_ref.GetField().bitmask() >> m_ref.GetField().first_bit; | ||
654 | QTableWidgetItem *item = m_value_table->item(row, FieldValueValueColumn); | ||
655 | if(val > max) | ||
656 | { | 881 | { |
657 | item->setIcon(QIcon::fromTheme("dialog-warning")); | 882 | int row = item->row(); |
658 | item->setToolTip("Value is too big for the field"); | 883 | my_remove_at(m_ref.get()->enum_, row); |
884 | m_enum_table->removeRow(row); | ||
885 | OnModified(); | ||
659 | } | 886 | } |
660 | else | 887 | else if(item->type() == RegFieldEditPanelAddType) |
661 | { | 888 | { |
662 | item->setIcon(QIcon()); | 889 | soc_desc::field_t& field = *m_ref.get(); |
663 | item->setToolTip(""); | 890 | int row = field.enum_.size(); |
891 | soc_desc::enum_t new_enum; | ||
892 | new_enum.id = GetFreshId(field.enum_); | ||
893 | new_enum.name = "UNNAMED"; | ||
894 | new_enum.value = 0; | ||
895 | field.enum_.push_back(new_enum); | ||
896 | m_enum_table->insertRow(row); | ||
897 | QTableWidgetItem *item = new QTableWidgetItem( | ||
898 | QIcon::fromTheme("list-remove"), "", RegFieldEditPanelDelType); | ||
899 | item->setFlags(Qt::ItemIsEnabled); | ||
900 | m_enum_table->setItem(row, 0, item); | ||
901 | item = new QTableWidgetItem(QString::fromStdString(new_enum.name)); | ||
902 | m_enum_table->setItem(row, 1, item); | ||
903 | item = new QTableWidgetItem(); | ||
904 | item->setData(Qt::EditRole, QVariant(new_enum.value)); | ||
905 | m_enum_table->setItem(row, 2, item); | ||
906 | item = new QTableWidgetItem(QString::fromStdString(new_enum.desc)); | ||
907 | m_enum_table->setItem(row, 3, item); | ||
908 | OnModified(); | ||
664 | } | 909 | } |
665 | } | 910 | } |
666 | 911 | ||
667 | void FieldEditPanel::FillRow(int row, const soc_reg_field_value_t& val) | 912 | void RegFieldEditPanel::OnFieldValueChanged(QTableWidgetItem *item) |
668 | { | 913 | { |
669 | QTableWidgetItem *item = new QTableWidgetItem(QString::fromStdString(val.name)); | 914 | soc_desc::field_t& field = *m_ref.get(); |
670 | item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); | 915 | if((size_t)item->row() >= field.enum_.size()) |
671 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | 916 | return; |
672 | m_value_table->setItem(row, FieldValueNameColumn, item); | 917 | soc_desc::enum_t& enum_ = field.enum_[item->row()]; |
673 | item = new QTableWidgetItem(); | 918 | if(item->column() == 1) |
674 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | 919 | enum_.name = item->text().toStdString(); |
675 | item->setData(Qt::DisplayRole, QVariant(val.value)); | 920 | else if(item->column() == 2) |
676 | m_value_table->setItem(row, FieldValueValueColumn, item); | 921 | enum_.value = item->data(Qt::EditRole).value< soc_word_t >(); |
677 | item = new QTableWidgetItem(QString::fromStdString(val.desc)); | 922 | else if(item->column() == 3) |
678 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | 923 | enum_.desc = item->text().toStdString(); |
679 | m_value_table->setItem(row, FieldValueDescColumn, item); | 924 | OnModified(); |
680 | item = new QTableWidgetItem(QIcon::fromTheme("list-remove"), "", FieldValueDeleteType); | 925 | } |
681 | item->setToolTip("Remove?"); | 926 | |
682 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | 927 | void RegFieldEditPanel::OnFieldNameChanged(const QString& name) |
683 | m_value_table->setItem(row, FieldValueIconColumn, item); | 928 | { |
684 | UpdateWarning(row); | 929 | m_ref.get()->name = name.toStdString(); |
685 | } | 930 | OnModified(); |
686 | |||
687 | void FieldEditPanel::CreateNewRow(int row) | ||
688 | { | ||
689 | QTableWidgetItem *item = new QTableWidgetItem(QIcon::fromTheme("list-add"), "", FieldValueNewType); | ||
690 | item->setToolTip("New?"); | ||
691 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
692 | m_value_table->setItem(row, FieldValueIconColumn, item); | ||
693 | item = new QTableWidgetItem("New value..."); | ||
694 | QFont font = item->font(); | ||
695 | font.setItalic(true); | ||
696 | item->setFont(font); | ||
697 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
698 | m_value_table->setItem(row, FieldValueNameColumn, item); | ||
699 | } | 931 | } |
700 | 932 | ||
701 | void FieldEditPanel::OnBitRangeEdited(const QString& input) | 933 | void RegFieldEditPanel::OnFieldRangeChanged(const QString& range) |
702 | { | 934 | { |
703 | const SocBitRangeValidator *validator = | 935 | soc_desc::field_t *field = m_ref.get(); |
704 | dynamic_cast< const SocBitRangeValidator *>(m_bitrange_edit->validator()); | 936 | int last, first; |
705 | int first, last; | 937 | if(m_range_validator->parse(range, last, first) != QValidator::Acceptable) |
706 | QValidator::State state = validator->parse(input, last, first); | ||
707 | if(state != QValidator::Acceptable) | ||
708 | return; | 938 | return; |
709 | m_ref.GetField().first_bit = first; | 939 | field->pos = first; |
710 | m_ref.GetField().last_bit = last; | 940 | field->width = last - first + 1; |
711 | // update all warning signs | 941 | m_enum_delegate->setWidth(field->width); |
712 | for(size_t row = 0; row < m_ref.GetField().value.size(); row++) | 942 | m_enum_editor->setWidth(field->width); |
713 | UpdateWarning(row); | 943 | OnModified(); |
714 | // also updates delegates because they now have the wrong view of the field | ||
715 | UpdateDelegates(); | ||
716 | OnModified(true); | ||
717 | } | 944 | } |
718 | 945 | ||
719 | void FieldEditPanel::OnNameEdited(const QString& text) | 946 | void RegFieldEditPanel::OnFieldDescChanged(const QString& desc) |
720 | { | 947 | { |
721 | m_ref.GetField().name = text.toStdString(); | 948 | m_ref.get()->desc = desc.toStdString(); |
722 | OnModified(m_name_edit->isModified()); | 949 | OnModified(); |
723 | } | 950 | } |
724 | 951 | ||
725 | void FieldEditPanel::OnDescEdited() | 952 | soc_desc::field_ref_t RegFieldEditPanel::GetField() |
726 | { | 953 | { |
727 | m_ref.GetField().desc = m_desc_edit->GetTextHtml().toStdString(); | 954 | return m_ref; |
728 | OnModified(m_desc_edit->IsModified()); | ||
729 | } | 955 | } |
730 | 956 | ||
731 | void FieldEditPanel::OnValueActivated(int row, int column) | 957 | /** |
958 | * RegEditPanel | ||
959 | */ | ||
960 | |||
961 | namespace | ||
732 | { | 962 | { |
733 | if(column != 0) | 963 | |
734 | return; | 964 | enum |
735 | int type = m_value_table->item(row, column)->type(); | 965 | { |
736 | if(type == FieldValueDeleteType) | 966 | RegVariantEditPanelDelType = QTableWidgetItem::UserType, |
967 | RegVariantEditPanelAddType, | ||
968 | }; | ||
969 | |||
970 | } | ||
971 | |||
972 | RegEditPanel::RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent) | ||
973 | :QWidget(parent), m_ref(ref), m_reg_font(font()) | ||
974 | { | ||
975 | m_reg_font.setWeight(100); | ||
976 | m_reg_font.setKerning(false); | ||
977 | |||
978 | m_value_model = new RegFieldTableModel(this); // view takes ownership | ||
979 | m_value_model->SetRegister(*ref.get()); | ||
980 | m_value_model->SetReadOnly(true); | ||
981 | |||
982 | m_sexy_display2 = new Unscroll<YRegDisplay>(this); | ||
983 | m_sexy_display2->setFont(m_reg_font); | ||
984 | m_sexy_display2->setModel(m_value_model); | ||
985 | m_sexy_display2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | ||
986 | m_sexy_display2->setContextMenuPolicy(Qt::CustomContextMenu); | ||
987 | m_sexy_display2->setWidth(m_ref.get()->width); | ||
988 | |||
989 | m_view_tab = new QTabWidget(this); | ||
990 | m_view_tab->setTabPosition(QTabWidget::West); | ||
991 | |||
992 | /* field tab */ | ||
993 | m_fields_tab = new YTabWidget(0, this); | ||
994 | m_fields_tab->setTabOpenable(true); | ||
995 | std::vector< soc_desc::field_ref_t > field_list = m_ref.fields(); | ||
996 | m_fields_tab->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); | ||
997 | m_fields_tab->setTabsClosable(true); | ||
998 | m_fields_tab->setElideMode(Qt::ElideRight); | ||
999 | for(size_t i = 0; i < field_list.size(); i++) | ||
737 | { | 1000 | { |
738 | m_ref.GetField().value.erase(m_ref.GetField().value.begin() + row); | 1001 | RegFieldEditPanel *p = new RegFieldEditPanel(field_list[i], this); |
739 | m_value_table->removeRow(row); | 1002 | connect(p, SIGNAL(OnModified()), this, SLOT(OnFieldModified())); |
740 | OnModified(true); | 1003 | m_fields_tab->addTab(p, QString::fromStdString(field_list[i].get()->name)); |
741 | } | 1004 | } |
742 | else if(type == FieldValueNewType) | 1005 | |
1006 | m_reg_size_group = new QButtonGroup(this); | ||
1007 | QRadioButton *reg_size_32 = new QRadioButton("32-bit"); | ||
1008 | QRadioButton *reg_size_16 = new QRadioButton("16-bit"); | ||
1009 | QRadioButton *reg_size_8 = new QRadioButton("8-bit"); | ||
1010 | m_reg_size_group->addButton(reg_size_32, 32); | ||
1011 | m_reg_size_group->addButton(reg_size_16, 16); | ||
1012 | m_reg_size_group->addButton(reg_size_8, 8); | ||
1013 | if(m_reg_size_group->button(m_ref.get()->width)) | ||
1014 | m_reg_size_group->button(m_ref.get()->width)->click(); | ||
1015 | QVBoxLayout *width_group_layout = new QVBoxLayout; | ||
1016 | width_group_layout->addWidget(reg_size_32); | ||
1017 | width_group_layout->addWidget(reg_size_16); | ||
1018 | width_group_layout->addWidget(reg_size_8); | ||
1019 | width_group_layout->addStretch(0); | ||
1020 | QGroupBox *width_group = new QGroupBox("Width"); | ||
1021 | width_group->setLayout(width_group_layout); | ||
1022 | |||
1023 | m_variant_table = new QTableWidget; | ||
1024 | m_variant_table->setColumnCount(3); | ||
1025 | m_variant_table->setHorizontalHeaderItem(0, new QTableWidgetItem("")); | ||
1026 | m_variant_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Type")); | ||
1027 | m_variant_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Offset")); | ||
1028 | m_variant_table->verticalHeader()->setVisible(false); | ||
1029 | m_variant_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | ||
1030 | m_variant_delegate = new SocFieldItemDelegate(this); | ||
1031 | m_variant_delegate->setItemEditorFactory(new QItemEditorFactory); | ||
1032 | m_variant_editor = new SocFieldEditorCreator; | ||
1033 | m_variant_delegate->itemEditorFactory()->registerEditor(QVariant::UInt, m_variant_editor); | ||
1034 | m_variant_table->setItemDelegate(m_variant_delegate); | ||
1035 | |||
1036 | std::vector< soc_desc::variant_ref_t > variants = m_ref.variants(); | ||
1037 | m_variant_table->setRowCount(variants.size() + 1); | ||
1038 | for(size_t i = 0; i < variants.size(); i++) | ||
743 | { | 1039 | { |
744 | m_value_table->insertRow(row); | 1040 | QTableWidgetItem *item = new QTableWidgetItem( |
745 | soc_reg_field_value_t val; | 1041 | QIcon::fromTheme("list-remove"), "", RegVariantEditPanelDelType); |
746 | val.name = QString("UNNAMED_%1").arg(row).toStdString(); | 1042 | item->setFlags(Qt::ItemIsEnabled); |
747 | val.value = 0; | 1043 | m_variant_table->setItem(i, 0, item); |
748 | m_ref.GetField().value.push_back(val); | 1044 | item = new QTableWidgetItem(QString::fromStdString(variants[i].get()->type)); |
749 | FillRow(row, val); | 1045 | m_variant_table->setItem(i, 1, item); |
1046 | item = new QTableWidgetItem(); | ||
1047 | item->setData(Qt::EditRole, QVariant(variants[i].get()->offset)); | ||
1048 | m_variant_table->setItem(i, 2, item); | ||
750 | } | 1049 | } |
1050 | QTableWidgetItem *new_item = new QTableWidgetItem( | ||
1051 | QIcon::fromTheme("list-add"), "", RegVariantEditPanelAddType); | ||
1052 | new_item->setFlags(Qt::ItemIsEnabled); | ||
1053 | m_variant_table->setItem(variants.size(), 0, new_item); | ||
1054 | new_item = new QTableWidgetItem("New variant..."); | ||
1055 | new_item->setFlags(Qt::ItemIsEnabled); | ||
1056 | QFont font = new_item->font(); | ||
1057 | font.setItalic(true); | ||
1058 | new_item->setFont(font); | ||
1059 | m_variant_table->setItem(variants.size(), 1, new_item); | ||
1060 | new_item = new QTableWidgetItem(); | ||
1061 | new_item->setFlags(Qt::ItemIsEnabled); | ||
1062 | m_variant_table->setItem(variants.size(), 2, new_item); | ||
1063 | new_item = new QTableWidgetItem(); | ||
1064 | new_item->setFlags(Qt::ItemIsEnabled); | ||
1065 | m_variant_table->resizeColumnsToContents(); | ||
1066 | m_variant_table->horizontalHeader()->setStretchLastSection(true); | ||
1067 | |||
1068 | m_desc_edit = new MyTextEditor(this); | ||
1069 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.get()->desc)); | ||
1070 | |||
1071 | QHBoxLayout *top_info_layout = new QHBoxLayout; | ||
1072 | top_info_layout->addWidget(width_group); | ||
1073 | top_info_layout->addWidget(Misc::EncloseInBox("Variants", m_variant_table)); | ||
1074 | top_info_layout->addWidget(Misc::EncloseInBox("Description", m_desc_edit)); | ||
1075 | |||
1076 | QWidget *reg_info = new QWidget(this); | ||
1077 | QVBoxLayout *reg_info_layout = new QVBoxLayout; | ||
1078 | reg_info_layout->addLayout(top_info_layout); | ||
1079 | reg_info_layout->addStretch(0); | ||
1080 | reg_info->setLayout(reg_info_layout); | ||
1081 | |||
1082 | m_view_tab->addTab(reg_info, "Information"); | ||
1083 | m_view_tab->addTab(m_fields_tab, "Fields"); | ||
1084 | |||
1085 | QVBoxLayout *main_layout = new QVBoxLayout; | ||
1086 | main_layout->addWidget(m_sexy_display2, 1); | ||
1087 | main_layout->addWidget(m_view_tab, 2); | ||
1088 | |||
1089 | m_delete_action = new QAction("&Delete", this); | ||
1090 | m_delete_action->setIcon(QIcon::fromTheme("list-remove")); | ||
1091 | m_new_action = new QAction("&New field", this); | ||
1092 | m_new_action->setIcon(QIcon::fromTheme("list-add")); | ||
1093 | |||
1094 | setLayout(main_layout); | ||
1095 | |||
1096 | OnRegFieldActivated(QModelIndex()); | ||
1097 | UpdateWidthRestrictions(); | ||
1098 | |||
1099 | connect(m_sexy_display2, SIGNAL(clicked(const QModelIndex&)), this, | ||
1100 | SLOT(OnRegFieldActivated(const QModelIndex&))); | ||
1101 | connect(m_sexy_display2, SIGNAL(customContextMenuRequested(QPoint)), this, | ||
1102 | SLOT(OnRegDisplayContextMenu(QPoint))); | ||
1103 | connect(m_reg_size_group, SIGNAL(buttonClicked(int)), this, SLOT(OnWidthChanged(int))); | ||
1104 | connect(m_delete_action, SIGNAL(triggered()), this, SLOT(OnRegFieldDelete())); | ||
1105 | connect(m_new_action, SIGNAL(triggered()), this, SLOT(OnRegFieldNew())); | ||
1106 | connect(m_variant_table, SIGNAL(itemActivated(QTableWidgetItem *)), this, | ||
1107 | SLOT(OnVariantActivated(QTableWidgetItem *))); | ||
1108 | connect(m_variant_table, SIGNAL(itemChanged(QTableWidgetItem *)), this, | ||
1109 | SLOT(OnVariantValueChanged(QTableWidgetItem *))); | ||
1110 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited())); | ||
1111 | connect(m_fields_tab, SIGNAL(tabCloseRequested(int)), this, SLOT(OnFieldRemove(int))); | ||
1112 | connect(m_fields_tab, SIGNAL(tabOpenRequested()), this, SLOT(OnFieldCreate())); | ||
751 | } | 1113 | } |
752 | 1114 | ||
753 | void FieldEditPanel::OnValueChanged(int row, int column) | 1115 | void RegEditPanel::UpdateWidthRestrictions() |
754 | { | 1116 | { |
755 | /* ignore extra row for addition */ | 1117 | /* only allow width large enough to fit all fields */ |
756 | if(row >= (int)m_ref.GetField().value.size()) | 1118 | size_t max_bit = 0; |
757 | return; | 1119 | std::vector< soc_desc::field_ref_t > field_list = m_ref.fields(); |
758 | QTableWidgetItem *item = m_value_table->item(row, column); | 1120 | for(size_t i = 0; i < field_list.size(); i++) |
759 | if(column == FieldValueNameColumn) | ||
760 | m_ref.GetField().value[row].name = item->text().toStdString(); | ||
761 | else if(column == FieldValueValueColumn) | ||
762 | { | 1121 | { |
763 | soc_word_t& fval = m_ref.GetField().value[row].value; | 1122 | soc_desc::field_t& f = *field_list[i].get(); |
764 | soc_word_t new_val = item->data(Qt::DisplayRole).toUInt(); | 1123 | max_bit = std::max(max_bit, f.pos + f.width - 1); |
765 | /* avoid infinite recursion by calling UpdateWarning() when | ||
766 | * only the icon changes which would trigger this callback again */ | ||
767 | if(fval != new_val) | ||
768 | { | ||
769 | fval = new_val; | ||
770 | UpdateWarning(row); | ||
771 | } | ||
772 | } | 1124 | } |
773 | else if(column == FieldValueDescColumn) | 1125 | /* update buttons */ |
774 | m_ref.GetField().value[row].desc = item->text().toStdString(); | 1126 | m_reg_size_group->button(8)->setEnabled(max_bit < 8); |
775 | OnModified(true); | 1127 | m_reg_size_group->button(16)->setEnabled(max_bit < 16); |
1128 | m_reg_size_group->button(32)->setEnabled(max_bit < 32); | ||
776 | } | 1129 | } |
777 | 1130 | ||
778 | namespace | 1131 | int RegEditPanel::IndexById(soc_id_t id) |
779 | { | 1132 | { |
1133 | for(int i = 0; i < m_fields_tab->count(); i++) | ||
1134 | { | ||
1135 | RegFieldEditPanel *p = dynamic_cast< RegFieldEditPanel * >(m_fields_tab->widget(i)); | ||
1136 | if(p->GetField().get()->id == id) | ||
1137 | return i; | ||
1138 | } | ||
1139 | return -1; | ||
1140 | } | ||
780 | 1141 | ||
781 | enum | 1142 | void RegEditPanel::OnWidthChanged(int w) |
782 | { | 1143 | { |
783 | SocTreeSocType = QTreeWidgetItem::UserType, | 1144 | m_ref.get()->width = w; |
784 | SocTreeDevType, | 1145 | m_sexy_display2->setWidth(w); |
785 | SocTreeRegType, | 1146 | for(int i = 0; i < m_fields_tab->count(); i++) |
786 | SocTreeFieldType, | 1147 | dynamic_cast< RegFieldEditPanel * >(m_fields_tab->widget(i))->UpdateWidth(); |
787 | SocTreeNewDevType, | 1148 | OnModified(); |
788 | SocTreeNewRegType, | 1149 | } |
789 | SocTreeNewFieldType, | ||
790 | }; | ||
791 | |||
792 | /** | ||
793 | * SocTreeItem | ||
794 | */ | ||
795 | 1150 | ||
796 | class SocTreeItem : public QTreeWidgetItem | 1151 | void RegEditPanel::OnDescEdited() |
797 | { | 1152 | { |
798 | public: | 1153 | m_ref.get()->desc = m_desc_edit->GetTextHtml().toStdString(); |
799 | SocTreeItem(const QString& string, const SocRef& ref) | 1154 | OnModified(); |
800 | :QTreeWidgetItem(QStringList(string), SocTreeSocType), m_ref(ref) {} | 1155 | } |
801 | 1156 | ||
802 | const SocRef& GetRef() { return m_ref; } | 1157 | void RegEditPanel::OnVariantActivated(QTableWidgetItem *item) |
803 | private: | 1158 | { |
804 | SocRef m_ref; | 1159 | if(item->type() == RegVariantEditPanelDelType) |
805 | }; | 1160 | { |
1161 | int row = item->row(); | ||
1162 | my_remove_at(m_ref.get()->variant, row); | ||
1163 | m_variant_table->removeRow(row); | ||
1164 | OnModified(); | ||
1165 | } | ||
1166 | else if(item->type() == RegVariantEditPanelAddType) | ||
1167 | { | ||
1168 | int row = m_ref.get()->variant.size(); | ||
1169 | soc_desc::variant_t& variant = *m_ref.create_variant().get(); | ||
1170 | variant.type = "untyped"; | ||
1171 | variant.offset = 0; | ||
1172 | m_variant_table->insertRow(row); | ||
1173 | QTableWidgetItem *item = new QTableWidgetItem( | ||
1174 | QIcon::fromTheme("list-remove"), "", RegVariantEditPanelDelType); | ||
1175 | item->setFlags(Qt::ItemIsEnabled); | ||
1176 | m_variant_table->setItem(row, 0, item); | ||
1177 | item = new QTableWidgetItem(QString::fromStdString(variant.type)); | ||
1178 | m_variant_table->setItem(row, 1, item); | ||
1179 | item = new QTableWidgetItem(); | ||
1180 | item->setData(Qt::EditRole, QVariant(variant.offset)); | ||
1181 | m_variant_table->setItem(row, 2, item); | ||
1182 | OnModified(); | ||
1183 | } | ||
1184 | } | ||
806 | 1185 | ||
807 | /** | 1186 | void RegEditPanel::OnVariantValueChanged(QTableWidgetItem *item) |
808 | * NewDevTreeItem | 1187 | { |
809 | */ | 1188 | soc_desc::register_t& reg = *m_ref.get(); |
1189 | if((size_t)item->row() >= reg.variant.size()) | ||
1190 | return; | ||
1191 | soc_desc::variant_t& var = reg.variant[item->row()]; | ||
1192 | if(item->column() == 1) | ||
1193 | var.type = item->text().toStdString(); | ||
1194 | else if(item->column() == 2) | ||
1195 | var.offset = item->data(Qt::EditRole).value< soc_word_t >(); | ||
1196 | OnModified(); | ||
1197 | } | ||
810 | 1198 | ||
811 | class NewDevTreeItem : public QTreeWidgetItem | 1199 | void RegEditPanel::OnRegFieldActivated(const QModelIndex& index) |
812 | { | 1200 | { |
813 | public: | 1201 | if(!index.isValid()) |
814 | NewDevTreeItem(const QString& string, const SocRef& ref) | 1202 | return; |
815 | :QTreeWidgetItem(QStringList(string), SocTreeNewDevType), m_ref(ref) {} | 1203 | m_fields_tab->setCurrentIndex(IndexById(m_ref.get()->field[index.row()].id)); |
1204 | m_view_tab->setCurrentIndex(1); | ||
1205 | } | ||
816 | 1206 | ||
817 | const SocRef& GetRef() { return m_ref; } | 1207 | void RegEditPanel::OnFieldModified() |
818 | private: | 1208 | { |
819 | SocRef m_ref; | 1209 | int idx = m_fields_tab->currentIndex(); |
820 | }; | 1210 | RegFieldEditPanel *p = dynamic_cast< RegFieldEditPanel * >(m_fields_tab->widget(idx)); |
1211 | m_fields_tab->setTabText(idx, QString::fromStdString(p->GetField().get()->name)); | ||
1212 | DoModify(); | ||
1213 | } | ||
821 | 1214 | ||
822 | /** | 1215 | void RegEditPanel::DoModify() |
823 | * DevTreeItem | 1216 | { |
824 | */ | 1217 | m_value_model->UpdateRegister(*m_ref.get()); |
1218 | UpdateWidthRestrictions(); | ||
1219 | OnModified(); | ||
1220 | } | ||
825 | 1221 | ||
826 | class DevTreeItem : public QTreeWidgetItem | 1222 | void RegEditPanel::OnRegFieldDelete() |
827 | { | 1223 | { |
828 | public: | 1224 | QModelIndex current = m_sexy_display2->currentIndex(); |
829 | DevTreeItem(const QString& string, const SocDevRef& ref) | 1225 | if(!current.isValid()) |
830 | :QTreeWidgetItem(QStringList(string), SocTreeDevType), m_ref(ref) {} | 1226 | return; |
1227 | QMessageBox msgbox(QMessageBox::Question, "Delete field ?", | ||
1228 | "Are you sure you want to delete this field ?", | ||
1229 | QMessageBox::Yes | QMessageBox::No, this); | ||
1230 | msgbox.setDefaultButton(QMessageBox::No); | ||
1231 | int ret = msgbox.exec(); | ||
1232 | if(ret != QMessageBox::Yes) | ||
1233 | return; | ||
1234 | m_fields_tab->removeTab(IndexById(m_ref.get()->field[current.row()].id)); | ||
1235 | my_remove_at(m_ref.get()->field, current.row()); | ||
1236 | DoModify(); | ||
1237 | OnRegFieldActivated(QModelIndex()); | ||
1238 | } | ||
831 | 1239 | ||
832 | const SocDevRef& GetRef() { return m_ref; } | 1240 | void RegEditPanel::OnFieldRemove(int index) |
833 | private: | 1241 | { |
834 | SocDevRef m_ref; | 1242 | Q_UNUSED(index); |
835 | }; | 1243 | } |
836 | 1244 | ||
837 | /** | 1245 | int RegEditPanel::FindFreeBit(int preferred) |
838 | * NewRegTreeItem | 1246 | { |
839 | */ | 1247 | int nr_bits = m_ref.get()->width; |
1248 | soc_word_t free_mask = (nr_bits == 32) ? 0xffffffff : (1 << nr_bits) - 1; | ||
1249 | soc_desc::register_t& reg = *m_ref.get(); | ||
1250 | for(size_t i = 0; i < reg.field.size(); i++) | ||
1251 | free_mask &= ~reg.field[i].bitmask(); | ||
1252 | /* any space ? */ | ||
1253 | if(free_mask == 0) | ||
1254 | return -1; | ||
1255 | int closest_bit = -1; | ||
1256 | int closest_dist = nr_bits; | ||
1257 | for(int bit = 0; bit < nr_bits; bit++) | ||
1258 | { | ||
1259 | if(!(free_mask & (1 << bit))) | ||
1260 | continue; | ||
1261 | if(abs(bit - preferred) < closest_dist) | ||
1262 | { | ||
1263 | closest_bit = bit; | ||
1264 | closest_dist = abs(bit - preferred); | ||
1265 | } | ||
1266 | } | ||
1267 | return closest_bit; | ||
1268 | } | ||
840 | 1269 | ||
841 | class NewRegTreeItem : public QTreeWidgetItem | 1270 | void RegEditPanel::OnRegFieldNew() |
842 | { | 1271 | { |
843 | public: | 1272 | int bit_col = m_sexy_display2->bitColumnAt(m_menu_point); |
844 | NewRegTreeItem(const QString& string, const SocDevRef& ref) | 1273 | /* we need to make sure the created field does not overlap something */ |
845 | :QTreeWidgetItem(QStringList(string), SocTreeNewRegType), m_ref(ref) {} | 1274 | bit_col = FindFreeBit(bit_col); |
1275 | if(bit_col == -1) | ||
1276 | return; /* impossible to find a free position */ | ||
1277 | soc_desc::field_ref_t ref = m_ref.create_field(); | ||
1278 | soc_desc::field_t& field = *ref.get(); | ||
1279 | field.pos = bit_col; | ||
1280 | field.width = 1; | ||
1281 | field.name = "UNNAMED"; | ||
846 | 1282 | ||
847 | const SocDevRef& GetRef() { return m_ref; } | 1283 | RegFieldEditPanel *p = new RegFieldEditPanel(ref, this); |
848 | private: | 1284 | connect(p, SIGNAL(OnModified()), this, SLOT(OnFieldModified())); |
849 | SocDevRef m_ref; | 1285 | m_fields_tab->addTab(p, QString::fromStdString(field.name)); |
850 | }; | ||
851 | 1286 | ||
852 | /** | 1287 | DoModify(); |
853 | * RegTreeItem | 1288 | } |
854 | */ | ||
855 | 1289 | ||
856 | class RegTreeItem : public QTreeWidgetItem | 1290 | void RegEditPanel::OnFieldCreate() |
857 | { | 1291 | { |
858 | public: | 1292 | OnRegFieldNew(); |
859 | RegTreeItem(const QString& string, const SocRegRef& ref) | 1293 | } |
860 | :QTreeWidgetItem(QStringList(string), SocTreeRegType), m_ref(ref) {} | ||
861 | |||
862 | const SocRegRef& GetRef() { return m_ref; } | ||
863 | private: | ||
864 | SocRegRef m_ref; | ||
865 | }; | ||
866 | 1294 | ||
867 | /** | 1295 | void RegEditPanel::OnRegDisplayContextMenu(QPoint point) |
868 | * NewFieldTreeItem | 1296 | { |
869 | */ | 1297 | m_menu_point = point; |
1298 | QMenu *menu = new QMenu(this); | ||
1299 | QModelIndex item = m_sexy_display2->indexAt(point); | ||
1300 | menu->addAction(m_new_action); | ||
1301 | if(item.isValid()) | ||
1302 | menu->addAction(m_delete_action); | ||
1303 | menu->popup(m_sexy_display2->viewport()->mapToGlobal(point)); | ||
1304 | } | ||
870 | 1305 | ||
871 | class NewFieldTreeItem : public QTreeWidgetItem | 1306 | namespace |
872 | { | 1307 | { |
873 | public: | ||
874 | NewFieldTreeItem(const QString& string, const SocRegRef& ref) | ||
875 | :QTreeWidgetItem(QStringList(string), SocTreeNewFieldType), m_ref(ref) {} | ||
876 | 1308 | ||
877 | const SocRegRef& GetRef() { return m_ref; } | 1309 | enum |
878 | private: | 1310 | { |
879 | SocRegRef m_ref; | 1311 | SocTreeSocType = QTreeWidgetItem::UserType, // SocRefRole -> node_ref_t to root |
1312 | SocTreeNodeType, // SocRefRole -> node_ref_t | ||
1313 | SocTreeRegType, // SocRefRole -> register_ref_t | ||
880 | }; | 1314 | }; |
881 | 1315 | ||
882 | /** | 1316 | enum |
883 | * FieldTreeItem | 1317 | { |
884 | */ | 1318 | SocRefRole = Qt::UserRole, |
1319 | }; | ||
885 | 1320 | ||
886 | class FieldTreeItem : public QTreeWidgetItem | 1321 | template<typename T> |
1322 | T SocTreeItemVal(QTreeWidgetItem *item) | ||
887 | { | 1323 | { |
888 | public: | 1324 | return item->data(0, SocRefRole).value<T>(); |
889 | FieldTreeItem(const QString& string, const SocFieldRef& ref) | 1325 | } |
890 | :QTreeWidgetItem(QStringList(string), SocTreeFieldType), m_ref(ref) {} | ||
891 | 1326 | ||
892 | const SocFieldRef& GetRef() { return m_ref; } | 1327 | template<typename T> |
893 | private: | 1328 | QTreeWidgetItem *MakeSocTreeItem(int type, const T& val) |
894 | SocFieldRef m_ref; | 1329 | { |
895 | }; | 1330 | QTreeWidgetItem *item = new QTreeWidgetItem(type); |
1331 | item->setData(0, SocRefRole, QVariant::fromValue(val)); | ||
1332 | return item; | ||
1333 | } | ||
896 | 1334 | ||
897 | } | 1335 | } |
898 | 1336 | ||
@@ -903,8 +1341,7 @@ RegEdit::RegEdit(Backend *backend, QWidget *parent) | |||
903 | :QWidget(parent), m_backend(backend) | 1341 | :QWidget(parent), m_backend(backend) |
904 | { | 1342 | { |
905 | QVBoxLayout *m_vert_layout = new QVBoxLayout(); | 1343 | QVBoxLayout *m_vert_layout = new QVBoxLayout(); |
906 | m_file_group = new QGroupBox("File selection", this); | 1344 | QLabel *file_static = new QLabel("File:"); |
907 | QHBoxLayout *m_file_group_layout = new QHBoxLayout(); | ||
908 | m_file_edit = new QLineEdit(this); | 1345 | m_file_edit = new QLineEdit(this); |
909 | m_file_edit->setReadOnly(true); | 1346 | m_file_edit->setReadOnly(true); |
910 | m_file_open = new QToolButton(this); | 1347 | m_file_open = new QToolButton(this); |
@@ -913,33 +1350,53 @@ RegEdit::RegEdit(Backend *backend, QWidget *parent) | |||
913 | m_file_open->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); | 1350 | m_file_open->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); |
914 | QMenu *file_open_menu = new QMenu(this); | 1351 | QMenu *file_open_menu = new QMenu(this); |
915 | QAction *new_act = file_open_menu->addAction(QIcon::fromTheme("document-new"), "New..."); | 1352 | QAction *new_act = file_open_menu->addAction(QIcon::fromTheme("document-new"), "New..."); |
1353 | m_file_open->setPopupMode(QToolButton::MenuButtonPopup); | ||
916 | m_file_open->setMenu(file_open_menu); | 1354 | m_file_open->setMenu(file_open_menu); |
917 | 1355 | ||
918 | m_file_save = new QToolButton(this); | 1356 | m_file_save = new QToolButton(this); |
919 | m_file_save->setText("Save"); | 1357 | m_file_save->setText("Save"); |
920 | m_file_save->setIcon(QIcon::fromTheme("document-save")); | 1358 | m_file_save->setIcon(QIcon::fromTheme("document-save")); |
921 | m_file_save->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); | 1359 | m_file_save->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); |
1360 | m_file_save->setPopupMode(QToolButton::MenuButtonPopup); | ||
922 | QMenu *file_save_menu = new QMenu(this); | 1361 | QMenu *file_save_menu = new QMenu(this); |
923 | QAction *saveas_act = file_save_menu->addAction(QIcon::fromTheme("document-save-as"), "Save as..."); | 1362 | QAction *saveas_act = file_save_menu->addAction(QIcon::fromTheme("document-save-as"), "Save as..."); |
924 | m_file_save->setMenu(file_save_menu); | 1363 | m_file_save->setMenu(file_save_menu); |
925 | m_file_group_layout->addWidget(m_file_open); | 1364 | |
926 | m_file_group_layout->addWidget(m_file_save); | 1365 | QHBoxLayout *file_group_layout = new QHBoxLayout(); |
927 | m_file_group_layout->addWidget(m_file_edit); | 1366 | file_group_layout->addWidget(m_file_open); |
1367 | file_group_layout->addWidget(m_file_save); | ||
1368 | file_group_layout->addWidget(file_static); | ||
1369 | file_group_layout->addWidget(m_file_edit); | ||
928 | 1370 | ||
929 | m_splitter = new QSplitter(this); | 1371 | m_splitter = new QSplitter(this); |
930 | m_soc_tree = new QTreeWidget(this); | 1372 | m_soc_tree = new QTreeWidget(this); |
931 | m_soc_tree->setColumnCount(1); | 1373 | m_soc_tree->setColumnCount(1); |
932 | m_soc_tree->setHeaderLabel(QString("Name")); | 1374 | m_soc_tree->setHeaderLabel(QString("Name")); |
933 | m_soc_tree->setContextMenuPolicy(Qt::ActionsContextMenu); | 1375 | m_soc_tree->setContextMenuPolicy(Qt::CustomContextMenu); |
934 | QAction *soc_tree_delete_action = new QAction("&Delete", this); | 1376 | |
935 | soc_tree_delete_action->setIcon(QIcon::fromTheme("list-remove")); | 1377 | m_delete_action = new QAction("&Delete", this); |
936 | connect(soc_tree_delete_action, SIGNAL(triggered()), this, SLOT(OnSocItemDelete())); | 1378 | m_delete_action->setIcon(QIcon::fromTheme("list-remove")); |
937 | m_soc_tree->addAction(soc_tree_delete_action); | 1379 | m_new_action = new QAction("&New", this); |
1380 | m_new_action->setIcon(QIcon::fromTheme("list-add")); | ||
1381 | m_create_action = new QAction("&Create register", this); | ||
1382 | m_create_action->setIcon(QIcon::fromTheme("folder-new")); | ||
1383 | |||
938 | m_splitter->addWidget(m_soc_tree); | 1384 | m_splitter->addWidget(m_soc_tree); |
939 | m_splitter->setStretchFactor(0, 0); | 1385 | m_splitter->setStretchFactor(0, 0); |
940 | 1386 | ||
941 | m_file_group->setLayout(m_file_group_layout); | 1387 | m_msg = new MessageWidget(this); |
942 | m_vert_layout->addWidget(m_file_group); | 1388 | QWidget *splitter_right = new QWidget(this); |
1389 | m_right_panel_layout = new QVBoxLayout; | ||
1390 | m_right_panel_layout->addWidget(m_msg, 0); | ||
1391 | splitter_right->setLayout(m_right_panel_layout); | ||
1392 | m_splitter->addWidget(splitter_right); | ||
1393 | m_splitter->setStretchFactor(1, 2); | ||
1394 | |||
1395 | m_msg_welcome_id = SetMessage(MessageWidget::Information, | ||
1396 | "Open a description file to edit, or create a new file from scratch."); | ||
1397 | m_msg_name_error_id = 0; | ||
1398 | |||
1399 | m_vert_layout->addLayout(file_group_layout); | ||
943 | m_vert_layout->addWidget(m_splitter, 1); | 1400 | m_vert_layout->addWidget(m_splitter, 1); |
944 | 1401 | ||
945 | setLayout(m_vert_layout); | 1402 | setLayout(m_vert_layout); |
@@ -949,14 +1406,17 @@ RegEdit::RegEdit(Backend *backend, QWidget *parent) | |||
949 | SetPanel(new EmptyEditPanel(this)); | 1406 | SetPanel(new EmptyEditPanel(this)); |
950 | UpdateTabName(); | 1407 | UpdateTabName(); |
951 | 1408 | ||
1409 | connect(m_soc_tree, SIGNAL(customContextMenuRequested(QPoint)), this, | ||
1410 | SLOT(OnSocTreeContextMenu(QPoint))); | ||
1411 | connect(m_delete_action, SIGNAL(triggered()), this, SLOT(OnSocItemDelete())); | ||
1412 | connect(m_new_action, SIGNAL(triggered()), this, SLOT(OnSocItemNew())); | ||
1413 | connect(m_create_action, SIGNAL(triggered()), this, SLOT(OnSocItemCreate())); | ||
952 | connect(m_file_open, SIGNAL(clicked()), this, SLOT(OnOpen())); | 1414 | connect(m_file_open, SIGNAL(clicked()), this, SLOT(OnOpen())); |
953 | connect(m_file_save, SIGNAL(clicked()), this, SLOT(OnSave())); | 1415 | connect(m_file_save, SIGNAL(clicked()), this, SLOT(OnSave())); |
954 | connect(new_act, SIGNAL(triggered()), this, SLOT(OnNew())); | 1416 | connect(new_act, SIGNAL(triggered()), this, SLOT(OnNew())); |
955 | connect(saveas_act, SIGNAL(triggered()), this, SLOT(OnSaveAs())); | 1417 | connect(saveas_act, SIGNAL(triggered()), this, SLOT(OnSaveAs())); |
956 | connect(m_soc_tree, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), | 1418 | connect(m_soc_tree, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), |
957 | this, SLOT(OnSocItemChanged(QTreeWidgetItem*, QTreeWidgetItem*))); | 1419 | this, SLOT(OnSocItemChanged(QTreeWidgetItem*, QTreeWidgetItem*))); |
958 | connect(m_soc_tree, SIGNAL(itemActivated(QTreeWidgetItem*, int)), | ||
959 | this, SLOT(OnSocItemActivated(QTreeWidgetItem*, int))); | ||
960 | } | 1420 | } |
961 | 1421 | ||
962 | QWidget *RegEdit::GetWidget() | 1422 | QWidget *RegEdit::GetWidget() |
@@ -968,6 +1428,16 @@ RegEdit::~RegEdit() | |||
968 | { | 1428 | { |
969 | } | 1429 | } |
970 | 1430 | ||
1431 | int RegEdit::SetMessage(MessageWidget::MessageType type, const QString& msg) | ||
1432 | { | ||
1433 | return m_msg->SetMessage(type, msg); | ||
1434 | } | ||
1435 | |||
1436 | void RegEdit::HideMessage(int id) | ||
1437 | { | ||
1438 | m_msg->HideMessage(id); | ||
1439 | } | ||
1440 | |||
971 | void RegEdit::OnSave() | 1441 | void RegEdit::OnSave() |
972 | { | 1442 | { |
973 | SaveSoc(); | 1443 | SaveSoc(); |
@@ -1007,7 +1477,10 @@ bool RegEdit::GetFilename(QString& filename, bool save) | |||
1007 | QFileDialog *fd = new QFileDialog(this); | 1477 | QFileDialog *fd = new QFileDialog(this); |
1008 | if(save) | 1478 | if(save) |
1009 | fd->setAcceptMode(QFileDialog::AcceptSave); | 1479 | fd->setAcceptMode(QFileDialog::AcceptSave); |
1010 | fd->setFilter("Description files (*.xml);;All files (*)"); | 1480 | QStringList filters; |
1481 | filters << "Description files (*.xml)"; | ||
1482 | filters << "All files (*)"; | ||
1483 | fd->setNameFilters(filters); | ||
1011 | fd->setDirectory(Settings::Get()->value("regedit/loaddescdir", QDir::currentPath()).toString()); | 1484 | fd->setDirectory(Settings::Get()->value("regedit/loaddescdir", QDir::currentPath()).toString()); |
1012 | if(fd->exec()) | 1485 | if(fd->exec()) |
1013 | { | 1486 | { |
@@ -1051,15 +1524,15 @@ void RegEdit::OnNew() | |||
1051 | 1524 | ||
1052 | bool RegEdit::SaveSocFile(const QString& filename) | 1525 | bool RegEdit::SaveSocFile(const QString& filename) |
1053 | { | 1526 | { |
1054 | normalize(m_cur_socfile.GetSoc()); | 1527 | soc_desc::error_context_t ctx; |
1055 | if(!produce_xml(filename.toStdString(), m_cur_socfile.GetSoc())) | 1528 | soc_desc::normalize(m_cur_socfile.GetSoc()); |
1529 | if(!soc_desc::produce_xml(filename.toStdString(), m_cur_socfile.GetSoc(), ctx)) | ||
1056 | { | 1530 | { |
1057 | QMessageBox::warning(this, "The description was not saved", | 1531 | QMessageBox::warning(this, "The description was not saved", |
1058 | "There was an error when saving the file"); | 1532 | "There was an error when saving the file"); |
1059 | return false; | 1533 | return false; |
1060 | } | 1534 | } |
1061 | m_soc_tree->clear(); | 1535 | UpdateSocFile(); |
1062 | FillSocTree(); | ||
1063 | SetModified(false, false); | 1536 | SetModified(false, false); |
1064 | return true; | 1537 | return true; |
1065 | } | 1538 | } |
@@ -1086,91 +1559,39 @@ void RegEdit::LoadSocFile(const QString& filename) | |||
1086 | SetModified(false, false); | 1559 | SetModified(false, false); |
1087 | UpdateSocFile(); | 1560 | UpdateSocFile(); |
1088 | UpdateTabName(); | 1561 | UpdateTabName(); |
1562 | m_msg_welcome_id = SetMessage(MessageWidget::Information, | ||
1563 | "Select items to edit in tree, or right-click on them to see available actions."); | ||
1089 | } | 1564 | } |
1090 | 1565 | ||
1091 | void RegEdit::CreateNewFieldItem(QTreeWidgetItem *_parent) | 1566 | void RegEdit::FillNodeTreeItem(QTreeWidgetItem *item) |
1092 | { | ||
1093 | RegTreeItem *parent = dynamic_cast< RegTreeItem* >(_parent); | ||
1094 | NewFieldTreeItem *newdev_item = new NewFieldTreeItem("New field...", parent->GetRef()); | ||
1095 | MakeItalic(newdev_item, true); | ||
1096 | newdev_item->setIcon(0, QIcon::fromTheme("list-add")); | ||
1097 | parent->addChild(newdev_item); | ||
1098 | } | ||
1099 | |||
1100 | void RegEdit::FillRegTreeItem(QTreeWidgetItem *_item) | ||
1101 | { | ||
1102 | RegTreeItem *item = dynamic_cast< RegTreeItem* >(_item); | ||
1103 | const soc_reg_t& reg = item->GetRef().GetReg(); | ||
1104 | for(size_t i = 0; i < reg.field.size(); i++) | ||
1105 | { | ||
1106 | const soc_reg_field_t& field = reg.field[i]; | ||
1107 | FieldTreeItem *field_item = new FieldTreeItem(QString::fromStdString(field.name), | ||
1108 | SocFieldRef(item->GetRef(), i)); | ||
1109 | FixupEmptyItem(field_item); | ||
1110 | item->addChild(field_item); | ||
1111 | } | ||
1112 | CreateNewFieldItem(item); | ||
1113 | } | ||
1114 | |||
1115 | void RegEdit::CreateNewRegisterItem(QTreeWidgetItem *_parent) | ||
1116 | { | ||
1117 | DevTreeItem *parent = dynamic_cast< DevTreeItem* >(_parent); | ||
1118 | NewRegTreeItem *newdev_item = new NewRegTreeItem("New register...", parent->GetRef()); | ||
1119 | MakeItalic(newdev_item, true); | ||
1120 | newdev_item->setIcon(0, QIcon::fromTheme("list-add")); | ||
1121 | parent->addChild(newdev_item); | ||
1122 | } | ||
1123 | |||
1124 | void RegEdit::FillDevTreeItem(QTreeWidgetItem *_item) | ||
1125 | { | 1567 | { |
1126 | DevTreeItem *item = dynamic_cast< DevTreeItem* >(_item); | 1568 | soc_desc::node_ref_t node = SocTreeItemVal< soc_desc::node_ref_t >(item); |
1127 | const soc_dev_t& dev = item->GetRef().GetDev(); | 1569 | soc_desc::register_ref_t reg = node.reg(); |
1128 | for(size_t i = 0; i < dev.reg.size(); i++) | 1570 | /* put register if there, otherwise offer to create one */ |
1571 | if(reg.valid() && reg.node() == node) | ||
1129 | { | 1572 | { |
1130 | const soc_reg_t& reg = dev.reg[i]; | 1573 | QTreeWidgetItem *reg_item = MakeSocTreeItem(SocTreeRegType, reg); |
1131 | RegTreeItem *reg_item = new RegTreeItem(QString::fromStdString(reg.name), | 1574 | FixupItem(reg_item); |
1132 | SocRegRef(item->GetRef(), i, -1)); | ||
1133 | FixupEmptyItem(reg_item); | ||
1134 | FillRegTreeItem(reg_item); | ||
1135 | item->addChild(reg_item); | 1575 | item->addChild(reg_item); |
1136 | } | 1576 | } |
1137 | CreateNewRegisterItem(item); | 1577 | std::vector< soc_desc::node_ref_t > list = node.children(); |
1138 | } | 1578 | for(size_t i = 0; i < list.size(); i++) |
1139 | |||
1140 | void RegEdit::CreateNewDeviceItem(QTreeWidgetItem *_parent) | ||
1141 | { | ||
1142 | SocTreeItem *parent = dynamic_cast< SocTreeItem* >(_parent); | ||
1143 | NewDevTreeItem *newdev_item = new NewDevTreeItem("New device...", parent->GetRef()); | ||
1144 | MakeItalic(newdev_item, true); | ||
1145 | newdev_item->setIcon(0, QIcon::fromTheme("list-add")); | ||
1146 | parent->addChild(newdev_item); | ||
1147 | } | ||
1148 | |||
1149 | void RegEdit::FillSocTreeItem(QTreeWidgetItem *_item) | ||
1150 | { | ||
1151 | SocTreeItem *item = dynamic_cast< SocTreeItem* >(_item); | ||
1152 | const soc_t& soc = item->GetRef().GetSoc(); | ||
1153 | for(size_t i = 0; i < soc.dev.size(); i++) | ||
1154 | { | 1579 | { |
1155 | const soc_dev_t& reg = soc.dev[i]; | 1580 | QTreeWidgetItem *node_item = MakeSocTreeItem(SocTreeNodeType, list[i]); |
1156 | DevTreeItem *dev_item = new DevTreeItem(QString::fromStdString(reg.name), | 1581 | FixupItem(node_item); |
1157 | SocDevRef(item->GetRef(), i, -1)); | 1582 | FillNodeTreeItem(node_item); |
1158 | FixupEmptyItem(dev_item); | 1583 | item->addChild(node_item); |
1159 | FillDevTreeItem(dev_item); | ||
1160 | item->addChild(dev_item); | ||
1161 | } | 1584 | } |
1162 | CreateNewDeviceItem(item); | ||
1163 | } | 1585 | } |
1164 | 1586 | ||
1165 | void RegEdit::FillSocTree() | 1587 | void RegEdit::FillSocTree() |
1166 | { | 1588 | { |
1167 | SocRef ref = m_cur_socfile.GetSocRef(); | 1589 | soc_desc::soc_ref_t ref = m_cur_socfile.GetSocRef(); |
1168 | SocTreeItem *soc_item = new SocTreeItem( | 1590 | QTreeWidgetItem *root_item = MakeSocTreeItem(SocTreeSocType, ref.root()); |
1169 | QString::fromStdString(ref.GetSoc().name), ref); | 1591 | FixupItem(root_item); |
1170 | FixupEmptyItem(soc_item); | 1592 | FillNodeTreeItem(root_item); |
1171 | FillSocTreeItem(soc_item); | 1593 | m_soc_tree->addTopLevelItem(root_item); |
1172 | m_soc_tree->addTopLevelItem(soc_item); | 1594 | root_item->setExpanded(true); |
1173 | soc_item->setExpanded(true); | ||
1174 | } | 1595 | } |
1175 | 1596 | ||
1176 | void RegEdit::MakeItalic(QTreeWidgetItem *item, bool it) | 1597 | void RegEdit::MakeItalic(QTreeWidgetItem *item, bool it) |
@@ -1180,17 +1601,46 @@ void RegEdit::MakeItalic(QTreeWidgetItem *item, bool it) | |||
1180 | item->setFont(0, font); | 1601 | item->setFont(0, font); |
1181 | } | 1602 | } |
1182 | 1603 | ||
1183 | void RegEdit::FixupEmptyItem(QTreeWidgetItem *item) | 1604 | QIcon RegEdit::GetIconFromType(int type) |
1605 | { | ||
1606 | switch(type) | ||
1607 | { | ||
1608 | case SocTreeSocType: return QIcon::fromTheme("computer"); | ||
1609 | case SocTreeNodeType: return QIcon::fromTheme("cpu"); | ||
1610 | case SocTreeRegType: return style()->standardIcon(QStyle::SP_ArrowRight); | ||
1611 | default: return QIcon(); | ||
1612 | } | ||
1613 | } | ||
1614 | |||
1615 | bool RegEdit::ValidateName(const QString& name) | ||
1184 | { | 1616 | { |
1185 | if(item->text(0).size() == 0) | 1617 | if(name.size() == 0) |
1618 | return false; | ||
1619 | for(int i = 0; i < name.size(); i++) | ||
1620 | if(!name[i].isLetterOrNumber() && name[i] != QChar('_')) | ||
1621 | return false; | ||
1622 | return true; | ||
1623 | } | ||
1624 | |||
1625 | void RegEdit::FixupItem(QTreeWidgetItem *item) | ||
1626 | { | ||
1627 | UpdateName(item); | ||
1628 | if(!ValidateName(item->text(0))) | ||
1186 | { | 1629 | { |
1187 | item->setIcon(0, QIcon::fromTheme("dialog-error")); | 1630 | item->setIcon(0, QIcon::fromTheme("dialog-error")); |
1188 | MakeItalic(item, true); | 1631 | if(item->text(0).size() == 0) |
1189 | item->setText(0, "Unnamed"); | 1632 | { |
1633 | MakeItalic(item, true); | ||
1634 | item->setText(0, "Unnamed"); | ||
1635 | } | ||
1636 | m_msg_name_error_id = SetMessage(MessageWidget::Error, | ||
1637 | "The item name is invalid. It must be non-empty and consists only " | ||
1638 | "of alphanumerical or underscore characters"); | ||
1190 | } | 1639 | } |
1191 | else | 1640 | else |
1192 | { | 1641 | { |
1193 | item->setIcon(0, QIcon::fromTheme("cpu")); | 1642 | HideMessage(m_msg_name_error_id); |
1643 | item->setIcon(0, GetIconFromType(item->type())); | ||
1194 | MakeItalic(item, false); | 1644 | MakeItalic(item, false); |
1195 | } | 1645 | } |
1196 | } | 1646 | } |
@@ -1206,9 +1656,9 @@ void RegEdit::SetPanel(QWidget *panel) | |||
1206 | { | 1656 | { |
1207 | delete m_right_panel; | 1657 | delete m_right_panel; |
1208 | m_right_panel = panel; | 1658 | m_right_panel = panel; |
1209 | connect(m_right_panel, SIGNAL(OnModified(bool)), this, SLOT(OnSocModified(bool))); | 1659 | connect(m_right_panel, SIGNAL(OnModified()), this, |
1210 | m_splitter->addWidget(m_right_panel); | 1660 | SLOT(OnSocModified())); |
1211 | m_splitter->setStretchFactor(1, 2); | 1661 | m_right_panel_layout->addWidget(m_right_panel, 1); |
1212 | } | 1662 | } |
1213 | 1663 | ||
1214 | void RegEdit::SetModified(bool add, bool mod) | 1664 | void RegEdit::SetModified(bool add, bool mod) |
@@ -1217,15 +1667,33 @@ void RegEdit::SetModified(bool add, bool mod) | |||
1217 | OnModified(mod); | 1667 | OnModified(mod); |
1218 | } | 1668 | } |
1219 | 1669 | ||
1220 | namespace | 1670 | void RegEdit::OnSocItemNew() |
1221 | { | ||
1222 | |||
1223 | template< typename T > | ||
1224 | void my_remove_at(std::vector< T >& v, size_t at) | ||
1225 | { | 1671 | { |
1226 | v.erase(v.begin() + at); | 1672 | QTreeWidgetItem *current = m_soc_tree->currentItem(); |
1673 | if(current == 0) | ||
1674 | return; | ||
1675 | soc_desc::node_ref_t node = SocTreeItemVal< soc_desc::node_ref_t >(current); | ||
1676 | node = node.create(); | ||
1677 | node.get()->name = "unnamed"; | ||
1678 | QTreeWidgetItem *node_item = MakeSocTreeItem(SocTreeNodeType, node); | ||
1679 | FixupItem(node_item); | ||
1680 | current->addChild(node_item); | ||
1681 | m_soc_tree->setCurrentItem(node_item); | ||
1227 | } | 1682 | } |
1228 | 1683 | ||
1684 | void RegEdit::OnSocItemCreate() | ||
1685 | { | ||
1686 | QTreeWidgetItem *current = m_soc_tree->currentItem(); | ||
1687 | if(current == 0) | ||
1688 | return; | ||
1689 | soc_desc::register_t reg; | ||
1690 | reg.width = 32; | ||
1691 | soc_desc::node_ref_t node = SocTreeItemVal< soc_desc::node_ref_t >(current); | ||
1692 | node.get()->register_.push_back(reg); | ||
1693 | QTreeWidgetItem *reg_item = MakeSocTreeItem(SocTreeRegType, node.reg()); | ||
1694 | FixupItem(reg_item); | ||
1695 | current->insertChild(0, reg_item); | ||
1696 | m_soc_tree->setCurrentItem(reg_item); | ||
1229 | } | 1697 | } |
1230 | 1698 | ||
1231 | void RegEdit::OnSocItemDelete() | 1699 | void RegEdit::OnSocItemDelete() |
@@ -1242,172 +1710,116 @@ void RegEdit::OnSocItemDelete() | |||
1242 | return; | 1710 | return; |
1243 | if(current->type() == SocTreeSocType) | 1711 | if(current->type() == SocTreeSocType) |
1244 | { | 1712 | { |
1245 | SocTreeItem *item = dynamic_cast< SocTreeItem * >(current); | 1713 | SocTreeItemVal< soc_desc::node_ref_t >(current).remove(); |
1246 | item->GetRef().GetSoc().dev.clear(); | 1714 | current->takeChildren(); |
1247 | item->takeChildren(); | 1715 | OnSocModified(); |
1248 | FillSocTreeItem(item); | ||
1249 | m_soc_tree->expandItem(item); | ||
1250 | } | 1716 | } |
1251 | else if(current->type() == SocTreeDevType) | 1717 | else if(current->type() == SocTreeNodeType) |
1252 | { | 1718 | { |
1253 | DevTreeItem *item = dynamic_cast< DevTreeItem * >(current); | 1719 | SocTreeItemVal< soc_desc::node_ref_t >(current).remove(); |
1254 | my_remove_at(item->GetRef().GetSoc().dev, item->GetRef().GetDevIndex()); | 1720 | current->parent()->removeChild(current); |
1255 | QTreeWidgetItem *parent = item->parent(); | 1721 | OnSocModified(); |
1256 | parent->takeChildren(); | ||
1257 | FillSocTreeItem(parent); | ||
1258 | m_soc_tree->expandItem(parent); | ||
1259 | } | 1722 | } |
1260 | else if(current->type() == SocTreeRegType) | 1723 | else if(current->type() == SocTreeRegType) |
1261 | { | 1724 | { |
1262 | RegTreeItem *item = dynamic_cast< RegTreeItem * >(current); | 1725 | SocTreeItemVal< soc_desc::register_ref_t >(current).remove(); |
1263 | my_remove_at(item->GetRef().GetDev().reg, item->GetRef().GetRegIndex()); | 1726 | current->parent()->removeChild(current); |
1264 | QTreeWidgetItem *parent = item->parent(); | 1727 | OnSocModified(); |
1265 | parent->takeChildren(); | ||
1266 | FillDevTreeItem(parent); | ||
1267 | m_soc_tree->expandItem(parent); | ||
1268 | } | ||
1269 | else if(current->type() == SocTreeFieldType) | ||
1270 | { | ||
1271 | FieldTreeItem *item = dynamic_cast< FieldTreeItem * >(current); | ||
1272 | my_remove_at(item->GetRef().GetReg().field, item->GetRef().GetFieldIndex()); | ||
1273 | QTreeWidgetItem *parent = item->parent(); | ||
1274 | parent->takeChildren(); | ||
1275 | FillRegTreeItem(parent); | ||
1276 | m_soc_tree->expandItem(parent); | ||
1277 | } | 1728 | } |
1278 | } | 1729 | } |
1279 | 1730 | ||
1280 | void RegEdit::OnSocModified(bool modified) | 1731 | void RegEdit::OnSocModified() |
1281 | { | 1732 | { |
1282 | // we might need to update the name in the tree | 1733 | // we might need to update the name in the tree |
1283 | UpdateName(m_soc_tree->currentItem()); | 1734 | FixupItem(m_soc_tree->currentItem()); |
1284 | if(modified) | 1735 | SetModified(true, true); |
1285 | SetModified(true, true); | ||
1286 | } | 1736 | } |
1287 | 1737 | ||
1288 | void RegEdit::DisplaySoc(SocRef ref) | 1738 | void RegEdit::DisplaySoc(const soc_desc::soc_ref_t& ref) |
1289 | { | 1739 | { |
1290 | SetPanel(new SocEditPanel(ref, this)); | 1740 | SetPanel(new SocEditPanel(ref, this)); |
1291 | } | 1741 | } |
1292 | 1742 | ||
1293 | void RegEdit::DisplayDev(SocDevRef ref) | 1743 | void RegEdit::DisplayNode(const soc_desc::node_ref_t& ref) |
1294 | { | 1744 | { |
1295 | SetPanel(new DevEditPanel(ref, this)); | 1745 | SetPanel(new NodeEditPanel(ref, this)); |
1296 | } | 1746 | } |
1297 | 1747 | ||
1298 | void RegEdit::DisplayReg(SocRegRef ref) | 1748 | void RegEdit::DisplayReg(const soc_desc::register_ref_t& ref) |
1299 | { | 1749 | { |
1300 | SetPanel(new RegEditPanel(ref, this)); | 1750 | SetPanel(new RegEditPanel(ref, this)); |
1301 | } | 1751 | } |
1302 | 1752 | ||
1303 | void RegEdit::DisplayField(SocFieldRef ref) | ||
1304 | { | ||
1305 | SetPanel(new FieldEditPanel(ref, this)); | ||
1306 | } | ||
1307 | |||
1308 | void RegEdit::UpdateName(QTreeWidgetItem *current) | 1753 | void RegEdit::UpdateName(QTreeWidgetItem *current) |
1309 | { | 1754 | { |
1310 | if(current == 0) | 1755 | if(current == 0) |
1311 | return; | 1756 | return; |
1757 | |||
1312 | if(current->type() == SocTreeSocType) | 1758 | if(current->type() == SocTreeSocType) |
1313 | { | 1759 | { |
1314 | SocTreeItem *item = dynamic_cast< SocTreeItem * >(current); | 1760 | current->setText(0, QString::fromStdString( |
1315 | item->setText(0, QString::fromStdString(item->GetRef().GetSoc().name)); | 1761 | SocTreeItemVal< soc_desc::node_ref_t >(current).soc().get()->name)); |
1316 | } | 1762 | } |
1317 | else if(current->type() == SocTreeDevType) | 1763 | else if(current->type() == SocTreeNodeType) |
1318 | { | 1764 | { |
1319 | DevTreeItem *item = dynamic_cast< DevTreeItem * >(current); | 1765 | current->setText(0, QString::fromStdString( |
1320 | item->setText(0, QString::fromStdString(item->GetRef().GetDev().name)); | 1766 | SocTreeItemVal< soc_desc::node_ref_t >(current).get()->name)); |
1321 | } | 1767 | } |
1322 | else if(current->type() == SocTreeRegType) | 1768 | else if(current->type() == SocTreeRegType) |
1323 | { | 1769 | { |
1324 | RegTreeItem *item = dynamic_cast< RegTreeItem * >(current); | 1770 | current->setText(0, "register"); |
1325 | item->setText(0, QString::fromStdString(item->GetRef().GetReg().name)); | ||
1326 | } | ||
1327 | else if(current->type() == SocTreeFieldType) | ||
1328 | { | ||
1329 | FieldTreeItem *item = dynamic_cast< FieldTreeItem * >(current); | ||
1330 | item->setText(0, QString::fromStdString(item->GetRef().GetField().name)); | ||
1331 | } | 1771 | } |
1332 | FixupEmptyItem(current); | ||
1333 | } | 1772 | } |
1334 | 1773 | ||
1335 | void RegEdit::OnSocItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) | 1774 | void RegEdit::OnSocTreeContextMenu(QPoint point) |
1336 | { | 1775 | { |
1337 | Q_UNUSED(previous); | 1776 | HideMessage(m_msg_welcome_id); |
1338 | if(current == 0) | 1777 | QTreeWidgetItem *item = m_soc_tree->itemAt(point); |
1778 | if(item == 0) | ||
1339 | return; | 1779 | return; |
1340 | if(current->type() == SocTreeSocType) | 1780 | /* customise messages with item */ |
1341 | { | 1781 | m_action_item = item; |
1342 | SocTreeItem *item = dynamic_cast< SocTreeItem * >(current); | 1782 | QMenu *menu = new QMenu(this); |
1343 | DisplaySoc(item->GetRef()); | 1783 | switch(item->type()) |
1344 | } | ||
1345 | else if(current->type() == SocTreeDevType) | ||
1346 | { | 1784 | { |
1347 | DevTreeItem *item = dynamic_cast< DevTreeItem * >(current); | 1785 | case SocTreeSocType: |
1348 | DisplayDev(item->GetRef()); | 1786 | m_new_action->setText("New node..."); |
1349 | } | 1787 | m_delete_action->setText("Delete all nodes..."); |
1350 | else if(current->type() == SocTreeRegType) | 1788 | menu->addAction(m_new_action); |
1351 | { | 1789 | menu->addAction(m_delete_action); |
1352 | RegTreeItem *item = dynamic_cast< RegTreeItem * >(current); | 1790 | break; |
1353 | DisplayReg(item->GetRef()); | 1791 | case SocTreeNodeType: |
1354 | } | 1792 | { |
1355 | else if(current->type() == SocTreeFieldType) | 1793 | m_new_action->setText("New node..."); |
1356 | { | 1794 | m_delete_action->setText("Delete node..."); |
1357 | FieldTreeItem *item = dynamic_cast< FieldTreeItem * >(current); | 1795 | soc_desc::node_ref_t node = SocTreeItemVal< soc_desc::node_ref_t >(item); |
1358 | DisplayField(item->GetRef()); | 1796 | if(node.reg().node() != node) |
1797 | menu->addAction(m_create_action); | ||
1798 | menu->addAction(m_new_action); | ||
1799 | menu->addAction(m_delete_action); | ||
1800 | break; | ||
1801 | } | ||
1802 | case SocTreeRegType: | ||
1803 | m_delete_action->setText("Delete register..."); | ||
1804 | menu->addAction(m_new_action); | ||
1805 | menu->addAction(m_delete_action); | ||
1806 | break; | ||
1359 | } | 1807 | } |
1808 | menu->popup(m_soc_tree->viewport()->mapToGlobal(point)); | ||
1360 | } | 1809 | } |
1361 | 1810 | ||
1362 | void RegEdit::OnSocItemActivated(QTreeWidgetItem *current, int column) | 1811 | void RegEdit::OnSocItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) |
1363 | { | 1812 | { |
1364 | Q_UNUSED(column); | 1813 | Q_UNUSED(previous); |
1814 | HideMessage(m_msg_welcome_id); | ||
1365 | if(current == 0) | 1815 | if(current == 0) |
1366 | return; | 1816 | return; |
1367 | if(current->type() == SocTreeNewDevType) | 1817 | if(current->type() == SocTreeSocType) |
1368 | AddDevice(current); | 1818 | DisplaySoc(SocTreeItemVal< soc_desc::node_ref_t >(current).soc()); |
1369 | else if(current->type() == SocTreeNewRegType) | 1819 | else if(current->type() == SocTreeNodeType) |
1370 | AddRegister(current); | 1820 | DisplayNode(SocTreeItemVal< soc_desc::node_ref_t >(current)); |
1371 | else if(current->type() == SocTreeNewFieldType) | 1821 | else if(current->type() == SocTreeRegType) |
1372 | AddField(current); | 1822 | DisplayReg(SocTreeItemVal< soc_desc::register_ref_t >(current)); |
1373 | } | ||
1374 | |||
1375 | void RegEdit::AddDevice(QTreeWidgetItem *_item) | ||
1376 | { | ||
1377 | NewDevTreeItem *item = dynamic_cast< NewDevTreeItem * >(_item); | ||
1378 | item->GetRef().GetSoc().dev.push_back(soc_dev_t()); | ||
1379 | DevTreeItem *dev_item = new DevTreeItem("", | ||
1380 | SocDevRef(item->GetRef(), item->GetRef().GetSoc().dev.size() - 1, -1)); | ||
1381 | FixupEmptyItem(dev_item); | ||
1382 | item->parent()->insertChild(item->parent()->indexOfChild(item), dev_item); | ||
1383 | CreateNewRegisterItem(dev_item); | ||
1384 | m_soc_tree->setCurrentItem(dev_item); | ||
1385 | OnModified(true); | ||
1386 | } | ||
1387 | |||
1388 | void RegEdit::AddRegister(QTreeWidgetItem *_item) | ||
1389 | { | ||
1390 | NewRegTreeItem *item = dynamic_cast< NewRegTreeItem * >(_item); | ||
1391 | item->GetRef().GetDev().reg.push_back(soc_reg_t()); | ||
1392 | RegTreeItem *reg_item = new RegTreeItem("", | ||
1393 | SocRegRef(item->GetRef(), item->GetRef().GetDev().reg.size() - 1, -1)); | ||
1394 | FixupEmptyItem(reg_item); | ||
1395 | item->parent()->insertChild(item->parent()->indexOfChild(item), reg_item); | ||
1396 | CreateNewFieldItem(reg_item); | ||
1397 | m_soc_tree->setCurrentItem(reg_item); | ||
1398 | OnModified(true); | ||
1399 | } | ||
1400 | |||
1401 | void RegEdit::AddField(QTreeWidgetItem *_item) | ||
1402 | { | ||
1403 | NewFieldTreeItem *item = dynamic_cast< NewFieldTreeItem * >(_item); | ||
1404 | item->GetRef().GetReg().field.push_back(soc_reg_field_t()); | ||
1405 | FieldTreeItem *field_item = new FieldTreeItem("", | ||
1406 | SocFieldRef(item->GetRef(), item->GetRef().GetReg().field.size() - 1)); | ||
1407 | FixupEmptyItem(field_item); | ||
1408 | item->parent()->insertChild(item->parent()->indexOfChild(item), field_item); | ||
1409 | m_soc_tree->setCurrentItem(field_item); | ||
1410 | OnModified(true); | ||
1411 | } | 1823 | } |
1412 | 1824 | ||
1413 | bool RegEdit::Quit() | 1825 | bool RegEdit::Quit() |