11#include < QtWidgets/QGridLayout>
22#include < QtWidgets/QHBoxLayout>
3+ #include < QtWidgets/QLabel>
34#include < algorithm>
45#include < vector>
56#include " sections.h"
67#include " headers.h"
78#include " fontsettings.h"
89
910
11+ SectionsModel::SectionsModel (QObject* parent, BinaryViewRef data) : QObject(parent), BinaryDataNotification(SectionUpdates)
12+ {
13+ m_data = data;
14+ m_data->RegisterNotification (this );
15+ updateSections ();
16+ }
17+
18+
19+ SectionsModel::~SectionsModel ()
20+ {
21+ m_data->UnregisterNotification (this );
22+ }
23+
24+
25+ void SectionsModel::updateSections ()
26+ {
27+ m_sections.clear ();
28+ for (auto & section : m_data->GetSections ())
29+ if (section->GetSemantics () != ExternalSectionSemantics)
30+ m_sections.push_back (section);
31+ sort (m_sections.begin (), m_sections.end (),
32+ [&](SectionRef a, SectionRef b) { return a->GetStart () < b->GetStart (); });
33+
34+ emit sectionsChanged ();
35+ }
36+
37+
38+ void SectionsModel::OnSectionAdded (BinaryNinja::BinaryView* data, BinaryNinja::Section* section)
39+ {
40+ QMetaObject::invokeMethod (this , &SectionsModel::updateSections, Qt::QueuedConnection);
41+ }
42+
43+
44+ void SectionsModel::OnSectionRemoved (BinaryNinja::BinaryView* data, BinaryNinja::Section* section)
45+ {
46+ QMetaObject::invokeMethod (this , &SectionsModel::updateSections, Qt::QueuedConnection);
47+ }
48+
49+
50+ void SectionsModel::OnSectionUpdated (BinaryNinja::BinaryView* data, BinaryNinja::Section* section)
51+ {
52+ QMetaObject::invokeMethod (this , &SectionsModel::updateSections, Qt::QueuedConnection);
53+ }
54+
55+
1056SegmentsWidget::SegmentsWidget (QWidget* parent, BinaryViewRef data) : QWidget(parent)
1157{
1258 QGridLayout* layout = new QGridLayout ();
@@ -63,29 +109,77 @@ SegmentsWidget::SegmentsWidget(QWidget* parent, BinaryViewRef data) : QWidget(pa
63109}
64110
65111
66- SectionsWidget::SectionsWidget (QWidget* parent, BinaryViewRef data) : QWidget(parent)
112+ SectionsWidget::SectionsWidget (QWidget* parent, BinaryViewRef data) : QWidget(parent), m_data(data), m_model( nullptr ), m_layout( nullptr ), m_isRebuilding( false )
67113{
68- QGridLayout* layout = new QGridLayout ();
69- layout->setContentsMargins (0 , 0 , 0 , 0 );
70- layout->setVerticalSpacing (1 );
71- layout->setHorizontalSpacing (UIContext::getScaledWindowSize (16 , 16 ).width ());
114+ m_model = new SectionsModel (this , data);
115+
116+ m_layout = new QGridLayout ();
117+ m_layout->setContentsMargins (0 , 0 , 0 , 0 );
118+ m_layout->setVerticalSpacing (1 );
119+ m_layout->setHorizontalSpacing (UIContext::getScaledWindowSize (16 , 16 ).width ());
120+ setLayout (m_layout);
121+
122+ connect (m_model, &SectionsModel::sectionsChanged, this , &SectionsWidget::rebuildLayout, Qt::QueuedConnection);
123+
124+ rebuildLayout ();
125+ }
126+
127+
128+ SectionsWidget::~SectionsWidget ()
129+ {
130+ if (m_model)
131+ {
132+ disconnect (m_model, nullptr , this , nullptr );
133+ m_model->blockSignals (true );
134+ }
135+ }
136+
137+
138+ void SectionsWidget::rebuildLayout ()
139+ {
140+ if (m_isRebuilding)
141+ return ;
142+
143+ m_isRebuilding = true ;
144+ setUpdatesEnabled (false );
145+
146+ QObjectList children = this ->children ();
147+ for (QObject* child : children)
148+ {
149+ if (QWidget* widget = qobject_cast<QWidget*>(child))
150+ delete widget;
151+ }
152+
153+ delete m_layout;
154+
155+ m_layout = new QGridLayout ();
156+ m_layout->setContentsMargins (0 , 0 , 0 , 0 );
157+ m_layout->setVerticalSpacing (1 );
158+ m_layout->setHorizontalSpacing (UIContext::getScaledWindowSize (16 , 16 ).width ());
159+ setLayout (m_layout);
160+
161+ auto sections = m_model->GetSections ();
162+
163+ if (sections.empty ())
164+ {
165+ setUpdatesEnabled (true );
166+ m_isRebuilding = false ;
167+ return ;
168+ }
72169
73170 size_t maxNameLen = 0 ;
74- for (auto & section : data->GetSections ())
171+ for (auto & section : sections)
172+ {
75173 if (section->GetName ().size () > maxNameLen)
76174 maxNameLen = section->GetName ().size ();
175+ }
77176 if (maxNameLen > 32 )
78177 maxNameLen = 32 ;
79178
80- for (auto & section : data->GetSections ())
81- if (section->GetSemantics () != ExternalSectionSemantics)
82- m_sections.push_back (section);
83- sort (m_sections.begin (), m_sections.end (),
84- [&](SectionRef a, SectionRef b) { return a->GetStart () < b->GetStart (); });
85-
86179 int row = 0 ;
87- for (auto & section : m_sections )
180+ for (auto & section : sections )
88181 {
182+
89183 std::string name = section->GetName ();
90184 if (name.size () > maxNameLen)
91185 name = name.substr (0 , maxNameLen - 1 ) + std::string (" …" );
@@ -95,15 +189,15 @@ SectionsWidget::SectionsWidget(QWidget* parent, BinaryViewRef data) : QWidget(pa
95189 QString typeName = QString::fromStdString (section->GetType ());
96190
97191 QString permissions;
98- if (data ->IsOffsetReadable (section->GetStart ()))
192+ if (m_data ->IsOffsetReadable (section->GetStart ()))
99193 permissions += " r" ;
100194 else
101195 permissions += " -" ;
102- if (data ->IsOffsetWritable (section->GetStart ()))
196+ if (m_data ->IsOffsetWritable (section->GetStart ()))
103197 permissions += " w" ;
104198 else
105199 permissions += " -" ;
106- if (data ->IsOffsetExecutable (section->GetStart ()))
200+ if (m_data ->IsOffsetExecutable (section->GetStart ()))
107201 permissions += " x" ;
108202 else
109203 permissions += " -" ;
@@ -118,7 +212,7 @@ SectionsWidget::SectionsWidget(QWidget* parent, BinaryViewRef data) : QWidget(pa
118212
119213 QLabel* nameLabel = new QLabel (QString::fromStdString (name));
120214 nameLabel->setFont (getMonospaceFont (this ));
121- layout ->addWidget (nameLabel, row, 0 );
215+ m_layout ->addWidget (nameLabel, row, 0 );
122216
123217 QHBoxLayout* rangeLayout = new QHBoxLayout ();
124218 rangeLayout->setContentsMargins (0 , 0 , 0 , 0 );
@@ -129,21 +223,23 @@ SectionsWidget::SectionsWidget(QWidget* parent, BinaryViewRef data) : QWidget(pa
129223 rangeLayout->addWidget (beginLabel);
130224 rangeLayout->addWidget (dashLabel);
131225 rangeLayout->addWidget (endLabel);
132- layout ->addLayout (rangeLayout, row, 1 );
226+ m_layout ->addLayout (rangeLayout, row, 1 );
133227
134228 QLabel* permissionsLabel = new QLabel (permissions);
135229 permissionsLabel->setFont (getMonospaceFont (this ));
136- layout ->addWidget (permissionsLabel, row, 2 );
230+ m_layout ->addWidget (permissionsLabel, row, 2 );
137231 QLabel* typeLabel = new QLabel (typeName);
138232 typeLabel->setFont (getMonospaceFont (this ));
139- layout ->addWidget (typeLabel, row, 3 );
233+ m_layout ->addWidget (typeLabel, row, 3 );
140234 QLabel* semanticsLabel = new QLabel (semantics);
141235 semanticsLabel->setFont (getMonospaceFont (this ));
142- layout ->addWidget (semanticsLabel, row, 4 );
236+ m_layout ->addWidget (semanticsLabel, row, 4 );
143237
144238 row++;
145239 }
146240
147- layout->setColumnStretch (5 , 1 );
148- setLayout (layout);
241+ m_layout->setColumnStretch (5 , 1 );
242+
243+ setUpdatesEnabled (true );
244+ m_isRebuilding = false ;
149245}
0 commit comments