diff options
author | dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7> | 2012-03-17 20:33:32 (GMT) |
---|---|---|
committer | dimitri <dimitri@afe2bf4a-e733-0410-8a33-86f594647bc7> | 2012-03-17 20:33:32 (GMT) |
commit | 8f455b66da9db238655242d1213c05affac412d9 (patch) | |
tree | fbaf0bfe6a7de14413f6738b180d69d4aeb3a69b /trunk/addon/doxywizard | |
parent | b9ef81152f75067cec55d4b37a4a25658f1f2a60 (diff) | |
download | Doxygen-8f455b66da9db238655242d1213c05affac412d9.zip Doxygen-8f455b66da9db238655242d1213c05affac412d9.tar.gz Doxygen-8f455b66da9db238655242d1213c05affac412d9.tar.bz2 |
Release-1.8.0
Diffstat (limited to 'trunk/addon/doxywizard')
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>© 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 Binary files differnew file mode 100644 index 0000000..10d1755 --- /dev/null +++ b/trunk/addon/doxywizard/doxywizard.ico 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 Binary files differnew file mode 100644 index 0000000..30a7090 --- /dev/null +++ b/trunk/addon/doxywizard/images/add.png diff --git a/trunk/addon/doxywizard/images/del.png b/trunk/addon/doxywizard/images/del.png Binary files differnew file mode 100644 index 0000000..ceb6a60 --- /dev/null +++ b/trunk/addon/doxywizard/images/del.png diff --git a/trunk/addon/doxywizard/images/file.png b/trunk/addon/doxywizard/images/file.png Binary files differnew file mode 100644 index 0000000..e204f67 --- /dev/null +++ b/trunk/addon/doxywizard/images/file.png diff --git a/trunk/addon/doxywizard/images/folder.png b/trunk/addon/doxywizard/images/folder.png Binary files differnew file mode 100644 index 0000000..2e420e0 --- /dev/null +++ b/trunk/addon/doxywizard/images/folder.png diff --git a/trunk/addon/doxywizard/images/refresh.png b/trunk/addon/doxywizard/images/refresh.png Binary files differnew file mode 100644 index 0000000..fd6d565 --- /dev/null +++ b/trunk/addon/doxywizard/images/refresh.png diff --git a/trunk/addon/doxywizard/images/tunecolor.png b/trunk/addon/doxywizard/images/tunecolor.png Binary files differnew file mode 100644 index 0000000..bf7be83 --- /dev/null +++ b/trunk/addon/doxywizard/images/tunecolor.png 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 |