diff --git a/CMakeLists.txt b/CMakeLists.txt index 4152a1ae..333b0be1 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,6 +140,7 @@ add_executable(Bloom src/Insight/UserInterfaces/InsightWindow/BloomProxyStyle.cpp src/Insight/UserInterfaces/InsightWindow/InsightWindow.cpp src/Insight/UserInterfaces/InsightWindow/AboutWindow.cpp + src/Insight/UserInterfaces/InsightWindow/Widgets/PaneWidget.hpp src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.cpp src/Insight/UserInterfaces/InsightWindow/Widgets/RotatableLabel.cpp src/Insight/UserInterfaces/InsightWindow/Widgets/LabeledSeparator.cpp diff --git a/src/Insight/UserInterfaces/InsightWindow/InsightWindow.hpp b/src/Insight/UserInterfaces/InsightWindow/InsightWindow.hpp index 4573861d..d980f7a6 100644 --- a/src/Insight/UserInterfaces/InsightWindow/InsightWindow.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/InsightWindow.hpp @@ -136,5 +136,7 @@ namespace Bloom void toggleTargetRegistersPane(); void toggleRamInspectionPane(); void toggleEepromInspectionPane(); + + void recordInsightSettings(); }; } diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/PaneState.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/PaneState.hpp new file mode 100644 index 00000000..9bcd2231 --- /dev/null +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/PaneState.hpp @@ -0,0 +1,11 @@ +#pragma once + +namespace Bloom::Widgets +{ + struct PaneState + { + bool activated = false; + + explicit PaneState(bool activated): activated(activated) {}; + }; +} diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/PaneWidget.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/PaneWidget.hpp new file mode 100644 index 00000000..dfd74c10 --- /dev/null +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/PaneWidget.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include "PanelWidget.hpp" +#include "PaneState.hpp" + +namespace Bloom::Widgets +{ + class PaneWidget: public QWidget + { + Q_OBJECT + + public: + bool activated = false; + PanelWidget* parentPanel = nullptr; + + explicit PaneWidget(PanelWidget* parent): QWidget(parent), parentPanel(parent) {}; + + [[nodiscard]] PaneState getCurrentState() const { + return PaneState( + this->activated + ); + } + }; +} diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/PanelState.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/PanelState.hpp new file mode 100644 index 00000000..bc47dc2c --- /dev/null +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/PanelState.hpp @@ -0,0 +1,12 @@ +#pragma once + +namespace Bloom::Widgets +{ + struct PanelState + { + int size = 0; + bool open = false; + + PanelState(int size, bool open): size(size), open(open) {}; + }; +} diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.cpp index ff2dfe5e..22ef7a6f 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.cpp @@ -48,9 +48,18 @@ namespace Bloom::Widgets } } + void PanelWidget::setSize(int size) { + if (this->panelType == PanelWidgetType::LEFT) { + this->setFixedWidth(std::min(std::max(size, this->minimumResize), this->maximumResize)); + + } else if (this->panelType == PanelWidgetType::BOTTOM) { + this->setFixedHeight(std::min(std::max(size, this->minimumResize), this->maximumResize)); + } + } + bool PanelWidget::event(QEvent* event) { if (event->type() == QEvent::Type::HoverMove) { - auto hoverEvent = static_cast(event); + auto* hoverEvent = dynamic_cast(event); if (this->resizingActive || this->isPositionWithinHandleArea(hoverEvent->position().toPoint())) { this->setCursor(this->resizeCursor); @@ -91,24 +100,10 @@ namespace Bloom::Widgets void PanelWidget::mouseMoveEvent(QMouseEvent* event) { if (this->resizingActive) { - const auto position = event->pos(); - - if (this->panelType == PanelWidgetType::LEFT) { - this->setFixedWidth( - std::max( - this->minimumResize, - std::min(this->maximumResize, position.x() + this->resizingOffset) - ) - ); - - } else if (this->panelType == PanelWidgetType::BOTTOM) { - this->setFixedHeight( - std::max( - this->minimumResize, - std::min(this->maximumResize, this->height() + (-position.y()) + this->resizingOffset) - ) - ); - } + this->setSize(this->panelType == PanelWidgetType::LEFT + ? event->pos().x() + this->resizingOffset + : this->height() + (-event->pos().y()) + this->resizingOffset + ); } } @@ -120,13 +115,12 @@ namespace Bloom::Widgets QPoint(currentSize.width() - this->handleSize, 0), QPoint(currentSize.width(), currentSize.height()) ); - - } else { - return std::pair( - QPoint(0, 0), - QPoint(currentSize.width(), this->handleSize) - ); } + + return std::pair( + QPoint(0, 0), + QPoint(currentSize.width(), this->handleSize) + ); } bool PanelWidget::isPositionWithinHandleArea(const QPoint& position) const { diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.hpp index cdd0ba9c..20268808 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.hpp @@ -6,6 +6,8 @@ #include #include +#include "PanelState.hpp" + namespace Bloom::Widgets { Q_NAMESPACE @@ -37,6 +39,8 @@ namespace Bloom::Widgets void setPanelType(PanelWidgetType panelType); + void setSize(int size); + [[nodiscard]] int getHandleSize() const { return this->handleSize; } @@ -53,6 +57,13 @@ namespace Bloom::Widgets return this->panelType; } + PanelState getCurrentState() { + return PanelState( + this->panelType == PanelWidgetType::LEFT ? this->width() : this->height(), + this->isVisible() + ); + } + protected: int handleSize = 10; int minimumResize = 10; diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPane.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPane.cpp index b831e13d..36498ac0 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPane.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPane.cpp @@ -23,12 +23,11 @@ TargetMemoryInspectionPane::TargetMemoryInspectionPane( TargetMemoryInspectionPaneSettings& settings, InsightWorker& insightWorker, PanelWidget* parent -): - QWidget(parent), - targetMemoryDescriptor(targetMemoryDescriptor), - settings(settings), - insightWorker(insightWorker), - parent(parent) +) + : PaneWidget(parent) + , targetMemoryDescriptor(targetMemoryDescriptor) + , settings(settings) + , insightWorker(insightWorker) { this->setObjectName("target-memory-inspection-pane"); @@ -175,7 +174,7 @@ void TargetMemoryInspectionPane::deactivate() { } void TargetMemoryInspectionPane::resizeEvent(QResizeEvent* event) { - const auto parentSize = this->parent->size(); + const auto parentSize = this->parentPanel->size(); const auto width = parentSize.width() - 1; this->container->setFixedSize(width, parentSize.height()); } diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPane.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPane.hpp index a301c1d1..d5d81d98 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPane.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPane.hpp @@ -4,11 +4,12 @@ #include #include +#include "src/Insight/UserInterfaces/InsightWindow/Widgets/PaneWidget.hpp" + #include "src/Insight/InsightWorker/InsightWorker.hpp" - #include "src/Targets/TargetMemory.hpp" -#include "src/Targets/TargetState.hpp" +#include "src/Targets/TargetState.hpp" #include "src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.hpp" #include "src/Insight/UserInterfaces/InsightWindow/Widgets/SvgToolButton.hpp" @@ -19,13 +20,12 @@ namespace Bloom::Widgets { - class TargetMemoryInspectionPane: public QWidget + class TargetMemoryInspectionPane: public PaneWidget { Q_OBJECT public: TargetMemoryInspectionPaneSettings& settings; - bool activated = false; TargetMemoryInspectionPane( const Targets::TargetMemoryDescriptor& targetMemoryDescriptor, @@ -48,7 +48,6 @@ namespace Bloom::Widgets const Targets::TargetMemoryDescriptor& targetMemoryDescriptor; InsightWorker& insightWorker; - PanelWidget* parent = nullptr; QWidget* container = nullptr; QWidget* titleBar = nullptr; diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPaneSettings.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPaneSettings.hpp index a18e2713..ce089e83 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPaneSettings.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPaneSettings.hpp @@ -11,9 +11,10 @@ namespace Bloom::Widgets { struct TargetMemoryInspectionPaneSettings { + bool activated = false; + HexViewerWidgetSettings hexViewerWidgetSettings; + std::vector focusedMemoryRegions; std::vector excludedMemoryRegions; - - HexViewerWidgetSettings hexViewerWidgetSettings; }; } diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/TargetRegistersPaneWidget.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/TargetRegistersPaneWidget.cpp index 110d04b7..75dfd880 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/TargetRegistersPaneWidget.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/TargetRegistersPaneWidget.cpp @@ -25,7 +25,7 @@ namespace Bloom::Widgets const TargetDescriptor& targetDescriptor, InsightWorker& insightWorker, PanelWidget* parent - ): QWidget(parent), parent(parent), targetDescriptor(targetDescriptor), insightWorker(insightWorker) { + ): PaneWidget(parent), targetDescriptor(targetDescriptor), insightWorker(insightWorker) { this->setObjectName("target-registers-side-pane"); auto targetRegistersPaneUiFile = QFile( @@ -208,7 +208,7 @@ namespace Bloom::Widgets } void TargetRegistersPaneWidget::resizeEvent(QResizeEvent* event) { - const auto parentSize = this->parent->size(); + const auto parentSize = this->parentPanel->size(); const auto width = parentSize.width() - 1; this->container->setFixedWidth(width); this->searchInput->setFixedWidth(width - 20); @@ -217,7 +217,7 @@ namespace Bloom::Widgets * In order to avoid the panel resize handle overlapping the scroll bar handle, we reduce the size of * the scroll area. */ - this->itemScrollArea->setFixedWidth(width - this->parent->getHandleSize()); + this->itemScrollArea->setFixedWidth(width - this->parentPanel->getHandleSize()); } void TargetRegistersPaneWidget::postActivate() { diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/TargetRegistersPaneWidget.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/TargetRegistersPaneWidget.hpp index 2df2d306..429d32b4 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/TargetRegistersPaneWidget.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/TargetRegistersPane/TargetRegistersPaneWidget.hpp @@ -9,8 +9,10 @@ #include #include -#include "ItemWidget.hpp" +#include "src/Insight/UserInterfaces/InsightWindow/Widgets/PaneWidget.hpp" #include "src/Insight/UserInterfaces/InsightWindow/Widgets/PanelWidget.hpp" + +#include "ItemWidget.hpp" #include "src/Insight/UserInterfaces/InsightWindow/Widgets/SvgToolButton.hpp" #include "src/Insight/InsightWorker/InsightWorker.hpp" #include "src/Targets/TargetState.hpp" @@ -19,13 +21,11 @@ namespace Bloom::Widgets { class RegisterGroupWidget; - class TargetRegistersPaneWidget: public QWidget + class TargetRegistersPaneWidget: public PaneWidget { Q_OBJECT public: - bool activated = false; - TargetRegistersPaneWidget( const Targets::TargetDescriptor& targetDescriptor, InsightWorker& insightWorker, @@ -54,7 +54,6 @@ namespace Bloom::Widgets const Targets::TargetDescriptor& targetDescriptor; InsightWorker& insightWorker; - PanelWidget* parent = nullptr; QWidget* container = nullptr; QWidget* toolBar = nullptr; diff --git a/src/ProjectSettings.cpp b/src/ProjectSettings.cpp index c53b1941..03900738 100644 --- a/src/ProjectSettings.cpp +++ b/src/ProjectSettings.cpp @@ -30,6 +30,36 @@ namespace Bloom } } + if (jsonObject.contains("previousLeftPanelState")) { + this->previousLeftPanelState = this->panelStateFromJson( + jsonObject.find("previousLeftPanelState")->toObject() + ); + } + + if (jsonObject.contains("previousBottomPanelState")) { + this->previousBottomPanelState = this->panelStateFromJson( + jsonObject.find("previousBottomPanelState")->toObject() + ); + } + + if (jsonObject.contains("previousRegistersPaneState")) { + this->previousRegistersPaneState = this->paneStateFromJson( + jsonObject.find("previousRegistersPaneState")->toObject() + ); + } + + if (jsonObject.contains("previousRamInspectionPaneState")) { + this->previousRamInspectionPaneState = this->paneStateFromJson( + jsonObject.find("previousRamInspectionPaneState")->toObject() + ); + } + + if (jsonObject.contains("previousEepromInspectionPaneState")) { + this->previousEepromInspectionPaneState = this->paneStateFromJson( + jsonObject.find("previousEepromInspectionPaneState")->toObject() + ); + } + if (jsonObject.contains("memoryInspectionPaneSettings")) { const auto settingsMappingObj = jsonObject.find("memoryInspectionPaneSettings")->toObject(); @@ -41,147 +71,10 @@ namespace Bloom continue; } - const auto memoryType = InsightProjectSettings::memoryTypesByName.at(memoryTypeName); - auto inspectionPaneSettings = Widgets::TargetMemoryInspectionPaneSettings(); - - if (settingsObj.contains("hexViewerSettings")) { - auto& hexViewerSettings = inspectionPaneSettings.hexViewerWidgetSettings; - const auto hexViewerSettingsObj = settingsObj.find("hexViewerSettings")->toObject(); - - if (hexViewerSettingsObj.contains("highlightStackMemory")) { - hexViewerSettings.highlightStackMemory = - hexViewerSettingsObj.value("highlightStackMemory").toBool(); - } - - if (hexViewerSettingsObj.contains("highlightFocusedMemory")) { - hexViewerSettings.highlightFocusedMemory = - hexViewerSettingsObj.value("highlightFocusedMemory").toBool(); - } - - if (hexViewerSettingsObj.contains("highlightHoveredRowAndCol")) { - hexViewerSettings.highlightHoveredRowAndCol = - hexViewerSettingsObj.value("highlightHoveredRowAndCol").toBool(); - } - - if (hexViewerSettingsObj.contains("displayAsciiValues")) { - hexViewerSettings.displayAsciiValues = - hexViewerSettingsObj.value("displayAsciiValues").toBool(); - } - - if (hexViewerSettingsObj.contains("displayAnnotations")) { - hexViewerSettings.displayAnnotations = - hexViewerSettingsObj.value("displayAnnotations").toBool(); - } - } - - if (settingsObj.contains("focusedRegions")) { - const auto focusedRegions = settingsObj.find("focusedRegions")->toArray(); - - for (const auto& regionValue : focusedRegions) { - const auto regionObj = regionValue.toObject(); - - if (!regionObj.contains("name") - || !regionObj.contains("addressRange") - || !regionObj.contains("addressInputType") - || !regionObj.contains("createdTimestamp") - || !regionObj.contains("dataType") - ) { - continue; - } - - const auto addressRangeObj = regionObj.find("addressRange")->toObject(); - if (!addressRangeObj.contains("startAddress") - || !addressRangeObj.contains("endAddress") - ) { - continue; - } - - auto region = FocusedMemoryRegion( - regionObj.find("name")->toString(), - { - static_cast(addressRangeObj.find("startAddress") - ->toInteger()), - static_cast(addressRangeObj.find("endAddress") - ->toInteger()), - } - ); - - region.createdDate.setSecsSinceEpoch(regionObj.find("createdTimestamp")->toInteger()); - - const auto addressInputType = InsightProjectSettings::addressRangeInputTypesByName.valueAt( - regionObj.find("addressInputType")->toString() - ); - - if (addressInputType.has_value()) { - region.addressRangeInputType = addressInputType.value(); - } - - const auto dataType = InsightProjectSettings::regionDataTypesByName.valueAt( - regionObj.find("dataType")->toString() - ); - - if (dataType.has_value()) { - region.dataType = dataType.value(); - } - - const auto endianness = InsightProjectSettings::regionEndiannessByName.valueAt( - regionObj.find("endianness")->toString() - ); - - if (endianness.has_value()) { - region.endianness = endianness.value(); - } - - inspectionPaneSettings.focusedMemoryRegions.emplace_back(region); - } - } - - if (settingsObj.contains("excludedRegions")) { - const auto excludedRegions = settingsObj.find("excludedRegions")->toArray(); - - for (const auto& regionValue : excludedRegions) { - const auto regionObj = regionValue.toObject(); - - if (!regionObj.contains("name") - || !regionObj.contains("addressRange") - || !regionObj.contains("addressInputType") - || !regionObj.contains("createdTimestamp") - ) { - continue; - } - - const auto addressRangeObj = regionObj.find("addressRange")->toObject(); - if (!addressRangeObj.contains("startAddress") - || !addressRangeObj.contains("endAddress") - ) { - continue; - } - - auto region = ExcludedMemoryRegion( - regionObj.find("name")->toString(), - { - static_cast(addressRangeObj.find("startAddress") - ->toInteger()), - static_cast(addressRangeObj.find("endAddress") - ->toInteger()), - } - ); - - region.createdDate.setSecsSinceEpoch(regionObj.find("createdTimestamp")->toInteger()); - - const auto addressInputType = InsightProjectSettings::addressRangeInputTypesByName.valueAt( - regionObj.find("addressInputType")->toString() - ); - - if (addressInputType.has_value()) { - region.addressRangeInputType = addressInputType.value(); - } - - inspectionPaneSettings.excludedMemoryRegions.emplace_back(region); - } - } - - this->memoryInspectionPaneSettingsByMemoryType.insert(std::pair(memoryType, inspectionPaneSettings)); + this->memoryInspectionPaneSettingsByMemoryType.insert(std::pair( + InsightProjectSettings::memoryTypesByName.at(memoryTypeName), + this->memoryInspectionPaneSettingsFromJson(settingsObj) + )); } } } @@ -204,77 +97,287 @@ namespace Bloom continue; } - auto settingsObj = QJsonObject(); - - const auto& hexViewerSettings = inspectionPaneSettings.hexViewerWidgetSettings; - settingsObj.insert("hexViewerSettings", QJsonObject({ - {"highlightStackMemory", hexViewerSettings.highlightStackMemory}, - {"highlightFocusedMemory", hexViewerSettings.highlightFocusedMemory}, - {"highlightHoveredRowAndCol", hexViewerSettings.highlightHoveredRowAndCol}, - {"displayAsciiValues", hexViewerSettings.displayAsciiValues}, - {"displayAnnotations", hexViewerSettings.displayAnnotations}, - })); - - const auto& regionDataTypesByName = InsightProjectSettings::regionDataTypesByName; - const auto& regionEndiannessByName = InsightProjectSettings::regionEndiannessByName; - const auto& addressRangeInputTypesByName = InsightProjectSettings::addressRangeInputTypesByName; - - auto focusedRegions = QJsonArray(); - for (const auto& focusedRegion : inspectionPaneSettings.focusedMemoryRegions) { - if (!regionDataTypesByName.contains(focusedRegion.dataType) - || !regionEndiannessByName.contains(focusedRegion.endianness) - || !addressRangeInputTypesByName.contains(focusedRegion.addressRangeInputType) - ) { - continue; - } - - const auto addressRangeObj = QJsonObject({ - {"startAddress", static_cast(focusedRegion.addressRange.startAddress)}, - {"endAddress", static_cast(focusedRegion.addressRange.endAddress)}, - }); - - auto regionObj = QJsonObject({ - {"name", focusedRegion.name}, - {"addressRange", addressRangeObj}, - {"createdTimestamp", focusedRegion.createdDate.toSecsSinceEpoch()}, - {"addressInputType", addressRangeInputTypesByName.at(focusedRegion.addressRangeInputType)}, - {"dataType", regionDataTypesByName.at(focusedRegion.dataType)}, - {"endianness", regionEndiannessByName.at(focusedRegion.endianness)}, - }); - - focusedRegions.push_back(regionObj); - } - - auto excludedRegions = QJsonArray(); - for (const auto& excludedRegion : inspectionPaneSettings.excludedMemoryRegions) { - if (!addressRangeInputTypesByName.contains(excludedRegion.addressRangeInputType)) { - continue; - } - - const auto addressRangeObj = QJsonObject({ - {"startAddress", static_cast(excludedRegion.addressRange.startAddress)}, - {"endAddress", static_cast(excludedRegion.addressRange.endAddress)}, - }); - - auto regionObj = QJsonObject({ - {"name", excludedRegion.name}, - {"addressRange", addressRangeObj}, - {"createdTimestamp", excludedRegion.createdDate.toSecsSinceEpoch()}, - {"addressInputType", addressRangeInputTypesByName.at(excludedRegion.addressRangeInputType)}, - }); - - excludedRegions.push_back(regionObj); - } - - settingsObj.insert("focusedRegions", focusedRegions); - settingsObj.insert("excludedRegions", excludedRegions); memoryInspectionPaneSettingsObj.insert( InsightProjectSettings::memoryTypesByName.at(memoryType), - settingsObj + this->memoryInspectionPaneSettingsToJson(inspectionPaneSettings) ); } insightObj.insert("memoryInspectionPaneSettings", memoryInspectionPaneSettingsObj); + + if (this->previousLeftPanelState.has_value()) { + insightObj.insert( + "previousLeftPanelState", + this->panelStateToJson(this->previousLeftPanelState.value()) + ); + } + + if (this->previousBottomPanelState.has_value()) { + insightObj.insert( + "previousBottomPanelState", + this->panelStateToJson(this->previousBottomPanelState.value()) + ); + } + + if (this->previousRegistersPaneState.has_value()) { + insightObj.insert( + "previousRegistersPaneState", + this->paneStateToJson(this->previousRegistersPaneState.value()) + ); + } + + if (this->previousRamInspectionPaneState.has_value()) { + insightObj.insert( + "previousRamInspectionPaneState", + this->paneStateToJson(this->previousRamInspectionPaneState.value()) + ); + } + + if (this->previousEepromInspectionPaneState.has_value()) { + insightObj.insert( + "previousEepromInspectionPaneState", + this->paneStateToJson(this->previousEepromInspectionPaneState.value()) + ); + } + return insightObj; } + + Widgets::TargetMemoryInspectionPaneSettings InsightProjectSettings::memoryInspectionPaneSettingsFromJson( + const QJsonObject& jsonObject + ) const { + auto inspectionPaneSettings = Widgets::TargetMemoryInspectionPaneSettings(); + + if (jsonObject.contains("hexViewerSettings")) { + auto& hexViewerSettings = inspectionPaneSettings.hexViewerWidgetSettings; + const auto hexViewerSettingsObj = jsonObject.find("hexViewerSettings")->toObject(); + + if (hexViewerSettingsObj.contains("highlightStackMemory")) { + hexViewerSettings.highlightStackMemory = + hexViewerSettingsObj.value("highlightStackMemory").toBool(); + } + + if (hexViewerSettingsObj.contains("highlightFocusedMemory")) { + hexViewerSettings.highlightFocusedMemory = + hexViewerSettingsObj.value("highlightFocusedMemory").toBool(); + } + + if (hexViewerSettingsObj.contains("highlightHoveredRowAndCol")) { + hexViewerSettings.highlightHoveredRowAndCol = + hexViewerSettingsObj.value("highlightHoveredRowAndCol").toBool(); + } + + if (hexViewerSettingsObj.contains("displayAsciiValues")) { + hexViewerSettings.displayAsciiValues = + hexViewerSettingsObj.value("displayAsciiValues").toBool(); + } + + if (hexViewerSettingsObj.contains("displayAnnotations")) { + hexViewerSettings.displayAnnotations = + hexViewerSettingsObj.value("displayAnnotations").toBool(); + } + } + + if (jsonObject.contains("focusedRegions")) { + const auto focusedRegions = jsonObject.find("focusedRegions")->toArray(); + + for (const auto& regionValue : focusedRegions) { + const auto regionObj = regionValue.toObject(); + + if (!regionObj.contains("name") + || !regionObj.contains("addressRange") + || !regionObj.contains("addressInputType") + || !regionObj.contains("createdTimestamp") + || !regionObj.contains("dataType") + ) { + continue; + } + + const auto addressRangeObj = regionObj.find("addressRange")->toObject(); + if (!addressRangeObj.contains("startAddress") + || !addressRangeObj.contains("endAddress") + ) { + continue; + } + + auto region = FocusedMemoryRegion( + regionObj.find("name")->toString(), + { + static_cast(addressRangeObj.find("startAddress")->toInteger()), + static_cast(addressRangeObj.find("endAddress")->toInteger()), + } + ); + + region.createdDate.setSecsSinceEpoch(regionObj.find("createdTimestamp")->toInteger()); + + const auto addressInputType = InsightProjectSettings::addressRangeInputTypesByName.valueAt( + regionObj.find("addressInputType")->toString() + ); + + if (addressInputType.has_value()) { + region.addressRangeInputType = addressInputType.value(); + } + + const auto dataType = InsightProjectSettings::regionDataTypesByName.valueAt( + regionObj.find("dataType")->toString() + ); + + if (dataType.has_value()) { + region.dataType = dataType.value(); + } + + const auto endianness = InsightProjectSettings::regionEndiannessByName.valueAt( + regionObj.find("endianness")->toString() + ); + + if (endianness.has_value()) { + region.endianness = endianness.value(); + } + + inspectionPaneSettings.focusedMemoryRegions.emplace_back(region); + } + } + + if (jsonObject.contains("excludedRegions")) { + const auto excludedRegions = jsonObject.find("excludedRegions")->toArray(); + + for (const auto& regionValue : excludedRegions) { + const auto regionObj = regionValue.toObject(); + + if (!regionObj.contains("name") + || !regionObj.contains("addressRange") + || !regionObj.contains("addressInputType") + || !regionObj.contains("createdTimestamp") + ) { + continue; + } + + const auto addressRangeObj = regionObj.find("addressRange")->toObject(); + if (!addressRangeObj.contains("startAddress") + || !addressRangeObj.contains("endAddress") + ) { + continue; + } + + auto region = ExcludedMemoryRegion( + regionObj.find("name")->toString(), + { + static_cast(addressRangeObj.find("startAddress")->toInteger()), + static_cast(addressRangeObj.find("endAddress")->toInteger()), + } + ); + + region.createdDate.setSecsSinceEpoch(regionObj.find("createdTimestamp")->toInteger()); + + const auto addressInputType = InsightProjectSettings::addressRangeInputTypesByName.valueAt( + regionObj.find("addressInputType")->toString() + ); + + if (addressInputType.has_value()) { + region.addressRangeInputType = addressInputType.value(); + } + + inspectionPaneSettings.excludedMemoryRegions.emplace_back(region); + } + } + + return inspectionPaneSettings; + } + + Widgets::PanelState InsightProjectSettings::panelStateFromJson(const QJsonObject& jsonObject) const { + return Widgets::PanelState( + (jsonObject.contains("size") ? static_cast(jsonObject.value("size").toInteger()) : 0), + (jsonObject.contains("open") ? jsonObject.value("open").toBool() : false) + ); + } + + Widgets::PaneState InsightProjectSettings::paneStateFromJson(const QJsonObject& jsonObject) const { + return Widgets::PaneState( + (jsonObject.contains("activated") ? jsonObject.value("activated").toBool() : false) + ); + } + + QJsonObject InsightProjectSettings::memoryInspectionPaneSettingsToJson( + const Widgets::TargetMemoryInspectionPaneSettings& inspectionPaneSettings + ) const { + auto settingsObj = QJsonObject(); + + const auto& hexViewerSettings = inspectionPaneSettings.hexViewerWidgetSettings; + settingsObj.insert("hexViewerSettings", QJsonObject({ + {"highlightStackMemory", hexViewerSettings.highlightStackMemory}, + {"highlightFocusedMemory", hexViewerSettings.highlightFocusedMemory}, + {"highlightHoveredRowAndCol", hexViewerSettings.highlightHoveredRowAndCol}, + {"displayAsciiValues", hexViewerSettings.displayAsciiValues}, + {"displayAnnotations", hexViewerSettings.displayAnnotations}, + })); + + const auto& regionDataTypesByName = InsightProjectSettings::regionDataTypesByName; + const auto& regionEndiannessByName = InsightProjectSettings::regionEndiannessByName; + const auto& addressRangeInputTypesByName = InsightProjectSettings::addressRangeInputTypesByName; + + auto focusedRegions = QJsonArray(); + for (const auto& focusedRegion : inspectionPaneSettings.focusedMemoryRegions) { + if (!regionDataTypesByName.contains(focusedRegion.dataType) + || !regionEndiannessByName.contains(focusedRegion.endianness) + || !addressRangeInputTypesByName.contains(focusedRegion.addressRangeInputType) + ) { + continue; + } + + const auto addressRangeObj = QJsonObject({ + {"startAddress", static_cast(focusedRegion.addressRange.startAddress)}, + {"endAddress", static_cast(focusedRegion.addressRange.endAddress)}, + }); + + auto regionObj = QJsonObject({ + {"name", focusedRegion.name}, + {"addressRange", addressRangeObj}, + {"createdTimestamp", focusedRegion.createdDate.toSecsSinceEpoch()}, + {"addressInputType", addressRangeInputTypesByName.at(focusedRegion.addressRangeInputType)}, + {"dataType", regionDataTypesByName.at(focusedRegion.dataType)}, + {"endianness", regionEndiannessByName.at(focusedRegion.endianness)}, + }); + + focusedRegions.push_back(regionObj); + } + + auto excludedRegions = QJsonArray(); + for (const auto& excludedRegion : inspectionPaneSettings.excludedMemoryRegions) { + if (!addressRangeInputTypesByName.contains(excludedRegion.addressRangeInputType)) { + continue; + } + + const auto addressRangeObj = QJsonObject({ + {"startAddress", static_cast(excludedRegion.addressRange.startAddress)}, + {"endAddress", static_cast(excludedRegion.addressRange.endAddress)}, + }); + + auto regionObj = QJsonObject({ + {"name", excludedRegion.name}, + {"addressRange", addressRangeObj}, + {"createdTimestamp", excludedRegion.createdDate.toSecsSinceEpoch()}, + {"addressInputType", addressRangeInputTypesByName.at(excludedRegion.addressRangeInputType)}, + }); + + excludedRegions.push_back(regionObj); + } + + settingsObj.insert("focusedRegions", focusedRegions); + settingsObj.insert("excludedRegions", excludedRegions); + + return settingsObj; + } + + QJsonObject InsightProjectSettings::panelStateToJson(const Widgets::PanelState& panelState) const { + return QJsonObject({ + {"size", panelState.size}, + {"open", panelState.open}, + }); + } + + QJsonObject InsightProjectSettings::paneStateToJson(const Widgets::PaneState& paneState) const { + return QJsonObject({ + {"activated", paneState.activated}, + }); + } } diff --git a/src/ProjectSettings.hpp b/src/ProjectSettings.hpp index 2d4f840c..986b309e 100644 --- a/src/ProjectSettings.hpp +++ b/src/ProjectSettings.hpp @@ -8,6 +8,8 @@ #include #include "src/Targets/TargetMemory.hpp" +#include "src/Insight/UserInterfaces/InsightWindow/Widgets/PanelState.hpp" +#include "src/Insight/UserInterfaces/InsightWindow/Widgets/PaneState.hpp" #include "src/Insight/UserInterfaces/InsightWindow/Widgets/TargetMemoryInspectionPane/TargetMemoryInspectionPaneSettings.hpp" #include "src/Helpers/BiMap.hpp" @@ -18,6 +20,11 @@ namespace Bloom { public: std::optional mainWindowSize; + std::optional previousLeftPanelState; + std::optional previousBottomPanelState; + std::optional previousRegistersPaneState; + std::optional previousRamInspectionPaneState; + std::optional previousEepromInspectionPaneState; std::map< Targets::TargetMemoryType, @@ -51,6 +58,22 @@ namespace Bloom {MemoryRegionAddressInputType::ABSOLUTE, "absolute"}, {MemoryRegionAddressInputType::RELATIVE, "relative"}, }; + + [[nodiscard]] Widgets::TargetMemoryInspectionPaneSettings memoryInspectionPaneSettingsFromJson( + const QJsonObject& jsonObject + ) const; + + [[nodiscard]] Widgets::PanelState panelStateFromJson(const QJsonObject& jsonObject) const; + + [[nodiscard]] Widgets::PaneState paneStateFromJson(const QJsonObject& jsonObject) const; + + [[nodiscard]] QJsonObject memoryInspectionPaneSettingsToJson( + const Widgets::TargetMemoryInspectionPaneSettings& inspectionPaneSettings + ) const; + + [[nodiscard]] QJsonObject panelStateToJson(const Widgets::PanelState& panelState) const; + + [[nodiscard]] QJsonObject paneStateToJson(const Widgets::PaneState& paneState) const; }; struct ProjectSettings