b320aaae40350dead3317db09b861ddfd24d0e0c
[platform/upstream/doxygen.git] / addon / doxywizard / wizard.cpp
1 #include "wizard.h"
2 #include "input.h"
3 #include "doxywizard.h"
4
5 #include <math.h>
6
7 #include <QGridLayout>
8 #include <QImage>
9 #include <QLabel>
10 #include <QHBoxLayout>
11 #include <QPushButton>
12 #include <QPixmap>
13 #include <QPainter>
14 #include <QMouseEvent>
15 #include <QLineEdit>
16 #include <QCheckBox>
17 #include <QFileInfo>
18 #include <QFileDialog>
19 #include <QButtonGroup>
20 #include <QGroupBox>
21 #include <QRadioButton>
22 #include <QTreeWidget>
23 #include <QStackedWidget>
24 #include <qdrawutil.h>
25
26 // options configurable via the wizard
27 #define STR_PROJECT_NAME          QString::fromLatin1("PROJECT_NAME")
28 #define STR_PROJECT_LOGO          QString::fromLatin1("PROJECT_LOGO")
29 #define STR_PROJECT_BRIEF         QString::fromLatin1("PROJECT_BRIEF")
30 #define STR_INPUT                 QString::fromLatin1("INPUT")
31 #define STR_OUTPUT_DIRECTORY      QString::fromLatin1("OUTPUT_DIRECTORY")
32 #define STR_PROJECT_NUMBER        QString::fromLatin1("PROJECT_NUMBER")
33 #define STR_RECURSIVE             QString::fromLatin1("RECURSIVE")
34 #define STR_OPTIMIZE_OUTPUT_FOR_C QString::fromLatin1("OPTIMIZE_OUTPUT_FOR_C")
35 #define STR_OPTIMIZE_OUTPUT_JAVA  QString::fromLatin1("OPTIMIZE_OUTPUT_JAVA")
36 #define STR_OPTIMIZE_FOR_FORTRAN  QString::fromLatin1("OPTIMIZE_FOR_FORTRAN")
37 #define STR_OPTIMIZE_OUTPUT_VHDL  QString::fromLatin1("OPTIMIZE_OUTPUT_VHDL")
38 #define STR_CPP_CLI_SUPPORT       QString::fromLatin1("CPP_CLI_SUPPORT")
39 #define STR_HIDE_SCOPE_NAMES      QString::fromLatin1("HIDE_SCOPE_NAMES")
40 #define STR_EXTRACT_ALL           QString::fromLatin1("EXTRACT_ALL")
41 #define STR_SOURCE_BROWSER        QString::fromLatin1("SOURCE_BROWSER")
42 #define STR_GENERATE_HTML         QString::fromLatin1("GENERATE_HTML")
43 #define STR_GENERATE_LATEX        QString::fromLatin1("GENERATE_LATEX")
44 #define STR_GENERATE_MAN          QString::fromLatin1("GENERATE_MAN")
45 #define STR_GENERATE_RTF          QString::fromLatin1("GENERATE_RTF")
46 #define STR_GENERATE_XML          QString::fromLatin1("GENERATE_XML")
47 #define STR_GENERATE_HTMLHELP     QString::fromLatin1("GENERATE_HTMLHELP")
48 #define STR_GENERATE_TREEVIEW     QString::fromLatin1("GENERATE_TREEVIEW")
49 #define STR_USE_PDFLATEX          QString::fromLatin1("USE_PDFLATEX")
50 #define STR_PDF_HYPERLINKS        QString::fromLatin1("PDF_HYPERLINKS")
51 #define STR_SEARCHENGINE          QString::fromLatin1("SEARCHENGINE")
52 #define STR_HAVE_DOT              QString::fromLatin1("HAVE_DOT")
53 #define STR_CLASS_DIAGRAMS        QString::fromLatin1("CLASS_DIAGRAMS")
54 #define STR_CLASS_GRAPH           QString::fromLatin1("CLASS_GRAPH")
55 #define STR_COLLABORATION_GRAPH   QString::fromLatin1("COLLABORATION_GRAPH")
56 #define STR_GRAPHICAL_HIERARCHY   QString::fromLatin1("GRAPHICAL_HIERARCHY")
57 #define STR_INCLUDE_GRAPH         QString::fromLatin1("INCLUDE_GRAPH")
58 #define STR_INCLUDED_BY_GRAPH     QString::fromLatin1("INCLUDED_BY_GRAPH")
59 #define STR_CALL_GRAPH            QString::fromLatin1("CALL_GRAPH")
60 #define STR_CALLER_GRAPH          QString::fromLatin1("CALLER_GRAPH")
61 #define STR_HTML_COLORSTYLE_HUE   QString::fromLatin1("HTML_COLORSTYLE_HUE")
62 #define STR_HTML_COLORSTYLE_SAT   QString::fromLatin1("HTML_COLORSTYLE_SAT")
63 #define STR_HTML_COLORSTYLE_GAMMA QString::fromLatin1("HTML_COLORSTYLE_GAMMA")
64
65 static bool g_optimizeMapping[6][6] = 
66 {
67   // A: OPTIMIZE_OUTPUT_FOR_C
68   // B: OPTIMIZE_OUTPUT_JAVA
69   // C: OPTIMIZE_FOR_FORTRAN
70   // D: OPTIMIZE_OUTPUT_VHDL
71   // E: CPP_CLI_SUPPORT
72   // F: HIDE_SCOPE_NAMES
73   // A     B     C     D     E      F
74   { false,false,false,false,false,false }, // 0: C++
75   { false,false,false,false,true, false }, // 1: C++/CLI
76   { false,true, false,false,false,false }, // 2: C#/Java
77   { true, false,false,false,false,true  }, // 3: C/PHP 
78   { false,false,true, false,false,false }, // 4: Fortran
79   { false,false,false,true, false,false }, // 5: VHDL
80 };
81
82 static QString g_optimizeOptionNames[6] =
83 {
84   STR_OPTIMIZE_OUTPUT_FOR_C,
85   STR_OPTIMIZE_OUTPUT_JAVA,
86   STR_OPTIMIZE_FOR_FORTRAN,
87   STR_OPTIMIZE_OUTPUT_VHDL,
88   STR_CPP_CLI_SUPPORT,
89   STR_HIDE_SCOPE_NAMES
90 };
91
92 //==========================================================================
93
94 static bool stringVariantToBool(const QVariant &v)
95 {
96   QString s = v.toString().toLower();
97   return s==QString::fromLatin1("yes") || s==QString::fromLatin1("true") || s==QString::fromLatin1("1");
98
99
100 static bool getBoolOption(
101     const QHash<QString,Input*>&model,const QString &name)
102 {
103   Input *option = model[name];
104   Q_ASSERT(option!=0);
105   return stringVariantToBool(option->value());
106
107
108 static int getIntOption(
109     const QHash<QString,Input*>&model,const QString &name)
110 {
111   Input *option = model[name];
112   Q_ASSERT(option!=0);
113   return option->value().toInt();
114
115
116 static QString getStringOption(
117     const QHash<QString,Input*>&model,const QString &name)
118 {
119   Input *option = model[name];
120   Q_ASSERT(option!=0);
121   return option->value().toString();
122 }
123
124 static void updateBoolOption(
125     const QHash<QString,Input*>&model,const QString &name,bool bNew)
126 {
127   Input *option = model[name];
128   Q_ASSERT(option!=0);
129   bool bOld = stringVariantToBool(option->value());
130   if (bOld!=bNew)
131   {
132     option->value()=QString::fromLatin1(bNew ? "true" : "false");
133     option->update();
134   }
135 }
136
137 static void updateIntOption(
138     const QHash<QString,Input*>&model,const QString &name,int iNew)
139 {
140   Input *option = model[name];
141   Q_ASSERT(option!=0);
142   int iOld = option->value().toInt();
143   if (iOld!=iNew)
144   {
145     option->value()=QString::fromLatin1("%1").arg(iNew);
146     option->update();
147   }
148 }
149
150
151 static void updateStringOption(
152     const QHash<QString,Input*>&model,const QString &name,const QString &s)
153 {
154   Input *option = model[name];
155   Q_ASSERT(option!=0);
156   if (option->value().toString()!=s)
157   {
158     option->value() = s;
159     option->update();
160   }
161 }
162
163 //==========================================================================
164
165 TuneColorDialog::TuneColorDialog(int hue,int sat,int gamma,QWidget *parent) : QDialog(parent)
166 {
167    setWindowTitle(tr("Tune the color of the HTML output"));
168    QGridLayout *layout = new QGridLayout(this);
169    m_image = new QImage(QString::fromLatin1(":/images/tunecolor.png"));
170    m_imageLab = new QLabel;
171    updateImage(hue,sat,gamma);
172    layout->addWidget(new QLabel(tr("Example output: use the sliders on the right to adjust the color")),0,0);
173    layout->addWidget(m_imageLab,1,0);
174    QHBoxLayout *buttonsLayout = new QHBoxLayout;
175
176    QPushButton *okButton = new QPushButton(tr("Ok"));
177    connect(okButton,SIGNAL(clicked()),SLOT(accept()));
178    okButton->setDefault(true);
179    QPushButton *cancelButton = new QPushButton(tr("Cancel"));
180    connect(cancelButton,SIGNAL(clicked()),SLOT(reject()));
181
182    ColorPicker *huePicker = new ColorPicker(ColorPicker::Hue);
183    huePicker->setCol(hue,sat,gamma);
184    huePicker->setFixedWidth(20);
185    layout->addWidget(huePicker,1,1);
186    ColorPicker *satPicker = new ColorPicker(ColorPicker::Saturation);
187    satPicker->setCol(hue,sat,gamma);
188    satPicker->setFixedWidth(20);
189    layout->addWidget(satPicker,1,2);
190    ColorPicker *gamPicker = new ColorPicker(ColorPicker::Gamma);
191    gamPicker->setCol(hue,sat,gamma);
192    gamPicker->setFixedWidth(20);
193    layout->addWidget(gamPicker,1,3);
194
195    connect(huePicker,SIGNAL(newHsv(int,int,int)),satPicker,SLOT(setCol(int,int,int)));
196    connect(satPicker,SIGNAL(newHsv(int,int,int)),huePicker,SLOT(setCol(int,int,int)));
197    connect(huePicker,SIGNAL(newHsv(int,int,int)),gamPicker,SLOT(setCol(int,int,int)));
198    connect(satPicker,SIGNAL(newHsv(int,int,int)),gamPicker,SLOT(setCol(int,int,int)));
199    connect(gamPicker,SIGNAL(newHsv(int,int,int)),satPicker,SLOT(setCol(int,int,int)));
200    connect(gamPicker,SIGNAL(newHsv(int,int,int)),huePicker,SLOT(setCol(int,int,int)));
201    connect(huePicker,SIGNAL(newHsv(int,int,int)),this,SLOT(updateImage(int,int,int)));
202    connect(satPicker,SIGNAL(newHsv(int,int,int)),this,SLOT(updateImage(int,int,int)));
203    connect(gamPicker,SIGNAL(newHsv(int,int,int)),this,SLOT(updateImage(int,int,int)));
204
205    buttonsLayout->addStretch();
206    buttonsLayout->addWidget(okButton);
207    buttonsLayout->addWidget(cancelButton);
208    layout->addLayout(buttonsLayout,5,0,1,4);
209 }
210
211 void hsl2rgb(double h,double s,double l,
212              double *pRed,double *pGreen,double *pBlue)
213 {
214   double v;
215   double r,g,b;
216
217   r = l;   // default to gray
218   g = l;
219   b = l;
220   v = (l <= 0.5) ? (l * (1.0 + s)) : (l + s - l * s);
221   if (v > 0)
222   {
223     double m;
224     double sv;
225     int sextant;
226     double fract, vsf, mid1, mid2;
227
228     m       = l + l - v;
229     sv      = (v - m ) / v;
230     h      *= 6.0;
231     sextant = (int)h;
232     fract   = h - sextant;
233     vsf     = v * sv * fract;
234     mid1    = m + vsf;
235     mid2    = v - vsf;
236     switch (sextant)
237     {
238       case 0:
239         r = v;
240         g = mid1;
241         b = m;
242         break;
243       case 1:
244         r = mid2;
245         g = v;
246         b = m;
247         break;
248       case 2:
249         r = m;
250         g = v;
251         b = mid1;
252         break;
253       case 3:
254         r = m;
255         g = mid2;
256         b = v;
257         break;
258       case 4:
259         r = mid1;
260         g = m;
261         b = v;
262         break;
263       case 5:
264         r = v;
265         g = m;
266         b = mid2;
267         break;
268     }
269   }
270   *pRed   = r;
271   *pGreen = g;
272   *pBlue  = b;
273 }
274
275
276
277 void TuneColorDialog::updateImage(int hue,int sat,int gam)
278 {
279   QImage coloredImg(m_image->width(),m_image->height(),QImage::Format_RGB32);
280   uint *srcPixel = (uint *)m_image->scanLine(0);
281   uint *dstPixel = (uint *)coloredImg.scanLine(0);
282   uint nrPixels = coloredImg.width()*coloredImg.height();
283   for (uint i=0;i<nrPixels;i++,srcPixel++,dstPixel++)
284   {
285     QColor c = QColor::fromRgb(*srcPixel);
286     double r,g,b;
287     hsl2rgb(hue/359.0, sat/255.0, pow(c.green()/255.0,gam/100.0),&r,&g,&b);
288     *dstPixel = qRgb((int)(r*255.0),(int)(g*255.0),(int)(b*255.0));
289   }
290   m_imageLab->setPixmap(QPixmap::fromImage(coloredImg));
291   m_hue = hue;
292   m_sat = sat;
293   m_gam = gam;
294 }
295
296 int TuneColorDialog::getHue() const
297 {
298   return m_hue;
299 }
300
301 int TuneColorDialog::getSaturation() const
302 {
303   return m_sat;
304 }
305
306 int TuneColorDialog::getGamma() const
307 {
308   return m_gam;
309 }
310
311 //==========================================================================
312
313 ColorPicker::ColorPicker(Mode m)
314 {
315   m_hue = 220;
316   m_gam = 100;
317   m_sat = 100;
318   m_mode = m;
319   m_pix = 0;
320 }
321
322 ColorPicker::~ColorPicker()
323 {
324   delete m_pix;
325 }
326
327 void ColorPicker::paintEvent(QPaintEvent*)
328 {
329   int w = width() - 5;
330
331   QRect r(0, foff, w, height() - 2*foff);
332   int wi = r.width() - 2;
333   int hi = r.height() - 2;
334   if (!m_pix || m_pix->height() != hi || m_pix->width() != wi) 
335   {
336     delete m_pix;
337     QImage img(wi, hi, QImage::Format_RGB32);
338     int y;
339     uint *pixel = (uint *) img.scanLine(0);
340     for (y = 0; y < hi; y++) 
341     {
342       const uint *end = pixel + wi;
343       int yh = y2hue(y+coff);
344       int ys = y2sat(y+coff);
345       int yg = y2gam(y+coff);
346       while (pixel < end) 
347       {
348         QColor c;
349         c.setHsv(yh, ys, (int)(255*pow(0.7,yg/100.0)));
350         *pixel = c.rgb();
351         ++pixel;
352       }
353     }
354     m_pix = new QPixmap(QPixmap::fromImage(img));
355   }
356   QPainter p(this);
357   p.drawPixmap(1, coff, *m_pix);
358   const QPalette &g = palette();
359   qDrawShadePanel(&p, r, g, true);
360   p.setPen(g.foreground().color());
361   p.setBrush(g.foreground());
362   QPolygon a;
363   int y = m_mode==Hue ?        hue2y(m_hue) : 
364           m_mode==Saturation ? sat2y(m_sat) :
365                                gam2y(m_gam);
366   a.setPoints(3, w, y, w+5, y+5, w+5, y-5);
367   p.eraseRect(w, 0, 5, height());
368   p.drawPolygon(a);
369 }
370
371 void ColorPicker::mouseMoveEvent(QMouseEvent *m)
372 {
373   if      (m_mode==Hue)        setHue(y2hue(m->y())); 
374   else if (m_mode==Saturation) setSat(y2sat(m->y()));
375   else                         setGam(y2gam(m->y()));
376 }
377
378 void ColorPicker::mousePressEvent(QMouseEvent *m)
379 {
380   if      (m_mode==Hue)        setHue(y2hue(m->y())); 
381   else if (m_mode==Saturation) setSat(y2sat(m->y()));
382   else                         setGam(y2gam(m->y()));
383 }
384
385 void ColorPicker::setHue(int h)
386 {
387   if (h==m_hue) return;
388   m_hue = qMax(0,qMin(h,359));
389   delete m_pix; m_pix=0;
390   repaint();
391   emit newHsv(m_hue,m_sat,m_gam);
392 }
393
394 void ColorPicker::setSat(int s)
395 {
396   if (s==m_sat) return;
397   m_sat = qMax(0,qMin(s,255));
398   delete m_pix; m_pix=0;
399   repaint();
400   emit newHsv(m_hue,m_sat,m_gam);
401 }
402
403 void ColorPicker::setGam(int g)
404 {
405   if (g==m_gam) return;
406   m_gam = qMax(40,qMin(g,240));
407   delete m_pix; m_pix=0;
408   repaint();
409   emit newHsv(m_hue,m_sat,m_gam);
410 }
411
412 void ColorPicker::setCol(int h, int s, int g)
413 {
414   if (m_hue!=h || m_sat!=s || m_gam!=g)
415   {
416     m_hue = h;
417     m_sat = s;
418     m_gam = g;
419     delete m_pix; m_pix=0;
420     repaint();
421   }
422 }
423
424 int ColorPicker::y2hue(int y)
425 {
426   int d = height() - 2*coff - 1;
427   return m_mode==Hue ? (y - coff)*359/d : m_hue;
428 }
429
430 int ColorPicker::hue2y(int v)
431 {
432   int d = height() - 2*coff - 1;
433   return coff + v*d/359;
434 }
435
436 int ColorPicker::y2sat(int y)
437 {
438   int d = height() - 2*coff - 1;
439   return m_mode==Saturation ? 255 - (y - coff)*255/d : m_sat;
440 }
441
442 int ColorPicker::sat2y(int v)
443 {
444   int d = height() - 2*coff - 1;
445   return coff + (255-v)*d/255;
446 }
447
448 int ColorPicker::y2gam(int y)
449 {
450   int d = height() - 2*coff - 1;
451   return m_mode==Gamma ? 240 - (y - coff)*200/d : m_gam;
452 }
453
454 int ColorPicker::gam2y(int g)
455 {
456   int d = height() - 2*coff - 1;
457   return coff + (240-g)*d/200;
458 }
459
460 //==========================================================================
461
462 Step1::Step1(Wizard *wizard,const QHash<QString,Input*> &modelData) : m_wizard(wizard), m_modelData(modelData)
463 {
464   QVBoxLayout *layout = new QVBoxLayout(this);
465   layout->setMargin(4);
466   layout->setSpacing(8);
467   QLabel *l = new QLabel(this);
468   l->setText(tr("Provide some information "
469               "about the project you are documenting"));
470   layout->addWidget(l);
471   QWidget *w      = new QWidget( this );
472   QGridLayout *grid = new QGridLayout(w);
473   grid->setSpacing(10);
474
475   // project name
476   QLabel *projName = new QLabel(this);
477   projName->setText(tr("Project name:"));
478   projName->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
479   // project brief
480   QLabel *projBrief = new QLabel(this);
481   projBrief->setText(tr("Project synopsis:"));
482   projBrief->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
483   // project version
484   QLabel *projVersion = new QLabel(this);
485   projVersion->setText(tr("Project version or id:"));
486   projVersion->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
487   // project icon
488   QLabel *projLogo = new QLabel(this);
489   projLogo->setMinimumSize(1,55);
490   projLogo->setText(tr("Project logo:"));
491   projLogo->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
492
493   grid->addWidget(projName,0,0);
494   grid->addWidget(projBrief,1,0);
495   grid->addWidget(projVersion,2,0);
496   grid->addWidget(projLogo,3,0);
497
498   m_projName   = new QLineEdit;
499   m_projBrief  = new QLineEdit;
500   m_projNumber = new QLineEdit;
501   QPushButton *projIconSel = new QPushButton(this);
502   projIconSel->setText(tr("Select..."));
503   m_projIconLab = new QLabel;
504
505   grid->addWidget(m_projName,0,1,1,2);
506   grid->addWidget(m_projBrief,1,1,1,2);
507   grid->addWidget(m_projNumber,2,1,1,2);
508   grid->addWidget(projIconSel,3,1);
509   grid->addWidget(m_projIconLab,3,2);
510
511   grid->setColumnStretch(2,1);
512
513   w->setLayout(grid);
514
515   layout->addWidget(w);
516
517   //---------------------------------------------------
518   QFrame *f = new QFrame( this );
519   f->setFrameStyle( QFrame::HLine | QFrame::Sunken );
520   layout->addWidget(f);
521   
522   l = new QLabel(this);
523   l->setText(tr("Specify the directory to scan for source code"));
524   layout->addWidget(l);
525   QWidget *row = new QWidget;
526   QHBoxLayout *rowLayout = new QHBoxLayout(row);
527   rowLayout->setSpacing(10);
528   l = new QLabel(this);
529   l->setText(tr("Source code directory:"));
530   rowLayout->addWidget(l);
531   m_sourceDir = new QLineEdit;
532   m_srcSelectDir = new QPushButton(this);
533   m_srcSelectDir->setText(tr("Select..."));
534   rowLayout->addWidget(m_sourceDir);
535   rowLayout->addWidget(m_srcSelectDir);
536   layout->addWidget(row);
537
538   m_recursive = new QCheckBox(this);
539   m_recursive->setText(tr("Scan recursively"));
540   m_recursive->setChecked(true);
541   layout->addWidget(m_recursive);
542
543   //---------------------------------------------------
544   f = new QFrame( this );
545   f->setFrameStyle( QFrame::HLine | QFrame::Sunken );
546   layout->addWidget(f);
547
548   l = new QLabel(this);
549   l->setText(tr("Specify the directory where doxygen should "
550               "put the generated documentation"));
551   layout->addWidget(l);
552   row = new QWidget;
553   rowLayout = new QHBoxLayout(row);
554   rowLayout->setSpacing(10);
555   l = new QLabel(this);
556   l->setText(tr("Destination directory:"));
557   rowLayout->addWidget(l);
558   m_destDir = new QLineEdit;
559   m_dstSelectDir = new QPushButton(this);
560   m_dstSelectDir->setText(tr("Select..."));
561   rowLayout->addWidget(m_destDir);
562   rowLayout->addWidget(m_dstSelectDir);
563   layout->addWidget(row);
564   layout->addStretch(1);
565   setLayout(layout);
566
567   connect(projIconSel,SIGNAL(clicked()),
568           this,SLOT(selectProjectIcon()));
569   connect(m_srcSelectDir,SIGNAL(clicked()),
570           this,SLOT(selectSourceDir()));
571   connect(m_dstSelectDir,SIGNAL(clicked()),
572           this,SLOT(selectDestinationDir()));
573   connect(m_projName,SIGNAL(textChanged(const QString &)),SLOT(setProjectName(const QString &)));
574   connect(m_projBrief,SIGNAL(textChanged(const QString &)),SLOT(setProjectBrief(const QString &)));
575   connect(m_projNumber,SIGNAL(textChanged(const QString &)),SLOT(setProjectNumber(const QString &)));
576   connect(m_sourceDir,SIGNAL(textChanged(const QString &)),SLOT(setSourceDir(const QString &)));
577   connect(m_recursive,SIGNAL(stateChanged(int)),SLOT(setRecursiveScan(int)));
578   connect(m_destDir,SIGNAL(textChanged(const QString &)),SLOT(setDestinationDir(const QString &)));
579 }
580
581 void Step1::selectProjectIcon()
582 {
583   QString path = QFileInfo(MainWindow::instance().configFileName()).path();
584   QString iconName = QFileDialog::getOpenFileName(this,
585                                     tr("Select project icon/image"),path);
586   if (iconName.isEmpty())
587   {
588     m_projIconLab->setText(tr("No Project logo selected."));
589   }
590   else
591   {
592     QFile Fout(iconName);
593     if(!Fout.exists()) 
594     {
595       m_projIconLab->setText(tr("Sorry, cannot find file(")+iconName+QString::fromLatin1(");"));
596     }
597     else
598     {
599       QPixmap pm(iconName);
600       if (!pm.isNull())
601       {
602         m_projIconLab->setPixmap(pm.scaledToHeight(55,Qt::SmoothTransformation));
603       }
604       else
605       {
606         m_projIconLab->setText(tr("Sorry, no preview available (")+iconName+QString::fromLatin1(");"));
607       }
608     }
609   }
610   updateStringOption(m_modelData,STR_PROJECT_LOGO,iconName);
611 }
612
613 void Step1::selectSourceDir()
614 {
615   QString path = QFileInfo(MainWindow::instance().configFileName()).path();
616   QString dirName = QFileDialog::getExistingDirectory(this,
617         tr("Select source directory"),path);
618   QDir dir(path);
619   if (!MainWindow::instance().configFileName().isEmpty() && dir.exists())
620   {
621     dirName = dir.relativeFilePath(dirName);
622   }
623   if (dirName.isEmpty())
624   {
625     dirName=QString::fromLatin1(".");
626   }
627   m_sourceDir->setText(dirName);
628 }
629
630 void Step1::selectDestinationDir()
631 {
632   QString path = QFileInfo(MainWindow::instance().configFileName()).path();
633   QString dirName = QFileDialog::getExistingDirectory(this,
634         tr("Select destination directory"),path);
635   QDir dir(path);
636   if (!MainWindow::instance().configFileName().isEmpty() && dir.exists())
637   {
638     dirName = dir.relativeFilePath(dirName);
639   }
640   if (dirName.isEmpty())
641   {
642     dirName=QString::fromLatin1(".");
643   }
644   m_destDir->setText(dirName);
645 }
646
647 void Step1::setProjectName(const QString &name)
648 {
649   updateStringOption(m_modelData,STR_PROJECT_NAME,name);
650 }
651
652 void Step1::setProjectBrief(const QString &desc)
653 {
654   updateStringOption(m_modelData,STR_PROJECT_BRIEF,desc);
655 }
656
657 void Step1::setProjectNumber(const QString &num)
658 {
659   updateStringOption(m_modelData,STR_PROJECT_NUMBER,num);
660 }
661
662 void Step1::setSourceDir(const QString &dir)
663 {
664   Input *option = m_modelData[STR_INPUT];
665   if (option->value().toStringList().count()>0)
666   {
667     QStringList sl = option->value().toStringList();
668     if (sl[0]!=dir)
669     {
670       sl[0] = dir;
671       option->value() = sl;
672       option->update();
673     }
674   }
675   else
676   {
677     option->value() = QStringList() << dir;
678     option->update();
679   }
680 }
681
682 void Step1::setDestinationDir(const QString &dir)
683 {
684   updateStringOption(m_modelData,STR_OUTPUT_DIRECTORY,dir);
685 }
686
687 void Step1::setRecursiveScan(int s)
688 {
689   updateBoolOption(m_modelData,STR_RECURSIVE,s==Qt::Checked);
690 }
691
692 void Step1::init()
693 {
694   Input *option;
695   m_projName->setText(getStringOption(m_modelData,STR_PROJECT_NAME));
696   m_projBrief->setText(getStringOption(m_modelData,STR_PROJECT_BRIEF));
697   m_projNumber->setText(getStringOption(m_modelData,STR_PROJECT_NUMBER));
698   QString iconName = getStringOption(m_modelData,STR_PROJECT_LOGO);
699   if (!iconName.isEmpty())
700   {
701     QFile Fout(iconName);
702     if(!Fout.exists()) 
703     {
704       m_projIconLab->setText(tr("Sorry, cannot find file(")+iconName+QString::fromLatin1(");"));
705     }
706     else
707     {
708       QPixmap pm(iconName);
709       if (!pm.isNull())
710       {
711         m_projIconLab->setPixmap(pm.scaledToHeight(55,Qt::SmoothTransformation));
712       }
713       else
714       {
715         m_projIconLab->setText(tr("Sorry, no preview available (")+iconName+QString::fromLatin1(");"));
716       }
717     }
718   }
719   else
720   {
721     m_projIconLab->setText(tr("No Project logo selected."));
722   }
723   option = m_modelData[STR_INPUT];
724   if (option->value().toStringList().count()>0)
725   {
726     m_sourceDir->setText(option->value().toStringList().first());
727   }
728   m_recursive->setChecked(
729       getBoolOption(m_modelData,STR_RECURSIVE) ? Qt::Checked : Qt::Unchecked);
730   m_destDir->setText(getStringOption(m_modelData,STR_OUTPUT_DIRECTORY));
731 }
732
733
734 //==========================================================================
735
736 Step2::Step2(Wizard *wizard,const QHash<QString,Input*> &modelData) 
737   : m_wizard(wizard), m_modelData(modelData)
738 {
739   QRadioButton *r;
740   QVBoxLayout *layout = new QVBoxLayout(this);
741
742   //---------------------------------------------------
743   m_extractModeGroup = new QButtonGroup(this);
744   m_extractMode = new QGroupBox(this);
745   m_extractMode->setTitle(tr("Select the desired extraction mode:"));
746   QGridLayout *gbox = new QGridLayout( m_extractMode );
747   r = new QRadioButton(tr("Documented entities only"));
748   r->setChecked(true);
749   m_extractModeGroup->addButton(r, 0);
750   gbox->addWidget(r,1,0);
751   // 1 -> EXTRACT_ALL = NO
752   r = new QRadioButton(tr("All Entities"));
753   m_extractModeGroup->addButton(r, 1);
754   gbox->addWidget(r,2,0);
755   // 2 -> EXTRACT_ALL = YES
756   m_crossRef = new QCheckBox(m_extractMode);
757   m_crossRef->setText(tr("Include cross-referenced source code in the output"));
758   // m_crossRef -> SOURCE_BROWSER = YES/NO
759   gbox->addWidget(m_crossRef,3,0);
760   layout->addWidget(m_extractMode);
761   
762   //---------------------------------------------------
763   QFrame *f = new QFrame( this );
764   f->setFrameStyle( QFrame::HLine | QFrame::Sunken );
765   layout->addWidget(f);
766
767   m_optimizeLangGroup = new QButtonGroup(this);
768   m_optimizeLang = new QGroupBox(this);
769   m_optimizeLang->setTitle(tr("Select programming language to optimize the results for"));
770   gbox = new QGridLayout( m_optimizeLang ); 
771   
772   r = new QRadioButton(m_optimizeLang);
773   r->setText(tr("Optimize for C++ output"));
774   r->setChecked(true);
775   m_optimizeLangGroup->addButton(r, 0);
776   // 0 -> OPTIMIZE_OUTPUT_FOR_C = NO
777   //      OPTIMIZE_OUTPUT_JAVA  = NO
778   //      OPTIMIZE_FOR_FORTRAN  = NO
779   //      OPTIMIZE_OUTPUT_VHDL  = NO
780   //      CPP_CLI_SUPPORT       = NO
781   //      HIDE_SCOPE_NAMES      = NO
782   gbox->addWidget(r,0,0);
783   r = new QRadioButton(tr("Optimize for C++/CLI output"));
784   gbox->addWidget(r,1,0);
785   m_optimizeLangGroup->addButton(r, 1);
786   // 1 -> OPTIMIZE_OUTPUT_FOR_C = NO
787   //      OPTIMIZE_OUTPUT_JAVA  = NO
788   //      OPTIMIZE_FOR_FORTRAN  = NO
789   //      OPTIMIZE_OUTPUT_VHDL  = NO
790   //      CPP_CLI_SUPPORT       = YES
791   //      HIDE_SCOPE_NAMES      = NO
792   r = new QRadioButton(tr("Optimize for Java or C# output"));
793   m_optimizeLangGroup->addButton(r, 2);
794   // 2 -> OPTIMIZE_OUTPUT_FOR_C = NO
795   //      OPTIMIZE_OUTPUT_JAVA  = YES
796   //      OPTIMIZE_FOR_FORTRAN  = NO
797   //      OPTIMIZE_OUTPUT_VHDL  = NO
798   //      CPP_CLI_SUPPORT       = NO
799   //      HIDE_SCOPE_NAMES      = NO
800   gbox->addWidget(r,2,0);
801   r = new QRadioButton(tr("Optimize for C or PHP output"));
802   m_optimizeLangGroup->addButton(r, 3);
803   // 3 -> OPTIMIZE_OUTPUT_FOR_C = YES
804   //      OPTIMIZE_OUTPUT_JAVA  = NO
805   //      OPTIMIZE_FOR_FORTRAN  = NO
806   //      OPTIMIZE_OUTPUT_VHDL  = NO
807   //      CPP_CLI_SUPPORT       = NO
808   //      HIDE_SCOPE_NAMES      = YES
809   gbox->addWidget(r,3,0);
810   r = new QRadioButton(tr("Optimize for Fortran output"));
811   m_optimizeLangGroup->addButton(r, 4);
812   // 4 -> OPTIMIZE_OUTPUT_FOR_C = NO
813   //      OPTIMIZE_OUTPUT_JAVA  = NO
814   //      OPTIMIZE_FOR_FORTRAN  = YES
815   //      OPTIMIZE_OUTPUT_VHDL  = NO
816   //      CPP_CLI_SUPPORT       = NO
817   //      HIDE_SCOPE_NAMES      = NO
818   gbox->addWidget(r,4,0);
819   r = new QRadioButton(tr("Optimize for VHDL output"));
820   m_optimizeLangGroup->addButton(r, 5);
821   // 5 -> OPTIMIZE_OUTPUT_FOR_C = NO
822   //      OPTIMIZE_OUTPUT_JAVA  = NO
823   //      OPTIMIZE_FOR_FORTRAN  = NO
824   //      OPTIMIZE_OUTPUT_VHDL  = YES
825   //      CPP_CLI_SUPPORT       = NO
826   //      HIDE_SCOPE_NAMES      = NO
827   gbox->addWidget(r,5,0);
828
829   layout->addWidget(m_optimizeLang);
830   layout->addStretch(1);
831
832   connect(m_crossRef,SIGNAL(stateChanged(int)),
833           SLOT(changeCrossRefState(int)));
834   connect(m_optimizeLangGroup,SIGNAL(buttonClicked(int)),
835           SLOT(optimizeFor(int)));
836   connect(m_extractModeGroup,SIGNAL(buttonClicked(int)),
837           SLOT(extractMode(int)));
838 }
839
840
841 void Step2::optimizeFor(int choice)
842 {
843   for (int i=0;i<6;i++)
844   {
845     updateBoolOption(m_modelData,
846                      g_optimizeOptionNames[i],
847                      g_optimizeMapping[choice][i]);
848   }
849 }
850
851 void Step2::extractMode(int choice)
852 {
853   updateBoolOption(m_modelData,STR_EXTRACT_ALL,choice==1);
854 }
855
856 void Step2::changeCrossRefState(int choice)
857 {
858   updateBoolOption(m_modelData,STR_SOURCE_BROWSER,choice==Qt::Checked);
859 }
860
861 void Step2::init()
862 {
863   m_extractModeGroup->button(
864       getBoolOption(m_modelData,STR_EXTRACT_ALL) ? 1 : 0)->setChecked(true);
865   m_crossRef->setChecked(getBoolOption(m_modelData,STR_SOURCE_BROWSER));
866
867   int x=0;
868   if (getBoolOption(m_modelData,STR_CPP_CLI_SUPPORT))            x=1;
869   else if (getBoolOption(m_modelData,STR_OPTIMIZE_OUTPUT_JAVA))  x=2;
870   else if (getBoolOption(m_modelData,STR_OPTIMIZE_OUTPUT_FOR_C)) x=3;
871   else if (getBoolOption(m_modelData,STR_OPTIMIZE_FOR_FORTRAN))  x=4;
872   else if (getBoolOption(m_modelData,STR_OPTIMIZE_OUTPUT_VHDL))  x=5;
873   m_optimizeLangGroup->button(x)->setChecked(true);
874 }
875
876 //==========================================================================
877
878 Step3::Step3(Wizard *wizard,const QHash<QString,Input*> &modelData) 
879   : m_wizard(wizard), m_modelData(modelData)
880 {
881   QVBoxLayout *vbox = 0;
882   QRadioButton *r   = 0;
883
884   QGridLayout *gbox = new QGridLayout( this );
885   gbox->addWidget(new QLabel(tr("Select the output format(s) to generate")),0,0);
886   {
887     m_htmlOptions = new QGroupBox(tr("HTML"));
888     m_htmlOptions->setCheckable(true);
889     // GENERATE_HTML
890     m_htmlOptionsGroup = new QButtonGroup(m_htmlOptions);
891     QRadioButton *r = new QRadioButton(tr("plain HTML"));
892     r->setChecked(true);
893     m_htmlOptionsGroup->addButton(r, 0);
894     vbox = new QVBoxLayout;
895     vbox->addWidget(r);
896     r = new QRadioButton(tr("with navigation panel"));
897     m_htmlOptionsGroup->addButton(r, 1);
898     // GENERATE_TREEVIEW
899     vbox->addWidget(r);
900     r = new QRadioButton(tr("prepare for compressed HTML (.chm)"));
901     m_htmlOptionsGroup->addButton(r, 2);
902     // GENERATE_HTMLHELP
903     vbox->addWidget(r);
904     m_searchEnabled=new QCheckBox(tr("With search function"));
905     vbox->addWidget(m_searchEnabled);
906     // SEARCH_ENGINE
907     QHBoxLayout *hbox = new QHBoxLayout;
908     m_tuneColor=new QPushButton(tr("Change color..."));
909     hbox->addWidget(m_tuneColor);
910     hbox->addStretch(1);
911     vbox->addLayout(hbox);
912     m_htmlOptions->setLayout(vbox);
913     m_htmlOptions->setChecked(true);
914   }
915   gbox->addWidget(m_htmlOptions,1,0);
916
917   {
918     m_texOptions = new QGroupBox(tr("LaTeX"));
919     m_texOptions->setCheckable(true);
920     // GENERATE_LATEX
921     m_texOptionsGroup = new QButtonGroup(m_texOptions);
922     vbox = new QVBoxLayout;
923     r = new QRadioButton(tr("as intermediate format for hyperlinked PDF"));
924     m_texOptionsGroup->addButton(r, 0);
925     // PDF_HYPERLINKS = YES
926     r->setChecked(true);
927     vbox->addWidget(r);
928     r = new QRadioButton(tr("as intermediate format for PDF"));
929     m_texOptionsGroup->addButton(r, 1);
930     // PDF_HYPERLINKS = NO, USE_PDFLATEX = YES
931     vbox->addWidget(r);
932     r = new QRadioButton(tr("as intermediate format for PostScript"));
933     m_texOptionsGroup->addButton(r, 2);
934     // USE_PDFLATEX = NO
935     vbox->addWidget(r);
936     vbox->addStretch(1);
937     m_texOptions->setLayout(vbox);
938     m_texOptions->setChecked(true);
939   }
940   gbox->addWidget(m_texOptions,2,0);
941
942   m_manEnabled=new QCheckBox(tr("Man pages"));
943   // GENERATE_MAN
944   m_rtfEnabled=new QCheckBox(tr("Rich Text Format (RTF)"));
945   // GENERATE_RTF
946   m_xmlEnabled=new QCheckBox(tr("XML"));
947   // GENERATE_XML
948   gbox->addWidget(m_manEnabled,3,0);
949   gbox->addWidget(m_rtfEnabled,4,0);
950   gbox->addWidget(m_xmlEnabled,5,0);
951
952   gbox->setRowStretch(6,1);
953   connect(m_htmlOptions,SIGNAL(toggled(bool)),SLOT(setHtmlEnabled(bool)));
954   connect(m_texOptions,SIGNAL(toggled(bool)),SLOT(setLatexEnabled(bool)));
955   connect(m_manEnabled,SIGNAL(stateChanged(int)),SLOT(setManEnabled(int)));
956   connect(m_rtfEnabled,SIGNAL(stateChanged(int)),SLOT(setRtfEnabled(int)));
957   connect(m_xmlEnabled,SIGNAL(stateChanged(int)),SLOT(setXmlEnabled(int)));
958   connect(m_searchEnabled,SIGNAL(stateChanged(int)),SLOT(setSearchEnabled(int)));
959   connect(m_htmlOptionsGroup,SIGNAL(buttonClicked(int)),
960           SLOT(setHtmlOptions(int)));
961   connect(m_texOptionsGroup,SIGNAL(buttonClicked(int)),
962           SLOT(setLatexOptions(int)));
963   connect(m_tuneColor,SIGNAL(clicked()),SLOT(tuneColorDialog()));
964 }
965
966 void Step3::tuneColorDialog()
967 {
968   int hue = getIntOption(m_modelData,STR_HTML_COLORSTYLE_HUE);
969   int sat = getIntOption(m_modelData,STR_HTML_COLORSTYLE_SAT);
970   int gam = getIntOption(m_modelData,STR_HTML_COLORSTYLE_GAMMA);
971   TuneColorDialog tuneColor(hue,sat,gam,this);
972   if (tuneColor.exec()==QDialog::Accepted)
973   {
974     updateIntOption(m_modelData,STR_HTML_COLORSTYLE_HUE,tuneColor.getHue());
975     updateIntOption(m_modelData,STR_HTML_COLORSTYLE_SAT,tuneColor.getSaturation());
976     updateIntOption(m_modelData,STR_HTML_COLORSTYLE_GAMMA,tuneColor.getGamma());
977   }
978 }
979
980 void Step3::setHtmlEnabled(bool b)
981 {
982   updateBoolOption(m_modelData,STR_GENERATE_HTML,b);
983 }
984
985 void Step3::setLatexEnabled(bool b)
986 {
987   updateBoolOption(m_modelData,STR_GENERATE_LATEX,b);
988 }
989
990 void Step3::setManEnabled(int state)
991 {
992   updateBoolOption(m_modelData,STR_GENERATE_MAN,state==Qt::Checked);
993 }
994
995 void Step3::setRtfEnabled(int state)
996 {
997   updateBoolOption(m_modelData,STR_GENERATE_RTF,state==Qt::Checked);
998 }
999
1000 void Step3::setXmlEnabled(int state)
1001 {
1002   updateBoolOption(m_modelData,STR_GENERATE_XML,state==Qt::Checked);
1003 }
1004
1005 void Step3::setSearchEnabled(int state)
1006 {
1007   updateBoolOption(m_modelData,STR_SEARCHENGINE,state==Qt::Checked);
1008 }
1009
1010 void Step3::setHtmlOptions(int id)
1011 {
1012   if (id==0) // plain HTML
1013   {
1014     updateBoolOption(m_modelData,STR_GENERATE_HTMLHELP,false);
1015     updateBoolOption(m_modelData,STR_GENERATE_TREEVIEW,false);
1016   }
1017   else if (id==1) // with navigation tree
1018   {
1019     updateBoolOption(m_modelData,STR_GENERATE_HTMLHELP,false);
1020     updateBoolOption(m_modelData,STR_GENERATE_TREEVIEW,true);
1021   }
1022   else if (id==2) // with compiled help
1023   {
1024     updateBoolOption(m_modelData,STR_GENERATE_HTMLHELP,true);
1025     updateBoolOption(m_modelData,STR_GENERATE_TREEVIEW,false);
1026   }
1027 }
1028
1029 void Step3::setLatexOptions(int id)
1030 {
1031   if (id==0) // hyperlinked PDF
1032   {
1033     updateBoolOption(m_modelData,STR_USE_PDFLATEX,true);
1034     updateBoolOption(m_modelData,STR_PDF_HYPERLINKS,true);
1035   }
1036   else if (id==1) // PDF
1037   {
1038     updateBoolOption(m_modelData,STR_USE_PDFLATEX,true);
1039     updateBoolOption(m_modelData,STR_PDF_HYPERLINKS,false);
1040   }
1041   else if (id==2) // PostScript
1042   {
1043     updateBoolOption(m_modelData,STR_USE_PDFLATEX,false);
1044     updateBoolOption(m_modelData,STR_PDF_HYPERLINKS,false);
1045   }
1046 }
1047
1048 void Step3::init()
1049 {
1050   m_htmlOptions->setChecked(getBoolOption(m_modelData,STR_GENERATE_HTML));
1051   m_texOptions->setChecked(getBoolOption(m_modelData,STR_GENERATE_LATEX));
1052   m_manEnabled->setChecked(getBoolOption(m_modelData,STR_GENERATE_MAN));
1053   m_rtfEnabled->setChecked(getBoolOption(m_modelData,STR_GENERATE_RTF));
1054   m_xmlEnabled->setChecked(getBoolOption(m_modelData,STR_GENERATE_XML));
1055   m_searchEnabled->setChecked(getBoolOption(m_modelData,STR_SEARCHENGINE));
1056   if (getBoolOption(m_modelData,STR_GENERATE_HTMLHELP))
1057   {
1058     m_htmlOptionsGroup->button(2)->setChecked(true); // compiled help
1059   }
1060   else if (getBoolOption(m_modelData,STR_GENERATE_TREEVIEW))
1061   {
1062     m_htmlOptionsGroup->button(1)->setChecked(true); // navigation tree
1063   }
1064   else
1065   {
1066     m_htmlOptionsGroup->button(0)->setChecked(true); // plain HTML
1067   }
1068   if (!getBoolOption(m_modelData,STR_USE_PDFLATEX))
1069   {
1070     m_texOptionsGroup->button(2)->setChecked(true); // PostScript
1071   }
1072   else if (!getBoolOption(m_modelData,STR_PDF_HYPERLINKS))
1073   {
1074     m_texOptionsGroup->button(1)->setChecked(true); // Plain PDF
1075   }
1076   else
1077   {
1078     m_texOptionsGroup->button(0)->setChecked(true); // PDF with hyperlinks
1079   }
1080 }
1081
1082 //==========================================================================
1083
1084 Step4::Step4(Wizard *wizard,const QHash<QString,Input*> &modelData) 
1085   : m_wizard(wizard), m_modelData(modelData)
1086 {
1087   m_diagramModeGroup = new QButtonGroup(this);
1088   QGridLayout *gbox = new QGridLayout( this );
1089   gbox->addWidget(new QLabel(tr("Diagrams to generate")),0,0);
1090
1091   QRadioButton *rb = new QRadioButton(tr("No diagrams"));
1092   m_diagramModeGroup->addButton(rb, 0);
1093   gbox->addWidget(rb,1,0);
1094   // CLASS_DIAGRAMS = NO, HAVE_DOT = NO
1095   rb->setChecked(true);
1096   rb = new QRadioButton(tr("Use built-in class diagram generator"));
1097   m_diagramModeGroup->addButton(rb, 1);
1098   // CLASS_DIAGRAMS = YES, HAVE_DOT = NO
1099   gbox->addWidget(rb,2,0);
1100   rb = new QRadioButton(tr("Use dot tool from the GraphViz package"));
1101   m_diagramModeGroup->addButton(rb, 2);
1102   gbox->addWidget(rb,3,0);
1103   // CLASS_DIAGRAMS = NO, HAVE_DOT = YES
1104
1105   m_dotGroup = new QGroupBox(tr("Dot graphs to generate"));
1106     QVBoxLayout *vbox = new QVBoxLayout;
1107     m_dotClass=new QCheckBox(tr("Class diagrams"));
1108     // CLASS_GRAPH
1109     m_dotCollaboration=new QCheckBox(tr("Collaboration diagrams"));
1110     // COLLABORATION_GRAPH
1111     m_dotInheritance=new QCheckBox(tr("Overall Class hierarchy"));
1112     // GRAPHICAL_HIERARCHY
1113     m_dotInclude=new QCheckBox(tr("Include dependency graphs"));
1114     // INCLUDE_GRAPH
1115     m_dotIncludedBy=new QCheckBox(tr("Included by dependency graphs"));
1116     // INCLUDED_BY_GRAPH
1117     m_dotCall=new QCheckBox(tr("Call graphs"));
1118     // CALL_GRAPH
1119     m_dotCaller=new QCheckBox(tr("Called by graphs"));
1120     // CALLER_GRAPH
1121     vbox->addWidget(m_dotClass);
1122     vbox->addWidget(m_dotCollaboration);
1123     vbox->addWidget(m_dotInheritance);
1124     vbox->addWidget(m_dotInclude);
1125     vbox->addWidget(m_dotIncludedBy);
1126     vbox->addWidget(m_dotCall);
1127     vbox->addWidget(m_dotCaller);
1128     vbox->addStretch(1);
1129     m_dotGroup->setLayout(vbox);
1130     m_dotClass->setChecked(true);
1131     m_dotGroup->setEnabled(false);
1132   gbox->addWidget(m_dotGroup,4,0);
1133
1134   m_dotInclude->setChecked(true);
1135   m_dotCollaboration->setChecked(true);
1136   gbox->setRowStretch(5,1);
1137
1138   connect(m_diagramModeGroup,SIGNAL(buttonClicked(int)),
1139           this,SLOT(diagramModeChanged(int)));
1140   connect(m_dotClass,SIGNAL(stateChanged(int)),
1141           this,SLOT(setClassGraphEnabled(int)));
1142   connect(m_dotCollaboration,SIGNAL(stateChanged(int)),
1143           this,SLOT(setCollaborationGraphEnabled(int)));
1144   connect(m_dotInheritance,SIGNAL(stateChanged(int)),
1145           this,SLOT(setGraphicalHierarchyEnabled(int)));
1146   connect(m_dotInclude,SIGNAL(stateChanged(int)),
1147           this,SLOT(setIncludeGraphEnabled(int)));
1148   connect(m_dotIncludedBy,SIGNAL(stateChanged(int)),
1149           this,SLOT(setIncludedByGraphEnabled(int)));
1150   connect(m_dotCall,SIGNAL(stateChanged(int)),
1151           this,SLOT(setCallGraphEnabled(int)));
1152   connect(m_dotCaller,SIGNAL(stateChanged(int)),
1153           this,SLOT(setCallerGraphEnabled(int)));
1154 }
1155
1156 void Step4::diagramModeChanged(int id)
1157 {
1158   if (id==0) // no diagrams
1159   {
1160     updateBoolOption(m_modelData,STR_HAVE_DOT,false);
1161     updateBoolOption(m_modelData,STR_CLASS_DIAGRAMS,false);
1162   }
1163   else if (id==1) // builtin diagrams
1164   {
1165     updateBoolOption(m_modelData,STR_HAVE_DOT,false);
1166     updateBoolOption(m_modelData,STR_CLASS_DIAGRAMS,true);
1167   }
1168   else if (id==2) // dot diagrams
1169   {
1170     updateBoolOption(m_modelData,STR_HAVE_DOT,true);
1171     updateBoolOption(m_modelData,STR_CLASS_DIAGRAMS,false);
1172   }
1173   m_dotGroup->setEnabled(id==2);
1174 }
1175
1176 void Step4::setClassGraphEnabled(int state)
1177 {
1178   updateBoolOption(m_modelData,STR_CLASS_GRAPH,state==Qt::Checked);
1179 }
1180
1181 void Step4::setCollaborationGraphEnabled(int state)
1182 {
1183   updateBoolOption(m_modelData,STR_COLLABORATION_GRAPH,state==Qt::Checked);
1184 }
1185
1186 void Step4::setGraphicalHierarchyEnabled(int state)
1187 {
1188   updateBoolOption(m_modelData,STR_GRAPHICAL_HIERARCHY,state==Qt::Checked);
1189 }
1190
1191 void Step4::setIncludeGraphEnabled(int state)
1192 {
1193   updateBoolOption(m_modelData,STR_INCLUDE_GRAPH,state==Qt::Checked);
1194 }
1195
1196 void Step4::setIncludedByGraphEnabled(int state)
1197 {
1198   updateBoolOption(m_modelData,STR_INCLUDED_BY_GRAPH,state==Qt::Checked);
1199 }
1200
1201 void Step4::setCallGraphEnabled(int state)
1202 {
1203   updateBoolOption(m_modelData,STR_CALL_GRAPH,state==Qt::Checked);
1204 }
1205
1206 void Step4::setCallerGraphEnabled(int state)
1207 {
1208   updateBoolOption(m_modelData,STR_CALLER_GRAPH,state==Qt::Checked);
1209 }
1210
1211 void Step4::init()
1212 {
1213   if (getBoolOption(m_modelData,STR_HAVE_DOT))
1214   {
1215     m_diagramModeGroup->button(2)->setChecked(true); // Dot
1216   }
1217   else if (getBoolOption(m_modelData,STR_CLASS_DIAGRAMS))
1218   {
1219     m_diagramModeGroup->button(1)->setChecked(true); // Builtin diagrams
1220   }
1221   else
1222   {
1223     m_diagramModeGroup->button(0)->setChecked(true); // no diagrams
1224   }
1225   m_dotClass->setChecked(getBoolOption(m_modelData,STR_CLASS_GRAPH));
1226   m_dotCollaboration->setChecked(getBoolOption(m_modelData,STR_COLLABORATION_GRAPH));
1227   m_dotInheritance->setChecked(getBoolOption(m_modelData,STR_GRAPHICAL_HIERARCHY));
1228   m_dotInclude->setChecked(getBoolOption(m_modelData,STR_INCLUDE_GRAPH));
1229   m_dotIncludedBy->setChecked(getBoolOption(m_modelData,STR_INCLUDED_BY_GRAPH));
1230   m_dotCall->setChecked(getBoolOption(m_modelData,STR_CALL_GRAPH));
1231   m_dotCaller->setChecked(getBoolOption(m_modelData,STR_CALLER_GRAPH));
1232 }
1233
1234 //==========================================================================
1235
1236 Wizard::Wizard(const QHash<QString,Input*> &modelData, QWidget *parent) : 
1237   QSplitter(parent), m_modelData(modelData)
1238 {
1239   m_treeWidget = new QTreeWidget;
1240   m_treeWidget->setColumnCount(1);
1241   m_treeWidget->setHeaderLabels(QStringList() << QString::fromLatin1("Topics"));
1242   QList<QTreeWidgetItem*> items;
1243   items.append(new QTreeWidgetItem((QTreeWidget*)0,QStringList(tr("Project"))));
1244   items.append(new QTreeWidgetItem((QTreeWidget*)0,QStringList(tr("Mode"))));
1245   items.append(new QTreeWidgetItem((QTreeWidget*)0,QStringList(tr("Output"))));
1246   items.append(new QTreeWidgetItem((QTreeWidget*)0,QStringList(tr("Diagrams"))));
1247   m_treeWidget->insertTopLevelItems(0,items);
1248
1249   m_topicStack = new QStackedWidget;
1250   m_step1 = new Step1(this,modelData);
1251   m_step2 = new Step2(this,modelData);
1252   m_step3 = new Step3(this,modelData);
1253   m_step4 = new Step4(this,modelData);
1254   m_topicStack->addWidget(m_step1);
1255   m_topicStack->addWidget(m_step2);
1256   m_topicStack->addWidget(m_step3);
1257   m_topicStack->addWidget(m_step4);
1258
1259   QWidget *rightSide = new QWidget;
1260   QGridLayout *grid = new QGridLayout(rightSide);
1261   m_prev = new QPushButton(tr("Previous"));
1262   m_prev->setEnabled(false);
1263   m_next = new QPushButton(tr("Next"));
1264   grid->addWidget(m_topicStack,0,0,1,2);
1265   grid->addWidget(m_prev,1,0,Qt::AlignLeft);
1266   grid->addWidget(m_next,1,1,Qt::AlignRight);
1267   grid->setColumnStretch(0,1);
1268   grid->setRowStretch(0,1);
1269   addWidget(m_treeWidget);
1270   addWidget(rightSide);
1271
1272   connect(m_treeWidget,
1273           SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),
1274           SLOT(activateTopic(QTreeWidgetItem *,QTreeWidgetItem *)));
1275   connect(m_next,SIGNAL(clicked()),SLOT(nextTopic()));
1276   connect(m_prev,SIGNAL(clicked()),SLOT(prevTopic()));
1277
1278   refresh();
1279 }
1280
1281 Wizard::~Wizard()
1282 {
1283 }
1284
1285 void Wizard::activateTopic(QTreeWidgetItem *item,QTreeWidgetItem *)
1286 {
1287   if (item)
1288   {
1289     
1290     QString label = item->text(0);
1291     if (label==tr("Project"))
1292     {
1293       m_topicStack->setCurrentWidget(m_step1);
1294       m_prev->setEnabled(false);
1295       m_next->setEnabled(true);
1296     }
1297     else if (label==tr("Mode"))
1298     {
1299       m_topicStack->setCurrentWidget(m_step2);
1300       m_prev->setEnabled(true);
1301       m_next->setEnabled(true);
1302     }
1303     else if (label==tr("Output"))
1304     {
1305       m_topicStack->setCurrentWidget(m_step3);
1306       m_prev->setEnabled(true);
1307       m_next->setEnabled(true);
1308     }
1309     else if (label==tr("Diagrams"))
1310     {
1311       m_topicStack->setCurrentWidget(m_step4);
1312       m_prev->setEnabled(true);
1313       m_next->setEnabled(true);
1314     }
1315   }
1316 }
1317
1318 void Wizard::nextTopic()
1319 {
1320   if (m_topicStack->currentIndex()+1==m_topicStack->count()) // last topic
1321   {
1322     done();
1323   }
1324   else
1325   {
1326     m_topicStack->setCurrentIndex(m_topicStack->currentIndex()+1);
1327     m_next->setEnabled(m_topicStack->count()!=m_topicStack->currentIndex()+1);
1328     m_prev->setEnabled(m_topicStack->currentIndex()!=0);
1329     m_treeWidget->setCurrentItem(m_treeWidget->invisibleRootItem()->child(m_topicStack->currentIndex()));
1330   }
1331 }
1332
1333 void Wizard::prevTopic()
1334 {
1335   m_topicStack->setCurrentIndex(m_topicStack->currentIndex()-1);
1336   m_next->setEnabled(m_topicStack->count()!=m_topicStack->currentIndex()+1);
1337   m_prev->setEnabled(m_topicStack->currentIndex()!=0);
1338   m_treeWidget->setCurrentItem(m_treeWidget->invisibleRootItem()->child(m_topicStack->currentIndex()));
1339 }
1340
1341 void Wizard::refresh()
1342 {
1343   m_treeWidget->setCurrentItem(m_treeWidget->invisibleRootItem()->child(0));
1344   m_step1->init();
1345   m_step2->init();
1346   m_step3->init();
1347   m_step4->init();
1348 }