diff options
Diffstat (limited to 'addon/doxywizard/doxywizard.cpp')
-rw-r--r-- | addon/doxywizard/doxywizard.cpp | 1646 |
1 files changed, 1240 insertions, 406 deletions
diff --git a/addon/doxywizard/doxywizard.cpp b/addon/doxywizard/doxywizard.cpp index e92509a..9c9737d 100644 --- a/addon/doxywizard/doxywizard.cpp +++ b/addon/doxywizard/doxywizard.cpp @@ -1,543 +1,1377 @@ -/****************************************************************************** - * - * - * - * Copyright (C) 1997-2004 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 <stdio.h> -#include <stdlib.h> -#include <qmainwindow.h> -#include <qpopupmenu.h> -#include <qfileinfo.h> -#include <qmenubar.h> -#include <qstatusbar.h> -#include <qfiledialog.h> -#include <qmessagebox.h> +#include <qlabel.h> +#include <qhbox.h> +#include <qvbox.h> +#include <qlineedit.h> #include <qapplication.h> -#include <qwhatsthis.h> +#include <qcheckbox.h> +#include <qpushbutton.h> +#include <qbuttongroup.h> +#include <qradiobutton.h> #include <qlayout.h> -#include <qtabwidget.h> -#include <qtoolbar.h> -#include <qtoolbutton.h> +#include <qcombobox.h> +#include <qfiledialog.h> +#include <qmessagebox.h> +#include <qtextedit.h> +#include <qprocess.h> +#include <qtimer.h> +#include <qstatusbar.h> +#include <qfileinfo.h> +#include <qpopupmenu.h> +#include <qmenubar.h> +#include <qtooltip.h> + +#if defined(Q_OS_MACX) +#include <CoreFoundation/CFBundle.h> +#include <ApplicationServices/ApplicationServices.h> +#undef check +#endif #include "doxywizard.h" -#include "pagewidget.h" -#include "inputbool.h" -#include "inputstring.h" -#include "inputstrlist.h" -#include "inputint.h" +#include "expert.h" #include "config.h" -#include "version.h" -#include "pixmaps.h" -QString configFileName; -const int messageTimeout = 4000; //!< status bar message timeout in millisec. +const int messageTimeout = 5000; //!< status bar message timeout in millisec. + +#if defined(Q_OS_MACX) +QCString getResourcePath() +{ + // todo: use qApp->applicationDirPath() + QCString result; + CFURLRef pluginRef = CFBundleCopyBundleURL(CFBundleGetMainBundle()); + CFStringRef macPath = CFURLCopyFileSystemPath(pluginRef, kCFURLPOSIXPathStyle); + result = CFStringGetCStringPtr(macPath, CFStringGetSystemEncoding()); + result+="/Contents/Resources/"; + return result; +} +#endif -//------------------------------------------------------------------------- -static bool loadConfig( QString loadFile ) +//========================================================================== + +Step1::Step1(QWidget *parent) : QWidget(parent,"Step1") { - QFileInfo fi( loadFile ); - if ( !fi.exists() ) - { - QMessageBox::warning(0, - "Warning","Input file "+loadFile+ - " does not exist! Starting new file.", - "ok" - ); - return FALSE; - } + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setMargin(4); + layout->setSpacing(8); + layout->addWidget(new QLabel( "Provide some information " + "about the project you are documenting",this)); + QWidget *w = new QWidget( this ); + QHBoxLayout *bl = new QHBoxLayout(w,10); - // set config values to their defaults - Config::instance()->init(); + QVBox *col1 = new QVBox( w ); + col1->setSpacing(8); + (new QLabel("Project name:",col1))->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + (new QLabel("Project version or id:",col1))->setAlignment(Qt::AlignRight|Qt::AlignVCenter); - // parse the config file - // this will initialize the various Config data members - if (!Config::instance()->parse(loadFile)) - { - QMessageBox::warning(0, - "Warning","Cannot open or read input "+loadFile+"!", - "abort" - ); - return FALSE; - } - - Config::instance()->convertStrToVal(); + QVBox *col2 = new QVBox( w ); + col2->setSpacing(8); + m_projName = new QLineEdit(col2); + m_projNumber = new QLineEdit(col2); + + bl->addWidget(col1); + bl->addWidget(col2); + + layout->addWidget(w); - return TRUE; + //--------------------------------------------------- + QFrame *f = new QFrame( this ); + f->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + layout->addWidget(f); + + layout->addWidget(new QLabel( "Specify the directory to " + "scan for source code", this)); + QHBox *row = new QHBox( this ); + row->setSpacing(10); + new QLabel("Source code directory:",row); + m_sourceDir = new QLineEdit(row); + m_srcSelectDir = new QPushButton("Select...",row); + layout->addWidget(row); + + m_recursive = new QCheckBox("Scan recursively",this); + m_recursive->setChecked(TRUE); + layout->addWidget(m_recursive); + + //--------------------------------------------------- + f = new QFrame( this ); + f->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + layout->addWidget(f); + + layout->addWidget(new QLabel( + "Specify the directory where doxygen should " + "put the generated documentation",this + )); + row = new QHBox( this ); + row->setSpacing(10); + new QLabel("Destination directory:",row); + m_destDir = new QLineEdit(row); + m_dstSelectDir = new QPushButton("Select...",row); + layout->addWidget(row); + layout->addStretch(1); + + connect(m_srcSelectDir,SIGNAL(clicked()), + this,SLOT(selectSourceDir())); + connect(m_dstSelectDir,SIGNAL(clicked()), + this,SLOT(selectDestinationDir())); } -static bool saveConfig( QString saveFile ) +void Step1::selectSourceDir() { - QFile f( saveFile ); - if ( !f.open(IO_WriteOnly) ) - { - QMessageBox::warning(0, - "Warning","Cannot open file "+saveFile+ - " for writing. Nothing saved!.", - "ok" - ); - return FALSE; // failure - } + m_sourceDir->setText(QFileDialog::getExistingDirectory(m_sourceDir->text(),this)); +} - QTextStream t(&f); - Config::instance()->writeTemplate(t,TRUE,FALSE); // write brief config file +void Step1::selectDestinationDir() +{ + m_destDir->setText(QFileDialog::getExistingDirectory(m_destDir->text(),this)); +} - return TRUE; // success +QString Step1::getProjectName() const +{ + return m_projName->text(); } -//-------------------------------------------------------------------------- +QString Step1::getProjectNumber() const +{ + return m_projNumber->text(); +} -Wizard::Wizard(int argc,char **argv) : - QMainWindow( 0, (QCString)"DoxyWizard v"+versionString ) +QString Step1::getSourceDir() const { - // File popupmenu + return m_sourceDir->text(); +} + +bool Step1::scanRecursively() const +{ + return m_recursive->isChecked(); +} + +QString Step1::getDestinationDir() const +{ + return m_destDir->text(); +} + +void Step1::setProjectName(const QString &name) +{ + m_projName->setText(name); +} + +void Step1::setProjectNumber(const QString &num) +{ + m_projNumber->setText(num); +} - hasChanged=FALSE; - - fileTools = new QToolBar( this, "file operations" ); - fileTools->setLabel( "File Operations" ); +void Step1::setSourceDir(const QString &dir) +{ + m_sourceDir->setText(dir); +} - new QToolButton( QPixmap( file_xpm ), "New File", QString::null, - this, SLOT(newFile()), fileTools, "new file" ); +void Step1::setRecursiveScan(bool enable) +{ + m_recursive->setChecked(enable); +} - //QToolButton * fileOpen = - new QToolButton( QPixmap( fileopen_xpm ), "Open File", QString::null, - this, SLOT(loadFile()), fileTools, "open file" ); +void Step1::setDestinationDir(const QString &dir) +{ + m_destDir->setText(dir); +} - //QToolButton * fileSave = - new QToolButton( QPixmap( filesave_xpm ), "Save File", QString::null, - this, SLOT(saveFile()), fileTools, "save file" ); - //Micha: QToolButton * = - new QToolButton( QPixmap( rundoxygen_xpm ), "Save and Run doxygen", QString::null, - this, SLOT(runDoxygen()), fileTools, "save and run doxygen" ); +//========================================================================== +Step2::Step2(QWidget *parent) : QWidget(parent,"Step2") +{ + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setSpacing(8); - QWhatsThis::whatsThisButton( fileTools ); + m_extractMode = new QButtonGroup("Select the desired extraction mode:",this); + QGridLayout *gbox = new QGridLayout( m_extractMode, 4, 1, 8, 0 ); + gbox->addRowSpacing( 0, fontMetrics().lineSpacing()+2 ); + gbox->addWidget(new QRadioButton("Documented entities only",m_extractMode),1,0); + gbox->addWidget(new QRadioButton("All entities",m_extractMode),2,0); + gbox->addWidget(m_crossRef = new QCheckBox("Include cross-referenced source code in the output",m_extractMode),3,0); + m_extractMode->setButton(0); + layout->addWidget(m_extractMode); - QPopupMenu* file = new QPopupMenu; - file->insertItem( QIconSet(QPixmap(file_xpm)), - "&New", this, SLOT(newFile()), CTRL+Key_N ); - file->insertItem( QIconSet(QPixmap(fileopen_xpm)), - "&Load", this, SLOT(loadFile()), CTRL+Key_O ); - file->insertSeparator(); - file->insertItem( QIconSet(QPixmap(filesave_xpm)), - "&Save", this, SLOT(saveFile()), CTRL+Key_S ); - file->insertItem( "&Save as ...", this, SLOT(saveAsFile()) ); - file->insertSeparator(); - file->insertItem( "&Quit", this, SLOT(quit()), CTRL+Key_Q ); - - // Doxygen popupmenu - QPopupMenu* doxygen = new QPopupMenu; - int itemIndex = doxygen->insertItem( QIconSet(QPixmap(rundoxygen_xpm)), - "&Run", this, SLOT(runDoxygen()), CTRL+Key_R ); - doxygen->setWhatsThis ( itemIndex, "Run doxygen with the current configuration file..." ); - - // Help popupmenu - QPopupMenu* help = new QPopupMenu; - help->insertItem( "&About", this, SLOT(about()), Key_F1 ); - help->insertItem( "What's &This", this , SLOT(whatsThis()), SHIFT+Key_F1); - - // menubar definition - menuBar()->insertItem( "&File", file ); - menuBar()->insertItem( "&Doxygen", doxygen ); - menuBar()->insertSeparator(); - menuBar()->insertItem( "&Help", help ); - - statusBar()->message("Welcome to DoxyWizard",messageTimeout); - - cw = new ConfigFile( this ); - connect(cw,SIGNAL(changed()),this,SLOT(changed())); - setCentralWidget( cw ); - cw->show(); - - if (argc==2) - { - loadFile(argv[1]); + //--------------------------------------------------- + QFrame *f = new QFrame( this ); + f->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + layout->addWidget(f); + + m_optimizeLang = new QButtonGroup("Select programming language to optimize the results for",this); + gbox = new QGridLayout( m_optimizeLang, 4, 1, 8, 0 ); + gbox->addRowSpacing( 0, fontMetrics().lineSpacing()+2 ); + gbox->addWidget(new QRadioButton("Optimize for C++ output",m_optimizeLang),1,0); + gbox->addWidget(new QRadioButton("Optimize for Java output",m_optimizeLang),2,0); + gbox->addWidget(new QRadioButton("Optimize for C output",m_optimizeLang),3,0); + m_optimizeLang->setButton(0); + layout->addWidget(m_optimizeLang); + + layout->addStretch(1); + + connect(m_crossRef,SIGNAL(stateChanged(int)), + parent,SLOT(changeCrossRefState(int))); +} + +bool Step2::crossReferencingEnabled() const +{ + return m_crossRef->isOn(); +} + +void Step2::enableCrossReferencing() +{ + m_crossRef->setChecked(TRUE); +} + +bool Step2::extractAll() const +{ + return m_extractMode->selectedId()==1; +} + +bool Step2::crossReferencing() const +{ + return m_crossRef->isChecked(); +} + +OptLang Step2::optimizeFor() const +{ + switch (m_optimizeLang->selectedId()) + { + case 0: return Lang_Cpp; + case 1: return Lang_Java; + case 2: return Lang_C; } - else + return Lang_Cpp; +} + +void Step2::setExtractAll(bool enable) +{ + m_extractMode->setButton(enable?1:0); +} + +void Step2::setCrossReferencing(bool enable) +{ + m_crossRef->setChecked(enable); +} + +void Step2::setOptimizeFor(OptLang lang) +{ + switch (lang) { - newFile(); + case Lang_Cpp: m_optimizeLang->setButton(0); break; + case Lang_Java: m_optimizeLang->setButton(1); break; + case Lang_C: m_optimizeLang->setButton(2); break; } - refreshCaption(); - - resize( 640, 480 ); +} +//========================================================================== + +Step3::Step3(QWidget *parent) : QWidget(parent,"Step3") +{ + QVBoxLayout *layout = new QVBoxLayout(this); + QButtonGroup *bg = new QButtonGroup("Output format(s) to generate",this); + QGridLayout *gbox = new QGridLayout( bg, 8, 1, 8, 0 ); + gbox->addRowSpacing( 0, fontMetrics().lineSpacing()+2 ); + gbox->addWidget(m_htmlEnabled=new QCheckBox("HTML",bg),1,0); + QWidget *w = new QWidget(bg); + QHBoxLayout *bl = new QHBoxLayout(w); + m_htmlOptions = new QButtonGroup(w); + m_htmlOptions->hide(); + m_htmlOptionBox = new QVBox(w); + m_htmlOptions->insert(new QRadioButton("plain HTML",m_htmlOptionBox)); + m_htmlOptions->insert(new QRadioButton("with frames and a navigation tree",m_htmlOptionBox)); + m_htmlOptions->insert(new QRadioButton("prepare for compressed HTML (.chm)",m_htmlOptionBox)); + m_htmlOptions->insert(m_searchEnabled=new QCheckBox("With search function (requires PHP enabled web server)",m_htmlOptionBox)); + bl->addSpacing(30); + bl->addWidget(m_htmlOptionBox); + m_htmlOptions->setButton(0); + m_htmlOptionBox->setEnabled(TRUE); + gbox->addWidget(w,2,0); + + gbox->addWidget(m_latexEnabled=new QCheckBox("LaTeX",bg),3,0); + w = new QWidget(bg); + bl = new QHBoxLayout(w); + m_texOptions = new QButtonGroup(w); + m_texOptions->hide(); + m_texOptionBox = new QVBox(w); + m_texOptions->insert(new QRadioButton("as intermediate format for hyperlinked PDF",m_texOptionBox)); + m_texOptions->insert(new QRadioButton("as intermediate format for PDF",m_texOptionBox)); + m_texOptions->insert(new QRadioButton("as intermediate format for PostScript",m_texOptionBox)); + bl->addSpacing(30); + bl->addWidget(m_texOptionBox); + m_texOptions->setButton(0); + m_texOptionBox->setEnabled(FALSE); + gbox->addWidget(w,4,0); + + gbox->addWidget(m_manEnabled=new QCheckBox("Man pages",bg),5,0); + gbox->addWidget(m_rtfEnabled=new QCheckBox("Rich Text Format (RTF)",bg),6,0); + gbox->addWidget(m_xmlEnabled=new QCheckBox("XML",bg),7,0); + bg->setButton(0); + layout->addWidget(bg); + + //w = new QWidget( this ); + //bl = new QHBoxLayout(w); + //bl->addWidget(new QLabel("Select the output language:",w)); + //m_outputLang = new QComboBox(w); + //m_outputLang->setMinimumSize(m_outputLang->sizeHint()); + //bl->setSpacing(10); + //bl->addWidget(m_outputLang); + //bl->addStretch(1); + //m_outputLang->insertItem("English"); + //m_outputLang->insertItem("Dutch"); + //m_outputLang->insertItem("German"); + //m_outputLang->insertItem("Spanish"); + //m_outputLang->insertItem("French"); + //m_outputLang->insertItem("Chinese"); + //m_outputLang->insertItem("Japanese"); + //m_outputLang->insertItem("Korean"); + //layout->addWidget(w); + + layout->addStretch(1); + + connect(m_latexEnabled,SIGNAL(stateChanged(int)), + this,SLOT(latexStateChange(int))); + connect(m_htmlEnabled,SIGNAL(stateChanged(int)), + this,SLOT(htmlStateChange(int))); } -void Wizard::newFile() +void Step3::latexStateChange(int state) { - if (hasChanged) + if (state==QButton::On) { - switch( QMessageBox::warning( this, "DoxyWizard", - "Start a new file and lose changes?", - "Yes", "No", 0, 0, 1 )) - { - case 0: - break; - default: // command aborted by the user - return; - } + m_texOptionBox->setEnabled(TRUE); + } + else if (state==QButton::Off) + { + m_texOptionBox->setEnabled(FALSE); } - Config::instance()->init(); - configFileName="Doxyfile"; - cw->init(); } -void Wizard::loadFile(const char *fileName) +void Step3::htmlStateChange(int state) { - if (fileName==0) + if (state==QButton::On) { - configFileName = QFileDialog::getOpenFileName(); + m_htmlOptionBox->setEnabled(TRUE); } - else + else if (state==QButton::Off) + { + m_htmlOptionBox->setEnabled(FALSE); + } +} + +bool Step3::htmlEnabled() const +{ + return m_htmlEnabled->isChecked(); +} + +bool Step3::latexEnabled() const +{ + return m_latexEnabled->isChecked(); +} + +bool Step3::manEnabled() const +{ + return m_manEnabled->isChecked(); +} + +bool Step3::rtfEnabled() const +{ + return m_rtfEnabled->isChecked(); +} + +bool Step3::xmlEnabled() const +{ + return m_xmlEnabled->isChecked(); +} + +bool Step3::searchEnabled() const +{ + return m_searchEnabled->isChecked(); +} + +HtmlStyle Step3::htmlStyle() const +{ + switch (m_htmlOptions->selectedId()) { - configFileName = fileName; + case 0: return HS_Plain; + case 1: return HS_TreeView; + case 2: return HS_CHM; } + return HS_Plain; +} - if ( !configFileName.isNull() ) +TexStyle Step3::texStyle() const +{ + switch (m_texOptions->selectedId()) { - //initData( configFileName ); - loadConfig(configFileName); - cw->init(); + case 0: return TS_PDFHyper; + case 1: return TS_PDF; + case 2: return TS_PS; + } + return TS_PDFHyper; +} - statusBar()->message(configFileName, messageTimeout); - } +void Step3::setHtmlEnabled(bool enable) +{ + m_htmlEnabled->setChecked(enable); } -void Wizard::loadFile() +void Step3::setLatexEnabled(bool enable) { - if (hasChanged) + m_latexEnabled->setChecked(enable); +} + +void Step3::setManEnabled(bool enable) +{ + m_manEnabled->setChecked(enable); +} + +void Step3::setRtfEnabled(bool enable) +{ + m_rtfEnabled->setChecked(enable); +} + +void Step3::setXmlEnabled(bool enable) +{ + m_xmlEnabled->setChecked(enable); +} + +void Step3::setSearchEnabled(bool enable) +{ + m_searchEnabled->setChecked(enable); +} + +void Step3::setHtmlStyle(HtmlStyle style) +{ + switch(style) { - switch( QMessageBox::warning( - this, "DoxyWizard", "Load a new file and lose changes?", - "Yes", "No", 0, 0, 1 )) - { - case 0: - break; - default: // command aborted by the user - return; - } + case HS_Plain: m_htmlOptions->setButton(0); break; + case HS_TreeView: m_htmlOptions->setButton(1); break; + case HS_CHM: m_htmlOptions->setButton(2); break; } - loadFile(0); } -void Wizard::saveFile() +void Step3::setTexStyle(TexStyle style) { - //printf("configFileName=`%s'\n",configFileName.data()); - if (configFileName.isEmpty()) + switch(style) { - saveAsFile(); - return; + case TS_PDFHyper: m_texOptions->setButton(0); break; + case TS_PDF: m_texOptions->setButton(1); break; + case TS_PS: m_texOptions->setButton(2); break; } - else +} + + +//========================================================================== + +Step4::Step4(QWidget *parent) : QWidget(parent,"Step4") +{ + QVBoxLayout *layout = new QVBoxLayout(this); + m_diagramMode = new QButtonGroup("Diagrams to generate",this); + QGridLayout *gbox = new QGridLayout( m_diagramMode, 5, 1, 8, 0 ); + gbox->addRowSpacing( 0, fontMetrics().lineSpacing()+2 ); + gbox->addWidget(new QRadioButton("No diagrams",m_diagramMode),1,0); + gbox->addWidget(new QRadioButton("Use built-in class diagram generator",m_diagramMode),2,0); + gbox->addWidget(new QRadioButton("Use dot tool from the GraphViz package to generate",m_diagramMode),3,0); + QWidget *w = new QWidget(m_diagramMode); + QHBoxLayout *bl = new QHBoxLayout(w); + QButtonGroup *dotGroup = new QButtonGroup(w); + dotGroup->hide(); + m_dotOptions = new QVBox(w); + dotGroup->insert(m_dotClass=new QCheckBox("Class diagrams",m_dotOptions)); + dotGroup->insert(m_dotCollaboration=new QCheckBox("Collaboration diagrams",m_dotOptions)); + dotGroup->insert(m_dotInclude=new QCheckBox("Include dependency graphs",m_dotOptions)); + dotGroup->insert(m_dotIncludedBy=new QCheckBox("Included by dependency graphs",m_dotOptions)); + dotGroup->insert(m_dotInheritance=new QCheckBox("Overall Class hierarchy",m_dotOptions)); + dotGroup->insert(m_dotCall=new QCheckBox("Call graphs",m_dotOptions)); + bl->addSpacing(30); + bl->addWidget(m_dotOptions); + dotGroup->setButton(0); + m_dotOptions->setEnabled(FALSE); + gbox->addWidget(w,4,0); + m_diagramMode->setButton(1); + layout->addWidget(m_diagramMode); + layout->addStretch(1); + + connect(m_diagramMode,SIGNAL(clicked(int)), + this,SLOT(diagramModeChanged(int))); + connect(m_dotCall,SIGNAL(stateChanged(int)), + parent,SLOT(changeCallGraphState(int))); +} + +void Step4::diagramModeChanged(int buttonId) +{ + m_dotOptions->setEnabled(buttonId==2); +} + +void Step4::disableCallGraphs() +{ + m_dotCall->setChecked(FALSE); +} + +bool Step4::callGraphEnabled() const +{ + return m_dotCall->isOn(); +} + +DiagramMode Step4::diagramMode() const +{ + switch(m_diagramMode->selectedId()) { - saveConfig(configFileName); - statusBar()->message(configFileName + " saved", messageTimeout); + case 0: return DM_None; + case 1: return DM_Builtin; + case 2: return DM_Dot; } - hasChanged = FALSE; - refreshCaption(); + return DM_None; +} + +bool Step4::classDiagram() const +{ + return m_dotClass->isChecked(); +} + +bool Step4::collaborationDiagram() const +{ + return m_dotCollaboration->isChecked(); +} + +bool Step4::includeGraph() const +{ + return m_dotInclude->isChecked(); +} + +bool Step4::includedByGraph() const +{ + return m_dotIncludedBy->isChecked(); +} + +bool Step4::inheritanceGraph() const +{ + return m_dotInheritance->isChecked(); } -void Wizard::saveAsFile() +bool Step4::callGraph() const { - configFileName = QFileDialog::getSaveFileName(); - if (configFileName.isNull()) + return m_dotCall->isChecked(); +} + +void Step4::setDiagramMode(DiagramMode mode) +{ + switch(mode) { - statusBar()->message("Save aborted", messageTimeout ); - return; // operation cancelled by the user + case DM_None: m_diagramMode->setButton(0); break; + case DM_Builtin: m_diagramMode->setButton(1); break; + case DM_Dot: m_diagramMode->setButton(2); break; } +} - saveConfig(configFileName); - statusBar()->message("Saved as "+ configFileName, messageTimeout ); +void Step4::setClassDiagram(bool enable) +{ + m_dotClass->setChecked(enable); } -//Micha -// TODO: Use QProcess to show the output in a window -void Wizard::runDoxygen() +void Step4::setCollaborationDiagram(bool enable) { - saveFile(); - QString orgDir = QDir::currentDirPath(); - QFileInfo fi(configFileName); - // cd to the config dir - QDir::setCurrent(fi.dirPath()); - // run doxygen on the config file - QString s = "doxygen \"" + fi.fileName() + "\""; - // actually run the exe - system((const char*)s); - statusBar()->message("doxygen completed: "+ configFileName, messageTimeout ); - hasChanged = FALSE; - refreshCaption(); - QDir::setCurrent(orgDir); -} + m_dotCollaboration->setChecked(enable); +} + +void Step4::setIncludeGraph(bool enable) +{ + m_dotInclude->setChecked(enable); +} + +void Step4::setIncludedByGraph(bool enable) +{ + m_dotIncludedBy->setChecked(enable); +} + +void Step4::setInheritanceGraph(bool enable) +{ + m_dotInheritance->setChecked(enable); +} + +void Step4::setCallGraph(bool enable) +{ + m_dotCall->setChecked(enable); +} -void Wizard::quit() +//========================================================================== + +Wizard::Wizard(QWidget *parent=0) : QTabDialog(parent) +{ + addTab( m_step1 = new Step1(this),"Project"); + addTab( m_step2 = new Step2(this),"Mode"); + addTab( m_step3 = new Step3(this),"Output"); + addTab( m_step4 = new Step4(this),"Diagrams"); + setCancelButton(); +} + +void Wizard::changeCallGraphState(int state) { - if (hasChanged) + if (state==QButton::On && !m_step2->crossReferencingEnabled()) { - switch( QMessageBox::warning( this, "DoxyWizard", "Quit and lose changes?", - "Yes", "No", 0, 0, 1 )) + if (QMessageBox::question(this,"This option depends on another option", + "The call graph option requires that cross-referencing " + "of source code is enabled.\nDo you want to enable this " + "option?",QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes) { - case 0: - qApp->quit(); - break; - case 1: - break; + m_step2->enableCrossReferencing(); + } + else + { + m_step4->disableCallGraphs(); } } - else +} + +void Wizard::changeCrossRefState(int state) +{ + if (state==QButton::Off && m_step4->callGraphEnabled()) { - qApp->quit(); + if (QMessageBox::question(this,"Another option depends on this one", + "The call graph option requires that cross-referencing " + "of source code is enabled.\nDo you want to disable the call " + "graph option?",QMessageBox::Yes,QMessageBox::No + )==QMessageBox::Yes + ) + { + m_step4->disableCallGraphs(); + } + else + { + m_step2->enableCrossReferencing(); + } } } -void Wizard::changed() +//========================================================================== + +MainWidget::MainWidget(QWidget *parent) + : QMainWindow(parent,"MainWidget") { - hasChanged = TRUE; - refreshCaption(); + setCaption("Doxygen GUI frontend"); + + // initialize config settings + Config::instance()->init(); + Config::instance()->check(); + + QWidget *w = new QWidget(this); + setCentralWidget(w); + QVBoxLayout *layout = new QVBoxLayout(w); + layout->setMargin(10); + + QPopupMenu *file = new QPopupMenu(this); + file->insertItem("Open...", this, SLOT(loadConfigFile()), CTRL+Key_O); + file->insertItem("Save As...", this, SLOT(saveConfigFile()), CTRL+Key_S); + m_recentMenu = new QPopupMenu; + file->insertItem( "&Recent configurations", m_recentMenu ); + connect(m_recentMenu,SIGNAL(activated(int)),this,SLOT(openRecent(int))); + file->insertItem("Set as default...",this,SLOT(saveDefaults()) ); + file->insertItem("Reset...",this,SLOT(resetConfig()) ); + file->insertItem("Quit", this, SLOT(quit()), CTRL+Key_Q); + QPopupMenu *help = new QPopupMenu(this); +#if defined(Q_OS_MACX) + help->insertItem("Online manual", this, SLOT(manual()), Key_F1); +#endif + help->insertItem("About", this, SLOT(about()) ); + menuBar()->insertItem("File",file); + menuBar()->insertItem("Help",help); + + //--------------------------------------------------- + QVBox *heading = new QVBox(w); + QLabel *l = new QLabel("Step 1: Configure doxygen",heading); + QFrame *f = new QFrame( heading ); + f->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + //f->setFixedSize(l->sizeHint().width(),f->sizeHint().height()); + layout->addWidget(heading); + layout->addSpacing(10); + + l = new QLabel("Choose one of the following ways to configure doxygen",w); + layout->addWidget(l); + layout->addSpacing(5); + QHBoxLayout *hbl = new QHBoxLayout(layout); + hbl->setSpacing(8); + + m_wizard = new QPushButton("Wizard...",w); + QToolTip::add(m_wizard,"Quickly configure the most important settings"); + hbl->addWidget(m_wizard); + + m_expert = new QPushButton("Expert...",w); + QToolTip::add(m_expert,"Determine all configuration settings in detail"); + hbl->addWidget(m_expert); + + m_load = new QPushButton("Load...",w); + QToolTip::add(m_load,"Load the configuration settings from file"); + hbl->addWidget(m_load); + + hbl->addStretch(1); + + //--------------------------------------------------- + heading = new QVBox(w); + l = new QLabel("Step 2: Save the configuration file",heading); + f = new QFrame( heading ); + f->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + //f->setFixedSize(l->sizeHint().width(),f->sizeHint().height()); + layout->addSpacing(15); + layout->addWidget(heading); + layout->addSpacing(5); + + QGridLayout *grid = new QGridLayout(layout,1,2,10); + m_save = new QPushButton("Save...",w); + m_save->setFixedSize(m_save->sizeHint()); + grid->addWidget(m_save,0,0); + grid->addWidget(m_saveStatus=new QLabel(w),0,1); + m_saveStatus->setTextFormat(Qt::RichText); + + //--------------------------------------------------- + heading = new QVBox(w); + l = new QLabel("Step 3: Specify the directory from which to run doxygen",heading); + f = new QFrame( heading ); + f->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + //f->setFixedSize(l->sizeHint().width(),f->sizeHint().height()); + layout->addSpacing(15); + layout->addWidget(heading); + layout->addSpacing(5); + + QHBoxLayout *row = new QHBoxLayout( layout ); + row->setSpacing(10); + row->addWidget(new QLabel("Working directory:",w)); + m_workingDir = new QLineEdit(w); + m_selWorkingDir = new QPushButton("Select...",w); + row->addWidget(m_workingDir,1); + row->addWidget(m_selWorkingDir); + + //--------------------------------------------------- + heading = new QVBox(w); + l = new QLabel("Step 4: Run doxygen",heading); + f = new QFrame( heading ); + f->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + //f->setFixedSize(l->sizeHint().width(),f->sizeHint().height()); + layout->addSpacing(15); + layout->addWidget(heading); + layout->addSpacing(5); + + row = new QHBoxLayout( layout ); + row->setSpacing(10); + m_run = new QPushButton("Start",w); + row->addWidget(m_run); + row->addWidget(m_runStatus = new QLabel("Status: not running",w)); + row->addStretch(1); + m_run->setEnabled(FALSE); + m_runStatus->setEnabled(FALSE); + + m_saveLog = new QPushButton("Save log...",w); + m_saveLog->setEnabled(FALSE); + row->addWidget(m_saveLog); + + layout->addSpacing(8); + layout->addWidget(m_outputHeading=new QLabel("Output produced by doxygen",w)); + grid = new QGridLayout(layout,1,1,3); + m_outputLog = new QTextEdit(w); + m_outputLog->setReadOnly(TRUE); + m_outputLog->setMinimumWidth(600); + grid->addWidget(m_outputLog,0,0); + grid->setColStretch(0,1); + grid->setRowStretch(0,1); + m_outputLog->setEnabled(FALSE); + m_outputHeading->setEnabled(FALSE); + + // make connections + connect(m_wizard,SIGNAL(clicked()), + this,SLOT(launchWizard())); + connect(m_expert,SIGNAL(clicked()), + this,SLOT(launchExpert())); + connect(m_load,SIGNAL(clicked()), + this,SLOT(loadConfigFile())); + connect(m_save,SIGNAL(clicked()), + this,SLOT(saveConfigFile())); + connect(m_selWorkingDir,SIGNAL(clicked()), + this,SLOT(selectWorkingDir())); + connect(m_workingDir,SIGNAL(textChanged(const QString&)), + this,SLOT(updateRunnable(const QString&))); + connect(m_run,SIGNAL(clicked()), + this,SLOT(runDoxygen())); + connect(m_saveLog,SIGNAL(clicked()), + this,SLOT(saveLog())); + + // load default settings + m_settings.setPath("www.doxygen.org","Doxygen GUI"); + bool ok; + QString config = m_settings.readEntry("/config/default",QString::null,&ok); + if (ok && !config.isEmpty()) + { + Config::instance()->parseString("default settings",config); + } + QString workingDir = m_settings.readEntry("/config/workingdir",QString::null,&ok); + if (ok && !workingDir.isEmpty()) + { + m_workingDir->setText(workingDir); + } + setConfigSaved(FALSE); + for (int i=0;i<10;i++) + { + QString entry = m_settings.readEntry(QString().sprintf("/recent/config%d",i)); + if (!entry.isEmpty()) + { + addRecentFile(entry); + } + } + + m_runProcess = new QProcess; + connect(m_runProcess,SIGNAL(readyReadStdout()),this,SLOT(readStdout())); + connect(m_runProcess,SIGNAL(processExited()),this,SLOT(runComplete())); + m_running = FALSE; + m_timer = new QTimer; + connect(m_timer,SIGNAL(timeout()),this,SLOT(readStdout())); + + statusBar()->message("Welcome to Doxygen",messageTimeout); } -void Wizard::refreshCaption() +MainWidget::~MainWidget() { - QString s; - if (hasChanged) s=" *"; - setCaption("Doxywizard - ["+configFileName+s+"]"); + delete m_runProcess; } -void Wizard::about() +void MainWidget::selectWorkingDir() { - QCString text(4096); - text.sprintf( "<qt><center>A tool to create and edit configuration files " - "that can be read by doxygen version %s.</center><p>" - "<center>Written by Dimitri van Heesch</center><p>" - "<center>(c) 2000-2003</center></qt>",versionString - ); - QMessageBox::about(this, "DoxyWizard",text); + QString selectedDir = QFileDialog::getExistingDirectory(m_workingDir->text()); + if (!selectedDir.isEmpty()) + { + m_workingDir->setText(selectedDir); + } } -//---------------------------------------------------------------------- - +void MainWidget::updateRunnable(const QString &newDirName) +{ + if (m_running) return; + QFileInfo fi(newDirName); + bool isRunnable = fi.exists() && fi.isDir() && m_configSaved; + m_run->setEnabled(isRunnable); + m_runStatus->setEnabled(isRunnable); + m_outputHeading->setEnabled(isRunnable); + m_outputLog->setEnabled(isRunnable); + m_saveLog->setEnabled(isRunnable && !m_outputLog->text().isEmpty()); +} -ConfigFile::ConfigFile( QWidget *parent ) : QWidget( parent ) +void MainWidget::launchWizard() { + Wizard wizard(this); - m_dependencies = new QDict< QList<IInput> >(257); - m_dependencies->setAutoDelete(TRUE); - m_inputWidgets = new QDict< IInput >; - m_switches = new QDict< QObject >; + // -------- Initialize the dialog ---------------- - QVBoxLayout *layout = new QVBoxLayout( this ); + // step1 + wizard.setProjectName(Config_getString("PROJECT_NAME")); + wizard.setProjectNumber(Config_getString("PROJECT_NUMBER")); + if (Config_getList("INPUT").count()==1) + { + QString dirName=Config_getList("INPUT").getFirst(); + QFileInfo fi(dirName); + if (fi.exists() && fi.isDir()) + { + wizard.setSourceDir(dirName); + } + } + wizard.setRecursiveScan(Config_getBool("RECURSIVE")); + wizard.setDestinationDir(Config_getString("OUTPUT_DIRECTORY")); - // QTabWidget definition - QTabWidget *tab = new QTabWidget( this ); - layout->addWidget( tab ); + // step2 + wizard.setExtractAll(Config_getBool("EXTRACT_ALL")); + wizard.setCrossReferencing(Config_getBool("SOURCE_BROWSER")); + if (Config_getBool("OPTIMIZE_OUTPUT_JAVA")) + { + wizard.setOptimizeFor(Lang_Java); + } + else if (Config_getBool("OPTIMIZE_OUTPUT_FOR_C")) + { + wizard.setOptimizeFor(Lang_C); + } + else + { + wizard.setOptimizeFor(Lang_Cpp); + } - QListIterator<ConfigOption> options = Config::instance()->iterator(); - PageWidget *page = 0; - ConfigOption *option = 0; - for (options.toFirst();(option=options.current());++options) + // step3 + wizard.setHtmlEnabled(Config_getBool("GENERATE_HTML")); + wizard.setLatexEnabled(Config_getBool("GENERATE_LATEX")); + wizard.setManEnabled(Config_getBool("GENERATE_MAN")); + wizard.setRtfEnabled(Config_getBool("GENERATE_RTF")); + wizard.setXmlEnabled(Config_getBool("GENERATE_XML")); + wizard.setSearchEnabled(Config_getBool("SEARCHENGINE")); + if (Config_getBool("GENERATE_HTMLHELP")) { - switch(option->kind()) + wizard.setHtmlStyle(HS_CHM); + } + else if (Config_getBool("GENERATE_TREEVIEW")) + { + wizard.setHtmlStyle(HS_TreeView); + } + else + { + wizard.setHtmlStyle(HS_Plain); + } + if (Config_getBool("USE_PDFLATEX")) + { + if (Config_getBool("PDF_HYPERLINKS")) { - case ConfigOption::O_Info: - if (page) page->addStretch(1); - page = new PageWidget( tab, option->name() ); - QWhatsThis::add(page, option->docs().simplifyWhiteSpace() ); - break; - case ConfigOption::O_String: - { - ASSERT(page!=0); - InputString::StringMode sm=InputString::StringFree; - switch(((ConfigString *)option)->widgetType()) - { - case ConfigString::String: sm=InputString::StringFree; break; - case ConfigString::File: sm=InputString::StringFile; break; - case ConfigString::Dir: sm=InputString::StringDir; break; - } - InputString *inputString = new InputString( - option->name(), // name - page, // widget - *((ConfigString *)option)->valueRef(), // variable - sm // type - ); - QWhatsThis::add(inputString, option->docs().simplifyWhiteSpace() ); - connect(inputString,SIGNAL(changed()),SIGNAL(changed())); - m_inputWidgets->insert(option->name(),inputString); - addDependency(m_switches,option->dependsOn(),option->name()); - } - break; - case ConfigOption::O_Enum: - { - ASSERT(page!=0); - InputString *inputString = new InputString( - option->name(), // name - page, // widget - *((ConfigEnum *)option)->valueRef(), // variable - InputString::StringFixed // type - ); - QStrListIterator sli=((ConfigEnum *)option)->iterator(); - for (sli.toFirst();sli.current();++sli) - { - inputString->addValue(sli.current()); - } - QWhatsThis::add(inputString, option->docs().simplifyWhiteSpace() ); - connect(inputString,SIGNAL(changed()),SIGNAL(changed())); - m_inputWidgets->insert(option->name(),inputString); - addDependency(m_switches,option->dependsOn(),option->name()); - } + wizard.setTexStyle(TS_PDFHyper); + } + else + { + wizard.setTexStyle(TS_PDF); + } + } + else + { + wizard.setTexStyle(TS_PS); + } + + // step4 + if (Config_getBool("HAVE_DOT")) + { + wizard.setDiagramMode(DM_Dot); + } + else if (Config_getBool("CLASS_DIAGRAMS")) + { + wizard.setDiagramMode(DM_Builtin); + } + else + { + wizard.setDiagramMode(DM_None); + } + wizard.setClassDiagram(Config_getBool("CLASS_GRAPH")); + wizard.setCollaborationDiagram(Config_getBool("COLLABORATION_GRAPH")); + wizard.setIncludeGraph(Config_getBool("INCLUDE_GRAPH")); + wizard.setIncludedByGraph(Config_getBool("INCLUDED_BY_GRAPH")); + wizard.setInheritanceGraph(Config_getBool("GRAPHICAL_HIERARCHY")); + wizard.setCallGraph(Config_getBool("CALL_GRAPH")); + + // -------- Run the dialog ---------------- + + if (wizard.exec()==QDialog::Accepted) + { + // -------- Store the results ---------------- + + // step1 + Config_getString("PROJECT_NAME")=wizard.getProjectName(); + Config_getString("PROJECT_NUMBER")=wizard.getProjectNumber(); + Config_getList("INPUT").clear(); + Config_getList("INPUT").append(wizard.getSourceDir()); + Config_getBool("RECURSIVE")=wizard.scanRecursively(); + Config_getString("OUTPUT_DIRECTORY")=wizard.getDestinationDir(); + + // step2 + if (wizard.extractAll()) + { + Config_getBool("EXTRACT_ALL")=TRUE; + Config_getBool("EXTRACT_PRIVATE")=TRUE; + Config_getBool("EXTRACT_STATIC")=TRUE; + Config_getBool("EXTRACT_LOCAL_CLASSES")=TRUE; + Config_getBool("HIDE_UNDOC_MEMBERS")=FALSE; + Config_getBool("HIDE_UNDOC_CLASSES")=FALSE; + } + else + { + Config_getBool("EXTRACT_ALL")=FALSE; + Config_getBool("EXTRACT_PRIVATE")=FALSE; + Config_getBool("EXTRACT_STATIC")=FALSE; + Config_getBool("EXTRACT_LOCAL_CLASSES")=TRUE; + Config_getBool("HIDE_UNDOC_MEMBERS")=TRUE; + Config_getBool("HIDE_UNDOC_CLASSES")=TRUE; + } + + if (wizard.crossReferencing()) + { + Config_getBool("SOURCE_BROWSER")=TRUE; + Config_getBool("REFERENCED_BY_RELATION")=TRUE; + Config_getBool("REFERENCES_RELATION")=TRUE; + Config_getBool("VERBATIM_HEADERS")=TRUE; + } + else + { + Config_getBool("SOURCE_BROWSER")=FALSE; + Config_getBool("REFERENCED_BY_RELATION")=FALSE; + Config_getBool("REFERENCES_RELATION")=FALSE; + Config_getBool("VERBATIM_HEADERS")=FALSE; + } + + switch(wizard.optimizeFor()) + { + case Lang_Cpp: + Config_getBool("OPTIMIZE_OUTPUT_FOR_C")=FALSE; + Config_getBool("OPTIMIZE_OUTPUT_JAVA")=FALSE; break; - case ConfigOption::O_List: - { - ASSERT(page!=0); - InputStrList::ListMode lm=InputStrList::ListString; - switch(((ConfigList *)option)->widgetType()) - { - case ConfigList::String: lm=InputStrList::ListString; break; - case ConfigList::File: lm=InputStrList::ListFile; break; - case ConfigList::Dir: lm=InputStrList::ListDir; break; - case ConfigList::FileAndDir: lm=InputStrList::ListFileDir; break; - } - InputStrList *inputStrList = new InputStrList( - option->name(), // name - page, // widget - *((ConfigList *)option)->valueRef(), // variable - lm // type - ); - QWhatsThis::add(inputStrList, option->docs().simplifyWhiteSpace() ); - connect(inputStrList,SIGNAL(changed()),SIGNAL(changed())); - m_inputWidgets->insert(option->name(),inputStrList); - addDependency(m_switches,option->dependsOn(),option->name()); - } + case Lang_Java: + Config_getBool("OPTIMIZE_OUTPUT_FOR_C")=FALSE; + Config_getBool("OPTIMIZE_OUTPUT_JAVA")=TRUE; break; + case Lang_C: + Config_getBool("OPTIMIZE_OUTPUT_FOR_C")=TRUE; + Config_getBool("OPTIMIZE_OUTPUT_JAVA")=FALSE; break; - case ConfigOption::O_Bool: - { - ASSERT(page!=0); - InputBool *inputBool = new InputBool( - option->name(), // name - page, // widget - *((ConfigBool *)option)->valueRef() // variable - ); - QWhatsThis::add(inputBool, option->docs().simplifyWhiteSpace() ); - connect(inputBool,SIGNAL(changed()),SIGNAL(changed())); - m_inputWidgets->insert(option->name(),inputBool); - addDependency(m_switches,option->dependsOn(),option->name()); - } + } + + // step3 + Config_getBool("GENERATE_HTML")=wizard.htmlEnabled(); + Config_getBool("GENERATE_LATEX")=wizard.latexEnabled(); + Config_getBool("GENERATE_MAN")=wizard.manEnabled(); + Config_getBool("GENERATE_RTF")=wizard.rtfEnabled(); + Config_getBool("GENERATE_XML")=wizard.xmlEnabled(); + Config_getBool("SEARCHENGINE")=wizard.searchEnabled(); + if (wizard.htmlEnabled()) + { + switch (wizard.htmlStyle()) + { + case HS_Plain: + Config_getBool("GENERATE_HTMLHELP")=FALSE; + Config_getBool("GENERATE_TREEVIEW")=FALSE; + break; + case HS_TreeView: + Config_getBool("GENERATE_HTMLHELP")=FALSE; + Config_getBool("GENERATE_TREEVIEW")=TRUE; + break; + case HS_CHM: + Config_getBool("GENERATE_HTMLHELP")=TRUE; + Config_getBool("GENERATE_TREEVIEW")=FALSE; + break; + } + } + if (wizard.latexEnabled()) + { + switch (wizard.texStyle()) + { + case TS_PDFHyper: + Config_getBool("USE_PDFLATEX")=TRUE; + Config_getBool("PDF_HYPERLINKS")=TRUE; + break; + case TS_PDF: + Config_getBool("USE_PDFLATEX")=TRUE; + Config_getBool("PDF_HYPERLINKS")=FALSE; + break; + case TS_PS: + Config_getBool("USE_PDFLATEX")=FALSE; + Config_getBool("PDF_HYPERLINKS")=FALSE; + break; + } + } + + // step4 + switch (wizard.diagramMode()) + { + case DM_None: + Config_getBool("CLASS_DIAGRAMS")=FALSE; + Config_getBool("HAVE_DOT")=FALSE; break; - case ConfigOption::O_Int: - { - ASSERT(page!=0); - InputInt *inputInt = new InputInt( - option->name(), // name - page, // widget - *((ConfigInt *)option)->valueRef(), // variable - ((ConfigInt *)option)->minVal(), // min value - ((ConfigInt *)option)->maxVal() // max value - ); - QWhatsThis::add(inputInt, option->docs().simplifyWhiteSpace() ); - connect(inputInt,SIGNAL(changed()),SIGNAL(changed())); - m_inputWidgets->insert(option->name(),inputInt); - addDependency(m_switches,option->dependsOn(),option->name()); - } + case DM_Builtin: + Config_getBool("CLASS_DIAGRAMS")=TRUE; + Config_getBool("HAVE_DOT")=FALSE; break; - case ConfigOption::O_Obsolete: + case DM_Dot: + Config_getBool("CLASS_DIAGRAMS")=FALSE; + Config_getBool("HAVE_DOT")=TRUE; + Config_getBool("CLASS_GRAPH")=wizard.classDiagram(); + Config_getBool("COLLABORATION_GRAPH")=wizard.collaborationDiagram(); + Config_getBool("INCLUDE_GRAPH")=wizard.includeGraph(); + Config_getBool("INCLUDED_BY_GRAPH")=wizard.includedByGraph(); + Config_getBool("GRAPHICAL_HIERARCHY")=wizard.inheritanceGraph(); + Config_getBool("CALL_GRAPH")=wizard.callGraph(); break; - } + } +#if defined(Q_OS_MACX) + Config_getString("DOT_PATH")=getResourcePath(); +#endif + setConfigSaved(FALSE); } - if (page) page->addStretch(1); +} - QDictIterator<QObject> di(*m_switches); - QObject *obj = 0; - for (di.toFirst();(obj=di.current());++di) +void MainWidget::loadConfigFromFile(const QString &fn) +{ + if (!Config::instance()->parse(fn)) { - connect(obj,SIGNAL(toggle(const char *,bool)),SLOT(toggle(const char *,bool))); - // UGLY HACK: assumes each item depends on a boolean without checking! - emit toggle(di.currentKey(),((InputBool *)obj)->getState()); + QMessageBox::warning(0,"Warning", + "Could not open or read config file "+fn+"!", + "abort" + ); + } + else + { + Config::instance()->convertStrToVal(); +#if defined(Q_OS_MACX) + if (Config_getString("DOT_PATH")!=getResourcePath()) + { + Config_getString("DOT_PATH")=getResourcePath(); + setConfigSaved(FALSE); + } + else + { + setConfigSaved(TRUE); + } +#else + setConfigSaved(TRUE); +#endif + addRecentFile(fn); + m_workingDir->setText(QFileInfo(fn).dirPath(TRUE)); + m_configFileName = fn; + statusBar()->message("New configuration loaded",messageTimeout); + } +} + +void MainWidget::loadConfigFile() +{ + QString fn = QFileDialog::getOpenFileName(m_workingDir->text(),QString::null,this); + if (!fn.isEmpty()) + { + loadConfigFromFile(fn); } - } -ConfigFile::~ConfigFile() +void MainWidget::launchExpert() { - delete m_dependencies; - delete m_inputWidgets; - delete m_switches; + Expert expert(this); + expert.init(); + expert.exec(); +#if defined(Q_OS_MACX) + Config_getString("DOT_PATH")=getResourcePath(); +#endif + setConfigSaved(FALSE); } -void ConfigFile::addDependency(QDict<QObject> *switches, - const QCString &dep,const QCString &name) +void MainWidget::saveDefaults() { - if (!dep.isEmpty()) + if (QMessageBox::question(this,"Store settings as defaults", + "Do you wish to use the " + "current configuration settings as the default settings?", + QMessageBox::Yes, QMessageBox::No)==QMessageBox::Yes) { - //printf("ConfigFile::addDependency(%s)\n",name.data()); - IInput *parent = m_inputWidgets->find(dep); - ASSERT(parent!=0); - IInput *child = m_inputWidgets->find(name); - ASSERT(child!=0); - if (switches->find(dep)==0) + QString newConfig; + QTextStream t(&newConfig,IO_WriteOnly); + Config::instance()->writeTemplate(t,TRUE,FALSE); + m_settings.writeEntry("/config/default",newConfig); + m_settings.writeEntry("/config/workingdir",m_workingDir->text()); + statusBar()->message("Current configuration saved as default",messageTimeout); + } +} + +void MainWidget::saveConfigFile() +{ + QString fn = QFileDialog::getSaveFileName(m_workingDir->text()+"/Doxyfile",QString::null,this); + if (!fn.isEmpty()) + { + QFile f(fn); + if (f.open(IO_WriteOnly)) { - switches->insert(dep,parent->qobject()); + QTextStream t(&f); + Config::instance()->writeTemplate(t,TRUE,FALSE); + m_configFileName = fn; + setConfigSaved(TRUE); + addRecentFile(fn); + statusBar()->message("Configuration saved",messageTimeout); } - QList<IInput> *list = m_dependencies->find(dep); - if (list==0) + else { - list = new QList<IInput>; - m_dependencies->insert(dep,list); + QMessageBox::warning(0,"Warning", + "Cannot open file "+fn+" for writing. Nothing saved!","ok"); } - list->append(child); } } -void ConfigFile::toggle(const char *name,bool state) +void MainWidget::resetConfig() { - QList<IInput> *inputs = m_dependencies->find(name); - ASSERT(inputs!=0); - IInput *input = inputs->first(); - while (input) + if (QMessageBox::question(this,"Reset settings to their defaults", + "Do you wish to reset the " + "current configuration settings to their factory defaults?", + QMessageBox::Yes, QMessageBox::No)==QMessageBox::Yes) { - input->setEnabled(state); - input = inputs->next(); + // initialize config settings + Config::instance()->init(); + m_configFileName = ""; + setConfigSaved(FALSE); + statusBar()->message("Configuration settings reset to their defaults",messageTimeout); } } -void ConfigFile::init() +void MainWidget::setConfigSaved(bool enable) { - QDictIterator<IInput> di(*m_inputWidgets); - IInput *input = 0; - for (di.toFirst();(input=di.current());++di) + m_configSaved=enable; + if (m_configSaved) { - input->init(); + m_saveStatus->setText("Status: saved"); } - QDictIterator<QObject> dio(*m_switches); - QObject *obj = 0; - for (dio.toFirst();(obj=dio.current());++dio) + else { - connect(obj,SIGNAL(toggle(const char *,bool)),SLOT(toggle(const char *,bool))); - // UGLY HACK: assumes each item depends on a boolean without checking! - emit toggle(dio.currentKey(),((InputBool *)obj)->getState()); + m_saveStatus->setText("Status: <font color=\"red\">not saved</font>"); + } + updateRunnable(m_workingDir->text()); +} + +void MainWidget::runDoxygen() +{ + if (!m_running) + { + QString doxygenPath; +#if defined(Q_OS_MACX) + doxygenPath = getResourcePath(); +#else + // TODO: get the right value if not in the search path +#endif + //printf("Trying to run doxygen from path %s\n",doxygenPath.data()); + + m_runProcess->setCommunication(QProcess::Stdout| + QProcess::Stderr| + QProcess::DupStderr + ); + m_runProcess->setWorkingDirectory(QDir(m_workingDir->text())); + m_runProcess->clearArguments(); + m_runProcess->addArgument(doxygenPath+"doxygen"); + m_runProcess->addArgument("-b"); + m_runProcess->addArgument(m_configFileName); + m_outputLog->clear(); + if (!m_runProcess->start()) + { + m_outputLog->append(QString("*** Failed to run doxygen\n")); + } + else + { + m_running=TRUE; + m_run->setText("Cancel"); + m_runStatus->setText("Status: running"); + m_timer->start(1000); + } + } + else + { + m_running=FALSE; + m_run->setText("Start"); + m_runStatus->setText("Status: not running"); + m_runProcess->kill(); + m_timer->stop(); + updateRunnable(m_workingDir->text()); + } +} + +void MainWidget::readStdout() +{ + m_outputLog->append(QString(m_runProcess->readStdout())); +} + +void MainWidget::runComplete() +{ + if (m_running) + { + m_outputLog->append(QString("*** Doxygen has finished\n")); + } + else + { + m_outputLog->append(QString("*** Cancelled by user\n")); + } + m_run->setText("Start"); + m_runStatus->setText("Status: not running"); + m_running=FALSE; + updateRunnable(m_workingDir->text()); +} + +void MainWidget::about() +{ + QString msg; + QTextStream t(&msg,IO_WriteOnly); + t << "<qt><center>A tool to configure and run doxygen " + "on your source files.</center><p><br>" + "<center>Written by<br> Dimitri van Heesch<br>© 2000-2004</center><p>" + "</qt>"; + QMessageBox::about(this,"Doxygen GUI",msg); +} + +void MainWidget::manual() +{ +#if defined(Q_OS_MACX) + const char *urlBytes = "http://www.doxygen.org/manual.html"; + CFURLRef url = CFURLCreateWithBytes ( + NULL, // allocator + (UInt8*)urlBytes, // bytes + strlen(urlBytes), // length + kCFStringEncodingASCII, // encoding + NULL // baseURL + ); + LSOpenCFURLRef(url,0); + CFRelease(url); +#endif +} + +void MainWidget::addRecentFile(const QString &file) +{ + QStringList::Iterator it = m_recentFiles.find(file); + if (it!=m_recentFiles.end()) + { + // already found => move to top + m_recentFiles.remove(it); + m_recentFiles.prepend(file); + } + else + { + // not found + if (m_recentFiles.count() < 10) // append + { + m_recentFiles.prepend(file); + } + else // add + drop last item + { + m_recentFiles.remove(m_recentFiles.last()); + m_recentFiles.prepend(file); + } + } + + m_recentMenu->clear(); + int i=0; + for ( it = m_recentFiles.begin(); it != m_recentFiles.end(); ++it, ++i ) + { + m_recentMenu->insertItem(*it); + m_settings.writeEntry(QString().sprintf("/recent/config%d",i),*it); } - } -//---------------------------------------------------------------------- + +void MainWidget::openRecent(int id) +{ + loadConfigFromFile(m_recentMenu->text(id)); +} + +void MainWidget::quit() +{ + if (!m_configSaved && + QMessageBox::warning( this, "DoxyWizard", "Quit and lose changes?", + QMessageBox::Yes, QMessageBox::No)==QMessageBox::No + ) return; // Quit cancelled by user + + qApp->quit(); +} + +void MainWidget::saveLog() +{ + QString fn = QFileDialog::getSaveFileName(m_workingDir->text()+"/doxygen_log.txt",QString::null,this); + if (!fn.isEmpty()) + { + QFile f(fn); + if (f.open(IO_WriteOnly)) + { + QTextStream t(&f); + t << m_outputLog->text(); + statusBar()->message("Output log saved",messageTimeout); + } + else + { + QMessageBox::warning(0,"Warning", + "Cannot open file "+fn+" for writing. Nothing saved!","ok"); + } + } +} + +//========================================================================== int main(int argc,char **argv) -{ - QApplication::setColorSpec( QApplication::NormalColor ); - QApplication app(argc,argv); - Wizard wizard(argc,argv); - app.setMainWidget( &wizard ); - wizard.show(); - return app.exec(); +{ + QApplication a(argc,argv); + MainWidget main; + a.setMainWidget(&main); + main.show(); + return a.exec(); } + |