diff --git a/src/IPGenerate/IPCatalog.cpp b/src/IPGenerate/IPCatalog.cpp index 5aecd5483..2ac7099f0 100644 --- a/src/IPGenerate/IPCatalog.cpp +++ b/src/IPGenerate/IPCatalog.cpp @@ -25,6 +25,7 @@ along with this program. If not, see . #include #include +#include #include #include #include @@ -37,6 +38,8 @@ along with this program. If not, see . #include "MainWindow/Session.h" #include "Utils/FileUtils.h" #include "Utils/StringUtils.h" +#include "nlohmann_json/json.hpp" +using json = nlohmann::ordered_json; extern FOEDAG::Session* GlobalSession; using namespace FOEDAG; @@ -116,3 +119,25 @@ std::filesystem::path IPCatalog::getPythonPath() { } return s_pythonPath; } + +IPDetails FOEDAG::readIpDetails(const std::filesystem::path& path) { + IPDetails details; + QFile file{QString::fromStdString(path.string())}; + if (!file.open(QFile::ReadOnly)) return details; + QString content = file.readAll(); + json object; + try { + object = json::parse(content.toStdString()); + } catch (std::exception& e) { + return details; + } + + if (object.contains("IP details")) { + auto ip_details = object.at("IP details"); + details.name = ip_details["Name"]; + details.description = ip_details["Description"]; + details.interface = ip_details["Interface"]; + details.version = ip_details["Version"]; + } + return details; +} diff --git a/src/IPGenerate/IPCatalog.h b/src/IPGenerate/IPCatalog.h index dd029adf1..a15d42e4c 100644 --- a/src/IPGenerate/IPCatalog.h +++ b/src/IPGenerate/IPCatalog.h @@ -261,24 +261,28 @@ class IPDefinition { const std::string& build_name, const std::filesystem::path& filePath, const std::vector& connections, - const std::vector& parameters) + const std::vector& parameters, + const std::filesystem::path& detailsPath) : m_type(type), m_name(name), m_build_name(build_name), m_filePath(filePath), + m_detailsPath(detailsPath), m_connections(connections), m_parameters(parameters){}; void apply(IPType type, const std::string& name, const std::string& build_name, const std::filesystem::path& filePath, const std::vector& connections, - const std::vector& parameters) { + const std::vector& parameters, + const std::filesystem::path& detailsPath) { m_type = type; m_name = name; m_build_name = build_name; m_filePath = filePath; m_connections = connections; m_parameters = parameters; + m_detailsPath = detailsPath; } ~IPDefinition() {} IPType Type() const { return m_type; } @@ -286,6 +290,7 @@ class IPDefinition { const std::string& BuildName() const { return m_build_name; } const std::vector& Connections() const { return m_connections; } const std::filesystem::path FilePath() const { return m_filePath; } + const std::filesystem::path FileDetailsPath() const { return m_detailsPath; } const std::vector Parameters() const { return m_parameters; } bool Valid() const { return m_valid; } void Valid(bool valid) { m_valid = valid; } @@ -295,6 +300,7 @@ class IPDefinition { std::string m_name; std::string m_build_name; std::filesystem::path m_filePath; + std::filesystem::path m_detailsPath; std::vector m_connections; std::vector m_parameters; bool m_valid{true}; @@ -355,7 +361,15 @@ struct VLNV { std::string version; }; +struct IPDetails { + std::string name; + std::string version; + std::string interface; + std::string description; +}; + VLNV getIpInfoFromPath(std::filesystem::path path); +IPDetails readIpDetails(const std::filesystem::path& path); } // namespace FOEDAG diff --git a/src/IPGenerate/IPCatalogBuilder.cpp b/src/IPGenerate/IPCatalogBuilder.cpp index d2d127ff4..983972639 100644 --- a/src/IPGenerate/IPCatalogBuilder.cpp +++ b/src/IPGenerate/IPCatalogBuilder.cpp @@ -56,9 +56,9 @@ void buildMockUpIPDef(IPCatalog* catalog) { Port* port = new Port("clk", Port::Direction::Input, Port::Function::Clock, Port::Polarity::High, range); connections.push_back(port); - IPDefinition* def = new IPDefinition(IPDefinition::IPType::Other, "MOCK_IP", - "MOCK_IP_wrapper", "path_to_nowhere", - connections, parameters); + IPDefinition* def = new IPDefinition( + IPDefinition::IPType::Other, "MOCK_IP", "MOCK_IP_wrapper", + "path_to_nowhere", connections, parameters, "ip_details.json"); catalog->addIP(def); // catalog->WriteCatalog(std::cout); } @@ -283,12 +283,13 @@ bool IPCatalogBuilder::buildLiteXIPFromJson( auto def = catalog->Definition(IPName); if (def) { def->apply(IPDefinition::IPType::LiteXGenerator, IPName, build_name, - pythonConverterScript, connections, parameters); + pythonConverterScript, connections, parameters, + "ip_Details.json"); def->Valid(true); } else { IPDefinition* def = new IPDefinition( IPDefinition::IPType::LiteXGenerator, IPName, build_name, - pythonConverterScript, connections, parameters); + pythonConverterScript, connections, parameters, "ip_Details.json"); catalog->addIP(def); } return true; @@ -315,9 +316,9 @@ bool IPCatalogBuilder::buildLiteXIPFromGeneratorInternal( auto info = FOEDAG::getIpInfoFromPath(pythonConverterScript); IPName += "_" + info.version; - IPDefinition* def = - new IPDefinition(IPDefinition::IPType::LiteXGenerator, IPName, - std::string{}, pythonConverterScript, {}, {}); + IPDefinition* def = new IPDefinition( + IPDefinition::IPType::LiteXGenerator, IPName, std::string{}, + pythonConverterScript, {}, {}, std::string{}); def->Valid(false); catalog->addIP(def); return result; diff --git a/src/IpConfigurator/IpCatalogTree.cpp b/src/IpConfigurator/IpCatalogTree.cpp index ee195f659..71c7e0756 100644 --- a/src/IpConfigurator/IpCatalogTree.cpp +++ b/src/IpConfigurator/IpCatalogTree.cpp @@ -52,6 +52,8 @@ IpCatalogTree::IpCatalogTree(QWidget* parent /*nullptr*/) refresh(); connect(this, &QTreeWidget::itemSelectionChanged, this, &IpCatalogTree::itemSelectionHasChanged); + connect(this, &QTreeWidget::itemDoubleClicked, this, + &IpCatalogTree::openIpSettings); } void IpCatalogTree::refresh() { diff --git a/src/IpConfigurator/IpCatalogTree.h b/src/IpConfigurator/IpCatalogTree.h index 344225222..29b5bb6b7 100644 --- a/src/IpConfigurator/IpCatalogTree.h +++ b/src/IpConfigurator/IpCatalogTree.h @@ -35,6 +35,7 @@ class IpCatalogTree : public QTreeWidget { signals: void ipReady(); + void openIpSettings(); private slots: void itemSelectionHasChanged(); diff --git a/src/IpConfigurator/IpConfigWidget.cpp b/src/IpConfigurator/IpConfigWidget.cpp index f84bb9c7e..0f4372c40 100644 --- a/src/IpConfigurator/IpConfigWidget.cpp +++ b/src/IpConfigurator/IpConfigWidget.cpp @@ -74,7 +74,7 @@ IpConfigWidget::IpConfigWidget(QWidget* parent /*nullptr*/, m_baseDirDefault{getUserProjectPath("IPs")}, m_requestedIpName(requestedIpName), m_instanceValueArgs(instanceValueArgs) { - this->setWindowTitle("Configure IP"); + this->setWindowTitle("IP Description/Details"); this->setObjectName("IpConfigWidget"); // Set the path related widgets' tooltips to whatever their text is so long @@ -106,12 +106,12 @@ IpConfigWidget::IpConfigWidget(QWidget* parent /*nullptr*/, // Fill and add Parameters box CreateParamFields(true); - containerLayout->addWidget(paramsBox); + // containerLayout->addWidget(paramsBox); // Add Output Box CreateOutputFields(); - containerLayout->addWidget(&outputBox); - containerLayout->addStretch(); + // containerLayout->addWidget(&outputBox); + // containerLayout->addStretch(); // Update the module name if one was passed (this occurs during a // re-configure) if (!moduleName.isEmpty()) { @@ -119,10 +119,10 @@ IpConfigWidget::IpConfigWidget(QWidget* parent /*nullptr*/, } // Add Dialog Buttons - AddDialogControls(topLayout); + // AddDialogControls(topLayout); // Update output path now that meta data has been loaded - updateOutputPath(); + // updateOutputPath(); // run with --json --json-template parameters to get default GUI if (!requestedIpName.isEmpty()) handleEditorChanged({}, nullptr); @@ -193,6 +193,7 @@ void IpConfigWidget::CreateParamFields(bool generateMetaLabel) { if (m_requestedIpName.toStdString() == def->Name()) { // Store VLNV meta data for the requested IP m_meta = FOEDAG::getIpInfoFromPath(def->FilePath()); + m_details = FOEDAG::readIpDetails(def->FileDetailsPath()); if (generateMetaLabel) { // set default module name to the BuildName provided by the generate @@ -204,10 +205,11 @@ void IpConfigWidget::CreateParamFields(bool generateMetaLabel) { moduleEdit.setText(QString::fromStdString(build_name)); // Update meta label now that vlnv and module info is updated - updateMetaLabel(m_meta); + updateMetaLabel(m_details); } // Build widget factory json for each parameter + /* for (auto paramVal : def->Parameters()) { if (paramVal->GetType() == Value::Type::ParamIpVal) { IPParameter* param = static_cast(paramVal); @@ -277,6 +279,7 @@ void IpConfigWidget::CreateParamFields(bool generateMetaLabel) { QString::fromStdString(param->Name()), valNoSpaces); } } + */ } } @@ -285,10 +288,10 @@ void IpConfigWidget::CreateParamFields(bool generateMetaLabel) { tclArgList = m_instanceValueArgs; } - containerLayout->removeWidget(paramsBox); - paramsBox->deleteLater(); - paramsBox = new QGroupBox{"Parameters", this}; - containerLayout->insertWidget(1, paramsBox); + // containerLayout->removeWidget(paramsBox); + // paramsBox->deleteLater(); + // paramsBox = new QGroupBox{"Parameters", this}; + // containerLayout->insertWidget(1, paramsBox); if (parentJson.empty()) { // Add a note if no parameters were available @@ -339,19 +342,34 @@ void IpConfigWidget::CreateOutputFields() { outputBox.setLayout(form); } -void IpConfigWidget::updateMetaLabel(VLNV info) { - // Create a descriptive sentence that lists all the VLNV info - QString verStr = QString::fromStdString(info.version).replace("_", "."); - QString action = "Configuring"; - if (!m_instanceValueArgs.empty()) { - // if params were passed then we are reconfiguring an existing instance - action = "Reconfiguring instance \"" + moduleEdit.text() + "\" for "; - } - std::string text = "" + action.toStdString() + " " + info.name + " (" + - verStr.toStdString() + ")" + " from " + info.vendor + - "'s " + info.library + " library"; +void IpConfigWidget::updateMetaLabel(const IPDetails& details) { + QString text = R"( + + + + + + + + + +
Name: + %1 +
Version: + %2 +
Interface: + %3 +
Description: + %4 +
+)"; + + text = text.arg(QString::fromStdString(details.name), + QString::fromStdString(details.version), + QString::fromStdString(details.interface), + QString::fromStdString(details.description)); metaLabel.setTextFormat(Qt::RichText); - metaLabel.setText(QString::fromStdString(text)); + metaLabel.setText(text); metaLabel.setWordWrap(true); } diff --git a/src/IpConfigurator/IpConfigWidget.h b/src/IpConfigurator/IpConfigWidget.h index 7f899074e..31f79fdaa 100644 --- a/src/IpConfigurator/IpConfigWidget.h +++ b/src/IpConfigurator/IpConfigWidget.h @@ -54,7 +54,7 @@ class IpConfigWidget : public QWidget { void AddIpToProject(const QString& cmd); void CreateParamFields(bool generateMetaLabel); void CreateOutputFields(); - void updateMetaLabel(VLNV info); + void updateMetaLabel(const IPDetails& details); std::vector getDefinitions(); QMap saveProperties(bool& valid) const; @@ -75,6 +75,7 @@ class IpConfigWidget : public QWidget { const QString m_requestedIpName; const QStringList m_instanceValueArgs; VLNV m_meta; + IPDetails m_details; QVBoxLayout* containerLayout{nullptr}; }; diff --git a/src/MainWindow/main_window.cpp b/src/MainWindow/main_window.cpp index 9675989a5..b151e65f9 100644 --- a/src/MainWindow/main_window.cpp +++ b/src/MainWindow/main_window.cpp @@ -1599,8 +1599,10 @@ void MainWindow::ipConfiguratorActionTriggered() { m_ipCatalogTree = ipsWidgets[0]; // Update the IP Config widget when the Available IPs selection changes - QObject::connect(m_ipCatalogTree, &IpCatalogTree::ipReady, this, - &MainWindow::handleIpTreeSelectionChanged); + connect(m_ipCatalogTree, &IpCatalogTree::ipReady, this, + &MainWindow::handleIpTreeSelectionChanged); + connect(m_ipCatalogTree, &IpCatalogTree::openIpSettings, this, + []() { qDebug() << __PRETTY_FUNCTION__; }); } // update the console for input incase the IP system printed any messages @@ -1668,8 +1670,8 @@ void MainWindow::handleIpReConfigRequested(const QString& ipName, } else { // If dock widget hasn't been created // Create and place new dockwidget m_ipConfigDockWidget = - PrepareTab(tr("Configure IP"), "configureIpsWidget", configWidget, - nullptr, Qt::RightDockWidgetArea); + PrepareTab(configWidget->windowTitle(), "configureIpsWidget", + configWidget, nullptr, Qt::RightDockWidgetArea); } }