Root/
Source at commit 1322 created 12 years 8 months ago. By meklort, Add doxygen to utils folder | |
---|---|
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 | ␊ |
15 | static 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 | ␊ |
31 | Expert::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 | ␊ |
79 | Expert::~Expert()␊ |
80 | {␊ |
81 | QHashIterator<QString,Input*> i(m_options);␊ |
82 | while (i.hasNext()) ␊ |
83 | {␊ |
84 | i.next();␊ |
85 | delete i.value();␊ |
86 | }␊ |
87 | }␊ |
88 | ␊ |
89 | void 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 | ␊ |
114 | QWidget *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 | ␊ |
307 | void 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 | ␊ |
318 | void 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 | ␊ |
334 | void 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 | ␊ |
348 | void Expert::loadConfig(const QString &fileName)␊ |
349 | {␊ |
350 | //printf("Expert::loadConfig(%s)\n",qPrintable(fileName));␊ |
351 | parseConfig(fileName,m_options);␊ |
352 | }␊ |
353 | ␊ |
354 | void 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 | ␊ |
391 | bool 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 | ␊ |
427 | QByteArray Expert::saveInnerState () const␊ |
428 | {␊ |
429 | return m_splitter->saveState();␊ |
430 | }␊ |
431 | ␊ |
432 | bool Expert::restoreInnerState ( const QByteArray & state )␊ |
433 | {␊ |
434 | return m_splitter->restoreState(state);␊ |
435 | }␊ |
436 | ␊ |
437 | void 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 | ␊ |
453 | void 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 | ␊ |
461 | void 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 | ␊ |
469 | void 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 | ␊ |
483 | static 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 | ␊ |
489 | static 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 | ␊ |
497 | static 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 | ␊ |
506 | bool 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 | ␊ |
515 | QString 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 | ␊ |
542 | bool 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 |