diff options
author | Dimitri van Heesch <dimitri@stack.nl> | 2009-07-20 20:05:52 (GMT) |
---|---|---|
committer | Dimitri van Heesch <dimitri@stack.nl> | 2009-07-20 20:05:52 (GMT) |
commit | 142b4807d2ae7479691bd0800d28364b9857b82f (patch) | |
tree | b8b0cb3ac894bdb88087d78e328a8a0d88943b97 | |
parent | b70a5b4f9325ec703db37394feeaa9ebc11228b4 (diff) | |
download | Doxygen-142b4807d2ae7479691bd0800d28364b9857b82f.zip Doxygen-142b4807d2ae7479691bd0800d28364b9857b82f.tar.gz Doxygen-142b4807d2ae7479691bd0800d28364b9857b82f.tar.bz2 |
Release-1.5.9-20090720
36 files changed, 2072 insertions, 380 deletions
@@ -1,7 +1,7 @@ -DOXYGEN Version 1.5.9-20090622 +DOXYGEN Version 1.5.9-20090720 Please read the installation section of the manual (http://www.doxygen.org/install.html) for instructions. -------- -Dimitri van Heesch (22 June 2009) +Dimitri van Heesch (20 July 2009) @@ -1,4 +1,4 @@ -DOXYGEN Version 1.5.9_20090622 +DOXYGEN Version 1.5.9_20090720 Please read INSTALL for compilation instructions. @@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives. Enjoy, -Dimitri van Heesch (dimitri@stack.nl) (22 June 2009) +Dimitri van Heesch (dimitri@stack.nl) (20 July 2009) diff --git a/addon/doxywizard/Makefile.in b/addon/doxywizard/Makefile.in index fa459c2..75a3a6d 100644 --- a/addon/doxywizard/Makefile.in +++ b/addon/doxywizard/Makefile.in @@ -10,16 +10,16 @@ # See the GNU General Public License for more details. # -QMAKE = qmake +QMAKE=qmake all: Makefile.doxywizard $(MAKE) -f Makefile.doxywizard Makefile.doxywizard: doxywizard.pro - $(QTDIR)/bin/qmake doxywizard.pro -o Makefile.doxywizard + $(QMAKE) doxywizard.pro -o Makefile.doxywizard qmake: - $(QTDIR)/bin/qmake doxywizard.pro -o Makefile.doxywizard + $(QMAKE) doxywizard.pro -o Makefile.doxywizard clean: Makefile.doxywizard $(MAKE) -f Makefile.doxywizard clean @@ -20,7 +20,7 @@ doxygen_version_minor=5 doxygen_version_revision=9 #NOTE: Setting version_mmn to "NO" will omit mmn info from the package. -doxygen_version_mmn=20090622 +doxygen_version_mmn=20090720 bin_dirs=`echo $PATH | sed -e "s/:/ /g"` diff --git a/doc/config.doc b/doc/config.doc index 7f9fe92..4679a4c 100644 --- a/doc/config.doc +++ b/doc/config.doc @@ -1431,6 +1431,26 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" If non-empty doxygen will try to run qhelpgenerator on the generated .qhp file. +\anchor cfg_searchengine +<dt>\c SEARCHENGINE <dd> + \addindex SEARCHENGINE + The \c SEARCHENGINE tag specifies whether or not the HTML output should + contain a search function. Possible values are \c YES and \c NO. + If set to YES, doxygen will produce a search index, and a search box at + the top of each page (or in the side bar in case GENERATE_TREE is enabled). + The search engine is implemented using javascript and DHTML and should + work on any modern browser. + + It is possible to search using the keyboard; + to jump to the search box use access key + S (what the access key is + depends on the OS and browser, but it is typically CTRL, ALT/option, or both). + Inside the search box use the cursor down key to jump into the search + results window, the results can be navigated using the cursor keys. + Press Enter to select an item or escape to cancel the search. The + filter options can be selected when the cursor is inside the search box + by pressing Shift+cursor down. Also here use the cursor keys to + select a filter and enter or escape to activate or cancel the filter option. + <!-- \anchor cfg_qthelp_file <dt>\c QTHELP_FILE <dd> @@ -1488,7 +1508,7 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" the \ref cfg_project_name "project name". \anchor cfg_use_inline_trees -<dt>\c USE_INLINE_TREES +<dt>\c USE_INLINE_TREES <dd> \addindex USE_INLINE_TREES By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, and Class Hierarchy pages using a tree view instead of an ordered list. @@ -2179,21 +2199,6 @@ remove the intermediate dot files that are used to generate the various graphs. </dl> -\section config_search Search engine options -\anchor cfg_searchengine -<dl> - -<dt>\c SEARCHENGINE <dd> - \addindex SEARCHENGINE - The \c SEARCHENGINE tag specifies whether or not the HTML output should - contain a search facility. Possible values are \c YES and \c NO. - If set to YES, doxygen will produce a search index and a PHP script - to search through the index. For this to work the documentation should - be viewed via a web-server running PHP version 4.1.0 or higher. - (See http://www.php.net/manual/en/installation.php for installation - instructions). - -</dl> <h2>Examples</h2> Suppose you have a simple project consisting of two files: a source file diff --git a/doc/dbusxml.doc b/doc/dbusxml.doc new file mode 100644 index 0000000..a8710cb --- /dev/null +++ b/doc/dbusxml.doc @@ -0,0 +1,141 @@ +/*! \page dbusxml DBus XML output format + +\addindex dbusxml + +<p>Doxygen can generate documentation for DBus XML files. This way +DBus interfaces can be annotated with doxygen style comments, and +without writing custom XML parsers. Doxygen extracts its text from +all XML comments starting with '*' or '!'. An additional '<' can be +used to assign the documentation string to the previous entity instead +of the one following the comment. + +\section dbusxml_supported Supported XML elements and attributes + +<p>The following DBus XML elemets can be annotated: + +<ul> +<li><b>interface</b> + +<li><b>method</b> or <b>signal</b> + +<li><b>arg</b> + +<li><b>property</b> + +</ul> + +Additional elements are supported. These are available once +the xmlns "http://psiamp.org/dtd/doxygen_dbusxml.dtd" is +available. + +<ul> +<li><b>namespace</b>: This can be used to group other more of the +additional elemets. This element requires a <b>name</b> attribute. + +<li><b>enum</b> is used to define enums. <b>value</b> element is + then used to define the individual values in the enum. This element + requires the <b>name</b> and <b>type</b> attributes. A + optional <b>named-type</b> attribute is allowed, referrencing typed + previously defined by one of the additional elements. A enum name + can be used anywhere a type is required using the <b>named-type</b> + attribute. + +<li><b>flagset</b> is used to define sets of flags. Required and + optional attributes are identical to the ones used by <b>enum</b>. + While <b>enum</b>s assume the values to be consecutive, while + a <b>flagset</b> is values suitable for flags. A flagset name + can be used anywhere a type is required using the <b>named-type</b> + attribute. + +<li><b>struct</b> is used to define structures. A <b>name</b> + attribute is required. + +<li><b>member</b> is used to define members of <b>structs</b>. It + is valid inside <b>struct</b> elements. This + element requires <b>name</b> and <b>type</b> attributes. In + addition to (or even instead of) the <b>type</b> attribute a + <b>named-type</b> attribute may be used to reference types defined + by <b>enum</b>, <b>flagset</b> or <b>struct</b>. + +\section dbusxml_example Example + +<pre> +<?xml version="1.0" ?> +<!-- Comment --> +<!--*< File comment --> +<node name="/SomeNode" xmlns:dx="http://psiamp.org/dtd/doxygen_dbusxml.dtd"> + <!--* test struct outside a namespace and interface --> + <dx:struct name="StructOutsideNamespace"> + <!--* member 1 --> + <dx:member name="member1" type="s"/> + <!--* complex member 1 --> + <dx:member name="complexMember1" type="(ssu)"/> + </dx:struct> + + <!--* Test flag set --> + <dx:flagset name="flagset"> + <!--* Flag 1 of flagset. --> + <dx:value name="FLAG1"/> + </dx:flagset> + + <!--* namespace comment --> + <dx:namespace name="SomeNamespace"> + <!--* struct inside a namespace --> + <dx:struct name="StructInNamespace"> + <!--* member 2 --> + <dx:member name="member2" type="s"/> + </dx:struct> + </dx:namespace> + <!--* Documentation on the interface --> + <interface name="nl.stack.doxygen.test.interface"> + <!--* Test Enum documentation --> + <dx:enum name="TestEnum"> + <!--* key 1 with value 13 --> + <dx:value name="KEY1" value="13"/> + <!--* key 2 without a value --> + <dx:value name="KEY2"/> + </dx:enum> + + <!--* struct inside a interface --> + <dx:struct name="StructInInterface"> + <!--* member 3 --> + <dx:member name="member3" type="s"/> + <!--* Struct in a struct --> + <dx:struct name="StructInAStruct"> + <!--* member4 --> + <dx:member name="member4" type="s"/> + </dx:struct> + <!--* struct member --> + <dx:member name="structMembor" type="(s)" named-type="StructInAStruct"/> + </dx:struct> + <!--* Document method + + Some extended documentation for the method. + + @param[in] input blah. + @param[out] output blub + --> + <method name="method"> + <arg direction="in" name="input" type="(s(s))" named-type="::nl::stack::doxygen::test::interface::StructInInterface"/> + <arg direction="out" type="v" name="output"/> + </method> + + <signal name="signal"> + <!--*< Documentation for signal. + + @param parameter some parameter. + --> + <arg name="parameter" type="s"/> + </signal> + + <!--* property documentation --> + <property name="property" type="s" access="readwrite"/> + + <!--* property documentation read-only --> + <property name="propertyRead" type="s" access="read"/> + <!--* property documentation write-only --> + <property name="propertyWrite" type="s" access="write"/> + </interface> +</node> +</pre> +*/ diff --git a/doc/installdox_usage.doc b/doc/installdox_usage.doc index 59057b1..b1415a5 100644 --- a/doc/installdox_usage.doc +++ b/doc/installdox_usage.doc @@ -18,14 +18,11 @@ Installdox is a perl script that is generated by doxygen whenever tag files are used (See \c TAGFILES -in section \ref config_extref) -or the search engine is enabled (See \c SEARCHENGINE -in section \ref config_search). The script is +in section \ref config_extref). The script is located in the same directory where the HTML files are located. Its purpose is to set the location of the external documentation -for each tag file and to set the correct links to the search engine -at install time. +for each tag file at install time. Calling \c installdox with option <b>-h</b> at the command line will give you a brief description of the usage of the program. diff --git a/doc/starting.doc b/doc/starting.doc index 29ebc39..8e3e0d2 100644 --- a/doc/starting.doc +++ b/doc/starting.doc @@ -157,12 +157,8 @@ a browser that supports cascading style sheets (CSS) should be used generated output). Some of the features the HTML section (such as -\ref cfg_generate_treeview "GENERATE_TREEVIEW") require a browser that -supports DHTML and Javascript. - -If you plan to use the search engine (see -\ref cfg_searchengine "SEARCHENGINE"), you should view the HTML output -via a PHP-enabled web server (e.g. apache with the PHP module installed). +\ref cfg_generate_treeview "GENERATE_TREEVIEW" or the search engine) +require a browser that supports DHTML and Javascript. \subsection latex_out LaTeX output \addindex LaTeX diff --git a/examples/dbusxml.cfg b/examples/dbusxml.cfg new file mode 100644 index 0000000..3620a4a --- /dev/null +++ b/examples/dbusxml.cfg @@ -0,0 +1,10 @@ +PROJECT_NAME = "DBusXMLDocs" +OUTPUT_DIRECTORY = dbusxml +GENERATE_LATEX = NO +GENERATE_MAN = NO +GENERATE_RTF = NO +CASE_SENSE_NAMES = NO +INPUT = dbusxml.xml +QUIET = YES +JAVADOC_AUTOBRIEF = YES +EXTRACT_ALL = YES diff --git a/examples/dbusxml.xml b/examples/dbusxml.xml new file mode 100644 index 0000000..4ab7f78 --- /dev/null +++ b/examples/dbusxml.xml @@ -0,0 +1,78 @@ +<?xml version="1.0" ?> +<!-- Comment --> +<!--*< File comment --> +<node name="/SomeNode" xmlns:dx="http://psiamp.org/dtd/doxygen_dbusxml.dtd"> + <!--* test struct outside a namespace and interface --> + <dx:struct name="StructOutsideNamespace"> + <!--* member 1 --> + <dx:member name="member1" type="s"/> + <!--* complex member 1 --> + <dx:member name="complexMember1" type="(ssu)"/> + </dx:struct> + + <!--* Test flag set --> + <dx:flagset name="flagset"> + <!--* Flag 1 of flagset. --> + <dx:value name="FLAG1"/> + </dx:flagset> + + <!--* namespace comment --> + <dx:namespace name="SomeNamespace"> + <!--* struct inside a namespace --> + <dx:struct name="StructInNamespace"> + <!--* member 2 --> + <dx:member name="member2" type="s"/> + </dx:struct> + </dx:namespace> + <!--* Documentation on the interface --> + <interface name="nl.stack.doxygen.test.interface"> + <!--* Test Enum documentation --> + <dx:enum name="TestEnum"> + <!--* key 1 with value 13 --> + <dx:value name="KEY1" value="13"/> + <!--* key 2 without a value --> + <dx:value name="KEY2"/> + </dx:enum> + + <!--* struct inside a interface --> + <dx:struct name="StructInInterface"> + <!--* member 3 --> + <dx:member name="member3" type="s"/> + <!--* Struct in a struct --> + <dx:struct name="StructInAStruct"> + <!--* member4 --> + <dx:member name="member4" type="s"/> + </dx:struct> + <!--* struct member --> + <dx:member name="structMembor" type="(s)" named-type="StructInAStruct"/> + </dx:struct> + <!--* Document method + + Some extended documentation for the method. + + @param[in] input blah. + @param[out] output blub + --> + <method name="method"> + <arg direction="in" name="input" type="(s(s))" named-type="::nl::stack::doxygen::test::interface::StructInInterface"/> + <arg direction="out" type="v" name="output"/> + </method> + + <signal name="signal"> + <!--*< Documentation for signal. + + @param parameter some parameter. + --> + <arg name="parameter" type="s"/> + </signal> + + <!--* property documentation --> + <property name="property" type="s" access="readwrite"/> + + <!--* property documentation read-only --> + <property name="propertyRead" type="s" access="read"/> + <!--* property documentation write-only --> + <property name="propertyWrite" type="s" access="write"/> + </interface> +</node> +<!-- vim:set sw=2 sts=2 et ft=xml: --> diff --git a/qtools/Doxyfile b/qtools/Doxyfile index 3ee0cd3..21e3bd0 100644 --- a/qtools/Doxyfile +++ b/qtools/Doxyfile @@ -149,14 +149,15 @@ QHP_SECT_FILTER_ATTRS = QHG_LOCATION = DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = YES +GENERATE_TREEVIEW = NO USE_INLINE_TREES = NO TREEVIEW_WIDTH = 250 FORMULA_FONTSIZE = 10 +SEARCHENGINE = YES #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- -GENERATE_LATEX = NO +GENERATE_LATEX = YES LATEX_OUTPUT = LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex @@ -164,11 +165,11 @@ COMPACT_LATEX = NO PAPER_TYPE = a4wide EXTRA_PACKAGES = LATEX_HEADER = -PDF_HYPERLINKS = NO -USE_PDFLATEX = NO +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO -LATEX_SOURCE_CODE = NO +LATEX_SOURCE_CODE = YES #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- @@ -254,7 +255,3 @@ DOT_TRANSPARENT = YES DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES -#--------------------------------------------------------------------------- -# Options related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = YES diff --git a/src/commentcnv.l b/src/commentcnv.l index 33d0c04..c18605d 100644 --- a/src/commentcnv.l +++ b/src/commentcnv.l @@ -348,7 +348,7 @@ void replaceComment(int offset); copyToOutput(yytext,yyleng); BEGIN(CComment); } -<Scan>"##" { +<Scan>"#"("#")? { if (g_lang!=SrcLangExt_Python) { REJECT; diff --git a/src/config.xml b/src/config.xml index 882c96b..55d809d 100644 --- a/src/config.xml +++ b/src/config.xml @@ -898,6 +898,14 @@ when you change the font size after a successful doxygen run you need to manually remove any form_*.png images from the HTML output directory to force them to be regenerated. ' minval='8' maxval='50' defval='10' depends='GENERATE_HTML'/> + <option type='bool' id='SEARCHENGINE' docs=' +When the SEARCHENGINE tag is enable doxygen will generate a search box +for the HTML output. The underlying search engine uses javascript +and DHTML and should work on any modern browser. Note that when using +HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP) +there is already a search function so this one should typically +be disabled. +' defval='1' depends='GENERATE_HTML'/> </group> <group name='LaTeX' docs='configuration options related to the LaTeX output'> <option type='bool' id='GENERATE_LATEX' docs=' @@ -1358,12 +1366,6 @@ If the DOT_CLEANUP tag is set to YES (the default) Doxygen will remove the intermediate dot files that are used to generate the various graphs. ' defval='1' depends='HAVE_DOT'/> - </group> - <group name='Search' docs='Options related to the search engine'> - <option type='bool' id='SEARCHENGINE' docs=' -The SEARCHENGINE tag specifies whether or not a search engine should be -used. If set to NO the values of all tags below this one will be ignored. -' defval='0'/> <option type='obsolete' id='SHOW_USED_FILES'/> <option type='obsolete' id='USE_WINDOWS_ENCODING'/> <option type='obsolete' id='DETAILS_AT_TOP'/> diff --git a/src/configoptions.cpp b/src/configoptions.cpp index bea89b6..d87fb24 100644 --- a/src/configoptions.cpp +++ b/src/configoptions.cpp @@ -1323,6 +1323,16 @@ void addConfigOptions(Config *cfg) 8,50,10 ); ci->addDependency("GENERATE_HTML"); + //---- + cb = cfg->addBool( + "SEARCHENGINE", + "When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript \n" + "and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP) \n" + "there is already a search function so this one should typically \n" + "be disabled.", + TRUE + ); + cb->addDependency("GENERATE_HTML"); //--------------------------------------------------------------------------- cfg->addInfo("LaTeX","configuration options related to the LaTeX output"); //--------------------------------------------------------------------------- @@ -2072,17 +2082,6 @@ void addConfigOptions(Config *cfg) TRUE ); cb->addDependency("HAVE_DOT"); - //--------------------------------------------------------------------------- - cfg->addInfo("Search","Options related to the search engine"); - //--------------------------------------------------------------------------- - - //---- - cb = cfg->addBool( - "SEARCHENGINE", - "The SEARCHENGINE tag specifies whether or not a search engine should be \n" - "used. If set to NO the values of all tags below this one will be ignored.", - FALSE - ); //---- cfg->addObsolete("SHOW_USED_FILES"); //---- diff --git a/src/dbusxmlscanner.cpp b/src/dbusxmlscanner.cpp new file mode 100644 index 0000000..8a07d81 --- /dev/null +++ b/src/dbusxmlscanner.cpp @@ -0,0 +1,874 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 2009 by Tobias Hunger <tobias@aquazul.com> + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#include "dbusxmlscanner.h" + +#include "commentscan.h" +#include "entry.h" + +#include <qfile.h> +#include <qxml.h> +#include <qstring.h> + +#include "message.h" +#include "util.h" + +// ----------------------------------------------------------------------- +// Convenience defines: +// ----------------------------------------------------------------------- + +#define CONDITION(cond, msg) \ + do {\ + if (cond)\ + {\ + if (m_errorString.isEmpty()) { m_errorString = msg; }\ + return false;\ + }\ + }\ + while (0) + +#define DOC_ERROR(msg) \ + warn_doc_error(m_fileName.utf8().data(), lineNumber(), msg.utf8().data()) + +#define COND_DOC_ERROR(cond, msg) \ + do {\ + if (cond)\ + {\ + DOC_ERROR(msg);\ + return true;\ + }\ + }\ + while (0) + +#define DBUS(name) isDBusElement(namespaceURI, localName, qName, name) +#define EXTENSION(name) isExtensionElement(namespaceURI, localName, qName, name) + +// ----------------------------------------------------------------------- +// DBusXMLHandler class +// ----------------------------------------------------------------------- + +const QString EXTENSION_URI("http://psiamp.org/dtd/doxygen_dbusxml.dtd"); + +class DBusXMLHandler : public QXmlDefaultHandler +{ +public: + DBusXMLHandler(ParserInterface * parser, + QXmlSimpleReader * reader, + const char * file_name, + Entry * root) : + m_parser(parser), + m_locator(reader), + m_currentEntry(0), + m_currentInterface(0), + m_currentMethod(0), + m_currentArgument(0), + m_currentProperty(0), + m_currentEnum(0), + m_fileName(file_name), + m_currentComment(0) + { + setDocumentLocator(&m_locator); + + m_scopeCount = 0; + + // Set up stack cleanup: + m_structStack.setAutoDelete(TRUE); + m_elementStack.setAutoDelete(TRUE); + m_scopeStack.setAutoDelete(TRUE); + + openScopes(root); + } + + ~DBusXMLHandler() + { closeScopes(); } + + QString errorString() + { return m_errorString; } + + bool startElement(const QString &namespaceURI, + const QString &localName, + const QString &qName, + const QXmlAttributes &attributes) + { + // add to elements stack: + m_elementStack.append(new ElementData(qName)); + + // First we need a node. + if (DBUS("node")) + { + CONDITION(!m_currentNode.isEmpty(), "Node inside a node."); + + const int idx(indexOf(attributes, "name")); + COND_DOC_ERROR(idx < 0, QString("Anonymous node found.")); + + m_currentNode = attributes.value(idx); + // A node is actually of little interest, so do nothing here. + return true; + } + + // Then we need an interface. + if (DBUS("interface")) + { + // We need a nodeName for interfaces: + CONDITION(m_currentNode.isEmpty(), "Interface without a node."); + CONDITION(m_currentInterface, "Interface within another interface."); + + const int idx(indexOf(attributes, "name")); + COND_DOC_ERROR(idx < 0, QString("Interface without a name found.")); + + // A interface is roughly equivalent to a class: + m_currentInterface = createEntry(); + + m_currentInterface->section = Entry::CLASS_SEC; + m_currentInterface->spec |= Entry::Interface; + m_currentInterface->type = "Interface"; + m_currentInterface->name = substitute(attributes.value(idx), ".", "::"); + + openScopes(m_currentInterface); + + return true; + } + + if (DBUS("method") || DBUS("signal")) + { + // We need a interfaceName for methods and signals: + CONDITION(!m_currentInterface, "Method or signal found outside a interface."); + CONDITION(m_currentMethod, "Method or signal found inside another method or signal."); + CONDITION(m_currentProperty, "Methor or signal found inside a property."); + CONDITION(!m_structStack.isEmpty(), "Method or signal found inside a struct."); + CONDITION(m_currentEnum, "Methor or signal found inside a enum."); + + const int idx(indexOf(attributes, "name")); + COND_DOC_ERROR(idx < 0, QString("Method or signal without a name found.")); + + m_currentMethod = createEntry(); + + m_currentMethod->section = Entry::FUNCTION_SEC; + m_currentMethod->name = attributes.value(idx); + m_currentMethod->mtype = Method; + m_currentMethod->type = "void"; + + if (DBUS("signal")) + { m_currentMethod->mtype = Signal; } + } + + if (DBUS("arg")) + { + // We need a method for arguments: + CONDITION(!m_currentMethod, "Argument found outside a method or signal."); + CONDITION(m_currentArgument, "Argument found inside another argument."); + + const int name_idx(indexOf(attributes, "name")); + COND_DOC_ERROR(name_idx < 0, QString("Argument without a name found.")); + COND_DOC_ERROR(!hasType(attributes), QString("Argument without a type found.")); + + const int direction_idx(indexOf(attributes, "direction")); + + if ((m_currentMethod->mtype == Signal && + direction_idx >= 0 && + attributes.value(direction_idx) != "in") || + (m_currentMethod->mtype == Method && + direction_idx >= 0 && + attributes.value(direction_idx) != "in" && + attributes.value(direction_idx) != "out")) + { + m_errorString = "Invalid direction found."; + return false; + } + + m_currentArgument = new Argument; + m_currentArgument->type = getType(attributes); + m_currentArgument->name = attributes.value(name_idx); + if (direction_idx >= 0) + { m_currentArgument->attrib = attributes.value(direction_idx); } + else + { + if (m_currentMethod->mtype == Signal) + { m_currentArgument->attrib = "in"; } + else + { m_currentArgument->attrib = "out"; } + } + } + + if (DBUS("property")) + { + CONDITION(m_currentMethod, "Property found inside a method or signal."); + CONDITION(!m_currentInterface, "Property found outside an interface."); + CONDITION(m_currentProperty, "Property found inside another property."); + CONDITION(!m_structStack.isEmpty(), "Property found inside a struct."); + CONDITION(m_currentEnum, "Property found inside a enum."); + + const int name_idx(indexOf(attributes, "name")); + COND_DOC_ERROR(name_idx < 0, QString("Anonymous property found.")); + COND_DOC_ERROR(!hasType(attributes), QString("Property without a type found.")); + + const int access_idx(indexOf(attributes, "access")); + COND_DOC_ERROR(access_idx < 0, QString("Property without a access attribute found.")); + COND_DOC_ERROR(attributes.value(access_idx) != "read" && + attributes.value(access_idx) != "write" && + attributes.value(access_idx) != "readwrite", + QString("Property with invalid access attribute \"%1\" found."). + arg(attributes.value(access_idx))); + + m_currentProperty = createEntry(); + + m_currentProperty->section = Entry::FUNCTION_SEC; + + if (attributes.value(access_idx) == "read" || + attributes.value(access_idx) == "readwrite") + { m_currentProperty->spec |= Entry::Readable; } + + if (attributes.value(access_idx) == "write" || + attributes.value(access_idx) == "readwrite") + { m_currentProperty->spec |= Entry::Writable; } + + m_currentProperty->name = attributes.value(name_idx); + m_currentProperty->mtype = Property; + m_currentProperty->type = getType(attributes); + } + + if (EXTENSION("namespace")) + { + CONDITION(m_currentNode.isEmpty(), "Namespace found outside a node."); + CONDITION(m_currentInterface, "Namespace found inside an interface."); + + const int idx(indexOf(attributes, "name")); + COND_DOC_ERROR(idx < 0, QString("Anonymous namespace found.")); + + m_namespaceStack.append(openNamespace(attributes.value(idx))); + openScopes(m_namespaceStack.last()); + } + + if (EXTENSION("struct")) + { + CONDITION(m_currentMethod, "Struct found inside a method or signal."); + CONDITION(m_currentProperty, "Struct found inside a property."); + CONDITION(m_currentEnum, "Struct found inside an enum."); + + const int idx(indexOf(attributes, "name")); + COND_DOC_ERROR(idx < 0, QString("Anonymous struct found.")); + + Entry * current_struct = createEntry(); + current_struct->section = Entry::CLASS_SEC; + current_struct->spec = Entry::Struct; + current_struct->name = attributes.value(idx); + + openScopes(current_struct); + + current_struct->type = current_struct->name + " struct"; + + m_structStack.append(new StructData(current_struct)); + } + + if (EXTENSION("member")) + { + CONDITION(m_structStack.isEmpty(), "Member found outside of struct."); + + const int name_idx(indexOf(attributes, "name")); + COND_DOC_ERROR(name_idx < 0, QString("Anonymous member found.")); + COND_DOC_ERROR(!hasType(attributes), QString("Member without a type found.")); + + createEntry(); + + m_currentEntry->section = Entry::VARIABLE_SEC; + m_currentEntry->name = attributes.value(name_idx); + m_currentEntry->type = getType(attributes); + + QString type(getDBusType(m_currentEntry->type)); + m_structStack.last()->type.append(type); + } + + if (EXTENSION("enum") || EXTENSION("flagset")) + { + CONDITION(m_currentMethod, "Enum found inside a method or signal."); + CONDITION(m_currentProperty, "Enum found inside a property."); + + const int name_idx(indexOf(attributes, "name")); + COND_DOC_ERROR(name_idx < 0, QString("Anonymous enum found.")); + + const int type_idx(indexOf(attributes, "type")); + QString type = "u"; + if (type_idx >= 0) + { type = attributes.value(type_idx); } + if (type != "y" && type != "q" && type != "u" && type != "t") + { DOC_ERROR(QString("Invalid enum type \"%1\" found.").arg(type)); } + + m_currentEnum = createEntry(); + m_currentEnum->section = Entry::ENUM_SEC; + m_currentEnum->name = attributes.value(name_idx); + + openScopes(m_currentEnum); + + m_currentEnum->type = m_currentEntry->name + " enum"; + + addNamedType(type); + } + + if (EXTENSION("value")) + { + CONDITION(!m_currentEnum, "Value found outside an enum."); + + const int name_idx(indexOf(attributes, "name")); + COND_DOC_ERROR(name_idx < 0, QString("Anonymous value found.")); + + const int value_idx(indexOf(attributes, "value")); + + createEntry(); + + m_currentEntry->section = Entry::VARIABLE_SEC; + m_currentEntry->name = attributes.value(name_idx); + m_currentEntry->type = m_currentEnum->name; // "@"; // enum marker! + if (value_idx >= 0) + { m_currentEntry->initializer = attributes.value(value_idx); } + } + + return true; + } + + bool endElement(const QString &namespaceURI, + const QString &localName, + const QString &qName) + { + // Clean up elements stack: + // Since we made sure to get the elements in the proper order when + // adding we do not need to do so again here. + COND_DOC_ERROR(m_elementStack.last()->element != qName, + QString("Malformed XML: Unexpected closing element found."). + arg(m_elementStack.last()->element)); + m_elementStack.removeLast(); + + // Interface: + if (DBUS("interface")) + { + m_currentInterface->endBodyLine = lineNumber(); + closeScopes(); + m_currentInterface = 0; + } + + if (DBUS("method") || DBUS("signal")) + { + m_currentMethod->endBodyLine = lineNumber(); + m_currentInterface->addSubEntry(m_currentMethod); + m_currentMethod = 0; + } + + if (DBUS("property")) + { + m_currentProperty->endBodyLine = lineNumber(); + m_currentInterface->addSubEntry(m_currentProperty); + m_currentProperty = 0; + } + + if (DBUS("arg")) + { + m_currentMethod->argList->append(m_currentArgument); + m_currentArgument = 0; + } + + if (EXTENSION("namespace")) + { + Entry * current = m_namespaceStack.last(); + m_namespaceStack.removeLast(); + + current->endBodyLine = lineNumber(); + closeScopes(); + } + + if (EXTENSION("struct")) + { + StructData * data = m_structStack.last(); + + data->entry->endBodyLine = lineNumber(); + + QString current_type; + current_type.append(QString("(")); + current_type.append(data->type); + current_type.append(QString(")")); + + addNamedType(current_type); + + closeScopes(); + + m_structStack.removeLast(); + } + + if (EXTENSION("member")) + { + m_structStack.last()->entry->addSubEntry(m_currentEntry); + } + + if (EXTENSION("enum") || EXTENSION("flagset")) + { + m_currentEnum->endBodyLine = lineNumber(); + closeScopes(); + + m_currentEnum = 0; + } + + if (EXTENSION("value")) + { + m_currentEntry->endBodyLine = lineNumber(); + + m_currentEnum->addSubEntry(m_currentEntry); + } + + return true; + } + + bool characters(const QString & /*chars*/) + { return true; } + + bool comment(const QString & comment_) + { + if (m_currentComment) + { handleComment(); } + + m_currentComment = new CommentData(m_fileName, lineNumber(), comment_); + + if (!m_currentComment->shouldIgnore) + { + delete m_currentComment; + m_currentComment = 0; + return true; + } + + if (m_currentComment->associateWithPrevious) + { handleComment(); } + + return true; + } + + void handleComment() + { + if (m_currentComment == 0 || m_currentEntry == 0) + { return; } + + QCString text(m_currentComment->text); + + m_currentEntry->docFile = m_currentComment->fileName; + m_currentEntry->docLine = m_currentComment->line; + + int position(0); + bool needs_entry(false); + bool brief(false); + Protection prot(Public); + + while (parseCommentBlock(m_parser, + m_currentEntry, + text, m_fileName.utf8().data(), lineNumber(), + brief, m_currentComment->isJavaStyle, + false, + prot, + position, + needs_entry)) + { + if (needs_entry) { createEntry(); } + } + if (needs_entry) { createEntry(); } + + delete m_currentComment; + m_currentComment = 0; + } + + QXmlLocator * locator() + { return &m_locator; } + + int lineNumber() + { return m_locator.lineNumber(); } + + void setSection() + { + Entry * current = createEntry(); + current->reset(); + + current->name = m_fileName.utf8(); + current->section = Entry::SOURCE_SEC; + + // Open/Close the scope to do the bookkeeping: + openScopes(current); + closeScopes(); + } + +private: + bool isDBusElement(const QString & namespaceURI, + const QString & localName, + const QString & qName, + const QString & element) + { + return (namespaceURI.isEmpty() && localName == element && qName == element) || + (namespaceURI.isEmpty() && localName.isEmpty() && qName == element); + } + + bool isExtensionElement(const QString & namespaceURI, + const QString & localName, + const QString & qName, + const QString & element) + { + // isNull happens in startelement if no URI is used. + if (namespaceURI.isNull()) + { return false; } + + // We are in a endElement: URI is always empty there:-( + if (namespaceURI.isEmpty()) + { return qName == m_scopeStack.last()->extensionPrefix + element; } + + // startElemennt: We need to save the qName prefix + // since endElement will forget about the namespaceURi:-( + if (namespaceURI == EXTENSION_URI) + { + int pos = qName.find(':'); + m_scopeStack.last()->extensionPrefix = qName.left(pos + 1); + } + + return namespaceURI == EXTENSION_URI && localName == element; + } + + bool hasType(const QXmlAttributes & attributes) + { + const int type_idx(indexOf(attributes, "type")); + const int named_type_idx(indexOf(attributes, "named-type")); + + return named_type_idx >= 0 || type_idx >= 0; + } + + QString getType(const QXmlAttributes & attributes) + { + const int type_idx(indexOf(attributes, "type")); + const int named_type_idx(indexOf(attributes, "named-type")); + + QString type; + + if (named_type_idx >= 0) + { + type = attributes.value(named_type_idx); + if (!type.startsWith("::")) + { type = getCurrentScope(attributes.value(named_type_idx)); } + else + { type = type.mid(2); } + if (m_namedTypeMap.contains(type)) + { + if (type_idx >= 0) + { + const QString dbus_type(attributes.value(type_idx)); + if (dbus_type != m_namedTypeMap[type]) + { + DOC_ERROR(QString("Type \"%1\" does not match up with " + "previous definition of named type \"%2\" (which was \"%3\"."). + arg(dbus_type). + arg(type). + arg(m_namedTypeMap[type])); + } + } + return type; + } + + DOC_ERROR(QString("Undefined named type \"%1\" used.").arg(type)); + } + + if (type_idx >= 0) + { + type = attributes.value(type_idx); + + QRegExp reg_exp(QString("(a?[ybnqiuxdtsogv]|a[{]sv[}])")); + if (reg_exp.match(type)) + { return type; } + + DOC_ERROR(QString("Unnamed complex D-Bus type \"%1\" found.").arg(type)); + } + + return QString(); + } + + QString getDBusType(const QString & type) + { + QString scoped_type = type; + if (!scoped_type.contains("::")) + { scoped_type = getCurrentScope(type); } + + if (m_namedTypeMap.contains(scoped_type)) + { return m_namedTypeMap[scoped_type]; } + else + { return type; } + } + + void addNamedType(const QString type) + { + QString scoped_name(getCurrentScope()); + + if (m_namedTypeMap.contains(scoped_name)) + { + DOC_ERROR(QString("Named type \"%1\" is already defined.").arg(scoped_name)); + return; + } + + m_namedTypeMap.insert(scoped_name, type); + } + + QString getCurrentScope(const QString & type = QString()) + { + QString scoped_name; + if (!m_scopeStack.isEmpty()) + { + scoped_name = m_scopeStack.last()->scope->name; + scoped_name.append("::"); + } + if (!type.isEmpty()) + { scoped_name.append(type); } + else + { scoped_name = scoped_name.left(scoped_name.length() - 2); } + + return scoped_name; + } + + int indexOf(const QXmlAttributes & attributes, const QString & name, + const QString & type = "CDATA", const bool mandatory = true) + { + const int idx(attributes.index(name)); + if (idx < 0 || idx > attributes.length()) { return -1; } + if (attributes.type(idx) != type) { return -1; } + if (mandatory && attributes.value(idx).isEmpty()) { return -1; } + + return idx; + } + + Entry * createEntry() + { + Entry * entry = new Entry(); + + entry->protection = Public ; + entry->virt = Normal; + entry->stat = false; + entry->objc = false; + entry->spec = 0; + + entry->fileName = m_fileName; + entry->startLine = lineNumber(); + entry->bodyLine = lineNumber(); + + entry->callGraph = false; + entry->callerGraph = false; + + initGroupInfo(entry); + + m_currentEntry = entry; + + handleComment(); + + return entry; + } + + void openScopes(Entry * object) + { + int cur_scope_separator_pos = 0; + int last_scope_separator_pos = 0; + while (0 <= (cur_scope_separator_pos = object->name.find("::", last_scope_separator_pos))) + { + QString scope = object->name.mid(last_scope_separator_pos, + cur_scope_separator_pos - last_scope_separator_pos); + last_scope_separator_pos = cur_scope_separator_pos + 2; + + Entry * current_namespace = openNamespace(scope); + + if (!m_scopeStack.isEmpty()) + { m_scopeStack.last()->scope->addSubEntry(current_namespace); } + + m_scopeStack.append(new ScopeData(current_namespace, m_scopeCount)); + } + + QString scoped_name(getCurrentScope()); + if (!scoped_name.isEmpty()) + { scoped_name.append("::"); } + scoped_name.append(object->name.mid(last_scope_separator_pos)); + + object->name = scoped_name; + + if (!m_scopeStack.isEmpty()) + { m_scopeStack.last()->scope->addSubEntry(object); } + m_scopeStack.append(new ScopeData(object, m_scopeCount)); + + ++m_scopeCount; + } + + Entry * openNamespace(const QString & name) + { + Entry * current_namespace = createEntry(); + QString scoped_name(getCurrentScope()); + if (!scoped_name.isEmpty()) + { scoped_name.append("::"); } + scoped_name.append(name); + current_namespace->name = scoped_name; + current_namespace->section = Entry::NAMESPACE_SEC; + current_namespace->type = "namespace" ; + + return current_namespace; + } + + void closeScopes() + { + const int current_scope_count(m_scopeStack.last()->count); + + // Do not close the root scope. + if (current_scope_count == 0) + { return; } + + while (current_scope_count == m_scopeStack.last()->count) + { m_scopeStack.removeLast(); } + } + + ParserInterface * m_parser; + + QXmlLocator m_locator; + QString m_currentNode; // Nodes can not be nested, no entry necessary. + + struct ElementData + { + ElementData(const QString & e) : + element(e) + { } + ~ElementData() { } + + QString element; //*< The element name + QString extensionPrefix; //*< The prefix used for our extension. + QString text; //*< The actual xml code. + }; + QList<ElementData> m_elementStack; + + Entry * m_currentEntry; // The currently open entry. + + Entry * m_currentInterface; // Interfaces can not be nested. + Entry * m_currentMethod; // Methods can not be nested. + Argument * m_currentArgument; // Arguments can not be nested. + Entry * m_currentProperty; // Properties can not be nested. + Entry * m_currentEnum; // Enums can not be nested. + QList<Entry> m_namespaceStack; + + struct StructData + { + StructData(Entry * e) : entry(e) { } + ~StructData() { } + + QString type; + Entry * entry; + }; + QList<StructData> m_structStack; // Structs can be nested. + + struct ScopeData + { + ScopeData(Entry * s, int c) : + scope(s), + count(c) + { } + ~ScopeData() { } + + Entry * scope; + QString extensionPrefix; + int count; + }; + QList<ScopeData> m_scopeStack; // Scopes are nested. + + QString m_fileName; + + struct CommentData + { + CommentData(const QString & f, const int l, const QString & t) : + isJavaStyle(false), + isQtStyle(false), + line(l), + fileName(f) + { + isJavaStyle = t.startsWith(QChar('*')); + isQtStyle = t.startsWith(QChar('!')); + shouldIgnore = (!isJavaStyle && !isQtStyle); + associateWithPrevious = (t.at(1) == QChar('<')); + if (associateWithPrevious) + { text = t.mid(2); } + else + { text = t.mid(1); } + } + ~CommentData() { } + + QString text; + bool isJavaStyle; + bool isQtStyle; + bool shouldIgnore; + bool associateWithPrevious; + int line; + QString fileName; + }; + CommentData * m_currentComment; + + int m_scopeCount; //*< unique scope id. + + QString m_errorString; + + QMap<QString, QString> m_namedTypeMap; +}; + +// ----------------------------------------------------------------------- +// DBusXMLScanner +// ----------------------------------------------------------------------- + +DBusXMLScanner::DBusXMLScanner() +{ } + +DBusXMLScanner::~DBusXMLScanner() +{ } + +void DBusXMLScanner::parseInput(const char * fileName, + const char * /* fileBuf */, + Entry * root) +{ + QFile inputFile(fileName); + + QXmlInputSource inputSource(inputFile); + QXmlSimpleReader reader; + + DBusXMLHandler handler(this, &reader, fileName, root); + reader.setContentHandler(&handler); + reader.setErrorHandler(&handler); + reader.setLexicalHandler(&handler); + + groupEnterFile(fileName, 1); + handler.setSection(); + reader.parse(inputSource); + + if (handler.errorString()) + { err("ERROR parsing XML: %s\n", handler.errorString().utf8().data()); } + + groupLeaveFile(fileName, 1); +} + +bool DBusXMLScanner::needsPreprocessing(const QCString & /* extension */) +{ return (false); } + +void DBusXMLScanner::parseCode(CodeOutputInterface & /* codeOutIntf */, + const char * /* scopeName */, + const QCString & /* input */, + bool /* isExampleBlock */, + const char * /* exampleName */, + FileDef * /* fileDef */, + int /* startLine */, + int /* endLine */, + bool /* inlineFragment */, + MemberDef * /* memberDef */) +{ } + +void DBusXMLScanner::resetCodeParserState() +{ } + +void DBusXMLScanner::parsePrototype(const char * /* text */) +{ } diff --git a/src/dbusxmlscanner.h b/src/dbusxmlscanner.h new file mode 100644 index 0000000..3a4994e --- /dev/null +++ b/src/dbusxmlscanner.h @@ -0,0 +1,57 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 2009 by Tobias Hunger <tobias@aquazul.com> + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#ifndef SCANNER_DBUSXML_H +#define SCANNER_DBUSXML_H + +#include "parserintf.h" + +/** \brief D-Bus XML parser. + * + * This is the D-Bus XML parser for doxygen. + */ +class DBusXMLScanner : public ParserInterface +{ +public: + DBusXMLScanner(); + virtual ~DBusXMLScanner(); + void parseInput(const char *fileName, + const char *fileBuf, + Entry *root); + + bool needsPreprocessing(const QCString &extension); + + void parseCode(CodeOutputInterface &codeOutIntf, + const char *scopeName, + const QCString &input, + bool isExampleBlock, + const char *exampleName=0, + FileDef *fileDef=0, + int startLine=-1, + int endLine=-1, + bool inlineFragment=FALSE, + MemberDef *memberDef=0 + ); + + void resetCodeParserState(); + + void parsePrototype(const char *text); + +private: +}; + +#endif diff --git a/src/docparser.h b/src/docparser.h index 5ecfb4b..bb867b8 100644 --- a/src/docparser.h +++ b/src/docparser.h @@ -169,6 +169,7 @@ template<class T> class CompAccept { public: CompAccept() { m_children.setAutoDelete(TRUE); } + virtual ~CompAccept() {} void accept(T *obj, DocVisitor *v) { v->visitPre(obj); diff --git a/src/docsets.cpp b/src/docsets.cpp index fe43791..76d7679 100644 --- a/src/docsets.cpp +++ b/src/docsets.cpp @@ -263,6 +263,7 @@ void DocSets::addIndexItem(const char *, const char *, case SrcLangExt_Python: lang="python"; break; // Python case SrcLangExt_F90: lang="fortran"; break; // Fortran case SrcLangExt_VHDL: lang="vhdl"; break; // VHDL + case SrcLangExt_XML: lang="xml"; break; // DBUS XML } // determine scope diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 81cb544..8b063f1 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -71,6 +71,7 @@ #include "htags.h" #include "pyscanner.h" #include "fortranscanner.h" +#include "dbusxmlscanner.h" #include "code.h" #include "objcache.h" #include "store.h" @@ -122,7 +123,6 @@ QTextStream Doxygen::tagFile; NamespaceDef *Doxygen::globalScope = 0; QDict<RefList> *Doxygen::xrefLists = new QDict<RefList>; // dictionary of cross-referenced item lists bool Doxygen::parseSourcesNeeded = FALSE; -double Doxygen::sysElapsedTime = 0.0; QTime Doxygen::runningTime; //SearchIndex * Doxygen::searchIndex=0; QDict<DefinitionIntf> *Doxygen::symbolMap; @@ -2924,10 +2924,23 @@ static void buildFunctionList(EntryNav *rootNav) //printf("matching arguments for %s%s %s%s\n", // md->name().data(),md->argsString(),rname.data(),argListToString(root->argList).data()); LockingPtr<ArgumentList> mdAl = md->argumentList(); + LockingPtr<ArgumentList> mdTempl = md->templateArguments(); + + // in case of template functions, we need to check if the + // functions have the same number of template parameters + bool sameNumTemplateArgs = TRUE; + if (mdTempl!=0 && root->tArgLists) + { + if (mdTempl->count()!=root->tArgLists->getLast()->count()) + { + sameNumTemplateArgs = FALSE; + } + } if ( matchArguments2(md->getOuterScope(),mfd,mdAl.pointer(), rnd ? rnd : Doxygen::globalScope,rfd,root->argList, - FALSE) + FALSE) && + sameNumTemplateArgs ) { GroupDef *gd=0; @@ -4931,6 +4944,22 @@ static bool findGlobalMember(EntryNav *rootNav, rnd ? rnd : Doxygen::globalScope,fd,root->argList, FALSE); + // for template members we need to check if the number of + // template arguments is the same, otherwise we are dealing with + // different functions. + if (matching && root->tArgLists) + { + LockingPtr<ArgumentList> mdTempl = md->templateArguments(); + if (mdTempl!=0) + { + if (root->tArgLists->getLast()->count()!=mdTempl->count()) + { + matching=FALSE; + } + } + } + + //printf("%s<->%s\n", // argListToString(md->argumentList()).data(), // argListToString(root->argList).data()); @@ -6572,7 +6601,7 @@ static void addEnumValuesToEnums(EntryNav *rootNav) SrcLangExt sle; if (rootNav->fileDef() && ( (sle=getLanguageFromFileName(rootNav->fileDef()->name()))==SrcLangExt_CSharp - || sle==SrcLangExt_Java + || sle==SrcLangExt_Java || sle==SrcLangExt_XML ) ) { @@ -9128,6 +9157,7 @@ void initDoxygen() Doxygen::parserManager->registerParser("python", new PythonLanguageScanner); Doxygen::parserManager->registerParser("fortran", new FortranLanguageScanner); Doxygen::parserManager->registerParser("vhdl", new VHDLLanguageScanner); + Doxygen::parserManager->registerParser("dbusxml", new DBusXMLScanner); // register any additional parsers here... @@ -10539,7 +10569,7 @@ void generateOutput() { msg("Total elapsed time: %.3f seconds\n(of which %.3f seconds waiting for external tools to finish)\n", ((double)Doxygen::runningTime.elapsed())/1000.0, - Doxygen::sysElapsedTime + portable_getSysElapsedTime() ); } diff --git a/src/doxygen.h b/src/doxygen.h index 1aee032..859f63c 100644 --- a/src/doxygen.h +++ b/src/doxygen.h @@ -111,7 +111,6 @@ class Doxygen static QDict<RefList> *xrefLists; // array of xref lists: todo, test, bug, deprecated ... static QCString htmlFileExtension; static bool parseSourcesNeeded; - static double sysElapsedTime; static QTime runningTime; //static SearchIndex *searchIndex; static QDict<DefinitionIntf> *symbolMap; diff --git a/src/fortranscanner.l b/src/fortranscanner.l index 766a261..97909f0 100644 --- a/src/fortranscanner.l +++ b/src/fortranscanner.l @@ -171,7 +171,7 @@ static int yyread(char *buf,int max_size); static void startCommentBlock(bool); static void handleCommentBlock(const QCString &doc,bool brief); static void addCurrentEntry(); -static void addModule(const char *name); +static void addModule(const char *name, bool isModule=FALSE); static void addSubprogram(const char *text); static void addInterface(QCString name); static Argument *addFortranParameter(const QCString &type,const QCString &name, const QCString docs); @@ -242,6 +242,7 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA %x Start %x Comment %x Module +%x Program %x ModuleBody %x ModuleBodyContains %x AttributeList @@ -437,7 +438,10 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA /*------ module handling ------------------------------------------------------------*/ <Start>module|program{BS_} { // - yy_push_state(Module); + if(yytext[0]=='m' || yytext[0]=='M') + yy_push_state(Module); + else + yy_push_state(Program); defaultProtection = Public; } <Start,ModuleBody,ModuleBodyContains>^{BS}"end"({BS}(module|program)({BS_}{ID})?)?{BS}/(\n|!) { // end module @@ -448,7 +452,12 @@ PREFIX (RECURSIVE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,2}(RECURSIVE|PURE|ELEMENTA yy_pop_state(); } <Module>{ID} { - addModule(yytext); + addModule(yytext, TRUE); + BEGIN(ModuleBody); + } + +<Program>{ID} { + addModule(yytext, FALSE); BEGIN(ModuleBody); } @@ -1468,11 +1477,15 @@ static void addCurrentEntry() static int max(int a, int b) {return a>b?a:b;} -static void addModule(const char *name) +static void addModule(const char *name, bool isModule) { //fprintf(stderr, "0=========> got module %s\n", name); - current->section = Entry::NAMESPACE_SEC; + if (isModule) + current->section = Entry::NAMESPACE_SEC; + else + current->section = Entry::FUNCTION_SEC; + if (name!=NULL) { current->name = name; diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp index 285988a..3988c57 100644 --- a/src/ftvhelp.cpp +++ b/src/ftvhelp.cpp @@ -731,10 +731,12 @@ void FTVHelp::generateTreeView(QString* OutString) t << " --></script>\n"; t << " <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n"; t << " <div class=\"MSearchBoxRow\"><span class=\"MSearchBoxLeft\">\n"; - t << " <input type=\"text\" id=\"MSearchField\" value=\"Search\" \n"; + t << " <a id=\"MSearchClose\" href=\"javascript:searchBox.CloseResultsWindow()\">" + << "<img id=\"MSearchCloseImg\" border=\"0\" src=\"search/close.png\" alt=\"\"/></a>\n"; + t << " <input type=\"text\" id=\"MSearchField\" value=\"Search\" accesskey=\"S\"\n"; t << " onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n"; t << " onblur=\"searchBox.OnSearchFieldFocus(false)\" \n"; - t << " onkeyup=\"searchBox.OnSearchFieldChange()\"/>\n"; + t << " onkeyup=\"searchBox.OnSearchFieldChange(event)\"/>\n"; t << " </span><span class=\"MSearchBoxRight\">\n"; t << " <img id=\"MSearchSelect\" src=\"search/search.png\"\n"; t << " onmouseover=\"return searchBox.OnSearchSelectShow()\"\n"; diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index 0383f55..74bea86 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -399,91 +399,31 @@ static unsigned int search_png_len = 527; static unsigned char close_png[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, - 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, - 0x08, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x76, 0x69, 0x23, 0x00, 0x00, 0x01, - 0xa0, 0x49, 0x44, 0x41, 0x54, 0x28, 0x15, 0x8d, 0x91, 0x3b, 0xaf, 0x01, - 0x51, 0x14, 0x85, 0xef, 0x3c, 0x5c, 0x42, 0xbc, 0x49, 0xbc, 0x12, 0x8d, - 0x02, 0x85, 0x76, 0x42, 0x49, 0xa3, 0x95, 0xe8, 0xfd, 0x1e, 0x9d, 0x9f, - 0x20, 0x51, 0xf2, 0x13, 0x24, 0x3a, 0x85, 0x82, 0x4a, 0xa2, 0x20, 0x9a, - 0x29, 0x86, 0x10, 0xef, 0x47, 0x98, 0xe1, 0x7e, 0x73, 0x8f, 0xea, 0x56, - 0xf7, 0x24, 0x8e, 0x73, 0xd6, 0x59, 0x7b, 0xed, 0xb5, 0xf6, 0x48, 0xcd, - 0x66, 0xf3, 0xeb, 0x7f, 0x4b, 0x95, 0x24, 0x49, 0x30, 0x5f, 0xaf, 0x97, - 0xae, 0xeb, 0xeb, 0xf5, 0xfa, 0x74, 0x3a, 0x01, 0xfa, 0x7c, 0xbe, 0x68, - 0x34, 0x9a, 0x4c, 0x26, 0x65, 0x59, 0x16, 0x84, 0x0f, 0xf5, 0x7e, 0xbf, - 0x4f, 0x26, 0x93, 0xdb, 0xed, 0xa6, 0xaa, 0xaa, 0xcb, 0xe5, 0xe2, 0xf9, - 0xf9, 0x7c, 0x52, 0xb9, 0xd9, 0x6c, 0xf2, 0xf9, 0x3c, 0x08, 0x6c, 0xbb, - 0x02, 0xbd, 0xf1, 0x78, 0x0c, 0xbb, 0x58, 0x2c, 0xa2, 0xf4, 0xfd, 0xbb, - 0x50, 0xd5, 0x34, 0xcd, 0x34, 0xcd, 0xd9, 0x6c, 0x06, 0x01, 0x9a, 0xca, - 0x8f, 0x6a, 0x78, 0xa5, 0x52, 0xa9, 0x5c, 0x2e, 0x1f, 0x0e, 0x87, 0x6e, - 0xb7, 0x0b, 0x58, 0xab, 0xd5, 0xc2, 0xe1, 0x30, 0xf2, 0xa3, 0xd1, 0x68, - 0xb5, 0x5a, 0xc5, 0xe3, 0x71, 0xdb, 0x00, 0xfe, 0x1c, 0x0e, 0xc7, 0x72, - 0xb9, 0x84, 0xe7, 0xf7, 0xfb, 0xeb, 0xf5, 0xba, 0x65, 0x59, 0xf0, 0x2e, - 0x97, 0xcb, 0x74, 0x3a, 0x7d, 0xbf, 0xdf, 0xfb, 0xfd, 0x3e, 0x91, 0x48, - 0xc8, 0x50, 0xc9, 0x81, 0x45, 0x8c, 0xf6, 0x7a, 0xbd, 0xe3, 0xf1, 0x18, - 0x0c, 0x06, 0x23, 0x91, 0x08, 0xbc, 0x4e, 0xa7, 0xb3, 0xdd, 0x6e, 0x11, - 0xa6, 0x27, 0x34, 0xdb, 0x2b, 0x7f, 0x8a, 0xa2, 0x00, 0x71, 0xc0, 0x1c, - 0x08, 0x8b, 0x58, 0x8f, 0xc7, 0x03, 0xdb, 0xa8, 0xf0, 0x0a, 0x62, 0x3f, - 0x87, 0x42, 0x21, 0x4e, 0xc4, 0x14, 0xfe, 0xce, 0xe7, 0x33, 0x4e, 0xd0, - 0x6e, 0x34, 0x1a, 0x84, 0x83, 0xe0, 0xf5, 0x7a, 0xd9, 0x6d, 0x55, 0x86, - 0x47, 0xc6, 0x5c, 0x2e, 0x47, 0x8d, 0xe8, 0xdb, 0x6e, 0xb7, 0xf1, 0x17, - 0x08, 0x04, 0x0a, 0x85, 0x02, 0x7d, 0x18, 0x0b, 0x34, 0xa5, 0x5a, 0xad, - 0x72, 0x32, 0x0c, 0x83, 0x39, 0x90, 0xa0, 0xdf, 0xef, 0xef, 0x76, 0x3b, - 0xcc, 0xcc, 0xe7, 0x73, 0x3c, 0x0c, 0x06, 0x03, 0x0a, 0xb2, 0xd9, 0x2c, - 0x05, 0x52, 0xab, 0xd5, 0xa2, 0xc2, 0xe3, 0xf1, 0x0c, 0x87, 0xc3, 0xeb, - 0xf5, 0x8a, 0x3c, 0x3c, 0xfc, 0x01, 0x32, 0x07, 0xb7, 0xdb, 0xcd, 0x10, - 0xb1, 0xc4, 0xd5, 0x86, 0x58, 0x64, 0xac, 0x54, 0x2a, 0x8b, 0xc5, 0x82, - 0xc1, 0x09, 0x55, 0xc4, 0x62, 0xb1, 0x58, 0x3a, 0x9d, 0xe6, 0x2a, 0x38, - 0x9f, 0x0f, 0x8b, 0x18, 0x73, 0x49, 0xa5, 0x52, 0x99, 0x4c, 0xc6, 0xe9, - 0x74, 0xf2, 0x46, 0x7c, 0xc6, 0x07, 0xc8, 0x99, 0x4c, 0xec, 0x1f, 0x55, - 0x51, 0x47, 0x23, 0xd1, 0x4b, 0x5c, 0xff, 0xec, 0x3f, 0x83, 0x85, 0xe4, - 0x1a, 0x44, 0x83, 0x01, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, - 0x44, 0xae, 0x42, 0x60, 0x82 + 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, + 0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0xac, 0x77, 0x26, 0x00, 0x00, 0x00, + 0xd8, 0x49, 0x44, 0x41, 0x54, 0x18, 0x19, 0x75, 0x51, 0xbd, 0x12, 0x46, + 0x40, 0x0c, 0xdc, 0x18, 0x15, 0x0a, 0x14, 0x14, 0x1a, 0x43, 0xeb, 0x35, + 0xbc, 0x7f, 0xa7, 0x43, 0x67, 0x06, 0x33, 0x28, 0xd0, 0xde, 0x77, 0x7b, + 0x23, 0x2a, 0xdf, 0x16, 0x97, 0x9f, 0xdb, 0xcb, 0x26, 0x39, 0xc1, 0x83, + 0x7d, 0xdf, 0xcd, 0xb2, 0x2c, 0xd8, 0xb6, 0x0d, 0xe7, 0x79, 0x22, 0x8a, + 0x22, 0xc4, 0x71, 0x8c, 0x3c, 0xcf, 0x91, 0xa6, 0xa9, 0x90, 0xe6, 0x8e, + 0x69, 0x9a, 0xcc, 0x38, 0x8e, 0xb8, 0xae, 0x4b, 0xdf, 0xbe, 0x36, 0x0c, + 0x43, 0x94, 0x65, 0x89, 0xa2, 0x28, 0xc4, 0x3b, 0x8e, 0xe3, 0x2f, 0x91, + 0x2f, 0xa8, 0xc2, 0x42, 0x56, 0xd1, 0x78, 0xf3, 0x3c, 0xbb, 0x04, 0x2f, + 0xda, 0xb6, 0x45, 0x55, 0x55, 0x74, 0x9d, 0x65, 0x2c, 0x22, 0xb8, 0xef, + 0x1b, 0xeb, 0xba, 0xc2, 0x67, 0x8f, 0x4c, 0x10, 0x7d, 0xdf, 0xa3, 0xae, + 0x6b, 0xe7, 0xd3, 0x32, 0x56, 0x90, 0xe7, 0x53, 0x46, 0x31, 0x0c, 0x83, + 0x73, 0x95, 0xa8, 0x31, 0x93, 0x9c, 0xc7, 0xe3, 0xd4, 0x0a, 0xb6, 0xa0, + 0x44, 0x5a, 0xc6, 0xc6, 0x18, 0x77, 0xcd, 0x41, 0xbd, 0x24, 0x49, 0x94, + 0xfb, 0x12, 0x59, 0x51, 0x5b, 0xd2, 0x16, 0xed, 0xfa, 0x20, 0xdc, 0x6f, + 0xd7, 0x75, 0x9f, 0x6b, 0xd3, 0x2a, 0x41, 0x10, 0xa0, 0x69, 0x1a, 0x57, + 0x59, 0x28, 0x47, 0x99, 0x2f, 0x30, 0xcf, 0x7b, 0xfb, 0x41, 0xcf, 0x1a, + 0x2c, 0xeb, 0xeb, 0x07, 0x29, 0x9d, 0x65, 0x19, 0x6c, 0xab, 0x6e, 0x5d, + 0x3f, 0x07, 0x0a, 0x79, 0x90, 0x0e, 0x11, 0x45, 0xc2, 0x00, 0x00, 0x00, + 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; -static unsigned int close_png_len = 473; +static unsigned int close_png_len = 273; -static unsigned char close_active_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, - 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, - 0x08, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x76, 0x69, 0x23, 0x00, 0x00, 0x01, - 0xa0, 0x49, 0x44, 0x41, 0x54, 0x28, 0x15, 0x8d, 0x91, 0x3d, 0x8f, 0x01, - 0x51, 0x14, 0x86, 0x77, 0x3e, 0xd6, 0x47, 0x22, 0xbe, 0x82, 0x10, 0x14, - 0xa2, 0x21, 0x12, 0x09, 0x89, 0x0a, 0x85, 0x4a, 0x68, 0xf4, 0x12, 0x3f, - 0x82, 0x52, 0xaf, 0x92, 0x68, 0x75, 0x5a, 0x7f, 0x41, 0x42, 0x47, 0xa3, - 0xa0, 0x42, 0x68, 0x49, 0x44, 0x47, 0x10, 0xf1, 0x11, 0xec, 0x33, 0x7b, - 0x67, 0xb7, 0xd8, 0x6a, 0x4f, 0x32, 0x33, 0x77, 0xee, 0x79, 0xce, 0x7b, - 0xdf, 0x73, 0xae, 0xd4, 0xe9, 0x74, 0x3e, 0xfe, 0x17, 0xea, 0x2f, 0xf6, - 0x7c, 0x3e, 0x17, 0x8b, 0xc5, 0x66, 0xb3, 0xd9, 0xef, 0xf7, 0x92, 0x24, - 0x39, 0x9d, 0xce, 0x40, 0x20, 0x10, 0x8d, 0x46, 0x15, 0x45, 0x11, 0x8c, - 0x8e, 0x9e, 0xcf, 0xe7, 0xc1, 0x60, 0xc0, 0x5b, 0x55, 0x55, 0xa3, 0xd1, - 0x28, 0xcb, 0xf2, 0xe5, 0x72, 0x59, 0x2e, 0x97, 0x54, 0x66, 0xb3, 0x59, - 0x8b, 0xc5, 0x02, 0x2d, 0xf3, 0xa0, 0xd7, 0xef, 0xf7, 0xc9, 0x55, 0x2a, - 0x95, 0x70, 0x38, 0xfc, 0xf9, 0x1d, 0x7e, 0xbf, 0xbf, 0x5c, 0x2e, 0xdf, - 0x6e, 0xb7, 0xd1, 0x68, 0x04, 0x00, 0xa6, 0x94, 0x4a, 0xa5, 0xf9, 0x7c, - 0x4e, 0x35, 0x5c, 0xb1, 0x58, 0x4c, 0x26, 0x93, 0xb3, 0xd9, 0xcc, 0x6c, - 0x36, 0xd7, 0x6a, 0xb5, 0x58, 0x2c, 0x66, 0xb5, 0x5a, 0x27, 0x93, 0x09, - 0x1e, 0x5c, 0x2e, 0x97, 0x66, 0x60, 0xbd, 0x5e, 0x73, 0xee, 0x78, 0x3c, - 0x4e, 0xa7, 0xd3, 0xe4, 0xaa, 0xd5, 0xea, 0xeb, 0xf5, 0x72, 0x38, 0x1c, - 0x9c, 0x33, 0x1c, 0x0e, 0xdf, 0xef, 0xf7, 0x6e, 0xb7, 0x8b, 0x44, 0x22, - 0x9a, 0x81, 0xc3, 0xe1, 0x00, 0xba, 0xdd, 0x6e, 0x5b, 0xad, 0xd6, 0xf1, - 0x78, 0xb4, 0xd9, 0x6c, 0x82, 0x6b, 0x36, 0x9b, 0xd8, 0xa5, 0xc5, 0xd3, - 0xe9, 0x04, 0xa6, 0xa1, 0x34, 0x21, 0x02, 0x4f, 0xc2, 0x16, 0x9b, 0x8f, - 0xc7, 0x03, 0x55, 0x83, 0xc1, 0x80, 0x0a, 0xa1, 0xa3, 0x1e, 0x8f, 0x87, - 0x15, 0x6f, 0xfc, 0x09, 0x3d, 0xa1, 0x5d, 0xaf, 0xd7, 0x83, 0xc1, 0x20, - 0x29, 0x36, 0x75, 0x34, 0x14, 0x0a, 0x61, 0x2e, 0x97, 0xcb, 0xfd, 0x9e, - 0xdb, 0x68, 0x34, 0x04, 0x9d, 0xcf, 0xe7, 0x39, 0x47, 0x14, 0x68, 0x13, - 0xf0, 0x7a, 0xbd, 0x74, 0x36, 0x9d, 0x4e, 0xed, 0x76, 0x7b, 0xb7, 0xdb, - 0x5d, 0xad, 0x56, 0xd7, 0xeb, 0x95, 0xb1, 0x30, 0xb4, 0x76, 0xbb, 0xed, - 0x76, 0xbb, 0x53, 0xa9, 0x14, 0x05, 0x92, 0xb8, 0x58, 0xc6, 0xde, 0xeb, - 0xf5, 0xb8, 0x27, 0xfa, 0xa5, 0x0f, 0x61, 0x8e, 0x34, 0xc5, 0x85, 0x42, - 0x81, 0x4a, 0x0c, 0x68, 0xaa, 0x7c, 0x20, 0x12, 0x89, 0x84, 0xc9, 0x64, - 0x62, 0x41, 0x37, 0x74, 0xe9, 0xf3, 0xf9, 0xe2, 0xf1, 0x78, 0x26, 0x93, - 0xe1, 0x97, 0x4d, 0x18, 0xfd, 0x62, 0xf1, 0x8a, 0x24, 0x57, 0xc5, 0xd8, - 0xe9, 0x9a, 0xc4, 0xfd, 0x7e, 0x47, 0x8c, 0x4d, 0xd6, 0x22, 0x74, 0x54, - 0xfc, 0x20, 0x40, 0xfc, 0xa4, 0xfe, 0x7e, 0xbf, 0x00, 0xa8, 0x79, 0xe1, - 0x90, 0xdb, 0x2c, 0x9e, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, - 0x44, 0xae, 0x42, 0x60, 0x82 -}; -static unsigned int close_active_png_len = 473; static const char tabs_css[] = "/* tabs styles, based on http://www.alistapart.com/articles/slidingdoors */\n" @@ -638,7 +578,6 @@ static img_data_item search_data[] = { { "search.png", search_png, search_png_len }, { "close.png", close_png, close_png_len }, - { "close_active.png", close_active_png, close_active_png_len }, { 0, 0, 0 } }; @@ -894,21 +833,17 @@ void HtmlGenerator::startFile(const char *name,const char *, void HtmlGenerator::writeSearchFooter(QTextStream &t,const QCString &relPath) { + (void)relPath; t << "<!--- window showing the filter options -->\n"; t << "<div id=\"MSearchSelectWindow\"\n"; t << " onmouseover=\"return searchBox.OnSearchSelectShow()\"\n"; - t << " onmouseout=\"return searchBox.OnSearchSelectHide()\">\n"; + t << " onmouseout=\"return searchBox.OnSearchSelectHide()\"\n"; + t << " onkeydown=\"return searchBox.OnSearchSelectKey(event)\">\n"; writeSearchCategories(t); t << "</div>\n"; t << "\n"; t << "<!-- iframe showing the search results (closed by default) -->\n"; t << "<div id=\"MSearchResultsWindow\">\n"; - t << "<a href=\"javascript:searchBox.CloseResultsWindow()\" \n"; - t << " id=\"MSearchResultsWindowClose\"\n"; - t << " onmouseover=\"return searchBox.OnCloseHighlight(true)\"\n"; - t << " onmouseout=\"return searchBox.OnCloseHighlight(false)\">" - << "<img border=\"0\" src=\"" << relPath << "search/close.png\" " - << "alt=\"\"/></a>\n"; t << "<iframe src=\"\" frameborder=\"0\" \n"; t << " name=\"MSearchResults\" id=\"MSearchResults\">\n"; t << "</iframe>\n"; @@ -2092,10 +2027,12 @@ static void renderQuickLinksAsTabs(QTextStream &t,const QCString &relPath, t << " onmouseover=\"return searchBox.OnSearchSelectShow()\"\n"; t << " onmouseout=\"return searchBox.OnSearchSelectHide()\"\n"; t << " alt=\"\"/>\n"; - t << " <input type=\"text\" id=\"MSearchField\" value=\"Search\" \n"; + t << " <input type=\"text\" id=\"MSearchField\" value=\"Search\" accesskey=\"S\"\n"; t << " onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n"; t << " onblur=\"searchBox.OnSearchFieldFocus(false)\" \n"; - t << " onkeyup=\"searchBox.OnSearchFieldChange()\"/>\n"; + t << " onkeyup=\"searchBox.OnSearchFieldChange(event)\"/>\n"; + t << " <a id=\"MSearchClose\" href=\"javascript:searchBox.CloseResultsWindow()\">" + << "<img id=\"MSearchCloseImg\" border=\"0\" src=\"" << relPath << "search/close.png\" alt=\"\"/></a>\n"; t << " </div>\n"; t << " </li>\n"; } diff --git a/src/index.cpp b/src/index.cpp index ae71d93..ff59003 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -2532,6 +2532,7 @@ void writeSearchIndex() SDict<QList<Definition> >::Iterator li(g_searchIndexSymbols[i][p]); QList<Definition> *dl; + int itemCount=0; for (li.toFirst();(dl=li.current());++li) { Definition *d = dl->first(); @@ -2544,8 +2545,18 @@ void writeSearchIndex() MemberDef *md = 0; bool isMemberDef = d->definitionType()==Definition::TypeMember; if (isMemberDef) md = (MemberDef*)d; - t << " <a class=\"SRSymbol\" href=\"../" << - d->getOutputFileBase() << Doxygen::htmlFileExtension; + t << " <a id=\"Item" << itemCount << "\" " + << "onkeydown=\"" + << "return searchResults.Nav(event," << itemCount << ")\" " + << "onkeypress=\"" + << "return searchResults.Nav(event," << itemCount << ")\" " + << "onkeyup=\"" + << "return searchResults.Nav(event," << itemCount << ")\" " + // << "onkeydown=\"return true\" " + // << "onkeypress=\"" + // << "return searchResults.Nav(event," << itemCount << ")\" " + << "class=\"SRSymbol\" href=\"../" + << d->getOutputFileBase() << Doxygen::htmlFileExtension; if (isMemberDef) { t << "#" << ((MemberDef *)d)->anchor(); @@ -2575,7 +2586,18 @@ void writeSearchIndex() } else // multiple items with the same name { - t << " <a class=\"SRSymbol\" href=\"javascript:searchResults.Toggle('SR_" + t << " <a id=\"Item" << itemCount << "\" " + << "onkeydown=\"" + << "return searchResults.Nav(event," << itemCount << ")\" " + << "onkeypress=\"" + << "return searchResults.Nav(event," << itemCount << ")\" " + << "onkeyup=\"" + << "return searchResults.Nav(event," << itemCount << ")\" " + // << "onkeydown=\"return true\" " + // << "onkeypress=\"" + // << "return searchResults.Nav(event," << itemCount << ")\" " + << "class=\"SRSymbol\" " + << "href=\"javascript:searchResults.Toggle('SR_" << searchId(d->localName()) << "')\">" << convertToXML(d->localName()) << "</a>" << endl; t << " <div class=\"SRChildren\">" << endl; @@ -2583,6 +2605,7 @@ void writeSearchIndex() QListIterator<Definition> di(*dl); bool overloadedFunction = FALSE; Definition *prevScope = 0; + int childCount=0; for (di.toFirst();(d=di.current());) { ++di; @@ -2594,7 +2617,22 @@ void writeSearchIndex() if (isMemberDef) md = (MemberDef*)d; if (next) nextScope = next->getOuterScope(); - t << " <a class=\"SRScope\" href=\"../" << + t << " <a id=\"Item" << itemCount << "_c" + << childCount << "\" " + << "onkeydown=\"" + << "return searchResults.NavChild(event," + << itemCount << "," << childCount << ")\" " + << "onkeypress=\"" + << "return searchResults.NavChild(event," + << itemCount << "," << childCount << ")\" " + << "onkeyup=\"" + << "return searchResults.NavChild(event," + << itemCount << "," << childCount << ")\" " + // << "onkeydown=\"return true\" " + // << "onkeypress=\"" + // << "return searchResults.NavChild(event," + // << itemCount << "," << childCount << ")\" " + << "class=\"SRScope\" href=\"../" << d->getOutputFileBase() << Doxygen::htmlFileExtension; if (isMemberDef) { @@ -2663,11 +2701,13 @@ void writeSearchIndex() } t << "</a>" << endl; prevScope = scope; + childCount++; } t << " </div>" << endl; // SRChildren } t << " </div>" << endl; // SREntry t << "</div>" << endl; // SRResult + itemCount++; } // TODO: translate "Searching" t << "<div class=\"SRStatus\" id=\"Searching\">Searching...</div>" << endl; @@ -2709,23 +2749,40 @@ void writeSearchIndex() t << "var indexSectionsWithContent =" << endl; t << "{" << endl; bool first=TRUE; + int j=0; for (i=0;i<NUM_SEARCH_INDICES;i++) { if (g_searchIndexCount[i]>0) { if (!first) t << "," << endl; - t << " \"" << g_searchIndexName[i] << "\": \""; + t << " " << j << ": \""; for (p=32;p<MEMBER_INDEX_ENTRIES;p++) { t << (g_searchIndexSymbols[i][p].count()>0 ? "1" : "0"); } t << "\""; first=FALSE; + j++; + } + } + if (!first) t << "\n"; + t << "};" << endl << endl; + t << "var indexSectionNames =" << endl; + t << "{" << endl; + first=TRUE; + j=0; + for (i=0;i<NUM_SEARCH_INDICES;i++) + { + if (g_searchIndexCount[i]>0) + { + if (!first) t << "," << endl; + t << " " << j << ": \"" << g_searchIndexName[i] << "\""; + first=FALSE; + j++; } } if (!first) t << "\n"; t << "};" << endl << endl; - t << search_script; } } @@ -2768,8 +2825,7 @@ void writeSearchCategories(QTextStream &t) if (g_searchIndexCount[i]>0) { t << "<a class=\"SelectItem\" href=\"javascript:void(0)\" " - << "onclick=\"searchBox.OnSelectItem(" << j << ",'" - << g_searchIndexName[i] << "')\">" + << "onclick=\"searchBox.OnSelectItem(" << j << ")\">" << "<span class=\"SelectionMark\"> </span>" << convertToXML(map.categoryLabel[i]) << "</a>"; diff --git a/src/latexgen.cpp b/src/latexgen.cpp index 37a3454..b76c7e2 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -793,9 +793,9 @@ void LatexGenerator::endIndexSection(IndexSections is) if (isFirst) { t << "}\n\\input{" << fd->getOutputFileBase() << "}\n"; - if (sourceBrowser && m_prettyCode) + if (sourceBrowser && m_prettyCode && fd->generateSourceFile()) { - t << "\\input{" << fd->getSourceFileBase() << "}\n"; + t << "\\include{" << fd->getSourceFileBase() << "}\n"; } isFirst=FALSE; } @@ -803,10 +803,9 @@ void LatexGenerator::endIndexSection(IndexSections is) { if (compactLatex) t << "\\input" ; else t << "\\include"; t << "{" << fd->getOutputFileBase() << "}\n"; - if (sourceBrowser && m_prettyCode) + if (sourceBrowser && m_prettyCode && fd->generateSourceFile()) { - if (compactLatex) t << "\\input" ; else t << "\\include"; - t << "{" << fd->getSourceFileBase() << "}\n"; + t << "\\include{" << fd->getSourceFileBase() << "}\n"; } } } diff --git a/src/libdoxygen.pro.in b/src/libdoxygen.pro.in index d66fed1..12711d1 100644 --- a/src/libdoxygen.pro.in +++ b/src/libdoxygen.pro.in @@ -88,6 +88,7 @@ HEADERS = bufstr.h \ pyscanner.h \ fortrancode.h \ fortranscanner.h \ + dbusxmlscanner.h \ qhp.h \ qhpxmlwriter.h \ qtbc.h \ @@ -231,6 +232,7 @@ SOURCES = ce_lex.cpp \ vhdlscanner.cpp \ xmldocvisitor.cpp \ xmlgen.cpp \ + dbusxmlscanner.cpp \ win32:TMAKE_CXXFLAGS += -DQT_NODLL win32-msvc:TMAKE_CXXFLAGS += -Zm200 diff --git a/src/portable.cpp b/src/portable.cpp index 0107f2c..17a65d8 100644 --- a/src/portable.cpp +++ b/src/portable.cpp @@ -368,3 +368,8 @@ int portable_pclose(FILE *stream) return pclose(stream); } +double portable_getSysElapsedTime() +{ + return sysElapsedTime; +} + diff --git a/src/portable.h b/src/portable.h index 3745d66..0718932 100644 --- a/src/portable.h +++ b/src/portable.h @@ -28,6 +28,7 @@ const char * portable_commandExtension(); bool portable_fileSystemIsCaseSensitive(); FILE * portable_popen(const char *name,const char *type); int portable_pclose(FILE *stream); +double portable_getSysElapsedTime(); extern "C" { void * portable_iconv_open(const char* tocode, const char* fromcode); @@ -104,6 +104,7 @@ static QCString g_blockName; static int g_condCtx; static bool g_skip; static QStack<bool> g_condStack; +static bool g_insideCS; // C# has simpler preprocessor static bool g_lexInit = FALSE; @@ -118,6 +119,7 @@ static void setFileName(const char *name) g_yyFileName=convertToQCString(fi.absFilePath()); g_yyFileDef=findFileDef(Doxygen::inputNameDict,g_yyFileName,ambig); if (g_yyFileDef && g_yyFileDef->isReference()) g_yyFileDef=0; + g_insideCS = g_yyFileName.right(3)==".cs"; } static void incrLevel() @@ -1817,7 +1819,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) g_insideComment=FALSE; BEGIN(DefineText); } -<DefName>{ID}/{B}*"\n" { +<DefName>{ID}/{B}*"\n" { // bare define g_argDict = 0; g_defArgs = -1; g_defName = yytext; @@ -1831,6 +1833,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) outputArray(tmp.data(),tmp.length()); g_quoteArg=FALSE; g_insideComment=FALSE; + if (g_insideCS) g_defText="1"; // for C#, use "1" as define text BEGIN(DefineText); } else // define is a guard => hide diff --git a/src/scanner.l b/src/scanner.l index 7862507..c6db28c 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -1713,6 +1713,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) } <FindMemberName>{SCOPENAME}{BN}*/"<" { sharpCount=0; + roundCount=0; lineCount(); current->name+=((QCString)yytext).stripWhiteSpace(); //current->memberSpec.resize(0); @@ -1722,7 +1723,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) else BEGIN( EndTemplate ); } -<EndTemplate>"<<" { +<ClassTemplSpec,EndTemplate>"<<" { current->name+=yytext; // *currentTemplateSpec+=yytext; } @@ -1731,8 +1732,8 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) // *currentTemplateSpec+='<'; sharpCount++; } -<EndTemplate>">>" { - if (insideJava || insideCS || insideCli) +<ClassTemplSpec,EndTemplate>">>" { + if (insideJava || insideCS || insideCli || roundCount==0) { unput('>'); unput(' '); @@ -1781,6 +1782,12 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) BEGIN(FindMemberName); } } +<ClassTemplSpec,EndTemplate>"(" { current->name+=*yytext; + roundCount++; + } +<ClassTemplSpec,EndTemplate>")" { current->name+=*yytext; + if (roundCount>0) roundCount--; + } <EndTemplate>. { current->name+=*yytext; // *currentTemplateSpec+=*yytext; @@ -4132,7 +4139,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) current->doc.resize(0); } #endif - if (current->sli) // copy special list items + if (current->sli && previous) // copy special list items { QListIterator<ListItemInfo> li(*current->sli); ListItemInfo *lii; @@ -4315,6 +4322,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) } else // C++ template specialization { + roundCount=0; BEGIN( ClassTemplSpec ); } } @@ -4770,9 +4778,22 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) { REJECT; } - else // for C++ >> is a bitshift operator and > > would end a nested template + else // for C++ >> is a bitshift + // operator and > > would end + // a nested template. + // We require the bitshift to be enclosed in braces. + // See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html { - *specName += yytext; + if (roundCount>0) + { + *specName += yytext; + } + else + { + unput('>'); + unput(' '); + unput('>'); + } } } <Specialization>"typename"{BN}+ { lineCount(); } diff --git a/src/search.css b/src/search.css index 7f316ab..0ef06d9 100644 --- a/src/search.css +++ b/src/search.css @@ -17,11 +17,12 @@ color: #999999; background-color: #FFFFFF; font-style: normal; - cursor: pointer; + cursor: text; padding: 0px 1px; margin: 0px 6px 0px 0px; border: none; outline: none; + vertical-align: middle; } #MSearchBox.MSearchBoxInactive:hover #MSearchField { background-color: #FFFFFF; @@ -41,14 +42,26 @@ display : inline; background : none; font: 9pt Verdana, sans-serif; - margin-right: -6px; - padding: 0; border: none; margin: 0px 0px 0px 6px; - vertical-align: bottom; + vertical-align: middle; + padding: 0px 0px; +} + +#MSearchClose { + float : none; + display : none; + background : none; + border: none; + margin: 0px 4px 0px 0px; padding: 0px 0px; - background-color: #84B0C7; + outline: none; +} + +#MSearchCloseImg { + vertical-align: middle; } + .MSearchBoxLeft { display: block; text-align: left; @@ -108,7 +121,7 @@ a.SelectItem { padding-left: 6px; padding-right: 12px; } -a.SelectItem:visited, +a.SelectItem:focus, a.SelectItem:active { color: #000000; outline-style: none; @@ -136,26 +149,6 @@ iframe#MSearchResults { border: 1px solid #000000; background-color: #EEF3F5; } -#MSearchResultsWindowClose { - font-weight: bold; - font-size: 8pt; - display: block; - padding: 0px; - margin: 0px; - text-align: right; - text-decoration: none; - outline-style: none; - } -#MSearchResultsWindowClose:link, -#MSearchResultsWindowClose:visited { - color: #8A8A8A; - background-color: #8A8A8A; - } -#MSearchResultsWindowClose:active, -#MSearchResultsWindowClose:hover { - color: #9E9E9E; - background-color: #9E9E9E; - } /* ----------------------------------- */ @@ -198,6 +191,11 @@ a.SRScope { outline: none; } +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + .SRPage .SRStatus { padding: 2px 5px; font-size: 8pt; diff --git a/src/search.js b/src/search.js index 02af28d..7f81e57 100644 --- a/src/search.js +++ b/src/search.js @@ -69,7 +69,7 @@ function SearchBox(name, resultsPath, inFrame) this.lastSearchValue = ""; this.lastResultsPage = ""; this.hideTimeout = 0; - this.searchTopic = "all"; + this.searchIndex = 0; this.searchActive = false; this.insideFrame = inFrame; @@ -90,8 +90,8 @@ function SearchBox(name, resultsPath, inFrame) this.DOMPopupSearchResultsWindow = function() { return document.getElementById("MSearchResultsWindow"); } - this.DOMSearchResultWindowClose = function() - { return document.getElementById("MSearchResultsWindowClose"); } + this.DOMSearchClose = function() + { return document.getElementById("MSearchClose"); } this.DOMSearchBox = function() { return document.getElementById("MSearchBox"); } @@ -150,7 +150,7 @@ function SearchBox(name, resultsPath, inFrame) } // Called when the content of the search field is changed. - this.OnSearchFieldChange = function() + this.OnSearchFieldChange = function(evt) { if (this.keyTimeout) // kill running timer { @@ -158,6 +158,40 @@ function SearchBox(name, resultsPath, inFrame) this.keyTimeout = 0; } + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 || e.keyCode==13) + { + if (e.shiftKey==1) + { + this.OnSearchSelectShow(); + var win=this.DOMSearchSelectWindow(); + for (i=0;i<win.childNodes.length;i++) + { + var child = win.childNodes[i]; // get span within a + if (child.className=='SelectItem') + { + child.focus(); + return; + } + } + return; + } + else if (window.frames.MSearchResults.searchResults) + { + var elem = window.frames.MSearchResults.searchResults.NavNext(0); + if (elem) elem.focus(); + } + } + else if (e.keyCode==27) // Escape out of the search field + { + this.DOMSearchField().blur(); + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.lastSearchValue = ''; + this.Activate(false); + return; + } + // strip whitespaces var searchValue = this.DOMSearchField().value.replace(/ +/g, ""); @@ -172,14 +206,28 @@ function SearchBox(name, resultsPath, inFrame) else // empty search field { this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; this.lastSearchValue = ''; } } } - // Called when an search filter selection is made. - // set item with index id as the active item - this.OnSelectItem = function(id,topic) + this.SelectItemCount = function(id) + { + var count=0; + var win=this.DOMSearchSelectWindow(); + for (i=0;i<win.childNodes.length;i++) + { + var child = win.childNodes[i]; // get span within a + if (child.className=='SelectItem') + { + count++; + } + } + return count; + } + + this.SelectItemSet = function(id) { var i,j=0; var win=this.DOMSearchSelectWindow(); @@ -191,7 +239,6 @@ function SearchBox(name, resultsPath, inFrame) var node = child.firstChild; if (j==id) { - // add a tickmark: see http://doogalbellend.blogspot.com/2007/05/even-more-on-tick-marks-in-html.html node.innerHTML='•'; } else @@ -201,31 +248,39 @@ function SearchBox(name, resultsPath, inFrame) j++; } } - if (topic) - { - this.searchTopic = topic; - var searchValue = this.DOMSearchField().value.replace(/ +/g, ""); - if (searchValue != "" && this.searchActive) // something was found -> do a search - { - this.Search(); - } - } - else + } + + // Called when an search filter selection is made. + // set item with index id as the active item + this.OnSelectItem = function(id) + { + this.searchIndex = id; + this.SelectItemSet(id); + var searchValue = this.DOMSearchField().value.replace(/ +/g, ""); + if (searchValue!="" && this.searchActive) // something was found -> do a search { - this.Activate(false); + this.Search(); } } - this.OnCloseHighlight = function(active) + this.OnSearchSelectKey = function(evt) { - var close = this.DOMSearchResultWindowClose(); - if (active) + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex<this.SelectItemCount()) // Down { - close.firstChild.src = this.resultsPath + '/close_active.png'; + this.searchIndex++; + this.OnSelectItem(this.searchIndex); } - else + else if (e.keyCode==38 && this.searchIndex>0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) { - close.firstChild.src = this.resultsPath + '/close.png'; + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); } return false; } @@ -235,13 +290,14 @@ function SearchBox(name, resultsPath, inFrame) // Closes the results window. this.CloseResultsWindow = function() { - this.DOMPopupSearchResultsWindow().style.display = "none"; + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; this.Activate(false); } this.CloseSelectionWindow = function() { - this.DOMSearchSelectWindow().style.display = "none"; + this.DOMSearchSelectWindow().style.display = 'none'; } // Performs a search. @@ -267,10 +323,9 @@ function SearchBox(name, resultsPath, inFrame) var resultsPageWithSearch; var hasResultsPage; - // indexSectionsWithContent is defined in searchdata.js - if (indexSectionsWithContent[this.searchTopic].charAt(code-32) == '1') + if (indexSectionsWithContent[this.searchIndex].charAt(code-32) == '1') { - resultsPage = this.resultsPath + '/' + this.searchTopic + '_' + hexCode + '.html'; + resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; resultsPageWithSearch = resultsPage+'?'+escape(searchValue); hasResultsPage = true; } @@ -284,13 +339,13 @@ function SearchBox(name, resultsPath, inFrame) window.frames.MSearchResults.location.href = resultsPageWithSearch; var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); - if (domPopupSearchResultsWindow.style.display!="block") + if (domPopupSearchResultsWindow.style.display!='block') { + var domSearchBox = this.DOMSearchBox(); + this.DOMSearchClose().style.display = 'inline'; if (this.insideFrame) { - var domSearchBox = this.DOMSearchBox(); var domPopupSearchResults = this.DOMPopupSearchResults(); - this.DOMSearchResultWindowClose().style.textAlign = 'left'; domPopupSearchResultsWindow.style.position = 'relative'; domPopupSearchResultsWindow.style.display = 'block'; var width = document.body.clientWidth - 8; // the -8 is for IE :-( @@ -299,10 +354,9 @@ function SearchBox(name, resultsPath, inFrame) } else { - var domSearchField = this.DOMSearchField(); var domPopupSearchResults = this.DOMPopupSearchResults(); - var left = getXPos(domSearchField) + domSearchField.offsetWidth; - var top = getYPos(domSearchField) + domSearchField.offsetHeight + 1; + var left = getXPos(domSearchBox) + domSearchBox.offsetWidth; + var top = getYPos(domSearchBox) + domSearchBox.offsetHeight + 1; domPopupSearchResultsWindow.style.display = 'block'; left -= domPopupSearchResults.offsetWidth; domPopupSearchResultsWindow.style.top = top + 'px'; @@ -352,9 +406,11 @@ function SearchResults(name) { // The number of matches from the last run of <Search()>. this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; // Toggles the visibility of the passed element ID. - this.Toggle = function(id) + this.FindChildElement = function(id) { var parentElement = document.getElementById(id); var element = parentElement.firstChild; @@ -363,14 +419,7 @@ function SearchResults(name) { if (element.nodeName == 'DIV' && element.className == 'SRChildren') { - if (element.style.display == 'block') - { - element.style.display = 'none'; - } - else - { - element.style.display = 'block'; - } + return element; } if (element.nodeName == 'DIV' && element.hasChildNodes()) @@ -397,6 +446,22 @@ function SearchResults(name) } } + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + // Searches for the passed string. If there is no parameter, // it takes it from the URL query. // @@ -431,26 +496,213 @@ function SearchResults(name) if (search.length<=rowMatchName.length && rowMatchName.substr(0, search.length)==search) { - row.style.display = "block"; + row.style.display = 'block'; matches++; } else { - row.style.display = "none"; + row.style.display = 'none'; } } i++; } - document.getElementById("Searching").style.display="none"; + document.getElementById("Searching").style.display='none'; if (matches == 0) // no results { - document.getElementById("NoMatches").style.display="block"; + document.getElementById("NoMatches").style.display='block'; } else // at least one result { - document.getElementById("NoMatches").style.display="none"; + document.getElementById("NoMatches").style.display='none'; } this.lastMatchCount = matches; return true; } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + parent.document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } } diff --git a/src/search_css.h b/src/search_css.h index 177dbe3..65ffed2 100644 --- a/src/search_css.h +++ b/src/search_css.h @@ -17,11 +17,12 @@ " color: #999999;\n" " background-color: #FFFFFF;\n" " font-style: normal;\n" -" cursor: pointer;\n" +" cursor: text;\n" " padding: 0px 1px;\n" " margin: 0px 6px 0px 0px;\n" " border: none;\n" " outline: none;\n" +" vertical-align: middle;\n" "}\n" "#MSearchBox.MSearchBoxInactive:hover #MSearchField {\n" " background-color: #FFFFFF;\n" @@ -41,14 +42,26 @@ " display : inline;\n" " background : none;\n" " font: 9pt Verdana, sans-serif;\n" -" margin-right: -6px;\n" -" padding: 0;\n" " border: none;\n" " margin: 0px 0px 0px 6px;\n" -" vertical-align: bottom;\n" +" vertical-align: middle;\n" +" padding: 0px 0px;\n" +"}\n" +"\n" +"#MSearchClose {\n" +" float : none;\n" +" display : none;\n" +" background : none;\n" +" border: none;\n" +" margin: 0px 4px 0px 0px;\n" " padding: 0px 0px;\n" -" background-color: #84B0C7;\n" +" outline: none;\n" +"}\n" +"\n" +"#MSearchCloseImg {\n" +" vertical-align: middle;\n" "}\n" +"\n" ".MSearchBoxLeft {\n" " display: block;\n" " text-align: left;\n" @@ -108,7 +121,7 @@ " padding-left: 6px;\n" " padding-right: 12px;\n" "}\n" -"a.SelectItem:visited,\n" +"a.SelectItem:focus,\n" "a.SelectItem:active {\n" " color: #000000; \n" " outline-style: none;\n" @@ -136,26 +149,6 @@ " border: 1px solid #000000;\n" " background-color: #EEF3F5;\n" " }\n" -"#MSearchResultsWindowClose {\n" -" font-weight: bold;\n" -" font-size: 8pt;\n" -" display: block;\n" -" padding: 0px;\n" -" margin: 0px;\n" -" text-align: right;\n" -" text-decoration: none;\n" -" outline-style: none;\n" -" }\n" -"#MSearchResultsWindowClose:link,\n" -"#MSearchResultsWindowClose:visited {\n" -" color: #8A8A8A;\n" -" background-color: #8A8A8A;\n" -" }\n" -"#MSearchResultsWindowClose:active,\n" -"#MSearchResultsWindowClose:hover {\n" -" color: #9E9E9E;\n" -" background-color: #9E9E9E;\n" -" }\n" "\n" "/* ----------------------------------- */\n" "\n" @@ -198,6 +191,11 @@ " outline: none;\n" "}\n" "\n" +"a.SRSymbol:focus, a.SRSymbol:active,\n" +"a.SRScope:focus, a.SRScope:active {\n" +" text-decoration: underline;\n" +"}\n" +"\n" ".SRPage .SRStatus {\n" " padding: 2px 5px;\n" " font-size: 8pt;\n" diff --git a/src/search_js.h b/src/search_js.h index 7a401e6..d7b2a75 100644 --- a/src/search_js.h +++ b/src/search_js.h @@ -69,7 +69,7 @@ " this.lastSearchValue = \"\";\n" " this.lastResultsPage = \"\";\n" " this.hideTimeout = 0;\n" -" this.searchTopic = \"all\";\n" +" this.searchIndex = 0;\n" " this.searchActive = false;\n" " this.insideFrame = inFrame;\n" "\n" @@ -90,8 +90,8 @@ " this.DOMPopupSearchResultsWindow = function()\n" " { return document.getElementById(\"MSearchResultsWindow\"); }\n" "\n" -" this.DOMSearchResultWindowClose = function()\n" -" { return document.getElementById(\"MSearchResultsWindowClose\"); }\n" +" this.DOMSearchClose = function()\n" +" { return document.getElementById(\"MSearchClose\"); }\n" "\n" " this.DOMSearchBox = function()\n" " { return document.getElementById(\"MSearchBox\"); }\n" @@ -150,7 +150,7 @@ " }\n" "\n" " // Called when the content of the search field is changed.\n" -" this.OnSearchFieldChange = function()\n" +" this.OnSearchFieldChange = function(evt)\n" " {\n" " if (this.keyTimeout) // kill running timer\n" " {\n" @@ -158,6 +158,40 @@ " this.keyTimeout = 0;\n" " }\n" "\n" +" var e = (evt) ? evt : window.event; // for IE\n" +" if (e.keyCode==40 || e.keyCode==13)\n" +" {\n" +" if (e.shiftKey==1)\n" +" {\n" +" this.OnSearchSelectShow();\n" +" var win=this.DOMSearchSelectWindow(); \n" +" for (i=0;i<win.childNodes.length;i++)\n" +" {\n" +" var child = win.childNodes[i]; // get span within a\n" +" if (child.className=='SelectItem')\n" +" {\n" +" child.focus();\n" +" return;\n" +" }\n" +" }\n" +" return;\n" +" }\n" +" else if (window.frames.MSearchResults.searchResults)\n" +" {\n" +" var elem = window.frames.MSearchResults.searchResults.NavNext(0);\n" +" if (elem) elem.focus();\n" +" }\n" +" }\n" +" else if (e.keyCode==27) // Escape out of the search field\n" +" {\n" +" this.DOMSearchField().blur();\n" +" this.DOMPopupSearchResultsWindow().style.display = 'none';\n" +" this.DOMSearchClose().style.display = 'none';\n" +" this.lastSearchValue = '';\n" +" this.Activate(false);\n" +" return;\n" +" }\n" +"\n" " // strip whitespaces\n" " var searchValue = this.DOMSearchField().value.replace(/ +/g, \"\");\n" "\n" @@ -172,14 +206,28 @@ " else // empty search field\n" " {\n" " this.DOMPopupSearchResultsWindow().style.display = 'none';\n" +" this.DOMSearchClose().style.display = 'none';\n" " this.lastSearchValue = '';\n" " }\n" " }\n" " }\n" "\n" -" // Called when an search filter selection is made.\n" -" // set item with index id as the active item\n" -" this.OnSelectItem = function(id,topic)\n" +" this.SelectItemCount = function(id)\n" +" {\n" +" var count=0;\n" +" var win=this.DOMSearchSelectWindow(); \n" +" for (i=0;i<win.childNodes.length;i++)\n" +" {\n" +" var child = win.childNodes[i]; // get span within a\n" +" if (child.className=='SelectItem')\n" +" {\n" +" count++;\n" +" }\n" +" }\n" +" return count;\n" +" }\n" +"\n" +" this.SelectItemSet = function(id)\n" " {\n" " var i,j=0;\n" " var win=this.DOMSearchSelectWindow(); \n" @@ -191,7 +239,6 @@ " var node = child.firstChild;\n" " if (j==id)\n" " {\n" -" // add a tickmark: see http://doogalbellend.blogspot.com/2007/05/even-more-on-tick-marks-in-html.html\n" " node.innerHTML='•';\n" " } \n" " else\n" @@ -201,31 +248,39 @@ " j++;\n" " }\n" " }\n" -" if (topic)\n" -" {\n" -" this.searchTopic = topic;\n" -" var searchValue = this.DOMSearchField().value.replace(/ +/g, \"\");\n" -" if (searchValue != \"\" && this.searchActive) // something was found -> do a search\n" -" {\n" -" this.Search();\n" -" }\n" -" }\n" -" else\n" +" }\n" +"\n" +" // Called when an search filter selection is made.\n" +" // set item with index id as the active item\n" +" this.OnSelectItem = function(id)\n" +" {\n" +" this.searchIndex = id;\n" +" this.SelectItemSet(id);\n" +" var searchValue = this.DOMSearchField().value.replace(/ +/g, \"\");\n" +" if (searchValue!=\"\" && this.searchActive) // something was found -> do a search\n" " {\n" -" this.Activate(false);\n" +" this.Search();\n" " }\n" " }\n" "\n" -" this.OnCloseHighlight = function(active)\n" +" this.OnSearchSelectKey = function(evt)\n" " {\n" -" var close = this.DOMSearchResultWindowClose();\n" -" if (active)\n" +" var e = (evt) ? evt : window.event; // for IE\n" +" if (e.keyCode==40 && this.searchIndex<this.SelectItemCount()) // Down\n" " {\n" -" close.firstChild.src = this.resultsPath + '/close_active.png';\n" +" this.searchIndex++;\n" +" this.OnSelectItem(this.searchIndex);\n" " }\n" -" else\n" +" else if (e.keyCode==38 && this.searchIndex>0) // Up\n" +" {\n" +" this.searchIndex--;\n" +" this.OnSelectItem(this.searchIndex);\n" +" }\n" +" else if (e.keyCode==13 || e.keyCode==27)\n" " {\n" -" close.firstChild.src = this.resultsPath + '/close.png';\n" +" this.OnSelectItem(this.searchIndex);\n" +" this.CloseSelectionWindow();\n" +" this.DOMSearchField().focus();\n" " }\n" " return false;\n" " }\n" @@ -235,13 +290,14 @@ " // Closes the results window.\n" " this.CloseResultsWindow = function()\n" " {\n" -" this.DOMPopupSearchResultsWindow().style.display = \"none\";\n" +" this.DOMPopupSearchResultsWindow().style.display = 'none';\n" +" this.DOMSearchClose().style.display = 'none';\n" " this.Activate(false);\n" " }\n" "\n" " this.CloseSelectionWindow = function()\n" " {\n" -" this.DOMSearchSelectWindow().style.display = \"none\";\n" +" this.DOMSearchSelectWindow().style.display = 'none';\n" " }\n" "\n" " // Performs a search.\n" @@ -267,10 +323,9 @@ " var resultsPageWithSearch;\n" " var hasResultsPage;\n" "\n" -" // indexSectionsWithContent is defined in searchdata.js\n" -" if (indexSectionsWithContent[this.searchTopic].charAt(code-32) == '1')\n" +" if (indexSectionsWithContent[this.searchIndex].charAt(code-32) == '1')\n" " {\n" -" resultsPage = this.resultsPath + '/' + this.searchTopic + '_' + hexCode + '.html';\n" +" resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html';\n" " resultsPageWithSearch = resultsPage+'?'+escape(searchValue);\n" " hasResultsPage = true;\n" " }\n" @@ -284,13 +339,13 @@ " window.frames.MSearchResults.location.href = resultsPageWithSearch; \n" " var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow();\n" "\n" -" if (domPopupSearchResultsWindow.style.display!=\"block\")\n" +" if (domPopupSearchResultsWindow.style.display!='block')\n" " {\n" +" var domSearchBox = this.DOMSearchBox();\n" +" this.DOMSearchClose().style.display = 'inline';\n" " if (this.insideFrame)\n" " {\n" -" var domSearchBox = this.DOMSearchBox();\n" " var domPopupSearchResults = this.DOMPopupSearchResults();\n" -" this.DOMSearchResultWindowClose().style.textAlign = 'left';\n" " domPopupSearchResultsWindow.style.position = 'relative';\n" " domPopupSearchResultsWindow.style.display = 'block';\n" " var width = document.body.clientWidth - 8; // the -8 is for IE :-(\n" @@ -299,10 +354,9 @@ " }\n" " else\n" " {\n" -" var domSearchField = this.DOMSearchField();\n" " var domPopupSearchResults = this.DOMPopupSearchResults();\n" -" var left = getXPos(domSearchField) + domSearchField.offsetWidth;\n" -" var top = getYPos(domSearchField) + domSearchField.offsetHeight + 1;\n" +" var left = getXPos(domSearchBox) + domSearchBox.offsetWidth;\n" +" var top = getYPos(domSearchBox) + domSearchBox.offsetHeight + 1;\n" " domPopupSearchResultsWindow.style.display = 'block';\n" " left -= domPopupSearchResults.offsetWidth;\n" " domPopupSearchResultsWindow.style.top = top + 'px';\n" @@ -352,9 +406,11 @@ "{\n" " // The number of matches from the last run of <Search()>.\n" " this.lastMatchCount = 0;\n" +" this.lastKey = 0;\n" +" this.repeatOn = false;\n" "\n" " // Toggles the visibility of the passed element ID.\n" -" this.Toggle = function(id)\n" +" this.FindChildElement = function(id)\n" " {\n" " var parentElement = document.getElementById(id);\n" " var element = parentElement.firstChild;\n" @@ -363,14 +419,7 @@ " {\n" " if (element.nodeName == 'DIV' && element.className == 'SRChildren')\n" " {\n" -" if (element.style.display == 'block')\n" -" { \n" -" element.style.display = 'none'; \n" -" }\n" -" else\n" -" { \n" -" element.style.display = 'block'; \n" -" }\n" +" return element;\n" " }\n" "\n" " if (element.nodeName == 'DIV' && element.hasChildNodes())\n" @@ -397,6 +446,22 @@ " }\n" " }\n" "\n" +" this.Toggle = function(id)\n" +" {\n" +" var element = this.FindChildElement(id);\n" +" if (element)\n" +" {\n" +" if (element.style.display == 'block')\n" +" { \n" +" element.style.display = 'none'; \n" +" }\n" +" else\n" +" { \n" +" element.style.display = 'block'; \n" +" }\n" +" }\n" +" }\n" +"\n" " // Searches for the passed string. If there is no parameter, \n" " // it takes it from the URL query.\n" " //\n" @@ -431,26 +496,213 @@ " if (search.length<=rowMatchName.length && \n" " rowMatchName.substr(0, search.length)==search)\n" " {\n" -" row.style.display = \"block\";\n" +" row.style.display = 'block';\n" " matches++;\n" " }\n" " else\n" " { \n" -" row.style.display = \"none\"; \n" +" row.style.display = 'none'; \n" " }\n" " }\n" " i++;\n" " }\n" -" document.getElementById(\"Searching\").style.display=\"none\";\n" +" document.getElementById(\"Searching\").style.display='none';\n" " if (matches == 0) // no results\n" " { \n" -" document.getElementById(\"NoMatches\").style.display=\"block\"; \n" +" document.getElementById(\"NoMatches\").style.display='block'; \n" " }\n" " else // at least one result\n" " { \n" -" document.getElementById(\"NoMatches\").style.display=\"none\"; \n" +" document.getElementById(\"NoMatches\").style.display='none'; \n" " }\n" " this.lastMatchCount = matches;\n" " return true;\n" " }\n" +"\n" +" // return the first item with index index or higher that is visible\n" +" this.NavNext = function(index)\n" +" {\n" +" var focusItem;\n" +" while (1)\n" +" {\n" +" var focusName = 'Item'+index;\n" +" focusItem = document.getElementById(focusName);\n" +" if (focusItem && focusItem.parentNode.parentNode.style.display=='block')\n" +" {\n" +" break;\n" +" }\n" +" else if (!focusItem) // last element\n" +" {\n" +" break;\n" +" }\n" +" focusItem=null;\n" +" index++;\n" +" }\n" +" return focusItem;\n" +" }\n" +"\n" +" this.NavPrev = function(index)\n" +" {\n" +" var focusItem;\n" +" while (1)\n" +" {\n" +" var focusName = 'Item'+index;\n" +" focusItem = document.getElementById(focusName);\n" +" if (focusItem && focusItem.parentNode.parentNode.style.display=='block')\n" +" {\n" +" break;\n" +" }\n" +" else if (!focusItem) // last element\n" +" {\n" +" break;\n" +" }\n" +" focusItem=null;\n" +" index--;\n" +" }\n" +" return focusItem;\n" +" }\n" +"\n" +" this.ProcessKeys = function(e)\n" +" {\n" +" if (e.type == \"keydown\") \n" +" {\n" +" this.repeatOn = false;\n" +" this.lastKey = e.keyCode;\n" +" }\n" +" else if (e.type == \"keypress\")\n" +" {\n" +" if (!this.repeatOn)\n" +" {\n" +" if (this.lastKey) this.repeatOn = true;\n" +" return false; // ignore first keypress after keydown\n" +" }\n" +" }\n" +" else if (e.type == \"keyup\")\n" +" {\n" +" this.lastKey = 0;\n" +" this.repeatOn = false;\n" +" }\n" +" return this.lastKey!=0;\n" +" }\n" +"\n" +" this.Nav = function(evt,itemIndex) \n" +" {\n" +" var e = (evt) ? evt : window.event; // for IE\n" +" if (e.keyCode==13) return true;\n" +" if (!this.ProcessKeys(e)) return false;\n" +"\n" +" if (this.lastKey==38) // Up\n" +" {\n" +" var newIndex = itemIndex-1;\n" +" var focusItem = this.NavPrev(newIndex);\n" +" if (focusItem)\n" +" {\n" +" var child = this.FindChildElement(focusItem.parentNode.parentNode.id);\n" +" if (child && child.style.display == 'block') // children visible\n" +" { \n" +" var n=0;\n" +" var tmpElem;\n" +" while (1) // search for last child\n" +" {\n" +" tmpElem = document.getElementById('Item'+newIndex+'_c'+n);\n" +" if (tmpElem) \n" +" {\n" +" focusItem = tmpElem; \n" +" }\n" +" else // found it!\n" +" {\n" +" break;\n" +" }\n" +" n++;\n" +" }\n" +" }\n" +" }\n" +" if (focusItem)\n" +" {\n" +" focusItem.focus();\n" +" }\n" +" else // return focus to search field\n" +" {\n" +" parent.document.getElementById(\"MSearchField\").focus();\n" +" }\n" +" }\n" +" else if (this.lastKey==40) // Down\n" +" {\n" +" var newIndex = itemIndex+1;\n" +" var focusItem;\n" +" var item = document.getElementById('Item'+itemIndex);\n" +" var elem = this.FindChildElement(item.parentNode.parentNode.id);\n" +" if (elem && elem.style.display == 'block') // children visible\n" +" {\n" +" focusItem = document.getElementById('Item'+itemIndex+'_c0');\n" +" }\n" +" if (!focusItem) focusItem = this.NavNext(newIndex);\n" +" if (focusItem) focusItem.focus();\n" +" }\n" +" else if (this.lastKey==39) // Right\n" +" {\n" +" var item = document.getElementById('Item'+itemIndex);\n" +" var elem = this.FindChildElement(item.parentNode.parentNode.id);\n" +" if (elem) elem.style.display = 'block';\n" +" }\n" +" else if (this.lastKey==37) // Left\n" +" {\n" +" var item = document.getElementById('Item'+itemIndex);\n" +" var elem = this.FindChildElement(item.parentNode.parentNode.id);\n" +" if (elem) elem.style.display = 'none';\n" +" }\n" +" else if (this.lastKey==27) // Escape\n" +" {\n" +" parent.searchBox.CloseResultsWindow();\n" +" parent.document.getElementById(\"MSearchField\").focus();\n" +" }\n" +" else if (this.lastKey==13) // Enter\n" +" {\n" +" return true;\n" +" }\n" +" return false;\n" +" }\n" +"\n" +" this.NavChild = function(evt,itemIndex,childIndex)\n" +" {\n" +" var e = (evt) ? evt : window.event; // for IE\n" +" if (e.keyCode==13) return true;\n" +" if (!this.ProcessKeys(e)) return false;\n" +"\n" +" if (this.lastKey==38) // Up\n" +" {\n" +" if (childIndex>0)\n" +" {\n" +" var newIndex = childIndex-1;\n" +" document.getElementById('Item'+itemIndex+'_c'+newIndex).focus();\n" +" }\n" +" else // already at first child, jump to parent\n" +" {\n" +" document.getElementById('Item'+itemIndex).focus();\n" +" }\n" +" }\n" +" else if (this.lastKey==40) // Down\n" +" {\n" +" var newIndex = childIndex+1;\n" +" var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex);\n" +" if (!elem) // last child, jump to parent next parent\n" +" {\n" +" elem = this.NavNext(itemIndex+1);\n" +" }\n" +" if (elem)\n" +" {\n" +" elem.focus();\n" +" } \n" +" }\n" +" else if (this.lastKey==27) // Escape\n" +" {\n" +" parent.searchBox.CloseResultsWindow();\n" +" parent.document.getElementById(\"MSearchField\").focus();\n" +" }\n" +" else if (this.lastKey==13) // Enter\n" +" {\n" +" return true;\n" +" }\n" +" return false;\n" +" }\n" "}\n" diff --git a/src/util.cpp b/src/util.cpp index ec8f8db..d6519c4 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -305,7 +305,8 @@ int guessSection(const char *name) n.right(4)==".ixx" || n.right(4)==".ipp" || n.right(4)==".i++" || - n.right(4)==".inl" + n.right(4)==".inl" || + n.right(4)==".xml" ) return Entry::SOURCE_SEC; if (n.right(2)==".h" || // header n.right(3)==".hh" || @@ -6069,22 +6070,6 @@ static void latin2ToLatex(QTextStream &t,unsigned char c) void filterLatexString(QTextStream &t,const char *str, bool insideTabbing,bool insidePre,bool insideItem) { -#if 0 - static bool isCzech = theTranslator->idLanguage()=="czech"; - static bool isSerbian = theTranslator->idLanguage()=="serbian"; - static bool isJapanese = theTranslator->idLanguage()=="japanese" || - theTranslator->idLanguage()=="japanese-en"; - static bool isKorean = theTranslator->idLanguage()=="korean" || - theTranslator->idLanguage()=="korean-en"; - static bool isRussian = theTranslator->idLanguage()=="russian"; - static bool isUkrainian = theTranslator->idLanguage()=="ukrainian"; - static bool isSlovene = theTranslator->idLanguage()=="solvene"; - static bool isChinese = theTranslator->idLanguage()=="chinese" || - theTranslator->idLanguage()=="chinese-traditional"; - static bool isLatin2 = theTranslator->idLanguageCharset()=="iso-8859-2"; - static bool isGreek = theTranslator->idLanguage()=="greek"; - //printf("filterLatexString(%s)\n",str); -#endif if (str) { const unsigned char *p=(const unsigned char *)str; @@ -6104,25 +6089,6 @@ void filterLatexString(QTextStream &t,const char *str, case '_': t << "\\_"; break; default: t << (char)c; -#if 0 - { - // Some languages use wide characters - if (c>=128 && (isJapanese || isKorean || isChinese || isSerbian)) - { - t << (char)c; - if (*p) - { - c = *p++; - t << (char)c; - } - } - else - { - t << (char)c; - } - break; - } -#endif } } else @@ -6155,10 +6121,7 @@ void filterLatexString(QTextStream &t,const char *str, else t << "]"; break; - case '-': if (*p=='>') - { t << " $\\rightarrow$ "; p++; } - else - { t << (char)c; } + case '-': t << "-\\/"; break; case '\\': if (*p=='<') { t << "$<$"; p++; } @@ -6445,6 +6408,7 @@ g_lang2extMap[] = { "python", "python", SrcLangExt_Python }, { "fortran", "fortran", SrcLangExt_F90 }, { "vhdl", "vhdl", SrcLangExt_VHDL }, + { "dbusxml", "dbusxml", SrcLangExt_XML }, { 0, 0, (SrcLangExt)0 } }; @@ -6507,6 +6471,7 @@ void initDefaultExtensionMapping() updateLanguageMapping(".f90", "fortran"); updateLanguageMapping(".vhd", "vhdl"); updateLanguageMapping(".vhdl", "vhdl"); + updateLanguageMapping(".xml", "dbusxml"); } SrcLangExt getLanguageFromFileName(const QCString fileName) @@ -95,7 +95,8 @@ enum SrcLangExt SrcLangExt_JS = 0x0400, SrcLangExt_Python = 0x0800, SrcLangExt_F90 = 0x1000, - SrcLangExt_VHDL = 0x2000 + SrcLangExt_VHDL = 0x2000, + SrcLangExt_XML = 0x4000 }; //-------------------------------------------------------------------- |