Improved preexisting and added new copy-to-clipboard functions in the hex viewer and target registers pane.

This commit is contained in:
Nav
2023-04-15 12:38:20 +01:00
parent 080bfcffbc
commit c63501ff11
4 changed files with 147 additions and 14 deletions

View File

@@ -5,6 +5,8 @@
#include <QApplication>
#include <QClipboard>
#include <QByteArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <map>
#include <algorithm>
@@ -107,7 +109,18 @@ namespace Bloom::Widgets
this->copyHexValuesAction,
&QAction::triggered,
this,
&ItemGraphicsScene::copyHexValuesToClipboard
[this] {
this->copyHexValuesToClipboard(false);
}
);
QObject::connect(
this->copyHexValuesWithDelimitersAction,
&QAction::triggered,
this,
[this] {
this->copyHexValuesToClipboard(true);
}
);
QObject::connect(
@@ -117,6 +130,38 @@ namespace Bloom::Widgets
&ItemGraphicsScene::copyDecimalValuesToClipboard
);
QObject::connect(
this->copyBinaryBitStringValues,
&QAction::triggered,
this,
[this] {
this->copyBinaryBitStringToClipboard(false);
}
);
QObject::connect(
this->copyBinaryBitStringWithDelimitersValues,
&QAction::triggered,
this,
[this] {
this->copyBinaryBitStringToClipboard(true);
}
);
QObject::connect(
this->copyValueJsonMapAction,
&QAction::triggered,
this,
&ItemGraphicsScene::copyValueMappingToClipboard
);
QObject::connect(
this->copyAsciiValuesAction,
&QAction::triggered,
this,
&ItemGraphicsScene::copyAsciiValueToClipboard
);
this->setSceneRect(0, 0, this->getSceneWidth(), 0);
static const auto hoverRectBackgroundColor = QColor(0x8E, 0x8B, 0x83, 30);
@@ -548,12 +593,17 @@ namespace Bloom::Widgets
menu->addAction(this->deselectByteItemsAction);
menu->addSeparator();
auto* copyMenu = new QMenu("Copy Selected", menu);
auto* copyMenu = new QMenu("Copy Selection", menu);
copyMenu->addAction(this->copyAbsoluteAddressAction);
copyMenu->addAction(this->copyRelativeAddressAction);
copyMenu->addSeparator();
copyMenu->addAction(this->copyHexValuesAction);
copyMenu->addAction(this->copyHexValuesWithDelimitersAction);
copyMenu->addAction(this->copyDecimalValuesAction);
copyMenu->addAction(this->copyAsciiValuesAction);
copyMenu->addAction(this->copyBinaryBitStringValues);
copyMenu->addAction(this->copyBinaryBitStringWithDelimitersValues);
copyMenu->addAction(this->copyValueJsonMapAction);
copyMenu->setEnabled(itemsSelected);
this->deselectByteItemsAction->setEnabled(itemsSelected);
@@ -768,7 +818,7 @@ namespace Bloom::Widgets
QApplication::clipboard()->setText(std::move(data));
}
void ItemGraphicsScene::copyHexValuesToClipboard() {
void ItemGraphicsScene::copyHexValuesToClipboard(bool withDelimiters) {
if (this->selectedByteItemsByAddress.empty()) {
return;
}
@@ -779,7 +829,12 @@ namespace Bloom::Widgets
const unsigned char byteValue = byteItem->excluded
? 0x00
: (*this->state.data)[byteItem->startAddress - this->state.memoryDescriptor.addressRange.startAddress];
data.append("0x" + QString::number(byteValue, 16).rightJustified(2, '0').toUpper() + "\n");
data.append(
withDelimiters
? "0x" + QString::number(byteValue, 16).rightJustified(2, '0').toUpper() + "\n"
: QString::number(byteValue, 16).rightJustified(2, '0').toUpper()
);
}
QApplication::clipboard()->setText(std::move(data));
@@ -801,4 +856,68 @@ namespace Bloom::Widgets
QApplication::clipboard()->setText(std::move(data));
}
void ItemGraphicsScene::copyBinaryBitStringToClipboard(bool withDelimiters) {
if (this->selectedByteItemsByAddress.empty()) {
return;
}
auto data = QString();
for (const auto& [address, byteItem] : this->sortedByteItemsByAddress()) {
const unsigned char byteValue = byteItem->excluded
? 0x00
: (*this->state.data)[byteItem->startAddress - this->state.memoryDescriptor.addressRange.startAddress];
data.append(
withDelimiters
? "0b" + QString::number(byteValue, 2).rightJustified(8, '0') + "\n"
: QString::number(byteValue, 2).rightJustified(8, '0') + " "
);
}
QApplication::clipboard()->setText(std::move(data));
}
void ItemGraphicsScene::copyValueMappingToClipboard() {
if (this->selectedByteItemsByAddress.empty() || !this->state.data.has_value()) {
return;
}
auto data = QJsonObject();
for (const auto& [address, byteItem] : this->sortedByteItemsByAddress()) {
const unsigned char byteValue = byteItem->excluded
? 0x00
: (*this->state.data)[byteItem->startAddress - this->state.memoryDescriptor.addressRange.startAddress];
data.insert(
"0x" + QString::number(address, 16).rightJustified(8, '0').toUpper(),
"0x" + QString::number(byteValue, 16).rightJustified(2, '0').toUpper()
);
}
QApplication::clipboard()->setText(QJsonDocument(data).toJson(QJsonDocument::JsonFormat::Indented));
}
void ItemGraphicsScene::copyAsciiValueToClipboard() {
if (this->selectedByteItemsByAddress.empty() || !this->state.data.has_value()) {
return;
}
auto data = QString();
for (const auto& [address, byteItem] : this->sortedByteItemsByAddress()) {
const unsigned char byteValue =
(*this->state.data)[byteItem->startAddress - this->state.memoryDescriptor.addressRange.startAddress];
if (byteItem->excluded || byteValue < 32 || byteValue > 126) {
continue;
}
data.append(QChar(byteValue));
}
QApplication::clipboard()->setText(std::move(data));
}
}

View File

@@ -114,10 +114,21 @@ namespace Bloom::Widgets
// Context menu actions
QAction* selectAllByteItemsAction = new QAction("Select All", this);
QAction* deselectByteItemsAction = new QAction("Deselect All", this);
QAction* copyAbsoluteAddressAction = new QAction("Copy Absolute Addresses", this);
QAction* copyRelativeAddressAction = new QAction("Copy Relative Addresses", this);
QAction* copyHexValuesAction = new QAction("Copy Hexadecimal Values", this);
QAction* copyDecimalValuesAction = new QAction("Copy Decimal Values", this);
QAction* copyAbsoluteAddressAction = new QAction("Absolute Addresses", this);
QAction* copyRelativeAddressAction = new QAction("Relative Addresses", this);
QAction* copyHexValuesAction = new QAction("Values as Hex Stream", this);
QAction* copyBinaryBitStringValues = new QAction("...as Binary Bit String", this);
QAction* copyBinaryBitStringWithDelimitersValues = new QAction(
"...as Prefixed Binary Bit Strings with Line Delimiters",
this
);
QAction* copyHexValuesWithDelimitersAction = new QAction(
"...as Prefixed Hex Strings with Line Delimiters",
this
);
QAction* copyDecimalValuesAction = new QAction("...as Decimals with Line Delimiters", this);
QAction* copyValueJsonMapAction = new QAction("...as Address to Value JSON Map", this);
QAction* copyAsciiValuesAction = new QAction("...as ASCII String", this);
// Address label container context menu actions
QAction* displayRelativeAddressAction = new QAction("Relative", this);
@@ -148,7 +159,10 @@ namespace Bloom::Widgets
void setAddressType(AddressType type);
std::map<Targets::TargetMemoryAddress, ByteItem*> sortedByteItemsByAddress();
void copyAddressesToClipboard(AddressType type);
void copyHexValuesToClipboard();
void copyHexValuesToClipboard(bool withDelimiters);
void copyDecimalValuesToClipboard();
void copyBinaryBitStringToClipboard(bool withDelimiters);
void copyValueMappingToClipboard();
void copyAsciiValueToClipboard();
};
}

View File

@@ -123,7 +123,7 @@ namespace Bloom::Widgets
memoryRegionsLayout->insertWidget(0, this->memoryRegionListView);
}
this->restoreBytesAction = new ContextMenuAction("Restore Selected", std::nullopt, this);
this->restoreBytesAction = new ContextMenuAction("Restore Selection", std::nullopt, this);
this->hexViewerWidget = new HexViewerWidget(
this->memoryDescriptor,

View File

@@ -71,10 +71,10 @@ namespace Bloom::Widgets
// Context-menu actions
QAction* openInspectionWindowAction = new QAction("Inspect", this);
QAction* refreshValueAction = new QAction("Refresh Value", this);
QAction* copyNameAction = new QAction("Copy Register Name", this);
QAction* copyValueHexAction = new QAction("Copy Hexadecimal Value", this);
QAction* copyValueDecimalAction = new QAction("Copy Decimal Value", this);
QAction* copyValueBinaryAction = new QAction("Copy Binary Value", this);
QAction* copyNameAction = new QAction("Register Name", this);
QAction* copyValueDecimalAction = new QAction("Value as Decimal", this);
QAction* copyValueHexAction = new QAction("...as Hex String", this);
QAction* copyValueBinaryAction = new QAction("...as Binary Bit String", this);
RegisterItem* contextMenuRegisterItem = nullptr;