20#include "../NumeReWindow.h"
21#include "../../kernel/core/utils/tools.hpp"
22#include "../../kernel/core/ui/language.hpp"
51DependencyDialog::
DependencyDialog(wxWindow* parent, wxWindowID
id, const wxString& title, const
string& mainfile,
ProcedureLibrary& lib,
long style) : wxDialog(parent,
id, title, wxDefaultPosition, wxSize(-1, 450), style)
53 wxBoxSizer* vsizer =
new wxBoxSizer(wxVERTICAL);
56 m_dependencyTree =
new wxcode::wxTreeListCtrl(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_TWIST_BUTTONS | wxTR_FULL_ROW_HIGHLIGHT);
57 m_dependencyTree->AddColumn(
_guilang.
get(
"GUI_DEPDLG_TREE"), GetClientSize().GetWidth());
58 vsizer->Add(m_dependencyTree, 1, wxEXPAND | wxALL, 5);
59 vsizer->Add(CreateButtonSizer(wxOK), 0, wxALL | wxALIGN_CENTER_HORIZONTAL, 5);
64 calculateDependencies(lib, mainfile);
93 auto iter =
m_deps.begin();
96 while (iter !=
m_deps.end())
101 for (
auto listiter = iter->second.begin(); listiter != iter->second.end(); ++listiter)
103 if (
m_deps.find(listiter->getProcedureName()) ==
m_deps.end() && listiter->getProcedureName().find(
"thisfile~") == string::npos)
151 for (
auto listiter = iter->second.begin(); listiter != iter->second.end(); ++listiter)
153 wxTreeItemId item =
m_dependencyTree->AppendItem(root, listiter->getProcedureName() +
"()");
156 if (listiter->getProcedureName().find(
"thisfile~") != string::npos)
186 auto iter =
m_deps.find(sParentProcedure);
192 for (
auto listiter = iter->second.begin(); listiter != iter->second.end(); ++listiter)
194 wxTreeItemId currItem;
198 if (
findInParents(item, listiter->getProcedureName() +
"()"))
199 currItem =
m_dependencyTree->AppendItem(item, listiter->getProcedureName() +
"()");
202 currItem =
m_dependencyTree->AppendItem(item, listiter->getProcedureName() +
"()");
207 if (listiter->getProcedureName().find(
"thisfile~") != string::npos)
258 wxTreeItemIdValue cookie;
281 std::vector<std::string> vNameSpace;
283 if (sNameSpace.front() ==
'$')
284 sNameSpace.erase(0, 1);
286 while (sNameSpace.length())
288 size_t pos = sNameSpace.find(
'~');
289 vNameSpace.push_back(sNameSpace.substr(0, pos));
290 sNameSpace.erase(0, pos);
292 if (pos != std::string::npos)
293 sNameSpace.erase(0, 1);
315 for (; nNameSpaces < (int)sCurrentNameSpace.size(); nNameSpaces++)
318 if ((
int)sNewNameSpace.size() <= nNameSpaces)
319 return nNameSpaces+1;
322 if (sCurrentNameSpace[nNameSpaces] != sNewNameSpace[nNameSpaces])
323 return nNameSpaces+1;
327 if (sNewNameSpace.size() > sCurrentNameSpace.size())
328 return sNewNameSpace.size();
343 std::string sClusterDefinition;
344 std::string sDotFileContent;
345 std::map<std::string, std::list<std::string> > mProcedures;
349 for (
auto caller =
m_deps.begin(); caller !=
m_deps.end(); ++caller)
351 for (
auto called = caller->second.begin(); called != caller->second.end(); ++called)
353 if (caller->first.find_last_of(
"~/") != std::string::npos)
354 mProcedures[caller->first.substr(0, caller->first.find_last_of(
"~/")+1)].push_back(caller->first);
356 mProcedures[caller->first].push_back(caller->first);
358 mProcedures[called->getProcedureName().substr(0, called->getProcedureName().find_last_of(
"~/")+1)].push_back(called->getProcedureName());
360 sDotFileContent +=
"\t\"" + caller->first +
"()\" -> \"" + called->getProcedureName() +
"()\"\n";
364 std::vector<std::string> vCurrentNameSpace;
365 std::vector<std::string> vNameSpace;
366 int nClusterindex = 0;
367 int nCurrentClusterLevel = 0;
371 for (
auto iter = mProcedures.begin(); iter != mProcedures.end(); ++iter)
373 std::string sNameSpace = iter->first;
375 if (sNameSpace.find_last_of(
"~/") != std::string::npos)
376 sNameSpace.erase(sNameSpace.find_last_of(
"~/")+1);
384 if (nNewClusterLevel < nCurrentClusterLevel)
386 sClusterDefinition +=
"\n";
388 for (
int i = nCurrentClusterLevel-nNewClusterLevel; i >= 0; i--)
389 sClusterDefinition += std::string(i+nNewClusterLevel,
'\t') +
"}\n";
391 nCurrentClusterLevel = nNewClusterLevel-1;
394 if (nCurrentClusterLevel < 0)
395 nCurrentClusterLevel = 0;
397 else if (nNewClusterLevel == nCurrentClusterLevel)
399 sClusterDefinition +=
"\n" + std::string(nNewClusterLevel,
'\t') +
"}\n";
400 nCurrentClusterLevel--;
403 sClusterDefinition +=
"\n";
405 vCurrentNameSpace = vNameSpace;
407 for (
int i = nCurrentClusterLevel; i < (int)vCurrentNameSpace.size(); i++)
410 if (vCurrentNameSpace[i].find(
"::thisfile") != std::string::npos)
411 sClusterDefinition +=
"\n" + std::string(i+1,
'\t')
412 +
"subgraph cluster_" +
toString(nClusterindex) +
"\n"
413 + std::string(i+1,
'\t') +
"{\n"
414 + std::string(i+2,
'\t') +
"style=filled\n"
415 + std::string(i+2,
'\t') +
"color=lightsteelblue\n"
416 + std::string(i+2,
'\t') +
"fillcolor=floralwhite\n"
417 + std::string(i+2,
'\t') +
"node [fillcolor=\"cornsilk\"]\n"
418 + std::string(i+2,
'\t') +
"label=\"" + vCurrentNameSpace[i] +
"\"\n";
420 sClusterDefinition +=
"\n" + std::string(i+1,
'\t')
421 +
"subgraph cluster_" +
toString(nClusterindex) +
"\n"
422 + std::string(i+1,
'\t') +
"{\n"
423 + std::string(i+2,
'\t') +
"style=rounded\n"
424 + std::string(i+2,
'\t') +
"color=mediumslateblue\n"
425 + std::string(i+2,
'\t') +
"label=\"" + vCurrentNameSpace[i] +
"\"\n";
430 sClusterDefinition += std::string(vCurrentNameSpace.size()+1,
'\t');
431 nCurrentClusterLevel = vCurrentNameSpace.size();
435 iter->second.unique();
438 for (
auto procedure = iter->second.begin(); procedure != iter->second.end(); ++procedure)
439 sClusterDefinition +=
"\"" + *procedure +
"()\" ";
444 for (
int i = nCurrentClusterLevel; i > 0; i--)
445 sClusterDefinition +=
"\n" + std::string(i,
'\t') +
"}";
448 wxFileDialog saveDialog(
this,
_guilang.
get(
"GUI_DLG_SAVE"),
"",
"dependency.dot",
_guilang.
get(
"COMMON_FILETYPE_DOT") +
" (*.dot)|*.dot", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
450 if (saveDialog.ShowModal() == wxID_CANCEL)
454 ofstream file(saveDialog.GetPath().ToStdString().c_str());
460 file <<
"digraph ProcedureDependency\n{\n\tratio=0.4\n\tfontname=\"Consolas\"\n\tnode [fontname=\"Consolas\" fontcolor=\"maroon\" style=\"filled\" fillcolor=\"palegoldenrod\"]";
461 file << sClusterDefinition <<
"\n\n";
462 file << sDotFileContent <<
"}\n";
483 procedureName.erase(procedureName.find(
'('));
487 if (procedureName.find(
"::thisfile~") != string::npos)
515 popupMenu.AppendSeparator();
533 switch (event.GetId())
This class handles the dependencies of the current procedure file (passed as pointer to a ProcedureEl...
std::map< std::string, DependencyList > & getDependencyMap()
std::string getMainProcedure() const
This class represents a dialog showing the dependencies of a selected procedure file.
std::string m_mainProcedure
void OnMenuEvent(wxCommandEvent &event)
This private member function handles all menu events yielded by clicking on an item of the popup menu...
wxTreeItemId m_selectedItem
void OnItemRightClick(wxTreeEvent &event)
This private member function shows the popup menu on a right click on any tree item.
std::map< std::string, DependencyList > m_deps
void calculateDependencies(ProcedureLibrary &lib, const std::string &mainfile)
This private member function calculates the dependencies of the current selected main file....
std::vector< std::string > parseNameSpace(std::string sNameSpace) const
Convert a name space into a vector of single namespaces for easier comparison.
void CreateDotFile()
This member function handles the creation of GraphViz DOT files.
void CollapseAll(wxTreeItemId item)
This private member function will collapse the current item and all corresponding subitems.
void OnItemActivate(wxTreeEvent &event)
This private member function is the event handler for double clicking on an item in the dependency tr...
int calculateClusterLevel(const std::vector< std::string > &sCurrentNameSpace, const std::vector< std::string > &sNewNameSpace)
This private member function calculates the level of nested clusters needed to correctly visualize th...
void fillDependencyTree()
This private member function fills the tree in the UI with the calculated dependencies....
wxcode::wxTreeListCtrl * m_dependencyTree
bool findInParents(wxTreeItemId item, const std::string &sCurrProc)
This private member function searches the procedure call in the parents of the current branch.
void insertChilds(wxTreeItemId item, const std::string &sParentProcedure)
This private member function is called recursively to fill the childs of a procedure call....
This class handles the internal language system and returns the language strings of the selected lang...
std::string get(const std::string &sMessage, const std::vector< std::string > &vTokens) const
This member function returns the language string for the passed language identifier and replaces all ...
This class is the actual NumeRe main frame. The application's logic is implemented here.
void FindAndOpenProcedure(const wxString &procedureName)
Wrapper for the corresponding function of the editor.
Dependencies * getDependencies()
This member function returns the first-level dependencies of the current procedure file....
This class manages all already read and possibly pre-parsed procedure files for easier and faster acc...
ProcedureElement * getProcedureContents(const std::string &sProcedureFileName)
Returns the ProcedureElement pointer to the desired procedure file. It also creates the element,...
@ ID_DEPENDENCYDIALOG_FOLDALL
@ ID_DEPENDENCYDIALOG_UNFOLDALL
@ ID_DEPENDENCYDIALOG_EXPORTDOT
@ ID_DEPENDENCYDIALOG_UNFOLDITEM
@ ID_DEPENDENCYDIALOG_FOLDITEM
std::string replacePathSeparator(const std::string &)
This function replaces the Windows style path sparators to UNIX style.
std::string toString(int)
Converts an integer to a string without the Settings bloat.