Chameleon

Chameleon Svn Source Tree

Root/branches/xZenu/src/util/doxygen/addon/doxywizard/expert.cpp

Source at commit 1406 created 12 years 10 months ago.
By meklort, Revert drivers.c so that kexts are only loaded when OSBundleRequired is set and that value is not safe mode. Added some comments about it too.
1#include "expert.h"
2#include "inputbool.h"
3#include "inputstring.h"
4#include "inputint.h"
5#include "inputstring.h"
6#include "inputstrlist.h"
7#include <QtGui>
8#include <QtXml>
9#include "config.h"
10#include "version.h"
11
12#undef SA
13#define SA(x) QString::fromAscii(x)
14
15static QString convertToComment(const QString &s)
16{
17 if (s.isEmpty())
18 {
19 return QString();
20 }
21 else
22 {
23 return SA("# ")+
24 s.trimmed().replace(SA("\n"),SA("\n# "))+
25 SA("\n");
26 }
27}
28
29//------------------------------------------------------------------------------------
30
31Expert::Expert()
32{
33 m_treeWidget = new QTreeWidget;
34 m_treeWidget->setColumnCount(1);
35 m_topicStack = new QStackedWidget;
36 m_inShowHelp = FALSE;
37
38 QFile file(SA(":/config.xml"));
39 QString err;
40 int errLine,errCol;
41 QDomDocument configXml;
42 if (file.open(QIODevice::ReadOnly))
43 {
44 if (!configXml.setContent(&file,false,&err,&errLine,&errCol))
45 {
46 QString msg = tr("Error parsing internal config.xml at line %1 column %2.\n%3").
47 arg(errLine).arg(errCol).arg(err);
48 QMessageBox::warning(this, tr("Error"), msg);
49 exit(1);
50 }
51 }
52 m_rootElement = configXml.documentElement();
53
54 createTopics(m_rootElement);
55 m_helper = new QTextEdit;
56 m_helper->setReadOnly(true);
57 m_splitter = new QSplitter(Qt::Vertical);
58 m_splitter->addWidget(m_treeWidget);
59 m_splitter->addWidget(m_helper);
60
61 QWidget *rightSide = new QWidget;
62 QGridLayout *grid = new QGridLayout(rightSide);
63 m_prev = new QPushButton(tr("Previous"));
64 m_prev->setEnabled(false);
65 m_next = new QPushButton(tr("Next"));
66 grid->addWidget(m_topicStack,0,0,1,2);
67 grid->addWidget(m_prev,1,0,Qt::AlignLeft);
68 grid->addWidget(m_next,1,1,Qt::AlignRight);
69 grid->setColumnStretch(0,1);
70 grid->setRowStretch(0,1);
71
72 addWidget(m_splitter);
73 addWidget(rightSide);
74 connect(m_next,SIGNAL(clicked()),SLOT(nextTopic()));
75
76 connect(m_prev,SIGNAL(clicked()),SLOT(prevTopic()));
77}
78
79Expert::~Expert()
80{
81 QHashIterator<QString,Input*> i(m_options);
82 while (i.hasNext())
83 {
84 i.next();
85 delete i.value();
86 }
87}
88
89void Expert::createTopics(const QDomElement &rootElem)
90{
91 QList<QTreeWidgetItem*> items;
92 QDomElement childElem = rootElem.firstChildElement();
93 while (!childElem.isNull())
94 {
95 if (childElem.tagName()==SA("group"))
96 {
97 QString name = childElem.attribute(SA("name"));
98 items.append(new QTreeWidgetItem((QTreeWidget*)0,QStringList(name)));
99 QWidget *widget = createTopicWidget(childElem);
100 m_topics[name] = widget;
101 m_topicStack->addWidget(widget);
102 }
103 childElem = childElem.nextSiblingElement();
104 }
105 m_treeWidget->setHeaderLabels(QStringList() << SA("Topics"));
106 m_treeWidget->insertTopLevelItems(0,items);
107 connect(m_treeWidget,
108 SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),
109 this,
110 SLOT(activateTopic(QTreeWidgetItem *,QTreeWidgetItem *)));
111}
112
113
114QWidget *Expert::createTopicWidget(QDomElement &elem)
115{
116 QScrollArea *area = new QScrollArea;
117 QWidget *topic = new QWidget;
118 QGridLayout *layout = new QGridLayout(topic);
119 QDomElement child = elem.firstChildElement();
120 int row=0;
121 while (!child.isNull())
122 {
123 QString type = child.attribute(SA("type"));
124 if (type==SA("bool"))
125 {
126 InputBool *boolOption =
127 new InputBool(
128 layout,row,
129 child.attribute(SA("id")),
130 child.attribute(SA("defval"))==SA("1"),
131 child.attribute(SA("docs"))
132 );
133 m_options.insert(
134 child.attribute(SA("id")),
135 boolOption
136 );
137 connect(boolOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
138 connect(boolOption,SIGNAL(changed()),SIGNAL(changed()));
139 }
140 else if (type==SA("string"))
141 {
142 InputString::StringMode mode;
143 QString format = child.attribute(SA("format"));
144 if (format==SA("dir"))
145 {
146 mode = InputString::StringDir;
147 }
148 else if (format==SA("file"))
149 {
150 mode = InputString::StringFile;
151 }
152 else // format=="string"
153 {
154 mode = InputString::StringFree;
155 }
156 InputString *stringOption =
157 new InputString(
158 layout,row,
159 child.attribute(SA("id")),
160 child.attribute(SA("defval")),
161 mode,
162 child.attribute(SA("docs")),
163 child.attribute(SA("abspath"))
164 );
165 m_options.insert(
166 child.attribute(SA("id")),
167 stringOption
168 );
169 connect(stringOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
170 connect(stringOption,SIGNAL(changed()),SIGNAL(changed()));
171 }
172 else if (type==SA("enum"))
173 {
174 InputString *enumList = new InputString(
175 layout,row,
176 child.attribute(SA("id")),
177 child.attribute(SA("defval")),
178 InputString::StringFixed,
179 child.attribute(SA("docs"))
180 );
181 QDomElement enumVal = child.firstChildElement();
182 while (!enumVal.isNull())
183 {
184 enumList->addValue(enumVal.attribute(SA("name")));
185 enumVal = enumVal.nextSiblingElement();
186 }
187 enumList->setDefault();
188
189 m_options.insert(child.attribute(SA("id")),enumList);
190 connect(enumList,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
191 connect(enumList,SIGNAL(changed()),SIGNAL(changed()));
192 }
193 else if (type==SA("int"))
194 {
195 InputInt *intOption =
196 new InputInt(
197 layout,row,
198 child.attribute(SA("id")),
199 child.attribute(SA("defval")).toInt(),
200 child.attribute(SA("minval")).toInt(),
201 child.attribute(SA("maxval")).toInt(),
202 child.attribute(SA("docs"))
203 );
204 m_options.insert(
205 child.attribute(SA("id")),
206 intOption
207 );
208 connect(intOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
209 connect(intOption,SIGNAL(changed()),SIGNAL(changed()));
210 }
211 else if (type==SA("list"))
212 {
213 InputStrList::ListMode mode;
214 QString format = child.attribute(SA("format"));
215 if (format==SA("dir"))
216 {
217 mode = InputStrList::ListDir;
218 }
219 else if (format==SA("file"))
220 {
221 mode = InputStrList::ListFile;
222 }
223 else if (format==SA("filedir"))
224 {
225 mode = InputStrList::ListFileDir;
226 }
227 else // format=="string"
228 {
229 mode = InputStrList::ListString;
230 }
231 QStringList sl;
232 QDomElement listVal = child.firstChildElement();
233 while (!listVal.isNull())
234 {
235 sl.append(listVal.attribute(SA("name")));
236 listVal = listVal.nextSiblingElement();
237 }
238 InputStrList *listOption =
239 new InputStrList(
240 layout,row,
241 child.attribute(SA("id")),
242 sl,
243 mode,
244 child.attribute(SA("docs"))
245 );
246 m_options.insert(
247 child.attribute(SA("id")),
248 listOption
249 );
250 connect(listOption,SIGNAL(showHelp(Input*)),SLOT(showHelp(Input*)));
251 connect(listOption,SIGNAL(changed()),SIGNAL(changed()));
252 }
253 else if (type==SA("obsolete"))
254 {
255 // ignore
256 }
257 else // should not happen
258 {
259 printf("Unsupported type %s\n",qPrintable(child.attribute(SA("type"))));
260 }
261 child = child.nextSiblingElement();
262 }
263
264 // compute dependencies between options
265 child = elem.firstChildElement();
266 while (!child.isNull())
267 {
268 QString dependsOn = child.attribute(SA("depends"));
269 QString id = child.attribute(SA("id"));
270 if (!dependsOn.isEmpty())
271 {
272 Input *parentOption = m_options[dependsOn];
273 Input *thisOption = m_options[id];
274 Q_ASSERT(parentOption);
275 Q_ASSERT(thisOption);
276 if (parentOption && thisOption)
277 {
278 //printf("Adding dependency '%s' (%p)->'%s' (%p)\n",
279 // qPrintable(dependsOn),parentOption,
280 // qPrintable(id),thisOption);
281 parentOption->addDependency(thisOption);
282 }
283 }
284 child = child.nextSiblingElement();
285 }
286
287 // set initial dependencies
288 QHashIterator<QString,Input*> i(m_options);
289 while (i.hasNext())
290 {
291 i.next();
292 if (i.value())
293 {
294 i.value()->updateDependencies();
295 }
296 }
297
298 layout->setRowStretch(row,1);
299 layout->setColumnStretch(1,2);
300 layout->setSpacing(5);
301 topic->setLayout(layout);
302 area->setWidget(topic);
303 area->setWidgetResizable(true);
304 return area;
305}
306
307void Expert::activateTopic(QTreeWidgetItem *item,QTreeWidgetItem *)
308{
309 if (item)
310 {
311 QWidget *w = m_topics[item->text(0)];
312 m_topicStack->setCurrentWidget(w);
313 m_prev->setEnabled(m_topicStack->currentIndex()!=0);
314 m_next->setEnabled(m_topicStack->currentIndex()!=m_topicStack->count()-1);
315 }
316}
317
318void Expert::loadSettings(QSettings *s)
319{
320 QHashIterator<QString,Input*> i(m_options);
321 while (i.hasNext())
322 {
323 i.next();
324 QVariant var = s->value(SA("config/")+i.key());
325 if (i.value())
326 {
327 //printf("Loading key %s: type=%d value='%s'\n",qPrintable(i.key()),var.type(),qPrintable(var.toString()));
328 i.value()->value() = var;
329 i.value()->update();
330 }
331 }
332}
333
334void Expert::saveSettings(QSettings *s)
335{
336 QHashIterator<QString,Input*> i(m_options);
337 while (i.hasNext())
338 {
339 i.next();
340 //printf("Saving key %s: type=%d value='%s'\n",qPrintable(i.key()),i.value()->value().type(),qPrintable(i.value()->value().toString()));
341 if (i.value())
342 {
343 s->setValue(SA("config/")+i.key(),i.value()->value());
344 }
345 }
346}
347
348void Expert::loadConfig(const QString &fileName)
349{
350 //printf("Expert::loadConfig(%s)\n",qPrintable(fileName));
351 parseConfig(fileName,m_options);
352}
353
354void Expert::saveTopic(QTextStream &t,QDomElement &elem,QTextCodec *codec,
355 bool brief)
356{
357 // write group header
358 t << endl;
359 t << "#---------------------------------------------------------------------------" << endl;
360 t << "# " << elem.attribute(SA("docs")) << endl;
361 t << "#---------------------------------------------------------------------------" << endl;
362
363 // write options...
364 QDomElement childElem = elem.firstChildElement();
365 while (!childElem.isNull())
366 {
367 QString type = childElem.attribute(SA("type"));
368 QString name = childElem.attribute(SA("id"));
369 QHash<QString,Input*>::const_iterator i = m_options.find(name);
370 if (i!=m_options.end())
371 {
372 Input *option = i.value();
373 if (!brief)
374 {
375 t << endl;
376 t << convertToComment(childElem.attribute(SA("docs")));
377 t << endl;
378 }
379 t << name.leftJustified(23) << "= ";
380 if (option)
381 {
382 option->writeValue(t,codec);
383 }
384 t << endl;
385 }
386 childElem = childElem.nextSiblingElement();
387 }
388
389}
390
391bool Expert::writeConfig(QTextStream &t,bool brief)
392{
393 if (!brief)
394 {
395 // write global header
396 t << "# Doxyfile " << versionString << endl << endl; // TODO: add version
397 t << "# This file describes the settings to be used by the documentation system\n";
398 t << "# doxygen (www.doxygen.org) for a project\n";
399 t << "#\n";
400 t << "# All text after a hash (#) is considered a comment and will be ignored\n";
401 t << "# The format is:\n";
402 t << "# TAG = value [value, ...]\n";
403 t << "# For lists items can also be appended using:\n";
404 t << "# TAG += value [value, ...]\n";
405 t << "# Values that contain spaces should be placed between quotes (\" \")\n";
406 }
407
408 QTextCodec *codec = 0;
409 Input *option = m_options[QString::fromAscii("DOXYFILE_ENCODING")];
410 if (option)
411 {
412 codec = QTextCodec::codecForName(option->value().toString().toAscii());
413 if (codec==0) // fallback: use UTF-8
414 {
415 codec = QTextCodec::codecForName("UTF-8");
416 }
417 }
418 QDomElement childElem = m_rootElement.firstChildElement();
419 while (!childElem.isNull())
420 {
421 saveTopic(t,childElem,codec,brief);
422 childElem = childElem.nextSiblingElement();
423 }
424 return true;
425}
426
427QByteArray Expert::saveInnerState () const
428{
429 return m_splitter->saveState();
430}
431
432bool Expert::restoreInnerState ( const QByteArray & state )
433{
434 return m_splitter->restoreState(state);
435}
436
437void Expert::showHelp(Input *option)
438{
439 if (!m_inShowHelp)
440 {
441 m_inShowHelp = TRUE;
442 m_helper->setText(
443 QString::fromAscii("<qt><b>")+option->id()+
444 QString::fromAscii("</b><br>")+
445 option->docs().
446 replace(QChar::fromAscii('\n'),QChar::fromAscii(' '))+
447 QString::fromAscii("<qt>")
448 );
449 m_inShowHelp = FALSE;
450 }
451}
452
453void Expert::nextTopic()
454{
455 m_topicStack->setCurrentIndex(m_topicStack->currentIndex()+1);
456 m_next->setEnabled(m_topicStack->count()!=m_topicStack->currentIndex()+1);
457 m_prev->setEnabled(m_topicStack->currentIndex()!=0);
458 m_treeWidget->setCurrentItem(m_treeWidget->invisibleRootItem()->child(m_topicStack->currentIndex()));
459}
460
461void Expert::prevTopic()
462{
463 m_topicStack->setCurrentIndex(m_topicStack->currentIndex()-1);
464 m_next->setEnabled(m_topicStack->count()!=m_topicStack->currentIndex()+1);
465 m_prev->setEnabled(m_topicStack->currentIndex()!=0);
466 m_treeWidget->setCurrentItem(m_treeWidget->invisibleRootItem()->child(m_topicStack->currentIndex()));
467}
468
469void Expert::resetToDefaults()
470{
471 //printf("Expert::makeDefaults()\n");
472 QHashIterator<QString,Input*> i(m_options);
473 while (i.hasNext())
474 {
475 i.next();
476 if (i.value())
477 {
478 i.value()->reset();
479 }
480 }
481}
482
483static bool stringVariantToBool(const QVariant &v)
484{
485 QString s = v.toString().toLower();
486 return s==QString::fromAscii("yes") || s==QString::fromAscii("true") || s==QString::fromAscii("1");
487}
488
489static bool getBoolOption(
490 const QHash<QString,Input*>&model,const QString &name)
491{
492 Input *option = model[name];
493 Q_ASSERT(option!=0);
494 return stringVariantToBool(option->value());
495}
496
497static QString getStringOption(
498 const QHash<QString,Input*>&model,const QString &name)
499{
500 Input *option = model[name];
501 Q_ASSERT(option!=0);
502 return option->value().toString();
503}
504
505
506bool Expert::htmlOutputPresent(const QString &workingDir) const
507{
508 bool generateHtml = getBoolOption(m_options,QString::fromAscii("GENERATE_HTML"));
509 if (!generateHtml || workingDir.isEmpty()) return false;
510 QString indexFile = getHtmlOutputIndex(workingDir);
511 QFileInfo fi(indexFile);
512 return fi.exists() && fi.isFile();
513}
514
515QString Expert::getHtmlOutputIndex(const QString &workingDir) const
516{
517 QString outputDir = getStringOption(m_options,QString::fromAscii("OUTPUT_DIRECTORY"));
518 QString htmlOutputDir = getStringOption(m_options,QString::fromAscii("HTML_OUTPUT"));
519 //printf("outputDir=%s\n",qPrintable(outputDir));
520 //printf("htmlOutputDir=%s\n",qPrintable(htmlOutputDir));
521 QString indexFile = workingDir;
522 if (QFileInfo(outputDir).isAbsolute()) // override
523 {
524 indexFile = outputDir;
525 }
526 else // append
527 {
528 indexFile += QString::fromAscii("/")+outputDir;
529 }
530 if (QFileInfo(htmlOutputDir).isAbsolute()) // override
531 {
532 indexFile = htmlOutputDir;
533 }
534 else // append
535 {
536 indexFile += QString::fromAscii("/")+htmlOutputDir;
537 }
538 indexFile+=QString::fromAscii("/index.html");
539 return indexFile;
540}
541
542bool Expert::pdfOutputPresent(const QString &workingDir) const
543{
544 bool generateLatex = getBoolOption(m_options,QString::fromAscii("GENERATE_LATEX"));
545 bool pdfLatex = getBoolOption(m_options,QString::fromAscii("USE_PDFLATEX"));
546 if (!generateLatex || !pdfLatex) return false;
547 QString latexOutput = getStringOption(m_options,QString::fromAscii("LATEX_OUTPUT"));
548 QString indexFile;
549 if (QFileInfo(latexOutput).isAbsolute())
550 {
551 indexFile = latexOutput+QString::fromAscii("/refman.pdf");
552 }
553 else
554 {
555 indexFile = workingDir+QString::fromAscii("/")+
556 latexOutput+QString::fromAscii("/refman.pdf");
557 }
558 QFileInfo fi(indexFile);
559 return fi.exists() && fi.isFile();
560}
561
562

Archive Download this file

Revision: 1406