Root/
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 | ␊ |
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 |