summaryrefslogtreecommitdiffstats
path: root/addon/doxywizard/expert.cpp
diff options
context:
space:
mode:
authorDimitri van Heesch <dimitri@stack.nl>2013-07-21 10:40:14 (GMT)
committerDimitri van Heesch <dimitri@stack.nl>2013-07-28 11:47:23 (GMT)
commit38e67b40b1c50e1ccbda4ffd867b6aa82a6c2212 (patch)
treec162a1ab1c375aa21c4f137ec30ae765b67527a4 /addon/doxywizard/expert.cpp
parent10ab1d5dddd63b5e7b3a65da8eb8a6416be7c914 (diff)
downloadDoxygen-38e67b40b1c50e1ccbda4ffd867b6aa82a6c2212.zip
Doxygen-38e67b40b1c50e1ccbda4ffd867b6aa82a6c2212.tar.gz
Doxygen-38e67b40b1c50e1ccbda4ffd867b6aa82a6c2212.tar.bz2
config.xml is now used to generate configoptions.cpp and config.doc
Diffstat (limited to 'addon/doxywizard/expert.cpp')
-rw-r--r--addon/doxywizard/expert.cpp368
1 files changed, 329 insertions, 39 deletions
diff --git a/addon/doxywizard/expert.cpp b/addon/doxywizard/expert.cpp
index e7b7507..8278641 100644
--- a/addon/doxywizard/expert.cpp
+++ b/addon/doxywizard/expert.cpp
@@ -1,16 +1,16 @@
+#include <QtGui>
+#include <QtXml>
#include "expert.h"
#include "inputbool.h"
#include "inputstring.h"
#include "inputint.h"
#include "inputstring.h"
#include "inputstrlist.h"
-#include <QtGui>
-#include <QtXml>
#include "config.h"
#include "version.h"
+#include "configdoc.h"
#include "../../src/settings.h"
-#undef SA
#define SA(x) QString::fromAscii(x)
static QString convertToComment(const QString &s)
@@ -27,6 +27,20 @@ static QString convertToComment(const QString &s)
}
}
+void Expert::setHeader(const char *header)
+{
+ m_header = SA(header);
+}
+
+void Expert::add(const char *name,const char *docs)
+{
+ Input *opt = m_options[SA(name)];
+ if (opt)
+ {
+ opt->setTemplateDocs(SA(docs));
+ }
+}
+
//------------------------------------------------------------------------------------
Expert::Expert()
@@ -53,8 +67,9 @@ Expert::Expert()
m_rootElement = configXml.documentElement();
createTopics(m_rootElement);
- m_helper = new QTextEdit;
+ m_helper = new QTextBrowser;
m_helper->setReadOnly(true);
+ m_helper->setOpenExternalLinks(TRUE);
m_splitter = new QSplitter(Qt::Vertical);
m_splitter->addWidget(m_treeWidget);
m_splitter->addWidget(m_helper);
@@ -75,6 +90,8 @@ Expert::Expert()
connect(m_next,SIGNAL(clicked()),SLOT(nextTopic()));
connect(m_prev,SIGNAL(clicked()),SLOT(prevTopic()));
+
+ addConfigDocs(this);
}
Expert::~Expert()
@@ -111,6 +128,273 @@ void Expert::createTopics(const QDomElement &rootElem)
SLOT(activateTopic(QTreeWidgetItem *,QTreeWidgetItem *)));
}
+static QString getDocsForNode(const QDomElement &child)
+{
+ QString type = child.attribute(SA("type"));
+ QString docs = SA("");
+ // read documentation text
+ QDomElement docsVal = child.firstChildElement();
+ while (!docsVal.isNull())
+ {
+ if (docsVal.tagName()==SA("docs") &&
+ docsVal.attribute(SA("doxywizard")) != SA("0"))
+ {
+ for (QDomNode n = docsVal.firstChild(); !n.isNull(); n = n.nextSibling())
+ {
+ QDomText t = n.toText();
+ if (!t.isNull()) docs+=t.data();
+ }
+ docs+=SA("<br/>");
+ }
+ docsVal = docsVal.nextSiblingElement();
+ }
+
+ // for an enum we list the values
+ if (type==SA("enum"))
+ {
+ docs += SA("Possible values are: ");
+ int numValues=0;
+ docsVal = child.firstChildElement();
+ while (!docsVal.isNull())
+ {
+ if (docsVal.tagName()==SA("value"))
+ {
+ numValues++;
+ }
+ docsVal = docsVal.nextSiblingElement();
+ }
+ int i=0;
+ docsVal = child.firstChildElement();
+ while (!docsVal.isNull())
+ {
+ if (docsVal.tagName()==SA("value"))
+ {
+ i++;
+ docs += SA("<code>") + docsVal.attribute(SA("name")) + SA("</code>");
+ QString desc = docsVal.attribute(SA("desc"));
+ if (!desc.isEmpty())
+ {
+ docs+= SA(" ")+desc;
+ }
+ if (i==numValues-1)
+ {
+ docs+=SA(" and ");
+ }
+ else if (i==numValues)
+ {
+ docs+=SA(".");
+ }
+ else
+ {
+ docs+=SA(", ");
+ }
+ }
+ docsVal = docsVal.nextSiblingElement();
+ }
+ docs+=SA("<br/>");
+ docs+=SA("The default value is: <code>")+
+ child.attribute(SA("defval"))+
+ SA("</code>.");
+ }
+ else if (type==SA("int"))
+ {
+ docs+=SA("Minimum value: ")+child.attribute(SA("minval"))+SA(", ");
+ docs+=SA("maximum value: ")+child.attribute(SA("maxval"))+SA(", ");
+ docs+=SA("default value: ")+child.attribute(SA("defval"))+SA(".");
+ }
+ else if (type==SA("bool"))
+ {
+ if (child.hasAttribute(SA("altdefval")))
+ {
+ docs+=SA("The default value is: system dependent.");
+ }
+ else
+ {
+ QString defval = child.attribute(SA("defval"));
+ docs+=SA("The default value is: <code>")+
+ (defval==SA("1")?SA("YES"):SA("NO"))+
+ SA("</code>.");
+ }
+ }
+ else if (type==SA("list"))
+ {
+ if (child.attribute(SA("format"))==SA("string"))
+ {
+ int numValues = 0;
+ docsVal = child.firstChildElement();
+ while (!docsVal.isNull())
+ {
+ if (docsVal.tagName()==SA("value"))
+ {
+ if (docsVal.attribute(SA("name"))!=SA("")) numValues++;
+ }
+ docsVal = docsVal.nextSiblingElement();
+ }
+ if (numValues>0)
+ {
+ int i = 0;
+ docsVal = child.firstChildElement();
+ while (!docsVal.isNull())
+ {
+ if (docsVal.tagName()==SA("value"))
+ {
+ i++;
+ docs += SA("<code>") + docsVal.attribute(SA("name")) + SA("</code>");
+ QString desc = docsVal.attribute(SA("desc"));
+ if (desc != SA(""))
+ {
+ docs += SA(" ") + desc;
+ }
+ if (i==numValues-1)
+ {
+ docs += SA(" and ");
+ }
+ else if (i==numValues)
+ {
+ docs += SA(".");
+ }
+ else
+ {
+ docs += SA(", ");
+ }
+ }
+ docsVal = docsVal.nextSiblingElement();
+ }
+ }
+ }
+ }
+ else if (type==SA("string"))
+ {
+ QString defval = child.attribute(SA("defval"));
+ if (child.attribute(SA("format")) == SA("dir"))
+ {
+ if (defval != SA(""))
+ {
+ docs += SA("The default directory is: <code>") + defval + SA("</code>.");
+ }
+ }
+ else if (child.attribute(SA("format")) == SA("file"))
+ {
+ QString abspath = child.attribute(SA("abspath"));
+ if (defval != SA(""))
+ {
+ if (abspath != SA("1"))
+ {
+ docs += SA("The default file is: <code>") + defval + SA("</code>.");
+ }
+ else
+ {
+ docs += SA("The default file (with absolute path) is: <code>") + defval + SA("</code>.");
+ }
+ }
+ else
+ {
+ if (abspath == SA("1"))
+ {
+ docs += SA("The file has to be specified with full path.");
+ }
+ }
+ }
+ else // if (child.attribute(SA("format")) == SA("string"))
+ {
+ if (defval != SA(""))
+ {
+ docs += SA("The default value is: <code>") + defval + SA("</code>.");
+ }
+ }
+ }
+
+ if (child.hasAttribute(SA("depends")))
+ {
+ QString dependsOn = child.attribute(SA("depends"));
+ docs += SA("<br/>");
+ docs+= SA("This tag requires that the tag \\ref cfg_");
+ docs+= dependsOn.toLower();
+ docs+= SA(" \"");
+ docs+= dependsOn.toUpper();
+ docs+= SA("\" is set to <code>YES</code>.");
+ }
+
+ // Remove / replace doxygen markup strings
+ // the regular expressions are hard to read so the intention will be given
+ QRegExp regexp;
+ // remove \n at end and replace by a space
+ regexp.setPattern(SA("\\n$"));
+ docs.replace(regexp,SA(" "));
+ // remove <br> at end
+ regexp.setPattern(SA("<br> *$"));
+ docs.replace(regexp,SA(" "));
+ // \c word -> <code>word</code>
+ regexp.setPattern(SA("\\\\c[ ]+([^ ]+) "));
+ docs.replace(regexp,SA("<code>\\1</code> "));
+ // `word` -> <code>word</code>
+ docs.replace(SA("``"),SA(""));
+ regexp.setPattern(SA("`([^`]+)`"));
+ docs.replace(regexp,SA("<code>\\1</code> "));
+ // \ref key "desc" -> <code>desc</code>
+ regexp.setPattern(SA("\\\\ref[ ]+[^ ]+[ ]+\"([^ ]+)\""));
+ docs.replace(regexp,SA("<code>\\1</code> "));
+ //\ref specials
+ // \ref <key> -> description
+ regexp.setPattern(SA("\\\\ref[ ]+doxygen_usage"));
+ docs.replace(regexp,SA("\"Doxygen usage\""));
+ regexp.setPattern(SA("\\\\ref[ ]+extsearch"));
+ docs.replace(regexp,SA("\"External Indexing and Searching\""));
+ regexp.setPattern(SA("\\\\ref[ ]+external"));
+ docs.replace(regexp,SA("\"Linking to external documentation\""));
+ // fallback for not handled
+ docs.replace(SA("\\\\ref"),SA(""));
+ // \b word -> <b>word<\b>
+ regexp.setPattern(SA("\\\\b[ ]+([^ ]+) "));
+ docs.replace(regexp,SA("<b>\\1</b> "));
+ // \e word -> <em>word<\em>
+ regexp.setPattern(SA("\\\\e[ ]+([^ ]+) "));
+ docs.replace(regexp,SA("<em>\\1</em> "));
+ // \note -> <br>Note:
+ // @note -> <br>Note:
+ docs.replace(SA("\\note"),SA("<br>Note:"));
+ docs.replace(SA("@note"),SA("<br>Note:"));
+ // \#include -> #include
+ // \#undef -> #undef
+ docs.replace(SA("\\#include"),SA("#include"));
+ docs.replace(SA("\\#undef"),SA("#undef"));
+ // -# -> <br>-
+ // " - " -> <br>-
+ docs.replace(SA("-#"),SA("<br>-"));
+ docs.replace(SA(" - "),SA("<br>-"));
+ // \verbatim -> <pre>
+ // \endverbatim -> </pre>
+ docs.replace(SA("\\verbatim"),SA("<pre>"));
+ docs.replace(SA("\\endverbatim"),SA("</pre>"));
+ // \sa -> <br>See also:
+ // \par -> <br>
+ docs.replace(SA("\\sa"),SA("<br>See also:"));
+ docs.replace(SA("\\par"),SA("<br>"));
+ // 2xbackslash -> backslash
+ // \@ -> @
+ docs.replace(SA("\\\\"),SA("\\"));
+ docs.replace(SA("\\@"),SA("@"));
+ // \& -> &
+ // \$ -> $
+ docs.replace(SA("\\&"),SA("&"));
+ docs.replace(SA("\\$"),SA("$"));
+ // \< -> &lt;
+ // \> -> &gt;
+ docs.replace(SA("\\<"),SA("&lt;"));
+ docs.replace(SA("\\>"),SA("&gt;"));
+ regexp.setPattern(SA(" (http:[^ \\)]*)([ \\)])"));
+ docs.replace(regexp,SA(" <a href=\"\\1\">\\1</a>\\2"));
+ // LaTeX name as formula -> LaTeX
+ regexp.setPattern(SA("\\\\f\\$\\\\mbox\\{\\\\LaTeX\\}\\\\f\\$"));
+ docs.replace(regexp,SA("LaTeX"));
+ // Other forula's (now just 2) so explicitely mentioned.
+ regexp.setPattern(SA("\\\\f\\$2\\^\\{\\(16\\+\\\\mbox\\{LOOKUP\\\\_CACHE\\\\_SIZE\\}\\)\\}\\\\f\\$"));
+ docs.replace(regexp,SA("2^(16+LOOKUP_CACHE_SIZE)"));
+ regexp.setPattern(SA("\\\\f\\$2\\^\\{16\\} = 65536\\\\f\\$"));
+ docs.replace(regexp,SA("2^16=65536"));
+
+ return docs.trimmed();
+}
QWidget *Expert::createTopicWidget(QDomElement &elem)
{
@@ -125,6 +409,7 @@ QWidget *Expert::createTopicWidget(QDomElement &elem)
if (setting.isEmpty() || IS_SUPPORTED(setting.toAscii()))
{
QString type = child.attribute(SA("type"));
+ QString docs = getDocsForNode(child);
if (type==SA("bool"))
{
InputBool *boolOption =
@@ -132,7 +417,7 @@ QWidget *Expert::createTopicWidget(QDomElement &elem)
layout,row,
child.attribute(SA("id")),
child.attribute(SA("defval"))==SA("1"),
- child.attribute(SA("docs"))
+ docs
);
m_options.insert(
child.attribute(SA("id")),
@@ -163,7 +448,7 @@ QWidget *Expert::createTopicWidget(QDomElement &elem)
child.attribute(SA("id")),
child.attribute(SA("defval")),
mode,
- child.attribute(SA("docs")),
+ docs,
child.attribute(SA("abspath"))
);
m_options.insert(
@@ -180,12 +465,15 @@ QWidget *Expert::createTopicWidget(QDomElement &elem)
child.attribute(SA("id")),
child.attribute(SA("defval")),
InputString::StringFixed,
- child.attribute(SA("docs"))
+ docs
);
QDomElement enumVal = child.firstChildElement();
while (!enumVal.isNull())
{
- enumList->addValue(enumVal.attribute(SA("name")));
+ if (enumVal.tagName()==SA("value"))
+ {
+ enumList->addValue(enumVal.attribute(SA("name")));
+ }
enumVal = enumVal.nextSiblingElement();
}
enumList->setDefault();
@@ -203,7 +491,7 @@ QWidget *Expert::createTopicWidget(QDomElement &elem)
child.attribute(SA("defval")).toInt(),
child.attribute(SA("minval")).toInt(),
child.attribute(SA("maxval")).toInt(),
- child.attribute(SA("docs"))
+ docs
);
m_options.insert(
child.attribute(SA("id")),
@@ -236,7 +524,10 @@ QWidget *Expert::createTopicWidget(QDomElement &elem)
QDomElement listVal = child.firstChildElement();
while (!listVal.isNull())
{
- sl.append(listVal.attribute(SA("name")));
+ if (listVal.tagName()==SA("value"))
+ {
+ sl.append(listVal.attribute(SA("name")));
+ }
listVal = listVal.nextSiblingElement();
}
InputStrList *listOption =
@@ -245,7 +536,7 @@ QWidget *Expert::createTopicWidget(QDomElement &elem)
child.attribute(SA("id")),
sl,
mode,
- child.attribute(SA("docs"))
+ docs
);
m_options.insert(
child.attribute(SA("id")),
@@ -366,55 +657,51 @@ void Expert::loadConfig(const QString &fileName)
void Expert::saveTopic(QTextStream &t,QDomElement &elem,QTextCodec *codec,
bool brief)
{
- // write group header
- t << endl;
+ if (!brief)
+ {
+ t << endl;
+ }
t << "#---------------------------------------------------------------------------" << endl;
t << "# " << elem.attribute(SA("docs")) << endl;
t << "#---------------------------------------------------------------------------" << endl;
-
// write options...
QDomElement childElem = elem.firstChildElement();
while (!childElem.isNull())
{
+ QString setting = childElem.attribute(SA("setting"));
QString type = childElem.attribute(SA("type"));
QString name = childElem.attribute(SA("id"));
- QHash<QString,Input*>::const_iterator i = m_options.find(name);
- if (i!=m_options.end())
+ if (setting.isEmpty() || IS_SUPPORTED(setting.toAscii()))
{
- Input *option = i.value();
- if (!brief)
+ QHash<QString,Input*>::const_iterator i = m_options.find(name);
+ if (i!=m_options.end())
{
- t << endl;
- t << convertToComment(childElem.attribute(SA("docs")));
+ Input *option = i.value();
+ if (option && !brief)
+ {
+ t << endl;
+ t << convertToComment(option->templateDocs());
+ t << endl;
+ }
+ t << name.leftJustified(23) << "= ";
+ if (option)
+ {
+ option->writeValue(t,codec);
+ }
t << endl;
}
- t << name.leftJustified(23) << "= ";
- if (option)
- {
- option->writeValue(t,codec);
- }
- t << endl;
}
childElem = childElem.nextSiblingElement();
}
-
}
bool Expert::writeConfig(QTextStream &t,bool brief)
{
+ // write global header
+ t << "# Doxyfile " << versionString << endl << endl;
if (!brief)
{
- // write global header
- t << "# Doxyfile " << versionString << endl << endl; // TODO: add version
- t << "# This file describes the settings to be used by the documentation system\n";
- t << "# doxygen (www.doxygen.org) for a project\n";
- t << "#\n";
- t << "# All text after a hash (#) is considered a comment and will be ignored\n";
- t << "# The format is:\n";
- t << "# TAG = value [value, ...]\n";
- t << "# For lists items can also be appended using:\n";
- t << "# TAG += value [value, ...]\n";
- t << "# Values that contain spaces should be placed between quotes (\" \")\n";
+ t << convertToComment(m_header);
}
QTextCodec *codec = 0;
@@ -430,7 +717,10 @@ bool Expert::writeConfig(QTextStream &t,bool brief)
QDomElement childElem = m_rootElement.firstChildElement();
while (!childElem.isNull())
{
- saveTopic(t,childElem,codec,brief);
+ if (childElem.tagName()==SA("group"))
+ {
+ saveTopic(t,childElem,codec,brief);
+ }
childElem = childElem.nextSiblingElement();
}
return true;