Improved preexisting and added new copy-to-clipboard functions in the hex viewer and target registers pane.
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user