]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
[bos #32523][EDF] SALOME on Demand GUI. Large getExtTreeWidget() method divided to...
authorkosta <kleontev@Debian11.kleontev.virtualbox.org>
Thu, 9 Feb 2023 21:07:17 +0000 (22:07 +0100)
committerKonstantin LEONTEV <konstantin.leontev@opencascade.com>
Wed, 8 Mar 2023 13:06:13 +0000 (14:06 +0100)
src/LightApp/LightApp_ExtInfoDlg.cxx
src/LightApp/LightApp_ExtInfoDlg.h

index 1695775f4582f7c026b5d7c1bb2b230ee1b5a05f..9589a8f9b785344b32dd3ffff68ce68bf59c2fd4 100644 (file)
 #include <QByteArray>
 #include <graphviz/gvc.h>
 
+
+/*! RAII wrapper to graphviz Agraph_t.*/
+class GraphWrapper
+{
+  public:
+    virtual ~GraphWrapper();
+
+    void init(char* name, Agdesc_t desc = Agstrictdirected, Agdisc_t* disc = nullptr);
+
+    Agraph_t* getGraph() const { return m_graph; }
+    GVC_t* getGvc() const { return m_gvc; }
+
+  private:
+    Agraph_t* m_graph = nullptr;
+    GVC_t* m_gvc = nullptr;
+};
+
+GraphWrapper::~GraphWrapper()
+{
+  if (m_graph)
+  {
+    agclose(m_graph);
+    m_graph = nullptr;
+  }
+
+  if (m_gvc)
+  {
+    gvFreeContext(m_gvc);
+    m_gvc = nullptr;
+  }
+}
+
+void GraphWrapper::init(char *name, Agdesc_t desc /* = Agstrictdirected */, Agdisc_t* disc /* = nullptr */)
+{
+  m_graph = agopen(name, desc, disc);
+  m_gvc = gvContext();
+}
+
 /*!Constructor.*/
 LightApp_ExtInfoDlg::LightApp_ExtInfoDlg(QWidget* parent)
 : QtxDialog(parent, true, true, ButtonFlags::OK)
@@ -165,33 +203,27 @@ QWidget* LightApp_ExtInfoDlg::getExtListWidget(QWidget* parent) const
   return extListWidget;
 }
 
-/*! Return widget with an image of dependency tree fot installed extensions */
-QWidget* LightApp_ExtInfoDlg::getExtTreeWidget(QWidget* parent) const
+/*! Fill a given extension tree graph with nodes and edges */
+bool LightApp_ExtInfoDlg::fillExtTreeGraph(const GraphWrapper& graph) const
 {
-  MESSAGE("Start to get extensions dependency tree...\n");
-
-  auto extTreeWidget = new QSvgWidget(parent);
+  MESSAGE("Start to get info from SalomeOnDemandTK.extension_query...\n");
 
   // Import Python module that manages SALOME extensions
   PyLockWrapper lck; // acquire GIL
   PyObjWrapper extensionQuery = PyImport_ImportModule((char*)"SalomeOnDemandTK.extension_query");
   auto extRootDir = getenv("SALOME_APPLICATION_DIR");
   PyObjWrapper dependencyTree = PyObject_CallMethod(extensionQuery, (char*)"dependency_tree", (char*)"s", extRootDir);
-  ASSERT(dependencyTree);
   if (!dependencyTree)
   {
     PyErr_Print();
-    return extTreeWidget;
+    return false;
   }
 
-  // Graph to be filled up from python data
-  char graphName[] = "extTreeGraph";
-  Agraph_t* extTreeGraph = agopen(graphName, Agstrictdirected, nullptr);
-  GVC_t* gvc = gvContext();
+  Agraph_t* extTreeGraph = graph.getGraph();
 
   // Python declarations
-  PyObject *extName = nullptr;
-  PyObject *dependantsList = nullptr;
+  PyObjectextName = nullptr;
+  PyObjectdependantsList = nullptr;
   Py_ssize_t pos = 0;
 
   // Iterate the tree
@@ -221,31 +253,58 @@ QWidget* LightApp_ExtInfoDlg::getExtTreeWidget(QWidget* parent) const
     }
   }
 
+  return true;
+}
+
+/*! Render dependency tree to array of bytes */
+QByteArray LightApp_ExtInfoDlg::renderExtTreeGraph(const GraphWrapper& graph) const
+{
+  Agraph_t* extTreeGraph = graph.getGraph();
+  GVC_t* gvc = graph.getGvc();
+
   // Layout and render to buffer
+  MESSAGE("Layout dependency tree...\n");
   int res = gvLayout(gvc, extTreeGraph, "dot");
   if (res)
   {
     MESSAGE("gvLayout failed!\n");
-    return extTreeWidget;
+    return {};
   }
 
+  MESSAGE("Render dependency tree...\n");
   char* buffer = nullptr;
   unsigned int bufferLength = 0;
   res = gvRenderData(gvc, extTreeGraph, "svg", &buffer, &bufferLength);
   if (res)
   {
     MESSAGE("gvRenderData failed!\n");
-    return extTreeWidget;
+    return {};
   }
 
-  // Load the buffer into widget
   QByteArray renderedGraph(buffer, bufferLength);
-  extTreeWidget->load(renderedGraph);
-
-  // Clean up section
+  
+  // Clean up layout and buffer
   gvFreeLayout(gvc, extTreeGraph);
   gvFreeRenderData(buffer);
-  agclose(extTreeGraph);
+
+  return renderedGraph;
+}
+
+/*! Return widget with an image of dependency tree fot installed extensions */
+QWidget* LightApp_ExtInfoDlg::getExtTreeWidget(QWidget* parent) const
+{
+  MESSAGE("Start to make a widget to show dependency tree...\n");
+
+  auto extTreeWidget = new QSvgWidget(parent);
+
+  // Graph to be filled up from python data
+  GraphWrapper extTreeGraph;
+  char graphName[] = "extTreeGraph";
+  extTreeGraph.init(graphName);
+  if (fillExtTreeGraph(extTreeGraph))
+  {
+    extTreeWidget->load(renderExtTreeGraph(extTreeGraph));
+  }
 
   return extTreeWidget;
 }
index 3db7e0a66488e833e463784ef2ea6b6c867f9040..b4d9323ce8e686c6437f5ad217d0df56cac178a8 100644 (file)
@@ -31,6 +31,8 @@
 #include <QtxDialog.h>
 
 class QTableWidget;
+class GraphWrapper;
+class QByteArray;
 
 /*!
   \class LightApp_ExtInfoDlg
@@ -49,6 +51,8 @@ private:
   QWidget* getExtTreeWidget(QWidget* parent) const;
 
   bool fillExtListWidget(QTableWidget* extListWidget) const;
+  bool fillExtTreeGraph(const GraphWrapper& graph) const;
+  QByteArray renderExtTreeGraph(const GraphWrapper& graph) const;
 };
 
 #endif