diff options
| -rw-r--r-- | examples/triage/baseaddress.cpp | 50 | ||||
| -rw-r--r-- | examples/triage/fileinfo.cpp | 34 | ||||
| -rw-r--r-- | examples/triage/fileinfo.h | 1 | ||||
| -rw-r--r-- | ui/copyablelabel.h | 2 |
4 files changed, 85 insertions, 2 deletions
diff --git a/examples/triage/baseaddress.cpp b/examples/triage/baseaddress.cpp index f32169ad..dacc6c53 100644 --- a/examples/triage/baseaddress.cpp +++ b/examples/triage/baseaddress.cpp @@ -1,4 +1,6 @@ #include "baseaddress.h" +#include <QScrollArea> +#include <QScrollBar> using namespace std; @@ -175,6 +177,23 @@ void BaseAddressDetectionWidget::GetClickedBaseAddress(const QModelIndex& index) void BaseAddressDetectionWidget::HandleResults(const BaseAddressDetectionQtResults& results) { + // Save scroll position to prevent unwanted scrolling when hiding/showing widgets + QScrollArea* scrollArea = nullptr; + int savedVerticalScrollPosition = 0; + int savedHorizontalScrollPosition = 0; + QWidget* ancestor = parentWidget(); + while (ancestor) + { + scrollArea = qobject_cast<QScrollArea*>(ancestor); + if (scrollArea) + { + savedVerticalScrollPosition = scrollArea->verticalScrollBar()->value(); + savedHorizontalScrollPosition = scrollArea->horizontalScrollBar()->value(); + break; + } + ancestor = ancestor->parentWidget(); + } + if (!results.Status.empty()) m_status->setText(QString::fromStdString(results.Status)); @@ -238,11 +257,35 @@ void BaseAddressDetectionWidget::HandleResults(const BaseAddressDetectionQtResul m_abortButton->setHidden(true); m_startButton->setHidden(false); m_startButton->setEnabled(true); + + // Restore scroll position after widget visibility changes + if (scrollArea) + { + scrollArea->verticalScrollBar()->setValue(savedVerticalScrollPosition); + scrollArea->horizontalScrollBar()->setValue(savedHorizontalScrollPosition); + } } void BaseAddressDetectionWidget::DetectBaseAddress() { + // Save scroll position to prevent unwanted scrolling when hiding/showing widgets + QScrollArea* scrollArea = nullptr; + int savedVerticalScrollPosition = 0; + int savedHorizontalScrollPosition = 0; + QWidget* ancestor = parentWidget(); + while (ancestor) + { + scrollArea = qobject_cast<QScrollArea*>(ancestor); + if (scrollArea) + { + savedVerticalScrollPosition = scrollArea->verticalScrollBar()->value(); + savedHorizontalScrollPosition = scrollArea->horizontalScrollBar()->value(); + break; + } + ancestor = ancestor->parentWidget(); + } + HideResultsWidgets(true); m_status->setText("Running..."); m_resultsTableWidget->clearContents(); @@ -254,6 +297,13 @@ void BaseAddressDetectionWidget::DetectBaseAddress() connect(m_worker, &BaseAddressDetectionThread::finished, m_worker, &QObject::deleteLater); m_worker->start(); m_abortButton->setHidden(false); + + // Restore scroll position after widget visibility changes + if (scrollArea) + { + scrollArea->verticalScrollBar()->setValue(savedVerticalScrollPosition); + scrollArea->horizontalScrollBar()->setValue(savedHorizontalScrollPosition); + } } diff --git a/examples/triage/fileinfo.cpp b/examples/triage/fileinfo.cpp index b6359fbf..e18c94d8 100644 --- a/examples/triage/fileinfo.cpp +++ b/examples/triage/fileinfo.cpp @@ -4,8 +4,12 @@ #include "copyablelabel.h" #include <QClipboard> #include <QApplication> +#include <QGuiApplication> +#include <QScreen> #include <QToolTip> #include <QPainter> +#include <QFontMetrics> +#include <QScrollArea> #include <QtConcurrent/QtConcurrent> #include <QFuture> #include <QFutureWatcher> @@ -21,6 +25,26 @@ void FileInfoWidget::addCopyableField(const QString& name, const QVariant& value this->m_layout->addWidget(valueLabel, row++, column + 1); } +void FileInfoWidget::addCopyableFieldWithElide(const QString& name, const QVariant& value, int maxWidth) +{ + auto& [row, column] = this->m_fieldPosition; + + const auto fullText = value.toString(); + const auto font = getMonospaceFont(this); + const QFontMetrics fontMetrics(font); + const auto elidedText = fontMetrics.elidedText(fullText, Qt::ElideMiddle, maxWidth); + + const auto valueLabel = new CopyableLabel(elidedText, getThemeColor(AlphanumericHighlightColor)); + valueLabel->setFont(font); + valueLabel->setCopyText(fullText); + valueLabel->setToolTip(fullText + "\n\nClick to Copy"); + valueLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + valueLabel->setWordWrap(false); + + this->m_layout->addWidget(new QLabel(name), row, column); + this->m_layout->addWidget(valueLabel, row++, column + 1); +} + void FileInfoWidget::addField(const QString& name, const QVariant& value) { auto& [row, column] = this->m_fieldPosition; @@ -115,13 +139,19 @@ FileInfoWidget::FileInfoWidget(QWidget* parent, BinaryViewRef bv) const auto file = bv->GetFile(); const auto filePath = file->GetOriginalFilename(); - this->addCopyableField("Path on disk: ", filePath.c_str()); + + // Calculate max path width as 50% of screen width + // Using screen width since the scroll area viewport isn't sized yet during construction + const int screenWidth = QGuiApplication::primaryScreen()->availableGeometry().width(); + const int maxPathWidth = screenWidth / 2; + + this->addCopyableFieldWithElide("Path on disk: ", filePath.c_str(), maxPathWidth); // If triage view is opened from a project, show both actual filepath and path relative to project if (const auto fileProjectRef = file->GetProjectFile()) { const auto projectFilePath = file->GetProjectFile()->GetPathInProject(); - this->addCopyableField("Path in project: ", projectFilePath.c_str()); + this->addCopyableFieldWithElide("Path in project: ", projectFilePath.c_str(), maxPathWidth); } const auto fileSize = QString::number(view->GetLength(), 16).prepend("0x"); diff --git a/examples/triage/fileinfo.h b/examples/triage/fileinfo.h index 4134ba45..78ba578b 100644 --- a/examples/triage/fileinfo.h +++ b/examples/triage/fileinfo.h @@ -13,6 +13,7 @@ class FileInfoWidget : public QWidget void addField(const QString& name, const QVariant& value); void addCopyableField(const QString& name, const QVariant& value); + void addCopyableFieldWithElide(const QString& name, const QVariant& value, int maxWidth); void addHashFields(BinaryViewRef view); public: diff --git a/ui/copyablelabel.h b/ui/copyablelabel.h index e0b79bed..65802160 100644 --- a/ui/copyablelabel.h +++ b/ui/copyablelabel.h @@ -5,10 +5,12 @@ class BINARYNINJAUIAPI CopyableLabel: public QLabel { QColor m_desiredColor {}; QString m_hiddenText; + QString m_copyText; public: CopyableLabel(const QString& text, const QColor& color); void setHiddenText(const QString& text); + void setCopyText(const QString& text); void enterEvent(QEnterEvent* event) override; void leaveEvent(QEvent* event) override; void mousePressEvent(QMouseEvent* event) override; |
