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 <QApplication>
#include <QClipboard> #include <QClipboard>
#include <QByteArray> #include <QByteArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <map> #include <map>
#include <algorithm> #include <algorithm>
@@ -107,7 +109,18 @@ namespace Bloom::Widgets
this->copyHexValuesAction, this->copyHexValuesAction,
&QAction::triggered, &QAction::triggered,
this, this,
&ItemGraphicsScene::copyHexValuesToClipboard [this] {
this->copyHexValuesToClipboard(false);
}
);
QObject::connect(
this->copyHexValuesWithDelimitersAction,
&QAction::triggered,
this,
[this] {
this->copyHexValuesToClipboard(true);
}
); );
QObject::connect( QObject::connect(
@@ -117,6 +130,38 @@ namespace Bloom::Widgets
&ItemGraphicsScene::copyDecimalValuesToClipboard &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); this->setSceneRect(0, 0, this->getSceneWidth(), 0);
static const auto hoverRectBackgroundColor = QColor(0x8E, 0x8B, 0x83, 30); static const auto hoverRectBackgroundColor = QColor(0x8E, 0x8B, 0x83, 30);
@@ -548,12 +593,17 @@ namespace Bloom::Widgets
menu->addAction(this->deselectByteItemsAction); menu->addAction(this->deselectByteItemsAction);
menu->addSeparator(); menu->addSeparator();
auto* copyMenu = new QMenu("Copy Selected", menu); auto* copyMenu = new QMenu("Copy Selection", menu);
copyMenu->addAction(this->copyAbsoluteAddressAction); copyMenu->addAction(this->copyAbsoluteAddressAction);
copyMenu->addAction(this->copyRelativeAddressAction); copyMenu->addAction(this->copyRelativeAddressAction);
copyMenu->addSeparator(); copyMenu->addSeparator();
copyMenu->addAction(this->copyHexValuesAction); copyMenu->addAction(this->copyHexValuesAction);
copyMenu->addAction(this->copyHexValuesWithDelimitersAction);
copyMenu->addAction(this->copyDecimalValuesAction); copyMenu->addAction(this->copyDecimalValuesAction);
copyMenu->addAction(this->copyAsciiValuesAction);
copyMenu->addAction(this->copyBinaryBitStringValues);
copyMenu->addAction(this->copyBinaryBitStringWithDelimitersValues);
copyMenu->addAction(this->copyValueJsonMapAction);
copyMenu->setEnabled(itemsSelected); copyMenu->setEnabled(itemsSelected);
this->deselectByteItemsAction->setEnabled(itemsSelected); this->deselectByteItemsAction->setEnabled(itemsSelected);
@@ -768,7 +818,7 @@ namespace Bloom::Widgets
QApplication::clipboard()->setText(std::move(data)); QApplication::clipboard()->setText(std::move(data));
} }
void ItemGraphicsScene::copyHexValuesToClipboard() { void ItemGraphicsScene::copyHexValuesToClipboard(bool withDelimiters) {
if (this->selectedByteItemsByAddress.empty()) { if (this->selectedByteItemsByAddress.empty()) {
return; return;
} }
@@ -779,7 +829,12 @@ namespace Bloom::Widgets
const unsigned char byteValue = byteItem->excluded const unsigned char byteValue = byteItem->excluded
? 0x00 ? 0x00
: (*this->state.data)[byteItem->startAddress - this->state.memoryDescriptor.addressRange.startAddress]; : (*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)); QApplication::clipboard()->setText(std::move(data));
@@ -801,4 +856,68 @@ namespace Bloom::Widgets
QApplication::clipboard()->setText(std::move(data)); 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 // Context menu actions
QAction* selectAllByteItemsAction = new QAction("Select All", this); QAction* selectAllByteItemsAction = new QAction("Select All", this);
QAction* deselectByteItemsAction = new QAction("Deselect All", this); QAction* deselectByteItemsAction = new QAction("Deselect All", this);
QAction* copyAbsoluteAddressAction = new QAction("Copy Absolute Addresses", this); QAction* copyAbsoluteAddressAction = new QAction("Absolute Addresses", this);
QAction* copyRelativeAddressAction = new QAction("Copy Relative Addresses", this); QAction* copyRelativeAddressAction = new QAction("Relative Addresses", this);
QAction* copyHexValuesAction = new QAction("Copy Hexadecimal Values", this); QAction* copyHexValuesAction = new QAction("Values as Hex Stream", this);
QAction* copyDecimalValuesAction = new QAction("Copy Decimal Values", 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 // Address label container context menu actions
QAction* displayRelativeAddressAction = new QAction("Relative", this); QAction* displayRelativeAddressAction = new QAction("Relative", this);
@@ -148,7 +159,10 @@ namespace Bloom::Widgets
void setAddressType(AddressType type); void setAddressType(AddressType type);
std::map<Targets::TargetMemoryAddress, ByteItem*> sortedByteItemsByAddress(); std::map<Targets::TargetMemoryAddress, ByteItem*> sortedByteItemsByAddress();
void copyAddressesToClipboard(AddressType type); void copyAddressesToClipboard(AddressType type);
void copyHexValuesToClipboard(); void copyHexValuesToClipboard(bool withDelimiters);
void copyDecimalValuesToClipboard(); void copyDecimalValuesToClipboard();
void copyBinaryBitStringToClipboard(bool withDelimiters);
void copyValueMappingToClipboard();
void copyAsciiValueToClipboard();
}; };
} }

View File

@@ -123,7 +123,7 @@ namespace Bloom::Widgets
memoryRegionsLayout->insertWidget(0, this->memoryRegionListView); 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->hexViewerWidget = new HexViewerWidget(
this->memoryDescriptor, this->memoryDescriptor,

View File

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