diff options
Diffstat (limited to 'trunk/addon/doxywizard')
26 files changed, 3517 insertions, 0 deletions
diff --git a/trunk/addon/doxywizard/Makefile.in b/trunk/addon/doxywizard/Makefile.in new file mode 100644 index 0000000..fa459c2 --- /dev/null +++ b/trunk/addon/doxywizard/Makefile.in @@ -0,0 +1,39 @@ +# +# +# +# Copyright (C) 1997-2008 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 + +all: Makefile.doxywizard + $(MAKE) -f Makefile.doxywizard + +Makefile.doxywizard: doxywizard.pro + $(QTDIR)/bin/qmake doxywizard.pro -o Makefile.doxywizard + +qmake: + $(QTDIR)/bin/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/doxywizard.cpp b/trunk/addon/doxywizard/doxywizard.cpp new file mode 100644 index 0000000..5928524 --- /dev/null +++ b/trunk/addon/doxywizard/doxywizard.cpp @@ -0,0 +1,600 @@ +#include <QtGui> +#include "doxywizard.h" +#include "version.h" +#include "expert.h" +#include "wizard.h" + +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())); + + 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); + +#if 0 + m_launchPdf = new QPushButton(tr("Show PDF output")); + launchLayout->addWidget(m_launchPdf); +#endif + 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); + loadSettings(); + + m_runProcess = new QProcess; + m_running = false; + m_timer = new QTimer; + updateLaunchButtonState(); + m_modified = false; + updateTitle(); + + // 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())); +} + +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-2008</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)) 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); + } +} + +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_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 expState = m_settings.value(QString::fromAscii("expert/state"), QVariant::Invalid); + QVariant expState2 = m_settings.value(QString::fromAscii("expert/state2"), 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("main/defdir"), QVariant::Invalid); + + if (geometry !=QVariant::Invalid) restoreGeometry(geometry.toByteArray()); + if (state !=QVariant::Invalid) restoreState (state.toByteArray()); + if (expState !=QVariant::Invalid) m_expert->restoreState(expState.toByteArray()); + if (expState2 !=QVariant::Invalid) m_expert->restoreInnerState(expState2.toByteArray()); + if (wizState !=QVariant::Invalid) m_wizard->restoreState(wizState.toByteArray()); + //if (workingDir!=QVariant::Invalid) + //{ + // QString dir = workingDir.toString(); + // m_workingDir->setText(dir); + // QDir::setCurrent(dir); + // m_run->setEnabled(!dir.isEmpty()); + //} + if (loadSettings!=QVariant::Invalid && loadSettings.toBool()) + { + m_expert->loadSettings(&m_settings); + } + + for (int i=0;i<10;i++) + { + QString entry = m_settings.value(QString().sprintf("recent/config%d",i)).toString(); + if (!entry.isEmpty()) 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("expert/state"), m_expert->saveState()); + m_settings.setValue(QString::fromAscii("expert/state2"), m_expert->saveInnerState()); + m_settings.setValue(QString::fromAscii("wizard/state"), m_wizard->saveState()); +} + +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() < 10) // 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); + } +} + +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); +#ifdef WIN32 + QString indexUrl(QString::fromAscii("file:///")); +#else + QString indexUrl(QString::fromAscii("file://")); +#endif + indexUrl+=fi.absoluteFilePath(); + QDesktopServices::openUrl(QUrl(indexUrl)); +} + +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..49e13cc --- /dev/null +++ b/trunk/addon/doxywizard/doxywizard.h @@ -0,0 +1,83 @@ +#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(); + + 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.pro.in b/trunk/addon/doxywizard/doxywizard.pro.in new file mode 100644 index 0000000..b9f8f70 --- /dev/null +++ b/trunk/addon/doxywizard/doxywizard.pro.in @@ -0,0 +1,27 @@ +###################################################################### +# 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 diff --git a/trunk/addon/doxywizard/doxywizard.qrc b/trunk/addon/doxywizard/doxywizard.qrc new file mode 100644 index 0000000..dd23c5d --- /dev/null +++ b/trunk/addon/doxywizard/doxywizard.qrc @@ -0,0 +1,10 @@ +<!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> +</qresource> +</RCC> diff --git a/trunk/addon/doxywizard/expert.cpp b/trunk/addon/doxywizard/expert.cpp new file mode 100644 index 0000000..7c16c28 --- /dev/null +++ b/trunk/addon/doxywizard/expert.cpp @@ -0,0 +1,553 @@ +#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; + + 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")) + ); + 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()); + //printf("Loading key %s: type=%d\n",qPrintable(i.key()),var.type()); + if (i.value()) + { + i.value()->value() = var; + i.value()->update(); + } + } +} + +void Expert::saveSettings(QSettings *s) +{ + QHashIterator<QString,Input*> i(m_options); + while (i.hasNext()) + { + i.next(); + if (i.value()) + { + s->value(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) +{ + m_helper->setText( + QString::fromAscii("<qt><b>")+option->id()+ + QString::fromAscii("</b><br>")+ + option->docs(). + replace(QChar::fromAscii('\n'),QChar::fromAscii(' '))+ + QString::fromAscii("<qt>") + ); +} + +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..3372ae6 --- /dev/null +++ b/trunk/addon/doxywizard/expert.h @@ -0,0 +1,64 @@ +#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; +}; + +#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/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..8dbedb1 --- /dev/null +++ b/trunk/addon/doxywizard/inputbool.cpp @@ -0,0 +1,110 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2007 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..5ec8998 --- /dev/null +++ b/trunk/addon/doxywizard/inputbool.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2007 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..cb9846b --- /dev/null +++ b/trunk/addon/doxywizard/inputint.cpp @@ -0,0 +1,96 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2007 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..73100ae --- /dev/null +++ b/trunk/addon/doxywizard/inputint.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2007 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..7b0aea0 --- /dev/null +++ b/trunk/addon/doxywizard/inputstring.cpp @@ -0,0 +1,191 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2007 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 ) + : m_default(s), m_sm(m), m_index(0), m_docs(docs), m_id(id) +{ + 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 = 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 = 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..13efb44 --- /dev/null +++ b/trunk/addon/doxywizard/inputstring.h @@ -0,0 +1,88 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2007 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 ); + ~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; +}; + +#endif diff --git a/trunk/addon/doxywizard/inputstrlist.cpp b/trunk/addon/doxywizard/inputstrlist.cpp new file mode 100644 index 0000000..d0ebdc7 --- /dev/null +++ b/trunk/addon/doxywizard/inputstrlist.cpp @@ -0,0 +1,254 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2007 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..912f441 --- /dev/null +++ b/trunk/addon/doxywizard/inputstrlist.h @@ -0,0 +1,91 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2007 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..a040af7 --- /dev/null +++ b/trunk/addon/doxywizard/version.h @@ -0,0 +1,23 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2007 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..7346bd2 --- /dev/null +++ b/trunk/addon/doxywizard/wizard.cpp @@ -0,0 +1,896 @@ +#include "wizard.h" +#include "input.h" +#include "doxywizard.h" + +#include <QtGui> + +// step1 options +#define STR_PROJECT_NAME QString::fromAscii("PROJECT_NAME") +#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") + + +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 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 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(); + } +} + +//========================================================================== + +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 ); + QHBoxLayout *bl = new QHBoxLayout(w); + bl->setSpacing(10); + + QWidget *col1 = new QWidget; + QVBoxLayout *col1Layout = new QVBoxLayout(col1); + col1Layout->setSpacing(8); + QLabel *projName = new QLabel(this); + projName->setText(tr("Project name:")); + projName->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + QLabel *projVersion = new QLabel(this); + projVersion->setText(tr("Project version or id:")); + projVersion->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + col1Layout->addWidget(projName); + col1Layout->addWidget(projVersion); + + QWidget *col2 = new QWidget; + QVBoxLayout *col2Layout = new QVBoxLayout(col2); + col2Layout->setSpacing(8); + m_projName = new QLineEdit; + m_projNumber = new QLineEdit; + col2Layout->addWidget(m_projName); + col2Layout->addWidget(m_projNumber); + + bl->addWidget(col1); + bl->addWidget(col2); + w->setLayout(bl); + + 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(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_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::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::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_projNumber->setText(getStringOption(m_modelData,STR_PROJECT_NUMBER)); + 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 frames and a navigation tree")); + 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 (requires PHP enabled web server)")); + vbox->addWidget(m_searchEnabled); + // SEARCH_ENGINE + 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))); +} + +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); + updateStringOption(m_modelData,STR_GENERATE_TREEVIEW,QString::fromAscii("NONE")); + } + else if (id==1) // with navigation tree + { + updateBoolOption(m_modelData,STR_GENERATE_HTMLHELP,false); + updateStringOption(m_modelData,STR_GENERATE_TREEVIEW,QString::fromAscii("ALL")); + } + else if (id==2) // with compiled help + { + updateBoolOption(m_modelData,STR_GENERATE_HTMLHELP,true); + updateStringOption(m_modelData,STR_GENERATE_TREEVIEW,QString::fromAscii("NONE")); + } +} + +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..d482db9 --- /dev/null +++ b/trunk/addon/doxywizard/wizard.h @@ -0,0 +1,182 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2007 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> + +class Input; +class QTreeWidget; +class QTreeWidgetItem; +class QStackedWidget; +class QCheckBox; +class QLineEdit; +class QPushButton; +class QRadioButton; +class QGroupBox; +class QButtonGroup; +class Wizard; + +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 Step1 : public QWidget +{ + Q_OBJECT + + public: + Step1(Wizard *parent,const QHash<QString,Input*> &modelData); + void init(); + + private slots: + void selectSourceDir(); + void selectDestinationDir(); + void setProjectName(const QString &name); + void setProjectNumber(const QString &num); + void setSourceDir(const QString &dir); + void setDestinationDir(const QString &dir); + void setRecursiveScan(int); + + private: + QLineEdit *m_projName; + QLineEdit *m_projNumber; + QLineEdit *m_sourceDir; + QLineEdit *m_destDir; + 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); + + 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; + 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 |