WingHexExplorer2/3rdparty/qcodemodel2/qcodeloader.cpp

239 lines
5.4 KiB
C++

/****************************************************************************
**
** Copyright (C) 2006-2009 fullmetalcoder <fullmetalcoder@hotmail.fr>
**
** This file is part of the Edyuk project <http://edyuk.org>
**
** This file may be used under the terms of the GNU General Public License
** version 3 as published by the Free Software Foundation and appearing in the
** file GPL.txt included in the packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#include "qcodeloader.h"
/*!
\file qcodeloader.cpp
\brief Implementation of the QCodeLoader class.
*/
#include "qcodemodel.h"
#include "qcodenode.h"
#include "qcodeparser.h"
#include <QByteArray>
#include <QFileInfo>
#include <QTimer>
/*!
\class QCodeLoader
\brief A parsers management class
QCodeLoader owns a collection of QCodeParser object
and request them to generate project trees from files.
*/
/*!
\brief ctor
*/
QCodeLoader::QCodeLoader(QObject *p) : QThread(p) {}
/*!
\brief dtor
*/
QCodeLoader::~QCodeLoader() {
// qDeleteAll(m_parsers);
}
/*!
\brief Add a parser to the collection
\warning The parser is not taken over. It won't get deleted
from QCodeLoader dtor.
*/
void QCodeLoader::addParser(QCodeParser *p) {
if (!m_parsers.contains(p))
m_parsers << p;
}
/*!
\brief Remove a parser from the collection
\warning The parser is NOT deleted.
*/
void QCodeLoader::removeParser(QCodeParser *p) { m_parsers.removeAll(p); }
/*!
\brief Update the content of a given node to
*/
void QCodeLoader::update(QCodeNode *group, const QString &file) {
if (!group)
return;
if (!QFile::exists(file)) {
QStack<QCodeNode *> l;
l.push(group);
while (l.count()) {
QCodeNode *n = l.pop();
if (n->context() == file) {
QCodeNode *p = n->parent;
n->detach();
delete n;
while (p && p->children.isEmpty() && (p != group)) {
n = p;
p = p->parent;
n->detach();
delete n;
}
} else {
foreach (QCodeNode *c, n->children)
l.push(c);
}
}
return;
}
// qDebug("update(%s, %s)", group->role(QCodeNode::Name).constData(),
// qPrintable(file));
foreach (QCodeParser *p, m_parsers) {
if (!p->canParse(file))
continue;
QCodeNode *ln = 0;
QByteArray roles("l@");
roles += p->language().toLocal8Bit();
foreach (QCodeNode *c, group->children) {
if (c->roles == roles) {
ln = c;
break;
}
}
if (!ln) {
ln = p->getNode();
ln->roles = roles;
ln->attach(group);
}
p->update(ln, file);
break;
}
}
/*!
\brief Attempt to open load class hierarchy from a set of files
\return true on success
\param group Name of the toplevel group which will get created on
success \param files Files to load \param dest Destination model
*/
bool QCodeLoader::load(const QString &group, QStringList files,
QCodeModel *dest) {
// qDebug("load(%s, (%s), %p)", qPrintable(group), qPrintable(files.join(",
// ")), dest);
bool done = false;
QCodeNode *g = new QCodeNode;
g->roles = QByteArray("g@") + QFileInfo(group).fileName().toLocal8Bit() +
"@" + group.toLocal8Bit();
dest->appendTopLevelNode(g);
foreach (QCodeParser *p, m_parsers) {
QStringList lf;
foreach (QString fn, files)
if (p->canParse(fn))
lf << fn;
if (lf.isEmpty())
continue;
done = true;
break;
}
if (!done)
return false;
OpenRequest r;
r.files = files;
r.group = group;
r.model = dest;
m_request.enqueue(r);
if (!isRunning())
QTimer::singleShot(0, this, SLOT(start()));
return true;
}
/*!
\internal
*/
void QCodeLoader::run() {
QTimer::singleShot(0, this, SLOT(process()));
exec();
// process();
}
/*!
\internal
*/
void QCodeLoader::process() {
while (m_request.count()) {
OpenRequest r = m_request.dequeue();
bool done = false;
QCodeNode *g;
QList<QCodeNode *> gl = r.model->topLevelNodes();
foreach (g, gl) {
if (g->role(QCodeNode::Context) != r.group)
continue;
foreach (QCodeParser *p, m_parsers) {
QStringList lf;
foreach (QString fn, r.files)
if (p->canParse(fn))
lf << fn;
if (lf.isEmpty())
continue;
done = true;
QCodeNode *ln = p->getNode();
ln->roles = QByteArray("l@") + p->language().toLocal8Bit();
foreach (QString fn, lf) {
r.files.removeAll(fn);
p->update(ln, fn);
}
ln->attach(g);
}
break;
}
}
quit();
}