summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>2009-07-20 20:05:52 (GMT)
committerdimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>2009-07-20 20:05:52 (GMT)
commit6e28050ef5483e624122b0bacb998c40664f78ee (patch)
treeb8b0cb3ac894bdb88087d78e328a8a0d88943b97
parent7c0a46b50fad0925e47b78326f8c2e92e3829fb4 (diff)
downloadDoxygen-6e28050ef5483e624122b0bacb998c40664f78ee.zip
Doxygen-6e28050ef5483e624122b0bacb998c40664f78ee.tar.gz
Doxygen-6e28050ef5483e624122b0bacb998c40664f78ee.tar.bz2
Release-1.5.9-20090720
-rw-r--r--INSTALL4
-rw-r--r--README4
-rw-r--r--addon/doxywizard/Makefile.in6
-rwxr-xr-xconfigure2
-rw-r--r--doc/config.doc37
-rw-r--r--doc/dbusxml.doc141
-rw-r--r--doc/installdox_usage.doc7
-rw-r--r--doc/starting.doc8
-rw-r--r--examples/dbusxml.cfg10
-rw-r--r--examples/dbusxml.xml78
-rw-r--r--qtools/Doxyfile15
-rw-r--r--src/commentcnv.l2
-rw-r--r--src/config.xml14
-rw-r--r--src/configoptions.cpp21
-rw-r--r--src/dbusxmlscanner.cpp874
-rw-r--r--src/dbusxmlscanner.h57
-rw-r--r--src/docparser.h1
-rw-r--r--src/docsets.cpp1
-rw-r--r--src/doxygen.cpp38
-rw-r--r--src/doxygen.h1
-rw-r--r--src/fortranscanner.l23
-rw-r--r--src/ftvhelp.cpp6
-rw-r--r--src/htmlgen.cpp123
-rw-r--r--src/index.cpp72
-rw-r--r--src/latexgen.cpp9
-rw-r--r--src/libdoxygen.pro.in2
-rw-r--r--src/portable.cpp5
-rw-r--r--src/portable.h1
-rw-r--r--src/pre.l5
-rw-r--r--src/scanner.l33
-rw-r--r--src/search.css50
-rw-r--r--src/search.js352
-rw-r--r--src/search_css.h50
-rw-r--r--src/search_js.h352
-rw-r--r--src/util.cpp45
-rw-r--r--src/util.h3
36 files changed, 2072 insertions, 380 deletions
diff --git a/INSTALL b/INSTALL
index 81b8294..012b839 100644
--- a/INSTALL
+++ b/INSTALL
@@ -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)
diff --git a/README b/README
index 8d60917..6d0ac8a 100644
--- a/README
+++ b/README
@@ -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
diff --git a/configure b/configure
index 4675673..dc6bf06 100755
--- a/configure
+++ b/configure
@@ -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\">&nbsp;</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);
diff --git a/src/pre.l b/src/pre.l
index c818ce9..83f5c9f 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -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='&bull;';
}
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='&bull;';\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)
diff --git a/src/util.h b/src/util.h
index d3d10fd..10f125f 100644
--- a/src/util.h
+++ b/src/util.h
@@ -95,7 +95,8 @@ enum SrcLangExt
SrcLangExt_JS = 0x0400,
SrcLangExt_Python = 0x0800,
SrcLangExt_F90 = 0x1000,
- SrcLangExt_VHDL = 0x2000
+ SrcLangExt_VHDL = 0x2000,
+ SrcLangExt_XML = 0x4000
};
//--------------------------------------------------------------------