connect\s*\((.+)\s*,\s*SIGNAL\((.+)\)\s*,\s*(.+)\s*,\s*(?:SLOT|SIGNAL)\((.+)\)\s*\)\s*\)
If it finds this signature (comments count as well) it generates a DOT (http://www.graphviz.org/) file. This graph can be visualized for example here or the command line tools generate an image. Because DOT tries to minimize the height of the graph a sightly better result can be achieved with the command line from here.
The this keyword will be replaced by the file name because otherwise DOT would connect all of them. The label of the edge is the signal in the first line and the slot (or signal) in the second one.
#include <QString> #include <QDir> #include <QDebug> #include <QFileInfo> #include <QFileInfoList> #include <QIODevice> #include <iostream> void IterateDirs(QDir dir); int main(int argc,char* argv[]) { bool foundSite = false; QString site; for(int i = 1; i < argc; ++i) { if(std::string(argv[i]) == "--path" || std::string(argv[i]) == "-p") { ++i; if (i < argc) site = argv[i]; else break; foundSite = true; continue; } } if (argc < 3 || !foundSite) { std::cerr << "Usage: ConVis --path <projectpath>" << std::endl; return EXIT_FAILURE; } QDir dir(site); std::cout << "digraph connections {\nconstraint=\"false\" minlen=2\n"; IterateDirs(dir); std::cout << "}\n"; return EXIT_SUCCESS; } int i = 0; void IterateDirs(QDir dir) { QStringList filter; filter << "*.cxx" << "*.hxx" << "*.cpp" << "*.hpp"; QFileInfoList files = dir.entryInfoList(filter, QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Files); QFileInfoList::const_iterator it = files.constBegin(); QFileInfoList::const_iterator en = files.constEnd(); while (it != en) { QFileInfo info = *it; //qDebug() << info.isDir() << info.absoluteFilePath() << info.isFile(); if (info.isDir()) IterateDirs(QDir(info.absoluteFilePath())); else if (info.isFile()) { QFile f(info.absoluteFilePath()); f.open(QIODevice::ReadOnly); QString content = f.readAll(); f.close(); QRegExp r("connect\\s*\\((.+)\\s*,\\s*SIGNAL\\((.+)\\)\\s*,\\s*(.+)\\s*," "\\s*(?:SLOT|SIGNAL)\\((.+)\\)\\s*\\)\\s*\\)"); r.setMinimal(true); bool output = r.indexIn(content) != -1; if (output) std::cout << "subgraph cluster_" << i << "{\n"; while (r.indexIn(content) != -1) { //qDebug() << r.capturedTexts(); QStringList l = r.capturedTexts(); if (l.at(1).trimmed() == "this") l.replace(1, info.fileName()); if (l.at(3).trimmed() == "this") l.replace(3, info.fileName()); std::cout << "\"" << l.at(1).trimmed().toStdString() << "\" -> \"" << l.at(3).trimmed().toStdString() << "\" [color=\"green\"" << " label=\"" << l.at(2).trimmed().toStdString() << "\\n" << l.at(4).trimmed().append(")").toStdString() << "\" style=\"solid\" labeldistance=2];\n"; content = content.mid(r.indexIn(content) + r.matchedLength()); } if (output) std::cout << "label=\"" << info.fileName().toStdString() << "\"\n}\n"; ++i; } ++it; } }