Skip to content

Commit

Permalink
feat: improve kaitai integration with new nested range highlights
Browse files Browse the repository at this point in the history
  • Loading branch information
hello-adam committed Apr 28, 2020
1 parent 1e872a3 commit 6b781a8
Show file tree
Hide file tree
Showing 14 changed files with 256 additions and 86 deletions.
43 changes: 37 additions & 6 deletions src/hobbits-core/bitinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ QList<RangeHighlight> BitInfo::highlights(QString category, QString label) const
if (highlight.label() == label) {
matching.append(highlight);
}
for (auto child : highlight.allDescendants()) {
if (child.label() == label) {
matching.append(child);
}
}
}
return matching;
}
Expand Down Expand Up @@ -165,19 +170,45 @@ void BitInfo::initFrames()
emit changed();
}

int BitInfo::frameOffsetContaining(Range target) const
int BitInfo::frameOffsetContaining(Range target, Range frameRange) const
{
if (frames().isEmpty()) {
return -1;
}
int offset = frames().size() / 2;
int index = offset;
if (!frameRange.isNull()) {
if (frameRange.end() > frames().size() || frameRange.start() < 0) {
return -1;
}
}
else {
frameRange = Range(0, frames().size() - 1);
}

if (frameRange.size() < 50) {
for (qint64 i = frameRange.start(); i <= frameRange.end(); i++) {
unsigned int compare = target.compare(frames().at(int(i)));
if (compare & Frame::Overlapping) {
return int(i);
}
}
return -1;
}

qint64 offset = frameRange.start() + frameRange.size() / 2;
qint64 index = offset;
int countdown = 7;
qint64 lowNo = frameRange.start() - 1;
while (true) {
unsigned int compare = target.compare(frames().at(index));
unsigned int compare = target.compare(frames().at(int(index)));

if (compare & Frame::Overlapping) {
return index;
if (index > lowNo + 1) {
int earlierIndex = frameOffsetContaining(target, Range(lowNo + 1, index - 1));
if (earlierIndex >= 0) {
return earlierIndex;
}
}
return int(index);
}

if (countdown < 1) {
Expand All @@ -197,7 +228,7 @@ int BitInfo::frameOffsetContaining(Range target) const
index -= offset;
}

if (index < 0 || index >= frames().size()) {
if (index < frameRange.start() || index > frameRange.end()) {
return -1;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/hobbits-core/bitinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class HOBBITSCORESHARED_EXPORT BitInfo : public QObject
bool containsHighlightCategory(QString category) const;
QVariant metadata(QString key) const;

int frameOffsetContaining(Range target) const;
int frameOffsetContaining(Range target, Range frameRange = Range()) const;

friend QDataStream& operator<<(QDataStream&, const BitInfo&);
friend QDataStream& operator>>(QDataStream&, BitInfo&);
Expand Down
13 changes: 11 additions & 2 deletions src/hobbits-core/displaybase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ QList<RangeHighlight> DisplayBase::getHighlightSpots(QList<RangeHighlight> highl
intersection = frame.compare(highlight.range());

if (intersection & Frame::Overlapping) {
RangeHighlight overlap(highlight.category(), highlight.label(), frame.getOverlap(highlight.range()), highlight.color());
RangeHighlight overlap(highlight.category(), highlight.label(), frame.getOverlap(highlight.range()), highlight.color(), highlight.children());
spots.append(overlap);
}
else if (intersection & Frame::After) {
Expand Down Expand Up @@ -246,7 +246,16 @@ QVector<QRectF> DisplayBase::drawHighlightRects(
lastHighlight,
displayFrame);

for (RangeHighlight spot : spots) {
while(!spots.isEmpty()) {
RangeHighlight spot = spots.takeFirst();
if (!spot.children().isEmpty()) {
painter->setOpacity(0.35);
int minIndex = 0;
spots.append(getHighlightSpots(spot.children(), minIndex, displayFrame));
}
else {
painter->setOpacity(1);
}
qint64 displayStart = (spot.range().start() - displayFrame.start());
double hx = getGroupedOffset(displayStart, colWidth, colGroupSize, bitOffset, colGroupMargin);
double hy = (i - frameOffset) * rowHeight;
Expand Down
110 changes: 71 additions & 39 deletions src/hobbits-core/highlightnavigator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ static const QString FOCUS_HIGHLIGHT_CATEGORY = "Highlight Nav Focus";
HighlightNavigator::HighlightNavigator(QWidget *parent) :
QWidget(parent),
ui(new Ui::HighlightNavigator),
m_allHighlightCount(0),
m_shouldHighlightSelection(false)
{
ui->setupUi(this);

connect(ui->tb_gotoNext, &QToolButton::pressed, this, &HighlightNavigator::selectNext);
connect(ui->tb_gotoPrevious, &QToolButton::pressed, this, &HighlightNavigator::selectPrevious);
connect(ui->lw_highlights, SIGNAL(currentRowChanged(int)), this, SLOT(updateSelection()));
connect(ui->lw_highlights, SIGNAL(currentRowChanged(int)), this, SIGNAL(selectionChanged()));
connect(ui->tw_highlights, SIGNAL(itemSelectionChanged()), this, SLOT(updateSelection()));
connect(ui->tw_highlights, SIGNAL(itemSelectionChanged()), this, SIGNAL(selectionChanged()));

Q_INIT_RESOURCE(hobbitscoreicons);
ui->tb_gotoNext->setIcon(QIcon(":/hobbits-core/images/icons/arrow-right.png"));
Expand All @@ -26,34 +27,27 @@ HighlightNavigator::~HighlightNavigator()
delete ui;
}


void HighlightNavigator::setShouldHighlightSelection(bool shouldHighlight)
{
m_shouldHighlightSelection = shouldHighlight;
}


int HighlightNavigator::currentlySelectedRow()
{
return ui->lw_highlights->currentRow();
}

QString HighlightNavigator::currentlySelectedLabel()
{
auto item = ui->lw_highlights->currentItem();
auto item = ui->tw_highlights->currentItem();
if (item) {
return item->text();
return item->text(0);
}
return QString();
}

bool HighlightNavigator::selectRow(QString text)
{
auto items = ui->lw_highlights->findItems(text, Qt::MatchFixedString | Qt::MatchCaseSensitive);
auto items = ui->tw_highlights->findItems(text, Qt::MatchFixedString | Qt::MatchCaseSensitive);
if (items.empty()) {
return false;
}
ui->lw_highlights->setCurrentItem(items.at(0));
ui->tw_highlights->setCurrentItem(items.at(0));
return true;
}

Expand Down Expand Up @@ -83,6 +77,29 @@ void HighlightNavigator::setTitle(QString title)
ui->lb_title->setText(title);
}

QTreeWidgetItem* HighlightNavigator::highlightToItem(const RangeHighlight &highlight, int &count) const
{
QTreeWidgetItem* item = new QTreeWidgetItem();

item->setText(0, highlight.label());

QPixmap pix(16,16);
pix.fill(highlight.color());
item->setIcon(0, QIcon(pix));

QVariant userData;
userData.setValue(highlight);
item->setData(0, Qt::UserRole, userData);

item->setData(0, Qt::UserRole + 1, ++count);

for (auto child : highlight.children()) {
item->addChild(highlightToItem(child, count));
}

return item;
}

void HighlightNavigator::refresh()
{
// has the important stuff actually changed?
Expand All @@ -103,7 +120,7 @@ void HighlightNavigator::refresh()
}
}

ui->lw_highlights->clear();
ui->tw_highlights->clear();
m_highlights.clear();

ui->tb_gotoNext->setEnabled(false);
Expand All @@ -124,57 +141,69 @@ void HighlightNavigator::refresh()

m_highlights = m_container->bitInfo()->highlights(m_category);

ui->lw_highlights->clear();
QStringList labels;
QList<QTreeWidgetItem*> items;
m_allHighlightCount = 0;
for (auto highlight: m_container->bitInfo()->highlights(m_category)) {
labels.append(highlight.label());
items.append(highlightToItem(highlight, m_allHighlightCount));
}
ui->tw_highlights->addTopLevelItems(items);
if (items.size() > 0) {
ui->tw_highlights->setCurrentItem(items.first());
}
ui->lw_highlights->addItems(labels);
ui->lw_highlights->setCurrentRow(0);
}

void HighlightNavigator::selectNext()
{
if (currentlySelectedRow() < 0) {
if (!ui->tw_highlights->currentItem()) {
return;
}
selectRow(currentlySelectedRow() + 1);
}

void HighlightNavigator::selectPrevious()
{
if (currentlySelectedRow() < 0) {
auto next = ui->tw_highlights->itemBelow(ui->tw_highlights->currentItem());
if (next) {
ui->tw_highlights->setCurrentItem(next);
return;
}
next = ui->tw_highlights->topLevelItem(0);
if (next) {
ui->tw_highlights->setCurrentItem(next);
return;
}
selectRow(currentlySelectedRow() - 1);
}

void HighlightNavigator::selectRow(int row)
void HighlightNavigator::selectPrevious()
{
if (currentlySelectedRow() < 0) {
if (!ui->tw_highlights->currentItem()) {
return;
}
if (row < 0) {
row = m_highlights.size() - 1;
auto prev = ui->tw_highlights->itemAbove(ui->tw_highlights->currentItem());
if (prev) {
ui->tw_highlights->setCurrentItem(prev);
return;
}
else if (row >= m_highlights.size()) {
row = 0;
prev = ui->tw_highlights->topLevelItem(ui->tw_highlights->topLevelItemCount()-1);
if (prev) {
ui->tw_highlights->setCurrentItem(prev);
return;
}
ui->lw_highlights->setCurrentRow(row);
}


void HighlightNavigator::updateSelection()
{
if (m_container.isNull()) {
return;
}

int currIndex = ui->lw_highlights->currentRow();
if (currIndex >= m_highlights.size() || currIndex < 0) {
auto curr = ui->tw_highlights->currentItem();
if (!curr) {
return;
}
RangeHighlight selected = m_highlights.at(currIndex);

RangeHighlight selected = curr->data(0, Qt::UserRole).value<RangeHighlight>();
// Make sure this exists in the container
if (m_container->bitInfo()->highlights(selected.category(), selected.label()).isEmpty()) {
return;
}

int selectedNum = curr->data(0, Qt::UserRole + 1).toInt();

QColor focusColor = SettingsManager::getInstance().getUiSetting(SettingsData::FOCUS_COLOR_KEY).value<QColor>();
RangeHighlight focus = RangeHighlight(FOCUS_HIGHLIGHT_CATEGORY, selected.label(), selected.range(), focusColor);
Expand All @@ -184,6 +213,9 @@ void HighlightNavigator::updateSelection()
int bitOffset = qMax(
0,
int(focus.range().start() - m_container->bitInfo()->frames().at(containingFrame).start() - 16));
if (bitOffset < 256) {
bitOffset = 0;
}
int frameOffset = qMax(0, containingFrame - 16);

if (m_shouldHighlightSelection) {
Expand All @@ -201,5 +233,5 @@ void HighlightNavigator::updateSelection()

ui->lb_selected->setText(
QString("%1 of %2").arg(
currIndex + 1).arg(m_highlights.size()));
selectedNum).arg(m_allHighlightCount));
}
6 changes: 4 additions & 2 deletions src/hobbits-core/highlightnavigator.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define HIGHLIGHTNAVIGATOR_H

#include <QWidget>
#include <QTreeWidgetItem>
#include "bitcontainerpreview.h"
#include "plugincallback.h"

Expand All @@ -17,7 +18,6 @@ class HOBBITSCORESHARED_EXPORT HighlightNavigator : public QWidget
explicit HighlightNavigator(QWidget *parent = nullptr);
~HighlightNavigator();

int currentlySelectedRow();
bool selectRow(QString);
QString currentlySelectedLabel();

Expand All @@ -29,16 +29,18 @@ public slots:
void refresh();
void selectNext();
void selectPrevious();
void selectRow(int);
void updateSelection();
void setShouldHighlightSelection(bool);

signals:
void selectionChanged();

private:
QTreeWidgetItem* highlightToItem(const RangeHighlight &highlight, int &count) const;

Ui::HighlightNavigator *ui;
QList<RangeHighlight> m_highlights;
int m_allHighlightCount;
QString m_category;
QSharedPointer<BitContainerPreview> m_container;
QSharedPointer<PluginCallback> m_pluginCallback;
Expand Down
Loading

0 comments on commit 6b781a8

Please sign in to comment.