summaryrefslogtreecommitdiffstats
path: root/trunk/addon/doxywizard
diff options
context:
space:
mode:
authordimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>2012-03-17 20:33:32 (GMT)
committerdimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7>2012-03-17 20:33:32 (GMT)
commit8f455b66da9db238655242d1213c05affac412d9 (patch)
treefbaf0bfe6a7de14413f6738b180d69d4aeb3a69b /trunk/addon/doxywizard
parentb9ef81152f75067cec55d4b37a4a25658f1f2a60 (diff)
downloadDoxygen-8f455b66da9db238655242d1213c05affac412d9.zip
Doxygen-8f455b66da9db238655242d1213c05affac412d9.tar.gz
Doxygen-8f455b66da9db238655242d1213c05affac412d9.tar.bz2
Release-1.8.0
Diffstat (limited to 'trunk/addon/doxywizard')
-rw-r--r--trunk/addon/doxywizard/Makefile.in39
-rw-r--r--trunk/addon/doxywizard/README3
-rw-r--r--trunk/addon/doxywizard/config.h18
-rw-r--r--trunk/addon/doxywizard/config.l555
-rw-r--r--trunk/addon/doxywizard/doxywizard.cpp639
-rw-r--r--trunk/addon/doxywizard/doxywizard.h84
-rw-r--r--trunk/addon/doxywizard/doxywizard.icobin0 -> 84071 bytes
-rw-r--r--trunk/addon/doxywizard/doxywizard.pro.in28
-rw-r--r--trunk/addon/doxywizard/doxywizard.qrc11
-rw-r--r--trunk/addon/doxywizard/doxywizard.rc1
-rw-r--r--trunk/addon/doxywizard/expert.cpp561
-rw-r--r--trunk/addon/doxywizard/expert.h65
-rw-r--r--trunk/addon/doxywizard/helplabel.h33
-rw-r--r--trunk/addon/doxywizard/images/add.pngbin0 -> 4321 bytes
-rw-r--r--trunk/addon/doxywizard/images/del.pngbin0 -> 4231 bytes
-rw-r--r--trunk/addon/doxywizard/images/file.pngbin0 -> 4380 bytes
-rw-r--r--trunk/addon/doxywizard/images/folder.pngbin0 -> 4308 bytes
-rw-r--r--trunk/addon/doxywizard/images/refresh.pngbin0 -> 4458 bytes
-rw-r--r--trunk/addon/doxywizard/images/tunecolor.pngbin0 -> 116333 bytes
-rw-r--r--trunk/addon/doxywizard/input.h34
-rw-r--r--trunk/addon/doxywizard/inputbool.cpp110
-rw-r--r--trunk/addon/doxywizard/inputbool.h70
-rw-r--r--trunk/addon/doxywizard/inputint.cpp96
-rw-r--r--trunk/addon/doxywizard/inputint.h70
-rw-r--r--trunk/addon/doxywizard/inputstring.cpp193
-rw-r--r--trunk/addon/doxywizard/inputstring.h90
-rw-r--r--trunk/addon/doxywizard/inputstrlist.cpp254
-rw-r--r--trunk/addon/doxywizard/inputstrlist.h91
-rw-r--r--trunk/addon/doxywizard/version.h23
-rw-r--r--trunk/addon/doxywizard/wizard.cpp1295
-rw-r--r--trunk/addon/doxywizard/wizard.h253
31 files changed, 4616 insertions, 0 deletions
diff --git a/trunk/addon/doxywizard/Makefile.in b/trunk/addon/doxywizard/Makefile.in
new file mode 100644
index 0000000..5b0876e
--- /dev/null
+++ b/trunk/addon/doxywizard/Makefile.in
@@ -0,0 +1,39 @@
+#
+#
+#
+# Copyright (C) 1997-2012 by Dimitri van Heesch.
+#
+# 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.
+#
+
+QMAKE=qmake $(MKSPECS)
+
+all: Makefile.doxywizard
+ $(MAKE) -f Makefile.doxywizard
+
+Makefile.doxywizard: doxywizard.pro
+ $(QMAKE) doxywizard.pro -o Makefile.doxywizard
+
+qmake:
+ $(QMAKE) doxywizard.pro -o Makefile.doxywizard
+
+clean: Makefile.doxywizard
+ $(MAKE) -f Makefile.doxywizard clean
+
+distclean: Makefile.doxywizard
+ $(MAKE) -f Makefile.doxywizard distclean
+ $(RM) Makefile.doxywizard
+
+install:
+ $(INSTTOOL) -d $(INSTALL)/bin
+ $(INSTTOOL) -m 755 ../../bin/doxywizard $(INSTALL)/bin
+ $(INSTTOOL) -d $(INSTALL)/$(MAN1DIR)
+ cat ../../doc/doxywizard.1 | sed -e "s/DATE/$(DATE)/g" -e "s/VERSION/$(VERSION)/g" > doxywizard.1
+ $(INSTTOOL) -m 644 doxywizard.1 $(INSTALL)/$(MAN1DIR)/doxywizard.1
+ rm doxywizard.1
+
+FORCE:
diff --git a/trunk/addon/doxywizard/README b/trunk/addon/doxywizard/README
new file mode 100644
index 0000000..57705f0
--- /dev/null
+++ b/trunk/addon/doxywizard/README
@@ -0,0 +1,3 @@
+Doxywizard is a graphical front-end to read/edit/write doxygen configuration
+files and to launch doxygen. It requires Qt version 4.3 or higher.
+
diff --git a/trunk/addon/doxywizard/config.h b/trunk/addon/doxywizard/config.h
new file mode 100644
index 0000000..d40f1f4
--- /dev/null
+++ b/trunk/addon/doxywizard/config.h
@@ -0,0 +1,18 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include <QHash>
+#include <QString>
+
+class Input;
+class QTextStream;
+class QTextCodec;
+
+bool parseConfig(
+ const QString &fileName,
+ const QHash<QString,Input *> &options
+ );
+
+void writeStringValue(QTextStream &t,QTextCodec *codec,const QString &s);
+
+#endif
diff --git a/trunk/addon/doxywizard/config.l b/trunk/addon/doxywizard/config.l
new file mode 100644
index 0000000..fa49eba
--- /dev/null
+++ b/trunk/addon/doxywizard/config.l
@@ -0,0 +1,555 @@
+/******************************************************************************
+ *
+ * $Id: config_templ.l,v 1.8 2001/01/01 10:15:16 root Exp $
+ *
+ * Copyright (C) 1997-2012 by Dimitri van Heesch.
+ *
+ * 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.
+ *
+ */
+
+%{
+
+/*
+ * includes
+ */
+#include "config.h"
+#include "input.h"
+#include <QtCore>
+
+#define MAX_INCLUDE_DEPTH 10
+
+
+/* -----------------------------------------------------------------
+ *
+ * static variables
+ */
+
+struct ConfigFileState
+{
+ int lineNr;
+ FILE *file;
+ YY_BUFFER_STATE oldState;
+ YY_BUFFER_STATE newState;
+ QString fileName;
+};
+
+static const QHash<QString,Input*> *g_options;
+static FILE *g_file;
+static QString g_yyFileName;
+static QString g_includeName;
+static QVariant g_includePathList;
+static QStack<ConfigFileState*> g_includeStack;
+static int g_includeDepth;
+static QVariant *g_arg;
+static Input *g_curOption=0;
+static QString g_elemStr;
+static QTextCodec *g_codec = QTextCodec::codecForName("UTF-8");
+static QString g_codecName = QString::fromAscii("UTF-8");
+static int g_lastState;
+static QByteArray g_tmpString;
+
+/* -----------------------------------------------------------------
+ */
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int maxSize)
+{
+ // no file included
+ if (g_includeStack.isEmpty())
+ {
+ return fread(buf,1,maxSize,g_file);
+ }
+ else
+ {
+ return fread(buf,1,maxSize,g_includeStack.top()->file);
+ }
+}
+
+void config_err(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+}
+void config_warn(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+}
+
+static void substEnvVarsInStrList(QStringList &sl);
+static void substEnvVarsInString(QString &s);
+
+static void checkEncoding()
+{
+ Input *option = g_options->value(QString::fromAscii("DOXYFILE_ENCODING"));
+ if (option && option->value().toString()!=g_codecName)
+ {
+ QTextCodec *newCodec = QTextCodec::codecForName(option->value().toString().toAscii());
+ if (newCodec)
+ {
+ g_codec = newCodec;
+ g_codecName = option->value().toString();
+ }
+ }
+}
+
+static FILE *tryPath(const QString &path,const QString &fileName)
+{
+ QString absName=!path.isEmpty() ? path+QString::fromAscii("/")+fileName : fileName;
+ QFileInfo fi(absName);
+ if (fi.exists() && fi.isFile())
+ {
+ FILE *f = fopen(absName.toLocal8Bit(),"r");
+ if (f==NULL)
+ config_err("Error: could not open file %s for reading\n",absName.toLatin1().data());
+ else
+ return f;
+ }
+ return NULL;
+}
+
+static FILE *findFile(const QString &fileName)
+{
+ if (QFileInfo(fileName).isAbsolute()) // absolute path
+ {
+ return tryPath(QString(), fileName);
+ }
+
+ // relative path, try with include paths in the list
+ QStringList sl = g_includePathList.toStringList();
+ substEnvVarsInStrList(sl);
+ foreach (QString s, sl)
+ {
+ FILE *f = tryPath(s,fileName);
+ if (f) return f;
+ }
+ // try cwd if g_includePathList fails
+ return tryPath(QString::fromAscii("."),fileName);
+}
+
+static void readIncludeFile(const QString &incName)
+{
+ if (g_includeDepth==MAX_INCLUDE_DEPTH)
+ {
+ config_err("Error: maximum include depth (%d) reached, %s is not included. Aborting...\n",
+ MAX_INCLUDE_DEPTH,qPrintable(incName));
+ exit(1);
+ }
+
+ QString inc = incName;
+ substEnvVarsInString(inc);
+ inc = inc.trimmed();
+ uint incLen = inc.length();
+ if (inc.at(0)==QChar::fromAscii('"') &&
+ inc.at(incLen-1)==QChar::fromAscii('"')) // strip quotes
+ {
+ inc=inc.mid(1,incLen-2);
+ }
+
+ FILE *f = findFile(inc);
+ if (f) // see if the include file can be found
+ {
+ // For debugging
+#if SHOW_INCLUDES
+ for (i=0;i<includeStack.count();i++) msg(" ");
+ msg("@INCLUDE = %s: parsing...\n",inc.toLatin1().data());
+#endif
+
+ // store the state of the old file
+ ConfigFileState *fs=new ConfigFileState;
+ fs->oldState=YY_CURRENT_BUFFER;
+ fs->fileName=g_yyFileName;
+ fs->file=f;
+ // push the state on the stack
+ g_includeStack.push(fs);
+ // set the scanner to the include file
+ yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
+ fs->newState=YY_CURRENT_BUFFER;
+ g_yyFileName=inc;
+ g_includeDepth++;
+ }
+ else
+ {
+ config_err("Error: @INCLUDE = %s: not found!\n",inc.toLatin1().data());
+ exit(1);
+ }
+}
+
+
+%}
+
+%option nounput
+%option noyywrap
+%option yylineno
+
+%x Start
+%x SkipComment
+%x SkipInvalid
+%x GetString
+%x GetStrList
+%x GetQuotedString
+%x GetEnvVar
+%x Include
+
+%%
+
+<*>\0x0d
+<Start,GetString,GetStrList,SkipInvalid>"#" { BEGIN(SkipComment); }
+<Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"=" { QString cmd = g_codec->toUnicode(yytext);
+ cmd=cmd.left(cmd.length()-1).trimmed();
+ g_curOption = g_options->value(cmd);
+ if (g_curOption==0) // oops not known
+ {
+ config_err("Warning: ignoring unsupported tag `%s' at line %d, file %s\n",
+ qPrintable(cmd),yylineno,qPrintable(g_yyFileName));
+ BEGIN(SkipInvalid);
+ }
+ else // known tag
+ {
+ //option->setEncoding(encoding);
+ g_arg = &g_curOption->value();
+ switch(g_curOption->kind())
+ {
+ case Input::StrList:
+ g_elemStr = QString();
+ *g_arg = QStringList();
+ BEGIN(GetStrList);
+ break;
+ case Input::String:
+ BEGIN(GetString);
+ break;
+ case Input::Int:
+ BEGIN(GetString);
+ break;
+ case Input::Bool:
+ BEGIN(GetString);
+ break;
+ case Input::Obsolete:
+ config_err("Warning: Tag `%s' at line %d of file %s has become obsolete.\n"
+ "To avoid this warning please update your configuration "
+ "file using \"doxygen -u\"\n", qPrintable(cmd),
+ yylineno,qPrintable(g_yyFileName));
+ BEGIN(SkipInvalid);
+ break;
+ }
+ }
+ }
+<Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"+=" { QString cmd=g_codec->toUnicode(yytext);
+ cmd=cmd.left(cmd.length()-2).trimmed();
+ g_curOption = g_options->value(cmd);
+ if (g_curOption==0) // oops not known
+ {
+ config_err("Warning: ignoring unsupported tag `%s' at line %d, file %s\n",
+ yytext,yylineno,qPrintable(g_yyFileName));
+ BEGIN(SkipInvalid);
+ }
+ else // known tag
+ {
+ switch(g_curOption->kind())
+ {
+ case Input::StrList:
+ g_arg = &g_curOption->value();
+ g_elemStr=QString();
+ BEGIN(GetStrList);
+ break;
+ case Input::String:
+ case Input::Int:
+ case Input::Bool:
+ config_err("Warning: operator += not supported for `%s'. Ignoring line at line %d, file %s\n",
+ yytext,yylineno,qPrintable(g_yyFileName));
+ BEGIN(SkipInvalid);
+ break;
+ case Input::Obsolete:
+ config_err("Warning: Tag `%s' at line %d of file %s has become obsolete.\n"
+ "To avoid this warning please update your configuration "
+ "file using \"doxygen -u\"\n",
+ qPrintable(cmd),yylineno,qPrintable(g_yyFileName));
+ BEGIN(SkipInvalid);
+ break;
+ }
+ }
+ }
+<Start>"@INCLUDE_PATH"[ \t]*"=" { BEGIN(GetStrList); g_arg=&g_includePathList; *g_arg = QStringList(); g_elemStr=QString(); }
+ /* include a config file */
+<Start>"@INCLUDE"[ \t]*"=" { BEGIN(Include);}
+<Include>([^ \"\t\r\n]+)|("\""[^\n\"]+"\"") {
+ readIncludeFile(g_codec->toUnicode(yytext));
+ BEGIN(Start);
+ }
+<<EOF>> {
+ //printf("End of include file\n");
+ //printf("Include stack depth=%d\n",g_includeStack.count());
+ if (g_includeStack.isEmpty())
+ {
+ //printf("Terminating scanner!\n");
+ yyterminate();
+ }
+ else
+ {
+ ConfigFileState *fs = g_includeStack.pop();
+ fclose(fs->file);
+ YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer( fs->oldState );
+ yy_delete_buffer( oldBuf );
+ g_yyFileName=fs->fileName;
+ delete fs;
+ g_includeDepth--;
+ }
+ }
+
+<Start>[a-z_A-Z0-9]+ { config_err("Warning: ignoring unknown tag `%s' at line %d, file %s\n",yytext,yylineno,qPrintable(g_yyFileName)); }
+<GetString,SkipInvalid>\n { BEGIN(Start); }
+<GetStrList>\n {
+ if (!g_elemStr.isEmpty())
+ {
+ //printf("elemStr1=`%s'\n",elemStr.toLatin1().data());
+ *g_arg = QVariant(g_arg->toStringList() << g_elemStr);
+ }
+ BEGIN(Start);
+ }
+<GetStrList>[ \t]+ {
+ if (!g_elemStr.isEmpty())
+ {
+ //printf("elemStr2=`%s'\n",elemStr.toLatin1().data());
+ *g_arg = QVariant(g_arg->toStringList() << g_elemStr);
+ }
+ g_elemStr = QString();
+ }
+<GetString>[^ \"\t\r\n]+ {
+ *g_arg = QVariant(g_codec->toUnicode(yytext));
+ checkEncoding();
+ }
+<GetString,GetStrList,SkipInvalid>"\"" { g_lastState=YY_START;
+ BEGIN(GetQuotedString);
+ g_tmpString="";
+ }
+<GetQuotedString>"\""|"\n" {
+ // we add a bogus space to signal that the string was quoted. This space will be stripped later on.
+ g_tmpString+=" ";
+ //printf("Quoted String = `%s'\n",tmpString.toLatin1().data());
+ if (g_lastState==GetString)
+ {
+ *g_arg = g_codec->toUnicode(g_tmpString);
+ checkEncoding();
+ }
+ else
+ {
+ g_elemStr+=g_codec->toUnicode(g_tmpString);
+ }
+ if (*yytext=='\n')
+ {
+ config_err("Warning: Missing end quote (\") on line %d, file %s\n",yylineno,
+ qPrintable(g_yyFileName));
+ }
+ BEGIN(g_lastState);
+ }
+<GetQuotedString>"\\\"" {
+ g_tmpString+='"';
+ }
+<GetQuotedString>. { g_tmpString+=*yytext; }
+<GetStrList>[^ \#\"\t\r\n]+ {
+ g_elemStr+=g_codec->toUnicode(yytext);
+ }
+<SkipComment>\n { BEGIN(Start); }
+<SkipComment>\\[ \r\t]*\n { BEGIN(Start); }
+<*>\\[ \r\t]*\n { }
+<*>\n
+<*>.
+
+%%
+
+/*@ ----------------------------------------------------------------------------
+ */
+
+static void substEnvVarsInString(QString &s)
+{
+ static QRegExp re(QString::fromAscii("\\$\\([a-z_A-Z0-9]+\\)"));
+ if (s.isEmpty()) return;
+ int p=0;
+ int i,l;
+ //printf("substEnvVarInString(%s) start\n",s.toLatin1().data());
+ while ((i=re.indexIn(s,p))!=-1)
+ {
+ l = re.matchedLength();
+ //printf("Found environment var s.mid(%d,%d)=`%s'\n",i+2,l-3,s.mid(i+2,l-3).toLatin1().data());
+ QString env=g_codec->toUnicode(getenv(s.mid(i+2,l-3).toLatin1()));
+ substEnvVarsInString(env); // recursively expand variables if needed.
+ s = s.left(i)+env+s.right(s.length()-i-l);
+ p=i+env.length(); // next time start at the end of the expanded string
+ }
+ s=s.trimmed(); // to strip the bogus space that was added when an argument
+ // has quotes
+ //printf("substEnvVarInString(%s) end\n",s.toLatin1().data());
+}
+
+static void substEnvVarsInStrList(QStringList &sl)
+{
+ QStringList out;
+
+ foreach (QString result, sl)
+ {
+ // an argument with quotes will have an extra space at the end, so wasQuoted will be TRUE.
+ bool wasQuoted = (result.indexOf(QChar::fromAscii(' '))!=-1) ||
+ (result.indexOf(QChar::fromAscii('\t'))!=-1);
+ // here we strip the quote again
+ substEnvVarsInString(result);
+
+ //printf("Result %s was quoted=%d\n",result.toLatin1().data(),wasQuoted);
+
+ if (!wasQuoted) /* as a result of the expansion, a single string
+ may have expanded into a list, which we'll
+ add to sl. If the orginal string already
+ contained multiple elements no further
+ splitting is done to allow quoted items with spaces! */
+ {
+ int l=result.length();
+ int i,p=0;
+ // skip spaces
+ // search for a "word"
+ for (i=0;i<l;i++)
+ {
+ QChar c=0;
+ // skip until start of new word
+ while (i<l && ((c=result.at(i))==QChar::fromAscii(' ') || c==QChar::fromAscii('\t'))) i++;
+ p=i; // p marks the start index of the word
+ // skip until end of a word
+ while (i<l && ((c=result.at(i))!=QChar::fromAscii(' ') &&
+ c!=QChar::fromAscii('\t') &&
+ c!=QChar::fromAscii('"'))) i++;
+ if (i<l) // not at the end of the string
+ {
+ if (c==QChar::fromAscii('"')) // word within quotes
+ {
+ p=i+1;
+ for (i++;i<l;i++)
+ {
+ c=result.at(i);
+ if (c==QChar::fromAscii('"')) // end quote
+ {
+ out += result.mid(p,i-p);
+ p=i+1;
+ break;
+ }
+ else if (c==QChar::fromAscii('\\')) // skip escaped stuff
+ {
+ i++;
+ }
+ }
+ }
+ else if (c==QChar::fromAscii(' ') || c==QChar::fromAscii('\t')) // separator
+ {
+ out += result.mid(p,i-p);
+ p=i+1;
+ }
+ }
+ }
+ if (p!=l) // add the leftover as a string
+ {
+ out += result.right(l-p);
+ }
+ }
+ else // just goto the next element in the list
+ {
+ out += result;
+ }
+ }
+ sl = out;
+}
+
+//--------------------------------------------------------------------------
+
+bool parseConfig(
+ const QString &fileName,
+ const QHash<QString,Input *> &options
+ )
+{
+ QHashIterator<QString, Input*> i(options);
+ g_file = fopen(fileName.toLocal8Bit(),"r");
+ if (g_file==NULL) return false;
+
+ // reset all values
+ i.toFront();
+ while (i.hasNext())
+ {
+ i.next();
+ if (i.value())
+ {
+ i.value()->reset();
+ }
+ }
+
+ // parse config file
+ g_options = &options;
+ g_yyFileName = fileName;
+ g_includeStack.clear();
+ g_includeDepth = 0;
+ configrestart( configin );
+ BEGIN( Start );
+ configlex();
+
+ // update the values in the UI
+ i.toFront();
+ while (i.hasNext())
+ {
+ i.next();
+ if (i.value())
+ {
+ //printf("Updating: %s\n",qPrintable(i.key()));
+ i.value()->update();
+ }
+ else
+ {
+ printf("Invalid option: %s\n",qPrintable(i.key()));
+ }
+ }
+ fclose(g_file);
+ return true;
+}
+
+void writeStringValue(QTextStream &t,QTextCodec *codec,const QString &s)
+{
+ QChar c;
+ bool needsEscaping=FALSE;
+ // convert the string back to it original encoding
+ //QByteArray se = codec->fromUnicode(s);
+ t.setCodec(codec);
+ const QChar *p=s.data();
+ if (!s.isEmpty() && !p->isNull())
+ {
+ while (!(c=*p++).isNull() && !needsEscaping)
+ {
+ needsEscaping = (c==QChar::fromAscii(' ') ||
+ c==QChar::fromAscii('\n') ||
+ c==QChar::fromAscii('\t') ||
+ c==QChar::fromAscii('"'));
+ }
+ if (needsEscaping)
+ {
+ t << "\"";
+ p=s.data();
+ while (!p->isNull())
+ {
+ if (*p ==QChar::fromAscii(' ') &&
+ *(p+1)==QChar::fromAscii('\0')) break; // skip inserted space at the end
+ if (*p ==QChar::fromAscii('"')) t << "\\"; // escape quotes
+ t << *p++;
+ }
+ t << "\"";
+ }
+ else
+ {
+ t << s;
+ }
+ }
+}
+
diff --git a/trunk/addon/doxywizard/doxywizard.cpp b/trunk/addon/doxywizard/doxywizard.cpp
new file mode 100644
index 0000000..fe8c961
--- /dev/null
+++ b/trunk/addon/doxywizard/doxywizard.cpp
@@ -0,0 +1,639 @@
+#include <QtGui>
+#include "doxywizard.h"
+#include "version.h"
+#include "expert.h"
+#include "wizard.h"
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#define MAX_RECENT_FILES 10
+
+const int messageTimeout = 5000; //!< status bar message timeout in millisec.
+
+MainWindow &MainWindow::instance()
+{
+ static MainWindow *theInstance = new MainWindow;
+ return *theInstance;
+}
+
+MainWindow::MainWindow()
+ : m_settings(QString::fromAscii("Doxygen.org"), QString::fromAscii("Doxywizard"))
+{
+ QMenu *file = menuBar()->addMenu(tr("File"));
+ file->addAction(tr("Open..."),
+ this, SLOT(openConfig()), Qt::CTRL+Qt::Key_O);
+ m_recentMenu = file->addMenu(tr("Open recent"));
+ file->addAction(tr("Save"),
+ this, SLOT(saveConfig()), Qt::CTRL+Qt::Key_S);
+ file->addAction(tr("Save as..."),
+ this, SLOT(saveConfigAs()), Qt::SHIFT+Qt::CTRL+Qt::Key_S);
+ file->addAction(tr("Quit"),
+ this, SLOT(quit()), Qt::CTRL+Qt::Key_Q);
+
+ QMenu *settings = menuBar()->addMenu(tr("Settings"));
+ settings->addAction(tr("Reset to factory defaults"),
+ this,SLOT(resetToDefaults()));
+ settings->addAction(tr("Use current settings at startup"),
+ this,SLOT(makeDefaults()));
+ settings->addAction(tr("Clear recent list"),
+ this,SLOT(clearRecent()));
+
+ QMenu *help = menuBar()->addMenu(tr("Help"));
+ help->addAction(tr("Online manual"),
+ this, SLOT(manual()), Qt::Key_F1);
+ help->addAction(tr("About"),
+ this, SLOT(about()) );
+
+ m_expert = new Expert;
+ m_wizard = new Wizard(m_expert->modelData());
+
+ // ----------- top part ------------------
+ QWidget *topPart = new QWidget;
+ QVBoxLayout *rowLayout = new QVBoxLayout(topPart);
+
+ // select working directory
+ QHBoxLayout *dirLayout = new QHBoxLayout;
+ m_workingDir = new QLineEdit;
+ m_selWorkingDir = new QPushButton(tr("Select..."));
+ dirLayout->addWidget(m_workingDir);
+ dirLayout->addWidget(m_selWorkingDir);
+
+ //------------- bottom part --------------
+ QWidget *runTab = new QWidget;
+ QVBoxLayout *runTabLayout = new QVBoxLayout(runTab);
+
+ // run doxygen
+ QHBoxLayout *runLayout = new QHBoxLayout;
+ m_run = new QPushButton(tr("Run doxygen"));
+ m_run->setEnabled(false);
+ m_runStatus = new QLabel(tr("Status: not running"));
+ m_saveLog = new QPushButton(tr("Save log..."));
+ m_saveLog->setEnabled(false);
+ QPushButton *showSettings = new QPushButton(tr("Show configuration"));
+ runLayout->addWidget(m_run);
+ runLayout->addWidget(m_runStatus);
+ runLayout->addStretch(1);
+ runLayout->addWidget(showSettings);
+ runLayout->addWidget(m_saveLog);
+
+ // output produced by doxygen
+ runTabLayout->addLayout(runLayout);
+ runTabLayout->addWidget(new QLabel(tr("Output produced by doxygen")));
+ QGridLayout *grid = new QGridLayout;
+ m_outputLog = new QTextEdit;
+ m_outputLog->setReadOnly(true);
+ m_outputLog->setFontFamily(QString::fromAscii("courier"));
+ m_outputLog->setMinimumWidth(600);
+ grid->addWidget(m_outputLog,0,0);
+ grid->setColumnStretch(0,1);
+ grid->setRowStretch(0,1);
+ QHBoxLayout *launchLayout = new QHBoxLayout;
+ m_launchHtml = new QPushButton(tr("Show HTML output"));
+ launchLayout->addWidget(m_launchHtml);
+
+ launchLayout->addStretch(1);
+ grid->addLayout(launchLayout,1,0);
+ runTabLayout->addLayout(grid);
+
+ QTabWidget *tabs = new QTabWidget;
+ tabs->addTab(m_wizard,tr("Wizard"));
+ tabs->addTab(m_expert,tr("Expert"));
+ tabs->addTab(runTab,tr("Run"));
+
+ rowLayout->addWidget(new QLabel(tr("Step 1: Specify the working directory from which doxygen will run")));
+ rowLayout->addLayout(dirLayout);
+ rowLayout->addWidget(new QLabel(tr("Step 2: Configure doxygen using the Wizard and/or Expert tab, then switch to the Run tab to generate the documentation")));
+ rowLayout->addWidget(tabs);
+
+ setCentralWidget(topPart);
+ statusBar()->showMessage(tr("Welcome to Doxygen"),messageTimeout);
+
+ m_runProcess = new QProcess;
+ m_running = false;
+ m_timer = new QTimer;
+
+ // connect signals and slots
+ connect(tabs,SIGNAL(currentChanged(int)),SLOT(selectTab(int)));
+ connect(m_selWorkingDir,SIGNAL(clicked()),SLOT(selectWorkingDir()));
+ connect(m_recentMenu,SIGNAL(triggered(QAction*)),SLOT(openRecent(QAction*)));
+ connect(m_workingDir,SIGNAL(returnPressed()),SLOT(updateWorkingDir()));
+ connect(m_runProcess,SIGNAL(readyReadStandardOutput()),SLOT(readStdout()));
+ connect(m_runProcess,SIGNAL(finished(int, QProcess::ExitStatus)),SLOT(runComplete()));
+ connect(m_timer,SIGNAL(timeout()),SLOT(readStdout()));
+ connect(m_run,SIGNAL(clicked()),SLOT(runDoxygen()));
+ connect(m_launchHtml,SIGNAL(clicked()),SLOT(showHtmlOutput()));
+ connect(m_saveLog,SIGNAL(clicked()),SLOT(saveLog()));
+ connect(showSettings,SIGNAL(clicked()),SLOT(showSettings()));
+ connect(m_expert,SIGNAL(changed()),SLOT(configChanged()));
+
+ loadSettings();
+ updateLaunchButtonState();
+ m_modified = false;
+ updateTitle();
+ m_wizard->refresh();
+}
+
+void MainWindow::closeEvent(QCloseEvent *event)
+{
+ if (discardUnsavedChanges())
+ {
+ saveSettings();
+ event->accept();
+ }
+ else
+ {
+ event->ignore();
+ }
+}
+
+void MainWindow::quit()
+{
+ if (discardUnsavedChanges())
+ {
+ saveSettings();
+ }
+ QApplication::exit(0);
+}
+
+void MainWindow::setWorkingDir(const QString &dirName)
+{
+ QDir::setCurrent(dirName);
+ m_workingDir->setText(dirName);
+ m_run->setEnabled(!dirName.isEmpty());
+}
+
+void MainWindow::selectWorkingDir()
+{
+ QString dirName = QFileDialog::getExistingDirectory(this,
+ tr("Select working directory"),m_workingDir->text());
+ if (!dirName.isEmpty())
+ {
+ setWorkingDir(dirName);
+ }
+}
+
+void MainWindow::updateWorkingDir()
+{
+ setWorkingDir(m_workingDir->text());
+}
+
+void MainWindow::manual()
+{
+ QDesktopServices::openUrl(QUrl(QString::fromAscii("http://www.doxygen.org/manual.html")));
+}
+
+void MainWindow::about()
+{
+ QString msg;
+ QTextStream t(&msg,QIODevice::WriteOnly);
+ t << QString::fromAscii("<qt><center>A tool to configure and run doxygen version ")+
+ QString::fromAscii(versionString)+
+ QString::fromAscii(" on your source files.</center><p><br>"
+ "<center>Written by<br> Dimitri van Heesch<br>&copy; 2000-2012</center><p>"
+ "</qt>");
+ QMessageBox::about(this,tr("Doxygen GUI"),msg);
+}
+
+void MainWindow::openConfig()
+{
+ if (discardUnsavedChanges(false))
+ {
+ QString fn = QFileDialog::getOpenFileName(this,
+ tr("Open configuration file"),
+ m_workingDir->text());
+ if (!fn.isEmpty())
+ {
+ loadConfigFromFile(fn);
+ }
+ }
+}
+
+void MainWindow::updateConfigFileName(const QString &fileName)
+{
+ if (m_fileName!=fileName)
+ {
+ m_fileName = fileName;
+ QString curPath = QFileInfo(fileName).path();
+ setWorkingDir(curPath);
+ addRecentFile(fileName);
+ updateTitle();
+ }
+}
+
+void MainWindow::loadConfigFromFile(const QString & fileName)
+{
+ m_expert->loadConfig(fileName);
+ m_wizard->refresh();
+ updateConfigFileName(fileName);
+ updateLaunchButtonState();
+ m_modified = false;
+ updateTitle();
+}
+
+void MainWindow::saveConfig(const QString &fileName)
+{
+ if (fileName.isEmpty()) return;
+ QFile f(fileName);
+ if (!f.open(QIODevice::WriteOnly))
+ {
+ QMessageBox::warning(this,
+ tr("Error saving"),
+ tr("Error: cannot open the file ")+fileName+tr(" for writing!\n")+
+ tr("Reason given: ")+f.error());
+ return;
+ }
+ QTextStream t(&f);
+ m_expert->writeConfig(t,false);
+ updateConfigFileName(fileName);
+ m_modified = false;
+ updateTitle();
+}
+
+bool MainWindow::saveConfig()
+{
+ if (m_fileName.isEmpty())
+ {
+ return saveConfigAs();
+ }
+ else
+ {
+ saveConfig(m_fileName);
+ return true;
+ }
+}
+
+bool MainWindow::saveConfigAs()
+{
+ QString fileName = QFileDialog::getSaveFileName(this, QString(),
+ m_workingDir->text()+QString::fromAscii("/Doxyfile"));
+ if (fileName.isEmpty()) return false;
+ saveConfig(fileName);
+ return true;
+}
+
+void MainWindow::makeDefaults()
+{
+ if (QMessageBox::question(this,tr("Use current setting at startup?"),
+ tr("Do you want to save the current settings "
+ "and use them next time Doxywizard starts?"),
+ QMessageBox::Save|
+ QMessageBox::Cancel)==QMessageBox::Save)
+ {
+ //printf("MainWindow:makeDefaults()\n");
+ m_expert->saveSettings(&m_settings);
+ m_settings.setValue(QString::fromAscii("wizard/loadsettings"), true);
+ m_settings.sync();
+ }
+}
+
+void MainWindow::clearRecent()
+{
+ if (QMessageBox::question(this,tr("Clear the list of recent files?"),
+ tr("Do you want to clear the list of recently "
+ "loaded configuration files?"),
+ QMessageBox::Yes|
+ QMessageBox::Cancel)==QMessageBox::Yes)
+ {
+ m_recentMenu->clear();
+ m_recentFiles.clear();
+ for (int i=0;i<MAX_RECENT_FILES;i++)
+ {
+ m_settings.setValue(QString().sprintf("recent/config%d",i++),QString::fromAscii(""));
+ }
+ m_settings.sync();
+ }
+
+}
+
+void MainWindow::resetToDefaults()
+{
+ if (QMessageBox::question(this,tr("Reset settings to their default values?"),
+ tr("Do you want to revert all settings back "
+ "to their original values?"),
+ QMessageBox::Reset|
+ QMessageBox::Cancel)==QMessageBox::Reset)
+ {
+ //printf("MainWindow:resetToDefaults()\n");
+ m_expert->resetToDefaults();
+ m_settings.setValue(QString::fromAscii("wizard/loadsettings"), false);
+ m_settings.sync();
+ m_wizard->refresh();
+ }
+}
+
+void MainWindow::loadSettings()
+{
+ QVariant geometry = m_settings.value(QString::fromAscii("main/geometry"), QVariant::Invalid);
+ QVariant state = m_settings.value(QString::fromAscii("main/state"), QVariant::Invalid);
+ QVariant wizState = m_settings.value(QString::fromAscii("wizard/state"), QVariant::Invalid);
+ QVariant loadSettings = m_settings.value(QString::fromAscii("wizard/loadsettings"), QVariant::Invalid);
+ QVariant workingDir = m_settings.value(QString::fromAscii("wizard/workingdir"), QVariant::Invalid);
+
+ if (geometry !=QVariant::Invalid) restoreGeometry(geometry.toByteArray());
+ if (state !=QVariant::Invalid) restoreState (state.toByteArray());
+ if (wizState !=QVariant::Invalid) m_wizard->restoreState(wizState.toByteArray());
+ if (loadSettings!=QVariant::Invalid && loadSettings.toBool())
+ {
+ m_expert->loadSettings(&m_settings);
+ if (workingDir!=QVariant::Invalid && QDir(workingDir.toString()).exists())
+ {
+ setWorkingDir(workingDir.toString());
+ }
+ }
+
+ for (int i=0;i<MAX_RECENT_FILES;i++)
+ {
+ QString entry = m_settings.value(QString().sprintf("recent/config%d",i)).toString();
+ if (!entry.isEmpty() && QFileInfo(entry).exists())
+ {
+ addRecentFile(entry);
+ }
+ }
+
+}
+
+void MainWindow::saveSettings()
+{
+ QSettings settings(QString::fromAscii("Doxygen.org"), QString::fromAscii("Doxywizard"));
+
+ m_settings.setValue(QString::fromAscii("main/geometry"), saveGeometry());
+ m_settings.setValue(QString::fromAscii("main/state"), saveState());
+ m_settings.setValue(QString::fromAscii("wizard/state"), m_wizard->saveState());
+ m_settings.setValue(QString::fromAscii("wizard/workingdir"), m_workingDir->text());
+}
+
+void MainWindow::selectTab(int id)
+{
+ if (id==0) m_wizard->refresh();
+}
+
+void MainWindow::addRecentFile(const QString &fileName)
+{
+ int i=m_recentFiles.indexOf(fileName);
+ if (i!=-1) m_recentFiles.removeAt(i);
+
+ // not found
+ if (m_recentFiles.count() < MAX_RECENT_FILES) // append
+ {
+ m_recentFiles.prepend(fileName);
+ }
+ else // add + drop last item
+ {
+ m_recentFiles.removeLast();
+ m_recentFiles.prepend(fileName);
+ }
+ m_recentMenu->clear();
+ i=0;
+ foreach( QString str, m_recentFiles )
+ {
+ m_recentMenu->addAction(str);
+ m_settings.setValue(QString().sprintf("recent/config%d",i++),str);
+ }
+ for (;i<MAX_RECENT_FILES;i++)
+ {
+ m_settings.setValue(QString().sprintf("recent/config%d",i++),QString::fromAscii(""));
+ }
+}
+
+void MainWindow::openRecent(QAction *action)
+{
+ if (discardUnsavedChanges(false))
+ {
+ loadConfigFromFile(action->text());
+ }
+}
+
+void MainWindow::runDoxygen()
+{
+ if (!m_running)
+ {
+ QString doxygenPath;
+#if defined(Q_OS_MACX)
+ doxygenPath = qApp->applicationDirPath()+QString::fromAscii("/../Resources/");
+ qDebug() << tr("Doxygen path: ") << doxygenPath;
+ if ( !QFile(doxygenPath + QString::fromAscii("doxygen")).exists() )
+ {
+ // No doygen binary in the resources, if there is a system doxygen binary, use that instead
+ if ( QFile(QString::fromAscii("/usr/local/bin/doxygen")).exists() )
+ {
+ doxygenPath = QString::fromAscii("/usr/local/bin/");
+ }
+ else
+ {
+ qDebug() << tr("Can't find the doxygen command, make sure it's in your $$PATH");
+ doxygenPath = QString::fromAscii("");
+ }
+ }
+ qDebug() << tr("Getting doxygen from: ") << doxygenPath;
+#endif
+
+ m_runProcess->setReadChannel(QProcess::StandardOutput);
+ m_runProcess->setProcessChannelMode(QProcess::MergedChannels);
+ m_runProcess->setWorkingDirectory(m_workingDir->text());
+ QStringList env=QProcess::systemEnvironment();
+ // set PWD environment variable to m_workingDir
+ env.replaceInStrings(QRegExp(QString::fromAscii("^PWD=(.*)"),Qt::CaseInsensitive),
+ QString::fromAscii("PWD=")+m_workingDir->text());
+ m_runProcess->setEnvironment(env);
+
+ QStringList args;
+ args << QString::fromAscii("-b"); // make stdout unbuffered
+ args << QString::fromAscii("-"); // read config from stdin
+
+ m_outputLog->clear();
+ m_runProcess->start(doxygenPath + QString::fromAscii("doxygen"), args);
+
+ if (!m_runProcess->waitForStarted())
+ {
+ m_outputLog->append(QString::fromAscii("*** Failed to run doxygen\n"));
+ return;
+ }
+ QTextStream t(m_runProcess);
+ m_expert->writeConfig(t,false);
+ m_runProcess->closeWriteChannel();
+
+ if (m_runProcess->state() == QProcess::NotRunning)
+ {
+ m_outputLog->append(QString::fromAscii("*** Failed to run doxygen\n"));
+ }
+ else
+ {
+ m_saveLog->setEnabled(false);
+ m_running=true;
+ m_run->setText(tr("Stop doxygen"));
+ m_runStatus->setText(tr("Status: running"));
+ m_timer->start(1000);
+ }
+ }
+ else
+ {
+ m_running=false;
+ m_run->setText(tr("Run doxygen"));
+ m_runStatus->setText(tr("Status: not running"));
+ m_runProcess->kill();
+ m_timer->stop();
+ //updateRunnable(m_workingDir->text());
+ }
+}
+
+void MainWindow::readStdout()
+{
+ if (m_running)
+ {
+ QByteArray data = m_runProcess->readAllStandardOutput();
+ QString text = QString::fromLocal8Bit(data);
+ if (!text.isEmpty())
+ {
+ m_outputLog->append(text.trimmed());
+ }
+ }
+}
+
+void MainWindow::runComplete()
+{
+ if (m_running)
+ {
+ m_outputLog->append(tr("*** Doxygen has finished\n"));
+ }
+ else
+ {
+ m_outputLog->append(tr("*** Cancelled by user\n"));
+ }
+ m_outputLog->ensureCursorVisible();
+ m_run->setText(tr("Run doxygen"));
+ m_runStatus->setText(tr("Status: not running"));
+ m_running=false;
+ updateLaunchButtonState();
+ //updateRunnable(m_workingDir->text());
+ m_saveLog->setEnabled(true);
+}
+
+void MainWindow::updateLaunchButtonState()
+{
+ m_launchHtml->setEnabled(m_expert->htmlOutputPresent(m_workingDir->text()));
+#if 0
+ m_launchPdf->setEnabled(m_expert->pdfOutputPresent(m_workingDir->text()));
+#endif
+}
+
+void MainWindow::showHtmlOutput()
+{
+ QString indexFile = m_expert->getHtmlOutputIndex(m_workingDir->text());
+ QFileInfo fi(indexFile);
+ // TODO: the following doesn't seem to work with IE
+#ifdef WIN32
+ //QString indexUrl(QString::fromAscii("file:///"));
+ ShellExecute(NULL, L"open", fi.absoluteFilePath().utf16(), NULL, NULL, SW_SHOWNORMAL);
+#else
+ QString indexUrl(QString::fromAscii("file://"));
+ indexUrl+=fi.absoluteFilePath();
+ QDesktopServices::openUrl(QUrl(indexUrl));
+#endif
+}
+
+void MainWindow::saveLog()
+{
+ QString fn = QFileDialog::getSaveFileName(this, tr("Save log file"),
+ m_workingDir->text()+
+ QString::fromAscii("/doxygen_log.txt"));
+ if (!fn.isEmpty())
+ {
+ QFile f(fn);
+ if (f.open(QIODevice::WriteOnly))
+ {
+ QTextStream t(&f);
+ t << m_outputLog->toPlainText();
+ statusBar()->showMessage(tr("Output log saved"),messageTimeout);
+ }
+ else
+ {
+ QMessageBox::warning(0,tr("Warning"),
+ tr("Cannot open file ")+fn+tr(" for writing. Nothing saved!"),tr("ok"));
+ }
+ }
+}
+
+void MainWindow::showSettings()
+{
+ QString text;
+ QTextStream t(&text);
+ m_expert->writeConfig(t,true);
+ m_outputLog->clear();
+ m_outputLog->append(text);
+ m_outputLog->ensureCursorVisible();
+ m_saveLog->setEnabled(true);
+}
+
+void MainWindow::configChanged()
+{
+ m_modified = true;
+ updateTitle();
+}
+
+void MainWindow::updateTitle()
+{
+ QString title = tr("Doxygen GUI frontend");
+ if (m_modified)
+ {
+ title+=QString::fromAscii(" +");
+ }
+ if (!m_fileName.isEmpty())
+ {
+ title+=QString::fromAscii(" (")+m_fileName+QString::fromAscii(")");
+ }
+ setWindowTitle(title);
+}
+
+bool MainWindow::discardUnsavedChanges(bool saveOption)
+{
+ if (m_modified)
+ {
+ QMessageBox::StandardButton button;
+ if (saveOption)
+ {
+ button = QMessageBox::question(this,
+ tr("Unsaved changes"),
+ tr("Unsaved changes will be lost! Do you want to save the configuration file?"),
+ QMessageBox::Save |
+ QMessageBox::Discard |
+ QMessageBox::Cancel
+ );
+ if (button==QMessageBox::Save)
+ {
+ return saveConfig();
+ }
+ }
+ else
+ {
+ button = QMessageBox::question(this,
+ tr("Unsaved changes"),
+ tr("Unsaved changes will be lost! Do you want to continue?"),
+ QMessageBox::Discard |
+ QMessageBox::Cancel
+ );
+ }
+ return button==QMessageBox::Discard;
+ }
+ return true;
+}
+
+//-----------------------------------------------------------------------
+
+int main(int argc,char **argv)
+{
+ QApplication a(argc,argv);
+ MainWindow &main = MainWindow::instance();
+ if (argc==2 && argv[1][0]!='-') // name of config file as an argument
+ {
+ main.loadConfigFromFile(QString::fromLocal8Bit(argv[1]));
+ }
+ else if (argc>1)
+ {
+ printf("Usage: %s [config file]\n",argv[0]);
+ exit(1);
+ }
+ main.show();
+ return a.exec();
+}
diff --git a/trunk/addon/doxywizard/doxywizard.h b/trunk/addon/doxywizard/doxywizard.h
new file mode 100644
index 0000000..46cd748
--- /dev/null
+++ b/trunk/addon/doxywizard/doxywizard.h
@@ -0,0 +1,84 @@
+#ifndef DOXYWIZARD_H
+#define DOXYWIZARD_H
+
+#include <QMainWindow>
+#include <QSettings>
+#include <QStringList>
+
+class Expert;
+class Wizard;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+class QTextEdit;
+class QMenu;
+class QProcess;
+class QTimer;
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+ public:
+ static MainWindow &instance();
+ void loadConfigFromFile(const QString &fileName);
+ void loadSettings();
+ void saveSettings();
+ void closeEvent(QCloseEvent *event);
+ QString configFileName() const { return m_fileName; }
+ void updateTitle();
+
+ public slots:
+ void manual();
+ void about();
+ void openConfig();
+ bool saveConfig();
+ bool saveConfigAs();
+ void makeDefaults();
+ void resetToDefaults();
+ void selectTab(int);
+ void quit();
+
+ private slots:
+ void openRecent(QAction *action);
+ void selectWorkingDir();
+ void updateWorkingDir();
+ void runDoxygen();
+ void readStdout();
+ void runComplete();
+ void showHtmlOutput();
+ void saveLog();
+ void showSettings();
+ void configChanged();
+ void clearRecent();
+
+ private:
+ MainWindow();
+ void saveConfig(const QString &fileName);
+ void addRecentFile(const QString &fileName);
+ void updateConfigFileName(const QString &fileName);
+ void setWorkingDir(const QString &dirName);
+ void updateLaunchButtonState();
+ bool discardUnsavedChanges(bool saveOption=true);
+
+ QLineEdit *m_workingDir;
+ QPushButton *m_selWorkingDir;
+ QPushButton *m_run;
+ QPushButton *m_saveLog;
+ QPushButton *m_launchHtml;
+ QPushButton *m_launchPdf;
+ QTextEdit *m_outputLog;
+ QLabel *m_runStatus;
+ Expert *m_expert;
+ Wizard *m_wizard;
+ QString m_fileName;
+ QSettings m_settings;
+ QMenu *m_recentMenu;
+ QStringList m_recentFiles;
+ QProcess *m_runProcess;
+ QTimer *m_timer;
+ bool m_running;
+ bool m_modified;
+};
+
+#endif
diff --git a/trunk/addon/doxywizard/doxywizard.ico b/trunk/addon/doxywizard/doxywizard.ico
new file mode 100644
index 0000000..10d1755
--- /dev/null
+++ b/trunk/addon/doxywizard/doxywizard.ico
Binary files differ
diff --git a/trunk/addon/doxywizard/doxywizard.pro.in b/trunk/addon/doxywizard/doxywizard.pro.in
new file mode 100644
index 0000000..3b40576
--- /dev/null
+++ b/trunk/addon/doxywizard/doxywizard.pro.in
@@ -0,0 +1,28 @@
+######################################################################
+# Automatically generated by qmake (2.01a) zo okt 19 12:50:02 2008
+######################################################################
+
+TEMPLATE = app
+DESTDIR = ../../bin
+TARGET =
+DEPENDPATH += .
+INCLUDEPATH += .
+QT += xml
+CONFIG += $extraopts
+OBJECTS_DIR = obj
+MOC_DIR = moc
+RCC_DIR = rcc
+DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
+
+macx-g++ {
+ CONFIG += x86 ppc
+}
+
+# Input
+HEADERS += doxywizard.h version.h expert.h config.h helplabel.h \
+ inputbool.h inputstring.h inputint.h inputstrlist.h wizard.h
+SOURCES += doxywizard.cpp ../../src/version.cpp expert.cpp wizard.cpp \
+ inputbool.cpp inputstring.cpp inputint.cpp inputstrlist.cpp
+LEXSOURCES += config.l
+RESOURCES += doxywizard.qrc
+win32:RC_FILE += doxywizard.rc
diff --git a/trunk/addon/doxywizard/doxywizard.qrc b/trunk/addon/doxywizard/doxywizard.qrc
new file mode 100644
index 0000000..88316ed
--- /dev/null
+++ b/trunk/addon/doxywizard/doxywizard.qrc
@@ -0,0 +1,11 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/">
+ <file alias="config.xml">../../src/config.xml</file>
+ <file>images/add.png</file>
+ <file>images/del.png</file>
+ <file>images/file.png</file>
+ <file>images/folder.png</file>
+ <file>images/refresh.png</file>
+ <file>images/tunecolor.png</file>
+</qresource>
+</RCC>
diff --git a/trunk/addon/doxywizard/doxywizard.rc b/trunk/addon/doxywizard/doxywizard.rc
new file mode 100644
index 0000000..7f5327c
--- /dev/null
+++ b/trunk/addon/doxywizard/doxywizard.rc
@@ -0,0 +1 @@
+IDI_ICON1 ICON DISCARDABLE "doxywizard.ico"
diff --git a/trunk/addon/doxywizard/expert.cpp b/trunk/addon/doxywizard/expert.cpp
new file mode 100644
index 0000000..4bbb104
--- /dev/null
+++ b/trunk/addon/doxywizard/expert.cpp
@@ -0,0 +1,561 @@
+#include "expert.h"
+#include "inputbool.h"
+#include "inputstring.h"
+#include "inputint.h"
+#include "inputstring.h"
+#include "inputstrlist.h"
+#include <QtGui>
+#include <QtXml>
+#include "config.h"
+#include "version.h"
+
+#undef SA
+#define SA(x) QString::fromAscii(x)
+
+static QString convertToComment(const QString &s)
+{
+ if (s.isEmpty())
+ {
+ return QString();
+ }
+ else
+ {
+ return SA("# ")+
+ s.trimmed().replace(SA("\n"),SA("\n# "))+
+ SA("\n");
+ }
+}
+
+//------------------------------------------------------------------------------------
+
+Expert::Expert()
+{
+ m_treeWidget = new QTreeWidget;
+ m_treeWidget->setColumnCount(1);
+ m_topicStack = new QStackedWidget;
+ m_inShowHelp = FALSE;
+
+ QFile file(SA(":/config.xml"));
+ QString err;
+ int errLine,errCol;
+ QDomDocument configXml;
+ if (file.open(QIODevice::ReadOnly))
+ {
+ if (!configXml.setContent(&file,false,&err,&errLine,&errCol))
+ {
+ QString msg = tr("Error parsing internal config.xml at line %1 column %2.\n%3").
+ arg(errLine).arg(errCol).arg(err);
+ QMessageBox::warning(this, tr("Error"), msg);
+ exit(1);
+ }
+ }
+ m_rootElement = configXml.documentElement();
+
+ createTopics(m_rootElement);
+ m_helper = new QTextEdit;
+ m_helper->setReadOnly(true);
+ m_splitter = new QSplitter(Qt::Vertical);
+ m_splitter->addWidget(m_treeWidget);
+ m_splitter->addWidget(m_helper);
+
+ QWidget *rightSide = new QWidget;
+ QGridLayout *grid = new QGridLayout(rightSide);
+ m_prev = new QPushButton(tr("Previous"));
+ m_prev->setEnabled(false);
+ m_next = new QPushButton(tr("Next"));
+ grid->addWidget(m_topicStack,0,0,1,2);
+ grid->addWidget(m_prev,1,0,Qt::AlignLeft);
+ grid->addWidget(m_next,1,1,Qt::AlignRight);
+ grid->setColumnStretch(0,1);
+ grid->setRowStretch(0,1);
+
+ addWidget(m_splitter);
+ addWidget(rightSide);
+ connect(m_next,SIGNAL(clicked()),SLOT(nextTopic()));
+
+ connect(m_prev,SIGNAL(clicked()),SLOT(prevTopic()));
+}
+
+Expert::~Expert()
+{
+ QHashIterator<QString,Input*> i(m_options);
+ while (i.hasNext())
+ {
+ i.next();
+ delete i.value();
+ }
+}
+
+void Expert::createTopics(const QDomElement &rootElem)
+{
+ QList<QTreeWidgetItem*> items;
+ QDomElement childElem = rootElem.firstChildElement();
+ while (!childElem.isNull())
+ {
+ if (childElem.tagName()==SA("group"))
+ {
+ QString name = childElem.attribute(SA("name"));
+ items.append(new QTreeWidgetItem((QTreeWidget*)0,QStringList(name)));
+ QWidget *widget = createTopicWidget(childElem);
+ m_topics[name] = widget;
+ m_topicStack->addWidget(widget);
+ }
+ childElem = childElem.nextSiblingElement();
+ }
+ m_treeWidget->setHeaderLabels(QStringList() << SA("Topics"));
+ m_treeWidget->insertTopLevelItems(0,items);
+ connect(m_treeWidget,
+ SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),
+ this,
+ SLOT(activateTopic(QTreeWidgetItem *,QTreeWidgetItem *)));
+}
+
+
+QWidget *Expert::createTopicWidget(QDomElement &elem)
+{
+ QScrollArea *area = new QScrollArea;
+ QWidget *topic = new QWidget;
+ QGridLayout *layout = new QGridLayout(topic);
+ QDomElement child = elem.firstChildElement();
+ int row=0;
+ while (!child.isNull())
+ {
+ QString type = child.attribute(SA("type"));
+ if (type==SA("bool"))
+ {
+ InputBool *boolOption =
+ new InputBool(
+ layout,row,
+ child.attribute(SA("id")),
+ child.attribute(SA("defval"))==SA("1"),
+ child.attribute(SA("docs"))
+ );
+ m_options.insert(
+ child.attribute(SA("id")),
+ boolOption
+ );
+ connect(boolOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
+ connect(boolOption,SIGNAL(changed()),SIGNAL(changed()));
+ }
+ else if (type==SA("string"))
+ {
+ InputString::StringMode mode;
+ QString format = child.attribute(SA("format"));
+ if (format==SA("dir"))
+ {
+ mode = InputString::StringDir;
+ }
+ else if (format==SA("file"))
+ {
+ mode = InputString::StringFile;
+ }
+ else // format=="string"
+ {
+ mode = InputString::StringFree;
+ }
+ InputString *stringOption =
+ new InputString(
+ layout,row,
+ child.attribute(SA("id")),
+ child.attribute(SA("defval")),
+ mode,
+ child.attribute(SA("docs")),
+ child.attribute(SA("abspath"))
+ );
+ m_options.insert(
+ child.attribute(SA("id")),
+ stringOption
+ );
+ connect(stringOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
+ connect(stringOption,SIGNAL(changed()),SIGNAL(changed()));
+ }
+ else if (type==SA("enum"))
+ {
+ InputString *enumList = new InputString(
+ layout,row,
+ child.attribute(SA("id")),
+ child.attribute(SA("defval")),
+ InputString::StringFixed,
+ child.attribute(SA("docs"))
+ );
+ QDomElement enumVal = child.firstChildElement();
+ while (!enumVal.isNull())
+ {
+ enumList->addValue(enumVal.attribute(SA("name")));
+ enumVal = enumVal.nextSiblingElement();
+ }
+ enumList->setDefault();
+
+ m_options.insert(child.attribute(SA("id")),enumList);
+ connect(enumList,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
+ connect(enumList,SIGNAL(changed()),SIGNAL(changed()));
+ }
+ else if (type==SA("int"))
+ {
+ InputInt *intOption =
+ new InputInt(
+ layout,row,
+ child.attribute(SA("id")),
+ child.attribute(SA("defval")).toInt(),
+ child.attribute(SA("minval")).toInt(),
+ child.attribute(SA("maxval")).toInt(),
+ child.attribute(SA("docs"))
+ );
+ m_options.insert(
+ child.attribute(SA("id")),
+ intOption
+ );
+ connect(intOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
+ connect(intOption,SIGNAL(changed()),SIGNAL(changed()));
+ }
+ else if (type==SA("list"))
+ {
+ InputStrList::ListMode mode;
+ QString format = child.attribute(SA("format"));
+ if (format==SA("dir"))
+ {
+ mode = InputStrList::ListDir;
+ }
+ else if (format==SA("file"))
+ {
+ mode = InputStrList::ListFile;
+ }
+ else if (format==SA("filedir"))
+ {
+ mode = InputStrList::ListFileDir;
+ }
+ else // format=="string"
+ {
+ mode = InputStrList::ListString;
+ }
+ QStringList sl;
+ QDomElement listVal = child.firstChildElement();
+ while (!listVal.isNull())
+ {
+ sl.append(listVal.attribute(SA("name")));
+ listVal = listVal.nextSiblingElement();
+ }
+ InputStrList *listOption =
+ new InputStrList(
+ layout,row,
+ child.attribute(SA("id")),
+ sl,
+ mode,
+ child.attribute(SA("docs"))
+ );
+ m_options.insert(
+ child.attribute(SA("id")),
+ listOption
+ );
+ connect(listOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
+ connect(listOption,SIGNAL(changed()),SIGNAL(changed()));
+ }
+ else if (type==SA("obsolete"))
+ {
+ // ignore
+ }
+ else // should not happen
+ {
+ printf("Unsupported type %s\n",qPrintable(child.attribute(SA("type"))));
+ }
+ child = child.nextSiblingElement();
+ }
+
+ // compute dependencies between options
+ child = elem.firstChildElement();
+ while (!child.isNull())
+ {
+ QString dependsOn = child.attribute(SA("depends"));
+ QString id = child.attribute(SA("id"));
+ if (!dependsOn.isEmpty())
+ {
+ Input *parentOption = m_options[dependsOn];
+ Input *thisOption = m_options[id];
+ Q_ASSERT(parentOption);
+ Q_ASSERT(thisOption);
+ if (parentOption && thisOption)
+ {
+ //printf("Adding dependency '%s' (%p)->'%s' (%p)\n",
+ // qPrintable(dependsOn),parentOption,
+ // qPrintable(id),thisOption);
+ parentOption->addDependency(thisOption);
+ }
+ }
+ child = child.nextSiblingElement();
+ }
+
+ // set initial dependencies
+ QHashIterator<QString,Input*> i(m_options);
+ while (i.hasNext())
+ {
+ i.next();
+ if (i.value())
+ {
+ i.value()->updateDependencies();
+ }
+ }
+
+ layout->setRowStretch(row,1);
+ layout->setColumnStretch(1,2);
+ layout->setSpacing(5);
+ topic->setLayout(layout);
+ area->setWidget(topic);
+ area->setWidgetResizable(true);
+ return area;
+}
+
+void Expert::activateTopic(QTreeWidgetItem *item,QTreeWidgetItem *)
+{
+ if (item)
+ {
+ QWidget *w = m_topics[item->text(0)];
+ m_topicStack->setCurrentWidget(w);
+ m_prev->setEnabled(m_topicStack->currentIndex()!=0);
+ m_next->setEnabled(m_topicStack->currentIndex()!=m_topicStack->count()-1);
+ }
+}
+
+void Expert::loadSettings(QSettings *s)
+{
+ QHashIterator<QString,Input*> i(m_options);
+ while (i.hasNext())
+ {
+ i.next();
+ QVariant var = s->value(SA("config/")+i.key());
+ if (i.value())
+ {
+ //printf("Loading key %s: type=%d value='%s'\n",qPrintable(i.key()),var.type(),qPrintable(var.toString()));
+ i.value()->value() = var;
+ i.value()->update();
+ }
+ }
+}
+
+void Expert::saveSettings(QSettings *s)
+{
+ QHashIterator<QString,Input*> i(m_options);
+ while (i.hasNext())
+ {
+ i.next();
+ //printf("Saving key %s: type=%d value='%s'\n",qPrintable(i.key()),i.value()->value().type(),qPrintable(i.value()->value().toString()));
+ if (i.value())
+ {
+ s->setValue(SA("config/")+i.key(),i.value()->value());
+ }
+ }
+}
+
+void Expert::loadConfig(const QString &fileName)
+{
+ //printf("Expert::loadConfig(%s)\n",qPrintable(fileName));
+ parseConfig(fileName,m_options);
+}
+
+void Expert::saveTopic(QTextStream &t,QDomElement &elem,QTextCodec *codec,
+ bool brief)
+{
+ // write group header
+ t << endl;
+ t << "#---------------------------------------------------------------------------" << endl;
+ t << "# " << elem.attribute(SA("docs")) << endl;
+ t << "#---------------------------------------------------------------------------" << endl;
+
+ // write options...
+ QDomElement childElem = elem.firstChildElement();
+ while (!childElem.isNull())
+ {
+ QString type = childElem.attribute(SA("type"));
+ QString name = childElem.attribute(SA("id"));
+ QHash<QString,Input*>::const_iterator i = m_options.find(name);
+ if (i!=m_options.end())
+ {
+ Input *option = i.value();
+ if (!brief)
+ {
+ t << endl;
+ t << convertToComment(childElem.attribute(SA("docs")));
+ t << endl;
+ }
+ t << name.leftJustified(23) << "= ";
+ if (option)
+ {
+ option->writeValue(t,codec);
+ }
+ t << endl;
+ }
+ childElem = childElem.nextSiblingElement();
+ }
+
+}
+
+bool Expert::writeConfig(QTextStream &t,bool brief)
+{
+ if (!brief)
+ {
+ // write global header
+ t << "# Doxyfile " << versionString << endl << endl; // TODO: add version
+ t << "# This file describes the settings to be used by the documentation system\n";
+ t << "# doxygen (www.doxygen.org) for a project\n";
+ t << "#\n";
+ t << "# All text after a hash (#) is considered a comment and will be ignored\n";
+ t << "# The format is:\n";
+ t << "# TAG = value [value, ...]\n";
+ t << "# For lists items can also be appended using:\n";
+ t << "# TAG += value [value, ...]\n";
+ t << "# Values that contain spaces should be placed between quotes (\" \")\n";
+ }
+
+ QTextCodec *codec = 0;
+ Input *option = m_options[QString::fromAscii("DOXYFILE_ENCODING")];
+ if (option)
+ {
+ codec = QTextCodec::codecForName(option->value().toString().toAscii());
+ if (codec==0) // fallback: use UTF-8
+ {
+ codec = QTextCodec::codecForName("UTF-8");
+ }
+ }
+ QDomElement childElem = m_rootElement.firstChildElement();
+ while (!childElem.isNull())
+ {
+ saveTopic(t,childElem,codec,brief);
+ childElem = childElem.nextSiblingElement();
+ }
+ return true;
+}
+
+QByteArray Expert::saveInnerState () const
+{
+ return m_splitter->saveState();
+}
+
+bool Expert::restoreInnerState ( const QByteArray & state )
+{
+ return m_splitter->restoreState(state);
+}
+
+void Expert::showHelp(Input *option)
+{
+ if (!m_inShowHelp)
+ {
+ m_inShowHelp = TRUE;
+ m_helper->setText(
+ QString::fromAscii("<qt><b>")+option->id()+
+ QString::fromAscii("</b><br>")+
+ option->docs().
+ replace(QChar::fromAscii('\n'),QChar::fromAscii(' '))+
+ QString::fromAscii("<qt>")
+ );
+ m_inShowHelp = FALSE;
+ }
+}
+
+void Expert::nextTopic()
+{
+ m_topicStack->setCurrentIndex(m_topicStack->currentIndex()+1);
+ m_next->setEnabled(m_topicStack->count()!=m_topicStack->currentIndex()+1);
+ m_prev->setEnabled(m_topicStack->currentIndex()!=0);
+ m_treeWidget->setCurrentItem(m_treeWidget->invisibleRootItem()->child(m_topicStack->currentIndex()));
+}
+
+void Expert::prevTopic()
+{
+ m_topicStack->setCurrentIndex(m_topicStack->currentIndex()-1);
+ m_next->setEnabled(m_topicStack->count()!=m_topicStack->currentIndex()+1);
+ m_prev->setEnabled(m_topicStack->currentIndex()!=0);
+ m_treeWidget->setCurrentItem(m_treeWidget->invisibleRootItem()->child(m_topicStack->currentIndex()));
+}
+
+void Expert::resetToDefaults()
+{
+ //printf("Expert::makeDefaults()\n");
+ QHashIterator<QString,Input*> i(m_options);
+ while (i.hasNext())
+ {
+ i.next();
+ if (i.value())
+ {
+ i.value()->reset();
+ }
+ }
+}
+
+static bool stringVariantToBool(const QVariant &v)
+{
+ QString s = v.toString().toLower();
+ return s==QString::fromAscii("yes") || s==QString::fromAscii("true") || s==QString::fromAscii("1");
+}
+
+static bool getBoolOption(
+ const QHash<QString,Input*>&model,const QString &name)
+{
+ Input *option = model[name];
+ Q_ASSERT(option!=0);
+ return stringVariantToBool(option->value());
+}
+
+static QString getStringOption(
+ const QHash<QString,Input*>&model,const QString &name)
+{
+ Input *option = model[name];
+ Q_ASSERT(option!=0);
+ return option->value().toString();
+}
+
+
+bool Expert::htmlOutputPresent(const QString &workingDir) const
+{
+ bool generateHtml = getBoolOption(m_options,QString::fromAscii("GENERATE_HTML"));
+ if (!generateHtml || workingDir.isEmpty()) return false;
+ QString indexFile = getHtmlOutputIndex(workingDir);
+ QFileInfo fi(indexFile);
+ return fi.exists() && fi.isFile();
+}
+
+QString Expert::getHtmlOutputIndex(const QString &workingDir) const
+{
+ QString outputDir = getStringOption(m_options,QString::fromAscii("OUTPUT_DIRECTORY"));
+ QString htmlOutputDir = getStringOption(m_options,QString::fromAscii("HTML_OUTPUT"));
+ //printf("outputDir=%s\n",qPrintable(outputDir));
+ //printf("htmlOutputDir=%s\n",qPrintable(htmlOutputDir));
+ QString indexFile = workingDir;
+ if (QFileInfo(outputDir).isAbsolute()) // override
+ {
+ indexFile = outputDir;
+ }
+ else // append
+ {
+ indexFile += QString::fromAscii("/")+outputDir;
+ }
+ if (QFileInfo(htmlOutputDir).isAbsolute()) // override
+ {
+ indexFile = htmlOutputDir;
+ }
+ else // append
+ {
+ indexFile += QString::fromAscii("/")+htmlOutputDir;
+ }
+ indexFile+=QString::fromAscii("/index.html");
+ return indexFile;
+}
+
+bool Expert::pdfOutputPresent(const QString &workingDir) const
+{
+ bool generateLatex = getBoolOption(m_options,QString::fromAscii("GENERATE_LATEX"));
+ bool pdfLatex = getBoolOption(m_options,QString::fromAscii("USE_PDFLATEX"));
+ if (!generateLatex || !pdfLatex) return false;
+ QString latexOutput = getStringOption(m_options,QString::fromAscii("LATEX_OUTPUT"));
+ QString indexFile;
+ if (QFileInfo(latexOutput).isAbsolute())
+ {
+ indexFile = latexOutput+QString::fromAscii("/refman.pdf");
+ }
+ else
+ {
+ indexFile = workingDir+QString::fromAscii("/")+
+ latexOutput+QString::fromAscii("/refman.pdf");
+ }
+ QFileInfo fi(indexFile);
+ return fi.exists() && fi.isFile();
+}
+
diff --git a/trunk/addon/doxywizard/expert.h b/trunk/addon/doxywizard/expert.h
new file mode 100644
index 0000000..8d43161
--- /dev/null
+++ b/trunk/addon/doxywizard/expert.h
@@ -0,0 +1,65 @@
+#ifndef EXPERT_H
+#define EXPERT_H
+
+#include <QSplitter>
+#include <QDomElement>
+#include <QHash>
+
+class QTreeWidget;
+class QTreeWidgetItem;
+class QStackedWidget;
+class QSettings;
+class QTextEdit;
+class QTextCodec;
+class QPushButton;
+class Input;
+
+class Expert : public QSplitter
+{
+ Q_OBJECT
+
+ public:
+ Expert();
+ ~Expert();
+ void loadSettings(QSettings *);
+ void saveSettings(QSettings *);
+ void loadConfig(const QString &fileName);
+ bool writeConfig(QTextStream &t,bool brief);
+ QByteArray saveInnerState () const;
+ bool restoreInnerState ( const QByteArray & state );
+ const QHash<QString,Input*> &modelData() const { return m_options; }
+ void resetToDefaults();
+ bool htmlOutputPresent(const QString &workingDir) const;
+ bool pdfOutputPresent(const QString &workingDir) const;
+ QString getHtmlOutputIndex(const QString &workingDir) const;
+
+ public slots:
+ void activateTopic(QTreeWidgetItem *,QTreeWidgetItem *);
+ QWidget *createTopicWidget(QDomElement &elem);
+
+ private slots:
+ void showHelp(Input *);
+ void nextTopic();
+ void prevTopic();
+
+ signals:
+ void changed();
+
+ private:
+ void createTopics(const QDomElement &);
+ void saveTopic(QTextStream &t,QDomElement &elem,QTextCodec *codec,bool brief);
+
+ QSplitter *m_splitter;
+ QTextEdit *m_helper;
+ QTreeWidget *m_treeWidget;
+ QStackedWidget *m_topicStack;
+ QHash<QString,QWidget *> m_topics;
+ QHash<QString,QObject *> m_optionWidgets;
+ QHash<QString,Input *> m_options;
+ QPushButton *m_next;
+ QPushButton *m_prev;
+ QDomElement m_rootElement;
+ bool m_inShowHelp;
+};
+
+#endif
diff --git a/trunk/addon/doxywizard/helplabel.h b/trunk/addon/doxywizard/helplabel.h
new file mode 100644
index 0000000..07e2932
--- /dev/null
+++ b/trunk/addon/doxywizard/helplabel.h
@@ -0,0 +1,33 @@
+#ifndef HELPLABEL_H
+#define HELPLABEL_H
+
+#include <QLabel>
+#include <QMenu>
+
+class HelpLabel : public QLabel
+{
+ Q_OBJECT
+ public:
+ HelpLabel(const QString &text) : QLabel(text)
+ { setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(this,SIGNAL(customContextMenuRequested(const QPoint&)),
+ this,SLOT(showMenu(const QPoint&)));
+ }
+ signals:
+ void enter();
+ void reset();
+ private slots:
+ void showMenu(const QPoint &p)
+ {
+ QMenu menu(this);
+ QAction *a = menu.addAction(tr("Reset to default"));
+ if (menu.exec(mapToGlobal(p))==a)
+ {
+ reset();
+ }
+ }
+ protected:
+ void enterEvent( QEvent * event ) { enter(); QLabel::enterEvent(event); }
+};
+
+#endif
diff --git a/trunk/addon/doxywizard/images/add.png b/trunk/addon/doxywizard/images/add.png
new file mode 100644
index 0000000..30a7090
--- /dev/null
+++ b/trunk/addon/doxywizard/images/add.png
Binary files differ
diff --git a/trunk/addon/doxywizard/images/del.png b/trunk/addon/doxywizard/images/del.png
new file mode 100644
index 0000000..ceb6a60
--- /dev/null
+++ b/trunk/addon/doxywizard/images/del.png
Binary files differ
diff --git a/trunk/addon/doxywizard/images/file.png b/trunk/addon/doxywizard/images/file.png
new file mode 100644
index 0000000..e204f67
--- /dev/null
+++ b/trunk/addon/doxywizard/images/file.png
Binary files differ
diff --git a/trunk/addon/doxywizard/images/folder.png b/trunk/addon/doxywizard/images/folder.png
new file mode 100644
index 0000000..2e420e0
--- /dev/null
+++ b/trunk/addon/doxywizard/images/folder.png
Binary files differ
diff --git a/trunk/addon/doxywizard/images/refresh.png b/trunk/addon/doxywizard/images/refresh.png
new file mode 100644
index 0000000..fd6d565
--- /dev/null
+++ b/trunk/addon/doxywizard/images/refresh.png
Binary files differ
diff --git a/trunk/addon/doxywizard/images/tunecolor.png b/trunk/addon/doxywizard/images/tunecolor.png
new file mode 100644
index 0000000..bf7be83
--- /dev/null
+++ b/trunk/addon/doxywizard/images/tunecolor.png
Binary files differ
diff --git a/trunk/addon/doxywizard/input.h b/trunk/addon/doxywizard/input.h
new file mode 100644
index 0000000..dd1773c
--- /dev/null
+++ b/trunk/addon/doxywizard/input.h
@@ -0,0 +1,34 @@
+#ifndef INPUT_H
+#define INPUT_H
+
+#include <QVariant>
+
+class QTextStream;
+class QTextCodec;
+
+class Input
+{
+ public:
+ enum Kind
+ {
+ Bool,
+ Int,
+ String,
+ StrList,
+ Obsolete
+ };
+ virtual ~Input() {}
+ virtual QVariant &value() = 0;
+ virtual void update() = 0;
+ virtual Kind kind() const = 0;
+ virtual QString docs() const = 0;
+ virtual QString id() const = 0;
+ virtual void addDependency(Input *option) = 0;
+ virtual void setEnabled(bool) = 0;
+ virtual void updateDependencies() = 0;
+ virtual void reset() = 0;
+ virtual void writeValue(QTextStream &t,QTextCodec *codec) = 0;
+};
+
+
+#endif
diff --git a/trunk/addon/doxywizard/inputbool.cpp b/trunk/addon/doxywizard/inputbool.cpp
new file mode 100644
index 0000000..cd83f88
--- /dev/null
+++ b/trunk/addon/doxywizard/inputbool.cpp
@@ -0,0 +1,110 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2012 by Dimitri van Heesch.
+ *
+ * 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.
+ *
+ */
+
+#include "inputbool.h"
+#include "helplabel.h"
+#include <QtGui>
+
+InputBool::InputBool( QGridLayout *layout, int &row,
+ const QString &id, bool checked,
+ const QString &docs )
+ : m_default(checked), m_docs(docs), m_id(id)
+{
+ m_lab = new HelpLabel(id);
+ m_cb = new QCheckBox;
+ layout->addWidget(m_lab,row, 0);
+ layout->addWidget(m_cb,row, 1);
+ m_enabled = true;
+ m_state=!checked; // force update
+ setValue(checked);
+ connect( m_cb, SIGNAL(toggled(bool)), SLOT(setValue(bool)) );
+ connect( m_lab, SIGNAL(enter()), SLOT(help()) );
+ connect( m_lab, SIGNAL(reset()), SLOT(reset()) );
+ row++;
+}
+
+void InputBool::help()
+{
+ showHelp(this);
+}
+
+void InputBool::setEnabled(bool b)
+{
+ m_enabled = b;
+ m_cb->setEnabled(b);
+ updateDependencies();
+}
+
+void InputBool::updateDependencies()
+{
+ for (int i=0;i<m_dependencies.count();i++)
+ {
+ m_dependencies[i]->setEnabled(m_enabled && m_state);
+ }
+}
+
+void InputBool::setValue( bool s )
+{
+ if (m_state!=s)
+ {
+ m_state=s;
+ updateDefault();
+ updateDependencies();
+ m_cb->setChecked( s );
+ m_value = m_state;
+ emit changed();
+ }
+}
+
+void InputBool::updateDefault()
+{
+ if (m_state==m_default)
+ {
+ m_lab->setText(QString::fromAscii("<qt>")+m_id+QString::fromAscii("</qt"));
+ }
+ else
+ {
+ m_lab->setText(QString::fromAscii("<qt><font color='red'>")+m_id+QString::fromAscii("</font></qt>"));
+ }
+}
+
+QVariant &InputBool::value()
+{
+ return m_value;
+}
+
+void InputBool::update()
+{
+ QString v = m_value.toString().toLower();
+ m_state = (v==QString::fromAscii("yes") ||
+ v==QString::fromAscii("true") ||
+ v==QString::fromAscii("1"));
+ m_cb->setChecked( m_state );
+ updateDefault();
+ updateDependencies();
+}
+
+void InputBool::reset()
+{
+ setValue(m_default);
+}
+
+void InputBool::writeValue(QTextStream &t,QTextCodec *codec)
+{
+ if (m_state)
+ t << codec->fromUnicode(QString::fromAscii("YES"));
+ else
+ t << codec->fromUnicode(QString::fromAscii("NO"));
+}
+
diff --git a/trunk/addon/doxywizard/inputbool.h b/trunk/addon/doxywizard/inputbool.h
new file mode 100644
index 0000000..63d16e6
--- /dev/null
+++ b/trunk/addon/doxywizard/inputbool.h
@@ -0,0 +1,70 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2012 by Dimitri van Heesch.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _INPUTBOOL_H
+#define _INPUTBOOL_H
+
+#include "input.h"
+#include <QObject>
+
+class QCheckBox;
+class QGridLayout;
+class QLabel;
+
+class InputBool : public QObject, public Input
+{
+ Q_OBJECT
+
+ public:
+ InputBool(QGridLayout *layout,int &row,const QString &id,
+ bool enabled, const QString &docs );
+
+ // Input
+ QVariant &value();
+ void update();
+ Kind kind() const { return Bool; }
+ QString docs() const { return m_docs; }
+ QString id() const { return m_id; }
+ void addDependency(Input *option) { m_dependencies+=option; }
+ void setEnabled(bool);
+ void updateDependencies();
+ void writeValue(QTextStream &t,QTextCodec *codec);
+
+ public slots:
+ void reset();
+ void setValue(bool);
+
+ signals:
+ void changed();
+ void toggle(QString,bool);
+ void showHelp(Input *);
+
+ private slots:
+ void help();
+
+ private:
+ void updateDefault();
+ bool m_state;
+ bool m_default;
+ bool m_enabled;
+ QVariant m_value;
+ QCheckBox *m_cb;
+ QString m_docs;
+ QList<Input*> m_dependencies;
+ QString m_id;
+ QLabel *m_lab;
+
+};
+
+#endif
diff --git a/trunk/addon/doxywizard/inputint.cpp b/trunk/addon/doxywizard/inputint.cpp
new file mode 100644
index 0000000..08df309
--- /dev/null
+++ b/trunk/addon/doxywizard/inputint.cpp
@@ -0,0 +1,96 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2012 by Dimitri van Heesch.
+ *
+ * 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.
+ *
+ */
+
+#include "inputint.h"
+#include "helplabel.h"
+
+#include <QtGui>
+
+InputInt::InputInt( QGridLayout *layout,int &row,
+ const QString & id,
+ int defVal, int minVal,int maxVal,
+ const QString & docs )
+ : m_default(defVal), m_minVal(minVal), m_maxVal(maxVal), m_docs(docs), m_id(id)
+{
+ m_lab = new HelpLabel(id);
+ m_sp = new QSpinBox;
+ m_sp->setMinimum(minVal);
+ m_sp->setMaximum(maxVal);
+ m_sp->setSingleStep(1);
+ m_val=defVal-1; // force update
+ setValue(defVal);
+
+ layout->addWidget( m_lab, row, 0 );
+ layout->addWidget( m_sp, row, 1 );
+
+ connect(m_sp, SIGNAL(valueChanged(int)),
+ this, SLOT(setValue(int)) );
+ connect( m_lab, SIGNAL(enter()), SLOT(help()) );
+ connect( m_lab, SIGNAL(reset()), SLOT(reset()) );
+ row++;
+}
+
+void InputInt::help()
+{
+ showHelp(this);
+}
+
+
+void InputInt::setValue(int val)
+{
+ val = qMax(m_minVal,val);
+ val = qMin(m_maxVal,val);
+ if (val!=m_val)
+ {
+ m_val = val;
+ m_sp->setValue(val);
+ m_value = m_val;
+ if (m_val==m_default)
+ {
+ m_lab->setText(QString::fromAscii("<qt>")+m_id+QString::fromAscii("</qt"));
+ }
+ else
+ {
+ m_lab->setText(QString::fromAscii("<qt><font color='red'>")+m_id+QString::fromAscii("</font></qt>"));
+ }
+ emit changed();
+ }
+}
+
+void InputInt::setEnabled(bool state)
+{
+ m_lab->setEnabled(state);
+ m_sp->setEnabled(state);
+}
+
+QVariant &InputInt::value()
+{
+ return m_value;
+}
+
+void InputInt::update()
+{
+ setValue(m_value.toInt());
+}
+
+void InputInt::reset()
+{
+ setValue(m_default);
+}
+
+void InputInt::writeValue(QTextStream &t,QTextCodec *)
+{
+ t << m_val;
+}
+
diff --git a/trunk/addon/doxywizard/inputint.h b/trunk/addon/doxywizard/inputint.h
new file mode 100644
index 0000000..9ac506d
--- /dev/null
+++ b/trunk/addon/doxywizard/inputint.h
@@ -0,0 +1,70 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2012 by Dimitri van Heesch.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _INPUTINT_H
+#define _INPUTINT_H
+
+#include "input.h"
+#include <QObject>
+
+class QGridLayout;
+class QLabel;
+class QSpinBox;
+
+class InputInt : public QObject, public Input
+{
+ Q_OBJECT
+
+ public:
+ InputInt( QGridLayout *layout,int &row,
+ const QString &id, int defVal,
+ int minVal, int maxVal,
+ const QString &docs );
+ ~InputInt(){};
+
+ // Input
+ QVariant &value();
+ void update();
+ Kind kind() const { return Int; }
+ QString docs() const { return m_docs; }
+ QString id() const { return m_id; }
+ void addDependency(Input *) { Q_ASSERT(false); }
+ void setEnabled(bool);
+ void updateDependencies() {}
+ void writeValue(QTextStream &t,QTextCodec *codec);
+
+ public slots:
+ void reset();
+ void setValue(int val);
+
+ private slots:
+ void help();
+
+ signals:
+ void changed();
+ void showHelp(Input *);
+
+ private:
+ QLabel *m_lab;
+ QSpinBox *m_sp;
+ int m_val;
+ int m_default;
+ int m_minVal;
+ int m_maxVal;
+ QVariant m_value;
+ QString m_docs;
+ QString m_id;
+};
+
+#endif
diff --git a/trunk/addon/doxywizard/inputstring.cpp b/trunk/addon/doxywizard/inputstring.cpp
new file mode 100644
index 0000000..c0b92b3
--- /dev/null
+++ b/trunk/addon/doxywizard/inputstring.cpp
@@ -0,0 +1,193 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2012 by Dimitri van Heesch.
+ *
+ * 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.
+ *
+ */
+
+#include "inputstring.h"
+#include "helplabel.h"
+#include "doxywizard.h"
+#include "config.h"
+
+#include <QtGui>
+
+InputString::InputString( QGridLayout *layout,int &row,
+ const QString & id, const QString &s,
+ StringMode m, const QString &docs,
+ const QString &absPath )
+ : m_default(s), m_sm(m), m_index(0), m_docs(docs), m_id(id),
+ m_absPath(absPath==QString::fromAscii("1"))
+{
+ m_lab = new HelpLabel(id);
+ if (m==StringFixed)
+ {
+ layout->addWidget( m_lab, row, 0 );
+ m_com = new QComboBox;
+ layout->addWidget( m_com, row, 1, 1, 3, Qt::AlignLeft );
+ m_le=0;
+ m_br=0;
+ row++;
+ }
+ else
+ {
+ layout->addWidget( m_lab, row, 0 );
+ m_le = new QLineEdit;
+ m_le->setText( s );
+ //layout->setColumnMinimumWidth(2,150);
+ if (m==StringFile || m==StringDir)
+ {
+ layout->addWidget( m_le, row, 1 );
+ m_br = new QToolBar;
+ m_br->setIconSize(QSize(24,24));
+ if (m==StringFile)
+ {
+ QAction *file = m_br->addAction(QIcon(QString::fromAscii(":/images/file.png")),QString(),this,SLOT(browse()));
+ file->setToolTip(tr("Browse to a file"));
+ }
+ else
+ {
+ QAction *dir = m_br->addAction(QIcon(QString::fromAscii(":/images/folder.png")),QString(),this,SLOT(browse()));
+ dir->setToolTip(tr("Browse to a folder"));
+ }
+ layout->addWidget( m_br,row,2 );
+ }
+ else
+ {
+ layout->addWidget( m_le, row, 1, 1, 2 );
+ m_br=0;
+ }
+ m_com=0;
+ row++;
+ }
+
+ if (m_le) connect( m_le, SIGNAL(textChanged(const QString&)),
+ this, SLOT(setValue(const QString&)) );
+ if (m_com) connect( m_com, SIGNAL(activated(const QString &)),
+ this, SLOT(setValue(const QString &)) );
+ m_str = s+QChar::fromAscii('!'); // force update
+ setValue(s);
+ connect( m_lab, SIGNAL(enter()), SLOT(help()) );
+ connect( m_lab, SIGNAL(reset()), SLOT(reset()) );
+}
+
+void InputString::help()
+{
+ showHelp(this);
+}
+
+
+InputString::~InputString()
+{
+}
+
+
+void InputString::setValue(const QString &s)
+{
+ if (m_str!=s)
+ {
+ m_str = s;
+ m_value = m_str;
+ if (m_str==m_default)
+ {
+ m_lab->setText(QString::fromAscii("<qt>")+m_id+QString::fromAscii("</qt"));
+ }
+ else
+ {
+ m_lab->setText(QString::fromAscii("<qt><font color='red'>")+m_id+QString::fromAscii("</font></qt>"));
+ }
+ if (m_le && m_le->text()!=m_str) m_le->setText( m_str );
+ emit changed();
+ }
+}
+
+void InputString::setEnabled(bool state)
+{
+ m_lab->setEnabled(state);
+ if (m_le) m_le->setEnabled(state);
+ if (m_br) m_br->setEnabled(state);
+ if (m_com) m_com->setEnabled(state);
+}
+
+void InputString::browse()
+{
+ QString path = QFileInfo(MainWindow::instance().configFileName()).path();
+ if (m_sm==StringFile)
+ {
+ QString fileName = QFileDialog::getOpenFileName(&MainWindow::instance(),
+ tr("Select file"),path);
+ if (!fileName.isNull())
+ {
+ QDir dir(path);
+ if (!MainWindow::instance().configFileName().isEmpty() && dir.exists())
+ {
+ fileName = m_absPath ? fileName : dir.relativeFilePath(fileName);
+ }
+ setValue(fileName);
+ }
+ }
+ else // sm==StringDir
+ {
+ QString dirName = QFileDialog::getExistingDirectory(&MainWindow::instance(),
+ tr("Select directory"),path);
+ if (!dirName.isNull())
+ {
+ QDir dir(path);
+ if (!MainWindow::instance().configFileName().isEmpty() && dir.exists())
+ {
+ dirName = m_absPath ? dirName : dir.relativeFilePath(dirName);
+ }
+ setValue(dirName);
+ }
+ }
+}
+
+void InputString::clear()
+{
+ setValue(QString());
+}
+
+void InputString::addValue(QString s)
+{
+ if (m_sm==StringFixed)
+ {
+ m_values.append(s);
+ m_com->addItem(s);
+ }
+}
+
+void InputString::setDefault()
+{
+ int index = m_values.indexOf(m_str);
+ if (index!=-1 && m_com) m_com->setCurrentIndex(index);
+}
+
+QVariant &InputString::value()
+{
+ return m_value;
+}
+
+void InputString::update()
+{
+ setValue(m_value.toString().trimmed());
+ setDefault();
+}
+
+void InputString::reset()
+{
+ setValue(m_default);
+ setDefault();
+}
+
+void InputString::writeValue(QTextStream &t,QTextCodec *codec)
+{
+ writeStringValue(t,codec,m_str);
+}
+
diff --git a/trunk/addon/doxywizard/inputstring.h b/trunk/addon/doxywizard/inputstring.h
new file mode 100644
index 0000000..b957bfa
--- /dev/null
+++ b/trunk/addon/doxywizard/inputstring.h
@@ -0,0 +1,90 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2012 by Dimitri van Heesch.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _INPUTSTRING_H
+#define _INPUTSTRING_H
+
+#include "input.h"
+
+#include <QObject>
+#include <QMap>
+#include <QStringList>
+
+class QLabel;
+class QLineEdit;
+class QToolBar;
+class QComboBox;
+class QGridLayout;
+
+class InputString : public QObject, public Input
+{
+ Q_OBJECT
+
+ public:
+ enum StringMode { StringFree=0,
+ StringFile=1,
+ StringDir=2,
+ StringFixed=3
+ };
+
+ InputString( QGridLayout *layout,int &row,
+ const QString &id, const QString &s,
+ StringMode m,
+ const QString &docs,
+ const QString &absPath = QString() );
+ ~InputString();
+ void addValue(QString s);
+ void setDefault();
+
+ // Input
+ QVariant &value();
+ void update();
+ Kind kind() const { return String; }
+ QString docs() const { return m_docs; }
+ QString id() const { return m_id; }
+ void addDependency(Input *) { Q_ASSERT(false); }
+ void setEnabled(bool);
+ void updateDependencies() {}
+ void writeValue(QTextStream &t,QTextCodec *codec);
+
+ public slots:
+ void reset();
+ void setValue(const QString&);
+
+ signals:
+ void changed();
+ void showHelp(Input *);
+
+ private slots:
+ void browse();
+ void clear();
+ void help();
+
+ private:
+ QLabel *m_lab;
+ QLineEdit *m_le;
+ QToolBar *m_br;
+ QComboBox *m_com;
+ QString m_str;
+ QString m_default;
+ StringMode m_sm;
+ QStringList m_values;
+ int m_index;
+ QVariant m_value;
+ QString m_docs;
+ QString m_id;
+ bool m_absPath;
+};
+
+#endif
diff --git a/trunk/addon/doxywizard/inputstrlist.cpp b/trunk/addon/doxywizard/inputstrlist.cpp
new file mode 100644
index 0000000..bca92e2
--- /dev/null
+++ b/trunk/addon/doxywizard/inputstrlist.cpp
@@ -0,0 +1,254 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2012 by Dimitri van Heesch.
+ *
+ * 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.
+ *
+ */
+
+#include "inputstrlist.h"
+#include "helplabel.h"
+#include "doxywizard.h"
+#include "config.h"
+
+#include <QtGui>
+
+InputStrList::InputStrList( QGridLayout *layout,int &row,
+ const QString & id,
+ const QStringList &sl, ListMode lm,
+ const QString & docs)
+ : m_default(sl), m_strList(sl), m_docs(docs), m_id(id)
+{
+ m_lab = new HelpLabel( id );
+
+ m_le = new QLineEdit;
+ m_le->clear();
+
+ QToolBar *toolBar = new QToolBar;
+ toolBar->setIconSize(QSize(24,24));
+ m_add = toolBar->addAction(QIcon(QString::fromAscii(":/images/add.png")),QString(),
+ this,SLOT(addString()));
+ m_add->setToolTip(tr("Add item"));
+ m_del = toolBar->addAction(QIcon(QString::fromAscii(":/images/del.png")),QString(),
+ this,SLOT(delString()));
+ m_del->setToolTip(tr("Delete selected item"));
+ m_upd = toolBar->addAction(QIcon(QString::fromAscii(":/images/refresh.png")),QString(),
+ this,SLOT(updateString()));
+ m_upd->setToolTip(tr("Update selected item"));
+
+ m_lb = new QListWidget;
+ //m_lb->setMinimumSize(400,100);
+ foreach (QString s, m_strList) m_lb->addItem(s);
+
+ m_brFile=0;
+ m_brDir=0;
+ if (lm!=ListString)
+ {
+ if (lm&ListFile)
+ {
+ m_brFile = toolBar->addAction(QIcon(QString::fromAscii(":/images/file.png")),QString(),
+ this,SLOT(browseFiles()));
+ m_brFile->setToolTip(tr("Browse to a file"));
+ }
+ if (lm&ListDir)
+ {
+ m_brDir = toolBar->addAction(QIcon(QString::fromAscii(":/images/folder.png")),QString(),
+ this,SLOT(browseDir()));
+ m_brDir->setToolTip(tr("Browse to a folder"));
+ }
+ }
+ QHBoxLayout *rowLayout = new QHBoxLayout;
+ rowLayout->addWidget( m_le );
+ rowLayout->addWidget( toolBar );
+ layout->addWidget( m_lab, row,0 );
+ layout->addLayout( rowLayout, row,1,1,2 );
+ layout->addWidget( m_lb, row+1,1,1,2 );
+ row+=2;
+
+ m_value = m_strList;
+
+ connect(m_le, SIGNAL(returnPressed()),
+ this, SLOT(addString()) );
+ connect(m_lb, SIGNAL(currentTextChanged(const QString &)),
+ this, SLOT(selectText(const QString &)));
+ connect( m_lab, SIGNAL(enter()), SLOT(help()) );
+ connect( m_lab, SIGNAL(reset()), SLOT(reset()) );
+}
+
+void InputStrList::help()
+{
+ showHelp(this);
+}
+
+
+void InputStrList::addString()
+{
+ if (!m_le->text().isEmpty())
+ {
+ m_lb->addItem(m_le->text());
+ m_strList.append(m_le->text());
+ m_value = m_strList;
+ updateDefault();
+ emit changed();
+ m_le->clear();
+ }
+}
+
+void InputStrList::delString()
+{
+ if (m_lb->currentRow()!=-1)
+ {
+ int itemIndex = m_lb->currentRow();
+ delete m_lb->currentItem();
+ m_strList.removeAt(itemIndex);
+ m_value = m_strList;
+ updateDefault();
+ emit changed();
+ }
+}
+
+void InputStrList::updateString()
+{
+ if (m_lb->currentRow()!=-1 && !m_le->text().isEmpty())
+ {
+ m_lb->currentItem()->setText(m_le->text());
+ m_strList.insert(m_lb->currentRow(),m_le->text());
+ m_strList.removeAt(m_lb->currentRow()+1);
+ m_value = m_strList;
+ updateDefault();
+ emit changed();
+ }
+}
+
+void InputStrList::selectText(const QString &s)
+{
+ m_le->setText(s);
+}
+
+void InputStrList::setEnabled(bool state)
+{
+ m_lab->setEnabled(state);
+ m_le->setEnabled(state);
+ m_add->setEnabled(state);
+ m_del->setEnabled(state);
+ m_upd->setEnabled(state);
+ m_lb->setEnabled(state);
+ if (m_brFile) m_brFile->setEnabled(state);
+ if (m_brDir) m_brDir->setEnabled(state);
+}
+
+void InputStrList::browseFiles()
+{
+ QString path = QFileInfo(MainWindow::instance().configFileName()).path();
+ QStringList fileNames = QFileDialog::getOpenFileNames();
+
+ if (!fileNames.isEmpty())
+ {
+ QStringList::Iterator it;
+ for ( it= fileNames.begin(); it != fileNames.end(); ++it )
+ {
+ QString fileName;
+ QDir dir(path);
+ if (!MainWindow::instance().configFileName().isEmpty() && dir.exists())
+ {
+ fileName = dir.relativeFilePath(*it);
+ }
+ if (fileName.isEmpty())
+ {
+ fileName = *it;
+ }
+ m_lb->addItem(fileName);
+ m_strList.append(fileName);
+ m_value = m_strList;
+ updateDefault();
+ emit changed();
+ }
+ m_le->setText(m_strList[0]);
+ }
+}
+
+void InputStrList::browseDir()
+{
+ QString path = QFileInfo(MainWindow::instance().configFileName()).path();
+ QString dirName = QFileDialog::getExistingDirectory();
+
+ if (!dirName.isNull())
+ {
+ QDir dir(path);
+ if (!MainWindow::instance().configFileName().isEmpty() && dir.exists())
+ {
+ dirName = dir.relativeFilePath(dirName);
+ }
+ if (dirName.isEmpty())
+ {
+ dirName=QString::fromAscii(".");
+ }
+ m_lb->addItem(dirName);
+ m_strList.append(dirName);
+ m_value = m_strList;
+ updateDefault();
+ emit changed();
+ m_le->setText(dirName);
+ }
+}
+
+void InputStrList::setValue(const QStringList &sl)
+{
+ m_le->clear();
+ m_lb->clear();
+ m_strList = sl;
+ for (int i=0;i<m_strList.size();i++)
+ {
+ m_lb->addItem(m_strList[i].trimmed());
+ }
+ updateDefault();
+}
+
+QVariant &InputStrList::value()
+{
+ return m_value;
+}
+
+void InputStrList::update()
+{
+ setValue(m_value.toStringList());
+}
+
+void InputStrList::updateDefault()
+{
+ if (m_strList==m_default)
+ {
+ m_lab->setText(QString::fromAscii("<qt>")+m_id+QString::fromAscii("</qt"));
+ }
+ else
+ {
+ m_lab->setText(QString::fromAscii("<qt><font color='red'>")+m_id+QString::fromAscii("</font></qt>"));
+ }
+}
+
+void InputStrList::reset()
+{
+ setValue(m_default);
+}
+
+void InputStrList::writeValue(QTextStream &t,QTextCodec *codec)
+{
+ bool first=TRUE;
+ foreach (QString s, m_strList)
+ {
+ if (!first)
+ {
+ t << " \\" << endl;
+ t << " ";
+ }
+ first=FALSE;
+ writeStringValue(t,codec,s);
+ }
+}
+
diff --git a/trunk/addon/doxywizard/inputstrlist.h b/trunk/addon/doxywizard/inputstrlist.h
new file mode 100644
index 0000000..0201aee
--- /dev/null
+++ b/trunk/addon/doxywizard/inputstrlist.h
@@ -0,0 +1,91 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2012 by Dimitri van Heesch.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _INPUTSTRLIST_H
+#define _INPUTSTRLIST_H
+
+#include "input.h"
+
+#include <QObject>
+#include <QStringList>
+
+class QLabel;
+class QLineEdit;
+class QPushButton;
+class QListWidget;
+class QStringList;
+class QGridLayout;
+class QAction;
+
+class InputStrList : public QObject, public Input
+{
+ Q_OBJECT
+
+ public:
+ enum ListMode { ListString = 0,
+ ListFile = 1,
+ ListDir = 2,
+ ListFileDir = ListFile | ListDir
+ };
+
+ InputStrList( QGridLayout *layout,int &row,
+ const QString &id, const QStringList &sl,
+ ListMode v, const QString &docs);
+ void setValue(const QStringList &sl);
+
+ QVariant &value();
+ void update();
+ Kind kind() const { return StrList; }
+ QString docs() const { return m_docs; }
+ QString id() const { return m_id; }
+ void addDependency(Input *) { Q_ASSERT(false); }
+ void setEnabled(bool);
+ void updateDependencies() {}
+ void writeValue(QTextStream &t,QTextCodec *codec);
+
+ public slots:
+ void reset();
+
+ signals:
+ void changed();
+ void showHelp(Input *);
+
+ private slots:
+ void addString();
+ void delString();
+ void updateString();
+ void selectText(const QString &s);
+ void browseFiles();
+ void browseDir();
+ void help();
+
+ private:
+ void updateDefault();
+ QLabel *m_lab;
+ QLineEdit *m_le;
+ QAction *m_add;
+ QAction *m_del;
+ QAction *m_upd;
+ QAction *m_brFile;
+ QAction *m_brDir;
+ QListWidget *m_lb;
+ QStringList m_default;
+ QStringList m_strList;
+ QVariant m_value;
+ QString m_docs;
+ QString m_id;
+
+};
+
+#endif
diff --git a/trunk/addon/doxywizard/version.h b/trunk/addon/doxywizard/version.h
new file mode 100644
index 0000000..4752520
--- /dev/null
+++ b/trunk/addon/doxywizard/version.h
@@ -0,0 +1,23 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2012 by Dimitri van Heesch.
+ *
+ * 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 VERSION_H
+#define VERSION_H
+
+extern char versionString[];
+
+#endif
diff --git a/trunk/addon/doxywizard/wizard.cpp b/trunk/addon/doxywizard/wizard.cpp
new file mode 100644
index 0000000..ce989e7
--- /dev/null
+++ b/trunk/addon/doxywizard/wizard.cpp
@@ -0,0 +1,1295 @@
+#include "wizard.h"
+#include "input.h"
+#include "doxywizard.h"
+
+#include <math.h>
+#include <QtGui>
+
+// options configurable via the wizard
+#define STR_PROJECT_NAME QString::fromAscii("PROJECT_NAME")
+#define STR_PROJECT_LOGO QString::fromAscii("PROJECT_LOGO")
+#define STR_PROJECT_BRIEF QString::fromAscii("PROJECT_BRIEF")
+#define STR_INPUT QString::fromAscii("INPUT")
+#define STR_OUTPUT_DIRECTORY QString::fromAscii("OUTPUT_DIRECTORY")
+#define STR_PROJECT_NUMBER QString::fromAscii("PROJECT_NUMBER")
+#define STR_RECURSIVE QString::fromAscii("RECURSIVE")
+#define STR_OPTIMIZE_OUTPUT_FOR_C QString::fromAscii("OPTIMIZE_OUTPUT_FOR_C")
+#define STR_OPTIMIZE_OUTPUT_JAVA QString::fromAscii("OPTIMIZE_OUTPUT_JAVA")
+#define STR_OPTIMIZE_FOR_FORTRAN QString::fromAscii("OPTIMIZE_FOR_FORTRAN")
+#define STR_OPTIMIZE_OUTPUT_VHDL QString::fromAscii("OPTIMIZE_OUTPUT_VHDL")
+#define STR_CPP_CLI_SUPPORT QString::fromAscii("CPP_CLI_SUPPORT")
+#define STR_HIDE_SCOPE_NAMES QString::fromAscii("HIDE_SCOPE_NAMES")
+#define STR_EXTRACT_ALL QString::fromAscii("EXTRACT_ALL")
+#define STR_SOURCE_BROWSER QString::fromAscii("SOURCE_BROWSER")
+#define STR_GENERATE_HTML QString::fromAscii("GENERATE_HTML")
+#define STR_GENERATE_LATEX QString::fromAscii("GENERATE_LATEX")
+#define STR_GENERATE_MAN QString::fromAscii("GENERATE_MAN")
+#define STR_GENERATE_RTF QString::fromAscii("GENERATE_RTF")
+#define STR_GENERATE_XML QString::fromAscii("GENERATE_XML")
+#define STR_GENERATE_HTMLHELP QString::fromAscii("GENERATE_HTMLHELP")
+#define STR_GENERATE_TREEVIEW QString::fromAscii("GENERATE_TREEVIEW")
+#define STR_USE_PDFLATEX QString::fromAscii("USE_PDFLATEX")
+#define STR_PDF_HYPERLINKS QString::fromAscii("PDF_HYPERLINKS")
+#define STR_SEARCHENGINE QString::fromAscii("SEARCHENGINE")
+#define STR_HAVE_DOT QString::fromAscii("HAVE_DOT")
+#define STR_CLASS_DIAGRAMS QString::fromAscii("CLASS_DIAGRAMS")
+#define STR_CLASS_GRAPH QString::fromAscii("CLASS_GRAPH")
+#define STR_COLLABORATION_GRAPH QString::fromAscii("COLLABORATION_GRAPH")
+#define STR_GRAPHICAL_HIERARCHY QString::fromAscii("GRAPHICAL_HIERARCHY")
+#define STR_INCLUDE_GRAPH QString::fromAscii("INCLUDE_GRAPH")
+#define STR_INCLUDED_BY_GRAPH QString::fromAscii("INCLUDED_BY_GRAPH")
+#define STR_CALL_GRAPH QString::fromAscii("CALL_GRAPH")
+#define STR_CALLER_GRAPH QString::fromAscii("CALLER_GRAPH")
+#define STR_HTML_COLORSTYLE_HUE QString::fromAscii("HTML_COLORSTYLE_HUE")
+#define STR_HTML_COLORSTYLE_SAT QString::fromAscii("HTML_COLORSTYLE_SAT")
+#define STR_HTML_COLORSTYLE_GAMMA QString::fromAscii("HTML_COLORSTYLE_GAMMA")
+
+static bool g_optimizeMapping[6][6] =
+{
+ // A: OPTIMIZE_OUTPUT_FOR_C
+ // B: OPTIMIZE_OUTPUT_JAVA
+ // C: OPTIMIZE_FOR_FORTRAN
+ // D: OPTIMIZE_OUTPUT_VHDL
+ // E: CPP_CLI_SUPPORT
+ // F: HIDE_SCOPE_NAMES
+ // A B C D E F
+ { false,false,false,false,false,false }, // 0: C++
+ { false,false,false,false,true, false }, // 1: C++/CLI
+ { false,true, false,false,false,false }, // 2: C#/Java
+ { true, false,false,false,false,true }, // 3: C/PHP
+ { false,false,true, false,false,false }, // 4: Fortran
+ { false,false,false,true, false,false }, // 5: VHDL
+};
+
+static QString g_optimizeOptionNames[6] =
+{
+ STR_OPTIMIZE_OUTPUT_FOR_C,
+ STR_OPTIMIZE_OUTPUT_JAVA,
+ STR_OPTIMIZE_FOR_FORTRAN,
+ STR_OPTIMIZE_OUTPUT_VHDL,
+ STR_CPP_CLI_SUPPORT,
+ STR_HIDE_SCOPE_NAMES
+};
+
+//==========================================================================
+
+static bool stringVariantToBool(const QVariant &v)
+{
+ QString s = v.toString().toLower();
+ return s==QString::fromAscii("yes") || s==QString::fromAscii("true") || s==QString::fromAscii("1");
+}
+
+static bool getBoolOption(
+ const QHash<QString,Input*>&model,const QString &name)
+{
+ Input *option = model[name];
+ Q_ASSERT(option!=0);
+ return stringVariantToBool(option->value());
+}
+
+static int getIntOption(
+ const QHash<QString,Input*>&model,const QString &name)
+{
+ Input *option = model[name];
+ Q_ASSERT(option!=0);
+ return option->value().toInt();
+}
+
+static QString getStringOption(
+ const QHash<QString,Input*>&model,const QString &name)
+{
+ Input *option = model[name];
+ Q_ASSERT(option!=0);
+ return option->value().toString();
+}
+
+static void updateBoolOption(
+ const QHash<QString,Input*>&model,const QString &name,bool bNew)
+{
+ Input *option = model[name];
+ Q_ASSERT(option!=0);
+ bool bOld = stringVariantToBool(option->value());
+ if (bOld!=bNew)
+ {
+ option->value()=QString::fromAscii(bNew ? "true" : "false");
+ option->update();
+ }
+}
+
+static void updateIntOption(
+ const QHash<QString,Input*>&model,const QString &name,int iNew)
+{
+ Input *option = model[name];
+ Q_ASSERT(option!=0);
+ int iOld = option->value().toInt();
+ if (iOld!=iNew)
+ {
+ option->value()=QString::fromAscii("%1").arg(iNew);
+ option->update();
+ }
+}
+
+
+static void updateStringOption(
+ const QHash<QString,Input*>&model,const QString &name,const QString &s)
+{
+ Input *option = model[name];
+ Q_ASSERT(option!=0);
+ if (option->value().toString()!=s)
+ {
+ option->value() = s;
+ option->update();
+ }
+}
+
+//==========================================================================
+
+TuneColorDialog::TuneColorDialog(int hue,int sat,int gamma,QWidget *parent) : QDialog(parent)
+{
+ setWindowTitle(tr("Tune the color of the HTML output"));
+ QGridLayout *layout = new QGridLayout(this);
+ m_image = new QImage(QString::fromAscii(":/images/tunecolor.png"));
+ m_imageLab = new QLabel;
+ updateImage(hue,sat,gamma);
+ layout->addWidget(new QLabel(tr("Example output: use the sliders on the right to adjust the color")),0,0);
+ layout->addWidget(m_imageLab,1,0);
+ QHBoxLayout *buttonsLayout = new QHBoxLayout;
+
+ QPushButton *okButton = new QPushButton(tr("Ok"));
+ connect(okButton,SIGNAL(clicked()),SLOT(accept()));
+ okButton->setDefault(true);
+ QPushButton *cancelButton = new QPushButton(tr("Cancel"));
+ connect(cancelButton,SIGNAL(clicked()),SLOT(reject()));
+
+ ColorPicker *huePicker = new ColorPicker(ColorPicker::Hue);
+ huePicker->setCol(hue,sat,gamma);
+ huePicker->setFixedWidth(20);
+ layout->addWidget(huePicker,1,1);
+ ColorPicker *satPicker = new ColorPicker(ColorPicker::Saturation);
+ satPicker->setCol(hue,sat,gamma);
+ satPicker->setFixedWidth(20);
+ layout->addWidget(satPicker,1,2);
+ ColorPicker *gamPicker = new ColorPicker(ColorPicker::Gamma);
+ gamPicker->setCol(hue,sat,gamma);
+ gamPicker->setFixedWidth(20);
+ layout->addWidget(gamPicker,1,3);
+
+ connect(huePicker,SIGNAL(newHsv(int,int,int)),satPicker,SLOT(setCol(int,int,int)));
+ connect(satPicker,SIGNAL(newHsv(int,int,int)),huePicker,SLOT(setCol(int,int,int)));
+ connect(huePicker,SIGNAL(newHsv(int,int,int)),gamPicker,SLOT(setCol(int,int,int)));
+ connect(satPicker,SIGNAL(newHsv(int,int,int)),gamPicker,SLOT(setCol(int,int,int)));
+ connect(gamPicker,SIGNAL(newHsv(int,int,int)),satPicker,SLOT(setCol(int,int,int)));
+ connect(gamPicker,SIGNAL(newHsv(int,int,int)),huePicker,SLOT(setCol(int,int,int)));
+ connect(huePicker,SIGNAL(newHsv(int,int,int)),this,SLOT(updateImage(int,int,int)));
+ connect(satPicker,SIGNAL(newHsv(int,int,int)),this,SLOT(updateImage(int,int,int)));
+ connect(gamPicker,SIGNAL(newHsv(int,int,int)),this,SLOT(updateImage(int,int,int)));
+
+ buttonsLayout->addStretch();
+ buttonsLayout->addWidget(okButton);
+ buttonsLayout->addWidget(cancelButton);
+ layout->addLayout(buttonsLayout,5,0,1,4);
+}
+
+void hsl2rgb(double h,double s,double l,
+ double *pRed,double *pGreen,double *pBlue)
+{
+ double v;
+ double r,g,b;
+
+ r = l; // default to gray
+ g = l;
+ b = l;
+ v = (l <= 0.5) ? (l * (1.0 + s)) : (l + s - l * s);
+ if (v > 0)
+ {
+ double m;
+ double sv;
+ int sextant;
+ double fract, vsf, mid1, mid2;
+
+ m = l + l - v;
+ sv = (v - m ) / v;
+ h *= 6.0;
+ sextant = (int)h;
+ fract = h - sextant;
+ vsf = v * sv * fract;
+ mid1 = m + vsf;
+ mid2 = v - vsf;
+ switch (sextant)
+ {
+ case 0:
+ r = v;
+ g = mid1;
+ b = m;
+ break;
+ case 1:
+ r = mid2;
+ g = v;
+ b = m;
+ break;
+ case 2:
+ r = m;
+ g = v;
+ b = mid1;
+ break;
+ case 3:
+ r = m;
+ g = mid2;
+ b = v;
+ break;
+ case 4:
+ r = mid1;
+ g = m;
+ b = v;
+ break;
+ case 5:
+ r = v;
+ g = m;
+ b = mid2;
+ break;
+ }
+ }
+ *pRed = r;
+ *pGreen = g;
+ *pBlue = b;
+}
+
+
+
+void TuneColorDialog::updateImage(int hue,int sat,int gam)
+{
+ QImage coloredImg(m_image->width(),m_image->height(),QImage::Format_RGB32);
+ uint *srcPixel = (uint *)m_image->scanLine(0);
+ uint *dstPixel = (uint *)coloredImg.scanLine(0);
+ uint nrPixels = coloredImg.width()*coloredImg.height();
+ for (uint i=0;i<nrPixels;i++,srcPixel++,dstPixel++)
+ {
+ QColor c = QColor::fromRgb(*srcPixel);
+ double r,g,b;
+ hsl2rgb(hue/359.0, sat/255.0, pow(c.green()/255.0,gam/100.0),&r,&g,&b);
+ *dstPixel = qRgb((int)(r*255.0),(int)(g*255.0),(int)(b*255.0));
+ }
+ m_imageLab->setPixmap(QPixmap::fromImage(coloredImg));
+ m_hue = hue;
+ m_sat = sat;
+ m_gam = gam;
+}
+
+int TuneColorDialog::getHue() const
+{
+ return m_hue;
+}
+
+int TuneColorDialog::getSaturation() const
+{
+ return m_sat;
+}
+
+int TuneColorDialog::getGamma() const
+{
+ return m_gam;
+}
+
+//==========================================================================
+
+ColorPicker::ColorPicker(Mode m)
+{
+ m_hue = 220;
+ m_gam = 100;
+ m_sat = 100;
+ m_mode = m;
+ m_pix = 0;
+}
+
+ColorPicker::~ColorPicker()
+{
+ delete m_pix;
+}
+
+void ColorPicker::paintEvent(QPaintEvent*)
+{
+ int w = width() - 5;
+
+ QRect r(0, foff, w, height() - 2*foff);
+ int wi = r.width() - 2;
+ int hi = r.height() - 2;
+ if (!m_pix || m_pix->height() != hi || m_pix->width() != wi)
+ {
+ delete m_pix;
+ QImage img(wi, hi, QImage::Format_RGB32);
+ int y;
+ uint *pixel = (uint *) img.scanLine(0);
+ for (y = 0; y < hi; y++)
+ {
+ const uint *end = pixel + wi;
+ int yh = y2hue(y+coff);
+ int ys = y2sat(y+coff);
+ int yg = y2gam(y+coff);
+ while (pixel < end)
+ {
+ QColor c;
+ c.setHsv(yh, ys, (int)(255*pow(0.7,yg/100.0)));
+ *pixel = c.rgb();
+ ++pixel;
+ }
+ }
+ m_pix = new QPixmap(QPixmap::fromImage(img));
+ }
+ QPainter p(this);
+ p.drawPixmap(1, coff, *m_pix);
+ const QPalette &g = palette();
+ qDrawShadePanel(&p, r, g, true);
+ p.setPen(g.foreground().color());
+ p.setBrush(g.foreground());
+ QPolygon a;
+ int y = m_mode==Hue ? hue2y(m_hue) :
+ m_mode==Saturation ? sat2y(m_sat) :
+ gam2y(m_gam);
+ a.setPoints(3, w, y, w+5, y+5, w+5, y-5);
+ p.eraseRect(w, 0, 5, height());
+ p.drawPolygon(a);
+}
+
+void ColorPicker::mouseMoveEvent(QMouseEvent *m)
+{
+ if (m_mode==Hue) setHue(y2hue(m->y()));
+ else if (m_mode==Saturation) setSat(y2sat(m->y()));
+ else setGam(y2gam(m->y()));
+}
+
+void ColorPicker::mousePressEvent(QMouseEvent *m)
+{
+ if (m_mode==Hue) setHue(y2hue(m->y()));
+ else if (m_mode==Saturation) setSat(y2sat(m->y()));
+ else setGam(y2gam(m->y()));
+}
+
+void ColorPicker::setHue(int h)
+{
+ if (h==m_hue) return;
+ m_hue = qMax(0,qMin(h,359));
+ delete m_pix; m_pix=0;
+ repaint();
+ emit newHsv(m_hue,m_sat,m_gam);
+}
+
+void ColorPicker::setSat(int s)
+{
+ if (s==m_sat) return;
+ m_sat = qMax(0,qMin(s,255));
+ delete m_pix; m_pix=0;
+ repaint();
+ emit newHsv(m_hue,m_sat,m_gam);
+}
+
+void ColorPicker::setGam(int g)
+{
+ if (g==m_gam) return;
+ m_gam = qMax(40,qMin(g,240));
+ delete m_pix; m_pix=0;
+ repaint();
+ emit newHsv(m_hue,m_sat,m_gam);
+}
+
+void ColorPicker::setCol(int h, int s, int g)
+{
+ if (m_hue!=h || m_sat!=s || m_gam!=g)
+ {
+ m_hue = h;
+ m_sat = s;
+ m_gam = g;
+ delete m_pix; m_pix=0;
+ repaint();
+ }
+}
+
+int ColorPicker::y2hue(int y)
+{
+ int d = height() - 2*coff - 1;
+ return m_mode==Hue ? (y - coff)*359/d : m_hue;
+}
+
+int ColorPicker::hue2y(int v)
+{
+ int d = height() - 2*coff - 1;
+ return coff + v*d/359;
+}
+
+int ColorPicker::y2sat(int y)
+{
+ int d = height() - 2*coff - 1;
+ return m_mode==Saturation ? 255 - (y - coff)*255/d : m_sat;
+}
+
+int ColorPicker::sat2y(int v)
+{
+ int d = height() - 2*coff - 1;
+ return coff + (255-v)*d/255;
+}
+
+int ColorPicker::y2gam(int y)
+{
+ int d = height() - 2*coff - 1;
+ return m_mode==Gamma ? 240 - (y - coff)*200/d : m_gam;
+}
+
+int ColorPicker::gam2y(int g)
+{
+ int d = height() - 2*coff - 1;
+ return coff + (240-g)*d/200;
+}
+
+//==========================================================================
+
+Step1::Step1(Wizard *wizard,const QHash<QString,Input*> &modelData) : m_wizard(wizard), m_modelData(modelData)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->setMargin(4);
+ layout->setSpacing(8);
+ QLabel *l = new QLabel(this);
+ l->setText(tr("Provide some information "
+ "about the project you are documenting"));
+ layout->addWidget(l);
+ QWidget *w = new QWidget( this );
+ QGridLayout *grid = new QGridLayout(w);
+ grid->setSpacing(10);
+
+ // project name
+ QLabel *projName = new QLabel(this);
+ projName->setText(tr("Project name:"));
+ projName->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+ // project brief
+ QLabel *projBrief = new QLabel(this);
+ projBrief->setText(tr("Project synopsis:"));
+ projBrief->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+ // project version
+ QLabel *projVersion = new QLabel(this);
+ projVersion->setText(tr("Project version or id:"));
+ projVersion->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+ // project icon
+ QLabel *projLogo = new QLabel(this);
+ projLogo->setText(tr("Project logo:"));
+ projLogo->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+
+ grid->addWidget(projName,0,0);
+ grid->addWidget(projBrief,1,0);
+ grid->addWidget(projVersion,2,0);
+ grid->addWidget(projLogo,3,0);
+
+ m_projName = new QLineEdit;
+ m_projBrief = new QLineEdit;
+ m_projNumber = new QLineEdit;
+ QPushButton *projIconSel = new QPushButton(this);
+ projIconSel->setText(tr("Select..."));
+ QPixmap pm(QSize(120,55));
+ pm.fill();
+ m_projIconLab = new QLabel;
+ m_projIconLab->setPixmap(pm);
+
+ grid->addWidget(m_projName,0,1,1,2);
+ grid->addWidget(m_projBrief,1,1,1,2);
+ grid->addWidget(m_projNumber,2,1,1,2);
+ grid->addWidget(projIconSel,3,1);
+ grid->addWidget(m_projIconLab,3,2);
+
+ grid->setColumnStretch(2,1);
+
+ w->setLayout(grid);
+
+ layout->addWidget(w);
+
+ //---------------------------------------------------
+ QFrame *f = new QFrame( this );
+ f->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+ layout->addWidget(f);
+
+ l = new QLabel(this);
+ l->setText(tr("Specify the directory to scan for source code"));
+ layout->addWidget(l);
+ QWidget *row = new QWidget;
+ QHBoxLayout *rowLayout = new QHBoxLayout(row);
+ rowLayout->setSpacing(10);
+ l = new QLabel(this);
+ l->setText(tr("Source code directory:"));
+ rowLayout->addWidget(l);
+ m_sourceDir = new QLineEdit;
+ m_srcSelectDir = new QPushButton(this);
+ m_srcSelectDir->setText(tr("Select..."));
+ rowLayout->addWidget(m_sourceDir);
+ rowLayout->addWidget(m_srcSelectDir);
+ layout->addWidget(row);
+
+ m_recursive = new QCheckBox(this);
+ m_recursive->setText(tr("Scan recursively"));
+ m_recursive->setChecked(TRUE);
+ layout->addWidget(m_recursive);
+
+ //---------------------------------------------------
+ f = new QFrame( this );
+ f->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+ layout->addWidget(f);
+
+ l = new QLabel(this);
+ l->setText(tr("Specify the directory where doxygen should "
+ "put the generated documentation"));
+ layout->addWidget(l);
+ row = new QWidget;
+ rowLayout = new QHBoxLayout(row);
+ rowLayout->setSpacing(10);
+ l = new QLabel(this);
+ l->setText(tr("Destination directory:"));
+ rowLayout->addWidget(l);
+ m_destDir = new QLineEdit;
+ m_dstSelectDir = new QPushButton(this);
+ m_dstSelectDir->setText(tr("Select..."));
+ rowLayout->addWidget(m_destDir);
+ rowLayout->addWidget(m_dstSelectDir);
+ layout->addWidget(row);
+ layout->addStretch(1);
+ setLayout(layout);
+
+ connect(projIconSel,SIGNAL(clicked()),
+ this,SLOT(selectProjectIcon()));
+ connect(m_srcSelectDir,SIGNAL(clicked()),
+ this,SLOT(selectSourceDir()));
+ connect(m_dstSelectDir,SIGNAL(clicked()),
+ this,SLOT(selectDestinationDir()));
+ connect(m_projName,SIGNAL(textChanged(const QString &)),SLOT(setProjectName(const QString &)));
+ connect(m_projBrief,SIGNAL(textChanged(const QString &)),SLOT(setProjectBrief(const QString &)));
+ connect(m_projNumber,SIGNAL(textChanged(const QString &)),SLOT(setProjectNumber(const QString &)));
+ connect(m_sourceDir,SIGNAL(textChanged(const QString &)),SLOT(setSourceDir(const QString &)));
+ connect(m_recursive,SIGNAL(stateChanged(int)),SLOT(setRecursiveScan(int)));
+ connect(m_destDir,SIGNAL(textChanged(const QString &)),SLOT(setDestinationDir(const QString &)));
+}
+
+void Step1::selectProjectIcon()
+{
+ QString path = QFileInfo(MainWindow::instance().configFileName()).path();
+ QString iconName = QFileDialog::getOpenFileName(this,
+ tr("Select project icon/image"),path);
+ QPixmap pm(iconName);
+ if (!pm.isNull())
+ {
+ m_projIconLab->setPixmap(pm.scaledToHeight(55,Qt::SmoothTransformation));
+ updateStringOption(m_modelData,STR_PROJECT_LOGO,iconName);
+ }
+}
+
+void Step1::selectSourceDir()
+{
+ QString path = QFileInfo(MainWindow::instance().configFileName()).path();
+ QString dirName = QFileDialog::getExistingDirectory(this,
+ tr("Select source directory"),path);
+ QDir dir(path);
+ if (!MainWindow::instance().configFileName().isEmpty() && dir.exists())
+ {
+ dirName = dir.relativeFilePath(dirName);
+ }
+ if (dirName.isEmpty())
+ {
+ dirName=QString::fromAscii(".");
+ }
+ m_sourceDir->setText(dirName);
+}
+
+void Step1::selectDestinationDir()
+{
+ QString path = QFileInfo(MainWindow::instance().configFileName()).path();
+ QString dirName = QFileDialog::getExistingDirectory(this,
+ tr("Select destination directory"),path);
+ QDir dir(path);
+ if (!MainWindow::instance().configFileName().isEmpty() && dir.exists())
+ {
+ dirName = dir.relativeFilePath(dirName);
+ }
+ if (dirName.isEmpty())
+ {
+ dirName=QString::fromAscii(".");
+ }
+ m_destDir->setText(dirName);
+}
+
+void Step1::setProjectName(const QString &name)
+{
+ updateStringOption(m_modelData,STR_PROJECT_NAME,name);
+}
+
+void Step1::setProjectBrief(const QString &desc)
+{
+ updateStringOption(m_modelData,STR_PROJECT_BRIEF,desc);
+}
+
+void Step1::setProjectNumber(const QString &num)
+{
+ updateStringOption(m_modelData,STR_PROJECT_NUMBER,num);
+}
+
+void Step1::setSourceDir(const QString &dir)
+{
+ Input *option = m_modelData[STR_INPUT];
+ if (option->value().toStringList().count()>0)
+ {
+ QStringList sl = option->value().toStringList();
+ if (sl[0]!=dir)
+ {
+ sl[0] = dir;
+ option->value() = sl;
+ option->update();
+ }
+ }
+ else
+ {
+ option->value() = QStringList() << dir;
+ option->update();
+ }
+}
+
+void Step1::setDestinationDir(const QString &dir)
+{
+ updateStringOption(m_modelData,STR_OUTPUT_DIRECTORY,dir);
+}
+
+void Step1::setRecursiveScan(int s)
+{
+ updateBoolOption(m_modelData,STR_RECURSIVE,s==Qt::Checked);
+}
+
+void Step1::init()
+{
+ Input *option;
+ m_projName->setText(getStringOption(m_modelData,STR_PROJECT_NAME));
+ m_projBrief->setText(getStringOption(m_modelData,STR_PROJECT_BRIEF));
+ m_projNumber->setText(getStringOption(m_modelData,STR_PROJECT_NUMBER));
+ QString iconName = getStringOption(m_modelData,STR_PROJECT_LOGO);
+ if (!iconName.isEmpty())
+ {
+ QPixmap pm(iconName);
+ if (!pm.isNull())
+ {
+ m_projIconLab->setPixmap(pm.scaledToHeight(55,Qt::SmoothTransformation));
+ }
+ }
+ else
+ {
+ QPixmap pm(QSize(120,55));
+ pm.fill();
+ m_projIconLab->setPixmap(pm);
+ }
+ option = m_modelData[STR_INPUT];
+ if (option->value().toStringList().count()>0)
+ {
+ m_sourceDir->setText(option->value().toStringList().first());
+ }
+ m_recursive->setChecked(
+ getBoolOption(m_modelData,STR_RECURSIVE) ? Qt::Checked : Qt::Unchecked);
+ m_destDir->setText(getStringOption(m_modelData,STR_OUTPUT_DIRECTORY));
+}
+
+
+//==========================================================================
+
+Step2::Step2(Wizard *wizard,const QHash<QString,Input*> &modelData)
+ : m_wizard(wizard), m_modelData(modelData)
+{
+ QRadioButton *r;
+ QVBoxLayout *layout = new QVBoxLayout(this);
+
+ //---------------------------------------------------
+ m_extractModeGroup = new QButtonGroup(this);
+ m_extractMode = new QGroupBox(this);
+ m_extractMode->setTitle(tr("Select the desired extraction mode:"));
+ QGridLayout *gbox = new QGridLayout( m_extractMode );
+ r = new QRadioButton(tr("Documented entities only"));
+ r->setChecked(true);
+ m_extractModeGroup->addButton(r, 0);
+ gbox->addWidget(r,1,0);
+ // 1 -> EXTRACT_ALL = NO
+ r = new QRadioButton(tr("All Entities"));
+ m_extractModeGroup->addButton(r, 1);
+ gbox->addWidget(r,2,0);
+ // 2 -> EXTRACT_ALL = YES
+ m_crossRef = new QCheckBox(m_extractMode);
+ m_crossRef->setText(tr("Include cross-referenced source code in the output"));
+ // m_crossRef -> SOURCE_BROWSER = YES/NO
+ gbox->addWidget(m_crossRef,3,0);
+ layout->addWidget(m_extractMode);
+
+ //---------------------------------------------------
+ QFrame *f = new QFrame( this );
+ f->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+ layout->addWidget(f);
+
+ m_optimizeLangGroup = new QButtonGroup(this);
+ m_optimizeLang = new QGroupBox(this);
+ m_optimizeLang->setTitle(tr("Select programming language to optimize the results for"));
+ gbox = new QGridLayout( m_optimizeLang );
+
+ r = new QRadioButton(m_optimizeLang);
+ r->setText(tr("Optimize for C++ output"));
+ r->setChecked(true);
+ m_optimizeLangGroup->addButton(r, 0);
+ // 0 -> OPTIMIZE_OUTPUT_FOR_C = NO
+ // OPTIMIZE_OUTPUT_JAVA = NO
+ // OPTIMIZE_FOR_FORTRAN = NO
+ // OPTIMIZE_OUTPUT_VHDL = NO
+ // CPP_CLI_SUPPORT = NO
+ // HIDE_SCOPE_NAMES = NO
+ gbox->addWidget(r,0,0);
+ r = new QRadioButton(tr("Optimize for C++/CLI output"));
+ gbox->addWidget(r,1,0);
+ m_optimizeLangGroup->addButton(r, 1);
+ // 1 -> OPTIMIZE_OUTPUT_FOR_C = NO
+ // OPTIMIZE_OUTPUT_JAVA = NO
+ // OPTIMIZE_FOR_FORTRAN = NO
+ // OPTIMIZE_OUTPUT_VHDL = NO
+ // CPP_CLI_SUPPORT = YES
+ // HIDE_SCOPE_NAMES = NO
+ r = new QRadioButton(tr("Optimize for Java or C# output"));
+ m_optimizeLangGroup->addButton(r, 2);
+ // 2 -> OPTIMIZE_OUTPUT_FOR_C = NO
+ // OPTIMIZE_OUTPUT_JAVA = YES
+ // OPTIMIZE_FOR_FORTRAN = NO
+ // OPTIMIZE_OUTPUT_VHDL = NO
+ // CPP_CLI_SUPPORT = NO
+ // HIDE_SCOPE_NAMES = NO
+ gbox->addWidget(r,2,0);
+ r = new QRadioButton(tr("Optimize for C or PHP output"));
+ m_optimizeLangGroup->addButton(r, 3);
+ // 3 -> OPTIMIZE_OUTPUT_FOR_C = YES
+ // OPTIMIZE_OUTPUT_JAVA = NO
+ // OPTIMIZE_FOR_FORTRAN = NO
+ // OPTIMIZE_OUTPUT_VHDL = NO
+ // CPP_CLI_SUPPORT = NO
+ // HIDE_SCOPE_NAMES = YES
+ gbox->addWidget(r,3,0);
+ r = new QRadioButton(tr("Optimize for Fortran output"));
+ m_optimizeLangGroup->addButton(r, 4);
+ // 4 -> OPTIMIZE_OUTPUT_FOR_C = NO
+ // OPTIMIZE_OUTPUT_JAVA = NO
+ // OPTIMIZE_FOR_FORTRAN = YES
+ // OPTIMIZE_OUTPUT_VHDL = NO
+ // CPP_CLI_SUPPORT = NO
+ // HIDE_SCOPE_NAMES = NO
+ gbox->addWidget(r,4,0);
+ r = new QRadioButton(tr("Optimize for VHDL output"));
+ m_optimizeLangGroup->addButton(r, 5);
+ // 5 -> OPTIMIZE_OUTPUT_FOR_C = NO
+ // OPTIMIZE_OUTPUT_JAVA = NO
+ // OPTIMIZE_FOR_FORTRAN = NO
+ // OPTIMIZE_OUTPUT_VHDL = YES
+ // CPP_CLI_SUPPORT = NO
+ // HIDE_SCOPE_NAMES = NO
+ gbox->addWidget(r,5,0);
+
+ layout->addWidget(m_optimizeLang);
+ layout->addStretch(1);
+
+ connect(m_crossRef,SIGNAL(stateChanged(int)),
+ SLOT(changeCrossRefState(int)));
+ connect(m_optimizeLangGroup,SIGNAL(buttonClicked(int)),
+ SLOT(optimizeFor(int)));
+ connect(m_extractModeGroup,SIGNAL(buttonClicked(int)),
+ SLOT(extractMode(int)));
+}
+
+
+void Step2::optimizeFor(int choice)
+{
+ for (int i=0;i<6;i++)
+ {
+ updateBoolOption(m_modelData,
+ g_optimizeOptionNames[i],
+ g_optimizeMapping[choice][i]);
+ }
+}
+
+void Step2::extractMode(int choice)
+{
+ updateBoolOption(m_modelData,STR_EXTRACT_ALL,choice==1);
+}
+
+void Step2::changeCrossRefState(int choice)
+{
+ updateBoolOption(m_modelData,STR_SOURCE_BROWSER,choice==Qt::Checked);
+}
+
+void Step2::init()
+{
+ m_extractModeGroup->button(
+ getBoolOption(m_modelData,STR_EXTRACT_ALL) ? 1 : 0)->setChecked(true);
+ m_crossRef->setChecked(getBoolOption(m_modelData,STR_SOURCE_BROWSER));
+
+ int x=0;
+ if (getBoolOption(m_modelData,STR_CPP_CLI_SUPPORT)) x=1;
+ else if (getBoolOption(m_modelData,STR_OPTIMIZE_OUTPUT_JAVA)) x=2;
+ else if (getBoolOption(m_modelData,STR_OPTIMIZE_OUTPUT_FOR_C)) x=3;
+ else if (getBoolOption(m_modelData,STR_OPTIMIZE_FOR_FORTRAN)) x=4;
+ else if (getBoolOption(m_modelData,STR_OPTIMIZE_OUTPUT_VHDL)) x=5;
+ m_optimizeLangGroup->button(x)->setChecked(true);
+}
+
+//==========================================================================
+
+Step3::Step3(Wizard *wizard,const QHash<QString,Input*> &modelData)
+ : m_wizard(wizard), m_modelData(modelData)
+{
+ QVBoxLayout *vbox = 0;
+ QRadioButton *r = 0;
+
+ QGridLayout *gbox = new QGridLayout( this );
+ gbox->addWidget(new QLabel(tr("Select the output format(s) to generate")),0,0);
+ {
+ m_htmlOptions = new QGroupBox(tr("HTML"));
+ m_htmlOptions->setCheckable(true);
+ // GENERATE_HTML
+ m_htmlOptionsGroup = new QButtonGroup(m_htmlOptions);
+ QRadioButton *r = new QRadioButton(tr("plain HTML"));
+ r->setChecked(true);
+ m_htmlOptionsGroup->addButton(r, 0);
+ vbox = new QVBoxLayout;
+ vbox->addWidget(r);
+ r = new QRadioButton(tr("with navigation panel"));
+ m_htmlOptionsGroup->addButton(r, 1);
+ // GENERATE_TREEVIEW
+ vbox->addWidget(r);
+ r = new QRadioButton(tr("prepare for compressed HTML (.chm)"));
+ m_htmlOptionsGroup->addButton(r, 2);
+ // GENERATE_HTMLHELP
+ vbox->addWidget(r);
+ m_searchEnabled=new QCheckBox(tr("With search function"));
+ vbox->addWidget(m_searchEnabled);
+ // SEARCH_ENGINE
+ QHBoxLayout *hbox = new QHBoxLayout;
+ m_tuneColor=new QPushButton(tr("Change color..."));
+ hbox->addWidget(m_tuneColor);
+ hbox->addStretch(1);
+ vbox->addLayout(hbox);
+ m_htmlOptions->setLayout(vbox);
+ m_htmlOptions->setChecked(true);
+ }
+ gbox->addWidget(m_htmlOptions,1,0);
+
+ {
+ m_texOptions = new QGroupBox(tr("LaTeX"));
+ m_texOptions->setCheckable(true);
+ // GENERATE_LATEX
+ m_texOptionsGroup = new QButtonGroup(m_texOptions);
+ vbox = new QVBoxLayout;
+ r = new QRadioButton(tr("as intermediate format for hyperlinked PDF"));
+ m_texOptionsGroup->addButton(r, 0);
+ // PDF_HYPERLINKS = YES
+ r->setChecked(true);
+ vbox->addWidget(r);
+ r = new QRadioButton(tr("as intermediate format for PDF"));
+ m_texOptionsGroup->addButton(r, 1);
+ // PDF_HYPERLINKS = NO, USE_PDFLATEX = YES
+ vbox->addWidget(r);
+ r = new QRadioButton(tr("as intermediate format for PostScript"));
+ m_texOptionsGroup->addButton(r, 2);
+ // USE_PDFLATEX = NO
+ vbox->addWidget(r);
+ vbox->addStretch(1);
+ m_texOptions->setLayout(vbox);
+ m_texOptions->setChecked(true);
+ }
+ gbox->addWidget(m_texOptions,2,0);
+
+ m_manEnabled=new QCheckBox(tr("Man pages"));
+ // GENERATE_MAN
+ m_rtfEnabled=new QCheckBox(tr("Rich Text Format (RTF)"));
+ // GENERATE_RTF
+ m_xmlEnabled=new QCheckBox(tr("XML"));
+ // GENERATE_XML
+ gbox->addWidget(m_manEnabled,3,0);
+ gbox->addWidget(m_rtfEnabled,4,0);
+ gbox->addWidget(m_xmlEnabled,5,0);
+
+ gbox->setRowStretch(6,1);
+ connect(m_htmlOptions,SIGNAL(toggled(bool)),SLOT(setHtmlEnabled(bool)));
+ connect(m_texOptions,SIGNAL(toggled(bool)),SLOT(setLatexEnabled(bool)));
+ connect(m_manEnabled,SIGNAL(stateChanged(int)),SLOT(setManEnabled(int)));
+ connect(m_rtfEnabled,SIGNAL(stateChanged(int)),SLOT(setRtfEnabled(int)));
+ connect(m_xmlEnabled,SIGNAL(stateChanged(int)),SLOT(setXmlEnabled(int)));
+ connect(m_searchEnabled,SIGNAL(stateChanged(int)),SLOT(setSearchEnabled(int)));
+ connect(m_htmlOptionsGroup,SIGNAL(buttonClicked(int)),
+ SLOT(setHtmlOptions(int)));
+ connect(m_texOptionsGroup,SIGNAL(buttonClicked(int)),
+ SLOT(setLatexOptions(int)));
+ connect(m_tuneColor,SIGNAL(clicked()),SLOT(tuneColorDialog()));
+}
+
+void Step3::tuneColorDialog()
+{
+ int hue = getIntOption(m_modelData,STR_HTML_COLORSTYLE_HUE);
+ int sat = getIntOption(m_modelData,STR_HTML_COLORSTYLE_SAT);
+ int gam = getIntOption(m_modelData,STR_HTML_COLORSTYLE_GAMMA);
+ TuneColorDialog tuneColor(hue,sat,gam,this);
+ if (tuneColor.exec()==QDialog::Accepted)
+ {
+ updateIntOption(m_modelData,STR_HTML_COLORSTYLE_HUE,tuneColor.getHue());
+ updateIntOption(m_modelData,STR_HTML_COLORSTYLE_SAT,tuneColor.getSaturation());
+ updateIntOption(m_modelData,STR_HTML_COLORSTYLE_GAMMA,tuneColor.getGamma());
+ }
+}
+
+void Step3::setHtmlEnabled(bool b)
+{
+ updateBoolOption(m_modelData,STR_GENERATE_HTML,b);
+}
+
+void Step3::setLatexEnabled(bool b)
+{
+ updateBoolOption(m_modelData,STR_GENERATE_LATEX,b);
+}
+
+void Step3::setManEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_GENERATE_MAN,state==Qt::Checked);
+}
+
+void Step3::setRtfEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_GENERATE_RTF,state==Qt::Checked);
+}
+
+void Step3::setXmlEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_GENERATE_XML,state==Qt::Checked);
+}
+
+void Step3::setSearchEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_SEARCHENGINE,state==Qt::Checked);
+}
+
+void Step3::setHtmlOptions(int id)
+{
+ if (id==0) // plain HTML
+ {
+ updateBoolOption(m_modelData,STR_GENERATE_HTMLHELP,false);
+ updateBoolOption(m_modelData,STR_GENERATE_TREEVIEW,false);
+ }
+ else if (id==1) // with navigation tree
+ {
+ updateBoolOption(m_modelData,STR_GENERATE_HTMLHELP,false);
+ updateBoolOption(m_modelData,STR_GENERATE_TREEVIEW,true);
+ }
+ else if (id==2) // with compiled help
+ {
+ updateBoolOption(m_modelData,STR_GENERATE_HTMLHELP,true);
+ updateBoolOption(m_modelData,STR_GENERATE_TREEVIEW,false);
+ }
+}
+
+void Step3::setLatexOptions(int id)
+{
+ if (id==0) // hyperlinked PDF
+ {
+ updateBoolOption(m_modelData,STR_USE_PDFLATEX,true);
+ updateBoolOption(m_modelData,STR_PDF_HYPERLINKS,true);
+ }
+ else if (id==1) // PDF
+ {
+ updateBoolOption(m_modelData,STR_USE_PDFLATEX,true);
+ updateBoolOption(m_modelData,STR_PDF_HYPERLINKS,false);
+ }
+ else if (id==2) // PostScript
+ {
+ updateBoolOption(m_modelData,STR_USE_PDFLATEX,false);
+ updateBoolOption(m_modelData,STR_PDF_HYPERLINKS,false);
+ }
+}
+
+void Step3::init()
+{
+ m_htmlOptions->setChecked(getBoolOption(m_modelData,STR_GENERATE_HTML));
+ m_texOptions->setChecked(getBoolOption(m_modelData,STR_GENERATE_LATEX));
+ m_manEnabled->setChecked(getBoolOption(m_modelData,STR_GENERATE_MAN));
+ m_rtfEnabled->setChecked(getBoolOption(m_modelData,STR_GENERATE_RTF));
+ m_xmlEnabled->setChecked(getBoolOption(m_modelData,STR_GENERATE_XML));
+ m_searchEnabled->setChecked(getBoolOption(m_modelData,STR_SEARCHENGINE));
+ if (getBoolOption(m_modelData,STR_GENERATE_HTMLHELP))
+ {
+ m_htmlOptionsGroup->button(2)->setChecked(true); // compiled help
+ }
+ else if (getBoolOption(m_modelData,STR_GENERATE_TREEVIEW))
+ {
+ m_htmlOptionsGroup->button(1)->setChecked(true); // navigation tree
+ }
+ else
+ {
+ m_htmlOptionsGroup->button(0)->setChecked(true); // plain HTML
+ }
+ if (!getBoolOption(m_modelData,STR_USE_PDFLATEX))
+ {
+ m_texOptionsGroup->button(2)->setChecked(true); // PostScript
+ }
+ else if (!getBoolOption(m_modelData,STR_PDF_HYPERLINKS))
+ {
+ m_texOptionsGroup->button(1)->setChecked(true); // Plain PDF
+ }
+ else
+ {
+ m_texOptionsGroup->button(0)->setChecked(true); // PDF with hyperlinks
+ }
+}
+
+//==========================================================================
+
+Step4::Step4(Wizard *wizard,const QHash<QString,Input*> &modelData)
+ : m_wizard(wizard), m_modelData(modelData)
+{
+ m_diagramModeGroup = new QButtonGroup(this);
+ QGridLayout *gbox = new QGridLayout( this );
+ gbox->addWidget(new QLabel(tr("Diagrams to generate")),0,0);
+
+ QRadioButton *rb = new QRadioButton(tr("No diagrams"));
+ m_diagramModeGroup->addButton(rb, 0);
+ gbox->addWidget(rb,1,0);
+ // CLASS_DIAGRAMS = NO, HAVE_DOT = NO
+ rb->setChecked(true);
+ rb = new QRadioButton(tr("Use built-in class diagram generator"));
+ m_diagramModeGroup->addButton(rb, 1);
+ // CLASS_DIAGRAMS = YES, HAVE_DOT = NO
+ gbox->addWidget(rb,2,0);
+ rb = new QRadioButton(tr("Use dot tool from the GraphViz package"));
+ m_diagramModeGroup->addButton(rb, 2);
+ gbox->addWidget(rb,3,0);
+ // CLASS_DIAGRAMS = NO, HAVE_DOT = YES
+
+ m_dotGroup = new QGroupBox(tr("Dot graphs to generate"));
+ QVBoxLayout *vbox = new QVBoxLayout;
+ m_dotClass=new QCheckBox(tr("Class diagrams"));
+ // CLASS_GRAPH
+ m_dotCollaboration=new QCheckBox(tr("Collaboration diagrams"));
+ // COLLABORATION_GRAPH
+ m_dotInheritance=new QCheckBox(tr("Overall Class hierarchy"));
+ // GRAPHICAL_HIERARCHY
+ m_dotInclude=new QCheckBox(tr("Include dependency graphs"));
+ // INCLUDE_GRAPH
+ m_dotIncludedBy=new QCheckBox(tr("Included by dependency graphs"));
+ // INCLUDED_BY_GRAPH
+ m_dotCall=new QCheckBox(tr("Call graphs"));
+ // CALL_GRAPH
+ m_dotCaller=new QCheckBox(tr("Called by graphs"));
+ // CALLER_GRAPH
+ vbox->addWidget(m_dotClass);
+ vbox->addWidget(m_dotCollaboration);
+ vbox->addWidget(m_dotInheritance);
+ vbox->addWidget(m_dotInclude);
+ vbox->addWidget(m_dotIncludedBy);
+ vbox->addWidget(m_dotCall);
+ vbox->addWidget(m_dotCaller);
+ vbox->addStretch(1);
+ m_dotGroup->setLayout(vbox);
+ m_dotClass->setChecked(true);
+ m_dotGroup->setEnabled(false);
+ gbox->addWidget(m_dotGroup,4,0);
+
+ m_dotInclude->setChecked(true);
+ m_dotCollaboration->setChecked(true);
+ gbox->setRowStretch(5,1);
+
+ connect(m_diagramModeGroup,SIGNAL(buttonClicked(int)),
+ this,SLOT(diagramModeChanged(int)));
+ connect(m_dotClass,SIGNAL(stateChanged(int)),
+ this,SLOT(setClassGraphEnabled(int)));
+ connect(m_dotCollaboration,SIGNAL(stateChanged(int)),
+ this,SLOT(setCollaborationGraphEnabled(int)));
+ connect(m_dotInheritance,SIGNAL(stateChanged(int)),
+ this,SLOT(setGraphicalHierarchyEnabled(int)));
+ connect(m_dotInclude,SIGNAL(stateChanged(int)),
+ this,SLOT(setIncludeGraphEnabled(int)));
+ connect(m_dotIncludedBy,SIGNAL(stateChanged(int)),
+ this,SLOT(setIncludedByGraphEnabled(int)));
+ connect(m_dotCall,SIGNAL(stateChanged(int)),
+ this,SLOT(setCallGraphEnabled(int)));
+ connect(m_dotCaller,SIGNAL(stateChanged(int)),
+ this,SLOT(setCallerGraphEnabled(int)));
+}
+
+void Step4::diagramModeChanged(int id)
+{
+ if (id==0) // no diagrams
+ {
+ updateBoolOption(m_modelData,STR_HAVE_DOT,false);
+ updateBoolOption(m_modelData,STR_CLASS_DIAGRAMS,false);
+ }
+ else if (id==1) // builtin diagrams
+ {
+ updateBoolOption(m_modelData,STR_HAVE_DOT,false);
+ updateBoolOption(m_modelData,STR_CLASS_DIAGRAMS,true);
+ }
+ else if (id==2) // dot diagrams
+ {
+ updateBoolOption(m_modelData,STR_HAVE_DOT,true);
+ updateBoolOption(m_modelData,STR_CLASS_DIAGRAMS,false);
+ }
+ m_dotGroup->setEnabled(id==2);
+}
+
+void Step4::setClassGraphEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_CLASS_GRAPH,state==Qt::Checked);
+}
+
+void Step4::setCollaborationGraphEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_COLLABORATION_GRAPH,state==Qt::Checked);
+}
+
+void Step4::setGraphicalHierarchyEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_GRAPHICAL_HIERARCHY,state==Qt::Checked);
+}
+
+void Step4::setIncludeGraphEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_INCLUDE_GRAPH,state==Qt::Checked);
+}
+
+void Step4::setIncludedByGraphEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_INCLUDED_BY_GRAPH,state==Qt::Checked);
+}
+
+void Step4::setCallGraphEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_CALL_GRAPH,state==Qt::Checked);
+}
+
+void Step4::setCallerGraphEnabled(int state)
+{
+ updateBoolOption(m_modelData,STR_CALLER_GRAPH,state==Qt::Checked);
+}
+
+void Step4::init()
+{
+ if (getBoolOption(m_modelData,STR_HAVE_DOT))
+ {
+ m_diagramModeGroup->button(2)->setChecked(true); // Dot
+ }
+ else if (getBoolOption(m_modelData,STR_CLASS_DIAGRAMS))
+ {
+ m_diagramModeGroup->button(1)->setChecked(true); // Builtin diagrams
+ }
+ else
+ {
+ m_diagramModeGroup->button(0)->setChecked(true); // no diagrams
+ }
+ m_dotClass->setChecked(getBoolOption(m_modelData,STR_CLASS_GRAPH));
+ m_dotCollaboration->setChecked(getBoolOption(m_modelData,STR_COLLABORATION_GRAPH));
+ m_dotInheritance->setChecked(getBoolOption(m_modelData,STR_GRAPHICAL_HIERARCHY));
+ m_dotInclude->setChecked(getBoolOption(m_modelData,STR_INCLUDE_GRAPH));
+ m_dotIncludedBy->setChecked(getBoolOption(m_modelData,STR_INCLUDED_BY_GRAPH));
+ m_dotCall->setChecked(getBoolOption(m_modelData,STR_CALL_GRAPH));
+ m_dotCaller->setChecked(getBoolOption(m_modelData,STR_CALLER_GRAPH));
+}
+
+//==========================================================================
+
+Wizard::Wizard(const QHash<QString,Input*> &modelData, QWidget *parent) :
+ QSplitter(parent), m_modelData(modelData)
+{
+ m_treeWidget = new QTreeWidget;
+ m_treeWidget->setColumnCount(1);
+ m_treeWidget->setHeaderLabels(QStringList() << QString::fromAscii("Topics"));
+ QList<QTreeWidgetItem*> items;
+ items.append(new QTreeWidgetItem((QTreeWidget*)0,QStringList(tr("Project"))));
+ items.append(new QTreeWidgetItem((QTreeWidget*)0,QStringList(tr("Mode"))));
+ items.append(new QTreeWidgetItem((QTreeWidget*)0,QStringList(tr("Output"))));
+ items.append(new QTreeWidgetItem((QTreeWidget*)0,QStringList(tr("Diagrams"))));
+ m_treeWidget->insertTopLevelItems(0,items);
+
+ m_topicStack = new QStackedWidget;
+ m_step1 = new Step1(this,modelData);
+ m_step2 = new Step2(this,modelData);
+ m_step3 = new Step3(this,modelData);
+ m_step4 = new Step4(this,modelData);
+ m_topicStack->addWidget(m_step1);
+ m_topicStack->addWidget(m_step2);
+ m_topicStack->addWidget(m_step3);
+ m_topicStack->addWidget(m_step4);
+
+ QWidget *rightSide = new QWidget;
+ QGridLayout *grid = new QGridLayout(rightSide);
+ m_prev = new QPushButton(tr("Previous"));
+ m_prev->setEnabled(false);
+ m_next = new QPushButton(tr("Next"));
+ grid->addWidget(m_topicStack,0,0,1,2);
+ grid->addWidget(m_prev,1,0,Qt::AlignLeft);
+ grid->addWidget(m_next,1,1,Qt::AlignRight);
+ grid->setColumnStretch(0,1);
+ grid->setRowStretch(0,1);
+ addWidget(m_treeWidget);
+ addWidget(rightSide);
+
+ connect(m_treeWidget,
+ SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),
+ SLOT(activateTopic(QTreeWidgetItem *,QTreeWidgetItem *)));
+ connect(m_next,SIGNAL(clicked()),SLOT(nextTopic()));
+ connect(m_prev,SIGNAL(clicked()),SLOT(prevTopic()));
+
+ refresh();
+}
+
+Wizard::~Wizard()
+{
+}
+
+void Wizard::activateTopic(QTreeWidgetItem *item,QTreeWidgetItem *)
+{
+ if (item)
+ {
+
+ QString label = item->text(0);
+ if (label==tr("Project"))
+ {
+ m_topicStack->setCurrentWidget(m_step1);
+ m_prev->setEnabled(false);
+ m_next->setEnabled(true);
+ }
+ else if (label==tr("Mode"))
+ {
+ m_topicStack->setCurrentWidget(m_step2);
+ m_prev->setEnabled(true);
+ m_next->setEnabled(true);
+ }
+ else if (label==tr("Output"))
+ {
+ m_topicStack->setCurrentWidget(m_step3);
+ m_prev->setEnabled(true);
+ m_next->setEnabled(true);
+ }
+ else if (label==tr("Diagrams"))
+ {
+ m_topicStack->setCurrentWidget(m_step4);
+ m_prev->setEnabled(true);
+ m_next->setEnabled(false);
+ }
+ }
+}
+
+void Wizard::nextTopic()
+{
+ m_topicStack->setCurrentIndex(m_topicStack->currentIndex()+1);
+ m_next->setEnabled(m_topicStack->count()!=m_topicStack->currentIndex()+1);
+ m_prev->setEnabled(m_topicStack->currentIndex()!=0);
+ m_treeWidget->setCurrentItem(m_treeWidget->invisibleRootItem()->child(m_topicStack->currentIndex()));
+}
+
+void Wizard::prevTopic()
+{
+ m_topicStack->setCurrentIndex(m_topicStack->currentIndex()-1);
+ m_next->setEnabled(m_topicStack->count()!=m_topicStack->currentIndex()+1);
+ m_prev->setEnabled(m_topicStack->currentIndex()!=0);
+ m_treeWidget->setCurrentItem(m_treeWidget->invisibleRootItem()->child(m_topicStack->currentIndex()));
+}
+
+void Wizard::refresh()
+{
+ m_step1->init();
+ m_step2->init();
+ m_step3->init();
+ m_step4->init();
+}
diff --git a/trunk/addon/doxywizard/wizard.h b/trunk/addon/doxywizard/wizard.h
new file mode 100644
index 0000000..99e1db5
--- /dev/null
+++ b/trunk/addon/doxywizard/wizard.h
@@ -0,0 +1,253 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2012 by Dimitri van Heesch.
+ *
+ * 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.
+ *
+ */
+
+#ifndef WIZARD_H
+#define WIZARD_H
+
+#include <QSplitter>
+#include <QHash>
+#include <QDialog>
+
+class Input;
+class QTreeWidget;
+class QTreeWidgetItem;
+class QStackedWidget;
+class QCheckBox;
+class QLineEdit;
+class QPushButton;
+class QRadioButton;
+class QGroupBox;
+class QButtonGroup;
+class Wizard;
+class QImage;
+class QLabel;
+
+enum OptLang { Lang_Cpp, Lang_C, Lang_Java, Lang_CS };
+enum HtmlStyle { HS_Plain, HS_TreeView, HS_CHM };
+enum TexStyle { TS_PDFHyper, TS_PDF, TS_PS };
+enum DiagramMode { DM_None, DM_Builtin, DM_Dot };
+
+class TuneColorDialog : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ TuneColorDialog(int hue,int sat,int gamma,QWidget *parent=0);
+ int getHue() const;
+ int getSaturation() const;
+ int getGamma() const;
+
+ private slots:
+ void updateImage(int hue,int sat,int val);
+
+ private:
+ QImage *m_image;
+ QLabel *m_imageLab;
+ int m_hue;
+ int m_sat;
+ int m_gam;
+};
+
+class ColorPicker : public QWidget
+{
+ Q_OBJECT
+public:
+ enum Mode { Hue, Saturation, Gamma };
+ ColorPicker(Mode m);
+ ~ColorPicker();
+
+public slots:
+ void setCol(int h, int s, int g);
+ //void setCol(int h, int s);
+
+signals:
+ void newHsv(int h, int s, int g);
+
+protected:
+ void paintEvent(QPaintEvent*);
+ void mouseMoveEvent(QMouseEvent *);
+ void mousePressEvent(QMouseEvent *);
+
+private:
+ enum { foff = 3, coff = 4 }; //frame and contents offset
+ int y2hue(int y);
+ int y2sat(int y);
+ int y2gam(int y);
+ int hue2y(int hue);
+ int sat2y(int sat);
+ int gam2y(int gamma);
+ void setHue(int v);
+ void setSat(int v);
+ void setGam(int v);
+
+ QPixmap *m_pix;
+ Mode m_mode;
+ int m_gam;
+ int m_hue;
+ int m_sat;
+
+};
+
+
+class Step1 : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ Step1(Wizard *parent,const QHash<QString,Input*> &modelData);
+ void init();
+
+ private slots:
+ void selectSourceDir();
+ void selectDestinationDir();
+ void selectProjectIcon();
+ void setProjectName(const QString &name);
+ void setProjectBrief(const QString &desc);
+ void setProjectNumber(const QString &num);
+ void setSourceDir(const QString &dir);
+ void setDestinationDir(const QString &dir);
+ void setRecursiveScan(int);
+
+ private:
+ QLineEdit *m_projName;
+ QLineEdit *m_projBrief;
+ QLineEdit *m_projNumber;
+ QLineEdit *m_sourceDir;
+ QLineEdit *m_destDir;
+ QLabel *m_projIconLab;
+ QCheckBox *m_recursive;
+ QPushButton *m_srcSelectDir;
+ QPushButton *m_dstSelectDir;
+ Wizard *m_wizard;
+ const QHash<QString,Input *> &m_modelData;
+};
+
+class Step2 : public QWidget
+{
+ Q_OBJECT
+ public:
+ Step2(Wizard *parent,const QHash<QString,Input*> &modelData);
+ void init();
+
+ private slots:
+ void optimizeFor(int choice);
+ void extractMode(int choice);
+ void changeCrossRefState(int choice);
+
+ private:
+ QGroupBox *m_extractMode;
+ QGroupBox *m_optimizeLang;
+ QButtonGroup *m_extractModeGroup;
+ QButtonGroup *m_optimizeLangGroup;
+ QCheckBox *m_crossRef;
+ Wizard *m_wizard;
+ const QHash<QString,Input *> &m_modelData;
+};
+
+class Step3 : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ Step3(Wizard *parent,const QHash<QString,Input*> &modelData);
+ void init();
+
+ private slots:
+ void setHtmlEnabled(bool);
+ void setLatexEnabled(bool);
+ void setManEnabled(int);
+ void setRtfEnabled(int);
+ void setXmlEnabled(int);
+ void setSearchEnabled(int);
+ void setHtmlOptions(int);
+ void setLatexOptions(int);
+ void tuneColorDialog();
+
+ private:
+ QGroupBox *m_texOptions;
+ QButtonGroup *m_texOptionsGroup;
+ QGroupBox *m_htmlOptions;
+ QButtonGroup *m_htmlOptionsGroup;
+ QCheckBox *m_htmlEnabled;
+ QCheckBox *m_latexEnabled;
+ QCheckBox *m_manEnabled;
+ QCheckBox *m_rtfEnabled;
+ QCheckBox *m_xmlEnabled;
+ QCheckBox *m_searchEnabled;
+ QPushButton *m_tuneColor;
+ Wizard *m_wizard;
+ const QHash<QString,Input *> &m_modelData;
+};
+
+class Step4 : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ Step4(Wizard *parent,const QHash<QString,Input*> &modelData);
+ void init();
+
+ private slots:
+ void diagramModeChanged(int);
+ void setClassGraphEnabled(int state);
+ void setCollaborationGraphEnabled(int state);
+ void setGraphicalHierarchyEnabled(int state);
+ void setIncludeGraphEnabled(int state);
+ void setIncludedByGraphEnabled(int state);
+ void setCallGraphEnabled(int state);
+ void setCallerGraphEnabled(int state);
+
+ private:
+ QGroupBox *m_diagramMode;
+ QButtonGroup *m_diagramModeGroup;
+ QGroupBox *m_dotGroup;
+ QCheckBox *m_dotClass;
+ QCheckBox *m_dotCollaboration;
+ QCheckBox *m_dotInclude;
+ QCheckBox *m_dotIncludedBy;
+ QCheckBox *m_dotInheritance;
+ QCheckBox *m_dotCall;
+ QCheckBox *m_dotCaller;
+ Wizard *m_wizard;
+ const QHash<QString,Input *> &m_modelData;
+};
+
+class Wizard : public QSplitter
+{
+ Q_OBJECT
+ public:
+ Wizard(const QHash<QString,Input*> &modelData, QWidget *parent=0);
+ ~Wizard();
+
+ public slots:
+ void refresh();
+
+ private slots:
+ void activateTopic(QTreeWidgetItem *item,QTreeWidgetItem *);
+ void nextTopic();
+ void prevTopic();
+
+ private:
+ const QHash<QString,Input *> &m_modelData;
+ QTreeWidget *m_treeWidget;
+ QStackedWidget *m_topicStack;
+ Step1 *m_step1;
+ Step2 *m_step2;
+ Step3 *m_step3;
+ Step4 *m_step4;
+ QPushButton *m_next;
+ QPushButton *m_prev;
+};
+
+#endif