Chameleon

Chameleon Svn Source Tree

Root/branches/xZenu/src/util/doxygen/addon/doxywizard/doxywizard.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 <QtGui>
2#include "doxywizard.h"
3#include "version.h"
4#include "expert.h"
5#include "wizard.h"
6
7#ifdef WIN32
8#include <windows.h>
9#endif
10
11#define MAX_RECENT_FILES 10
12
13const int messageTimeout = 5000; //!< status bar message timeout in millisec.
14
15MainWindow &MainWindow::instance()
16{
17 static MainWindow *theInstance = new MainWindow;
18 return *theInstance;
19}
20
21MainWindow::MainWindow()
22 : m_settings(QString::fromAscii("Doxygen.org"), QString::fromAscii("Doxywizard"))
23{
24 QMenu *file = menuBar()->addMenu(tr("File"));
25 file->addAction(tr("Open..."),
26 this, SLOT(openConfig()), Qt::CTRL+Qt::Key_O);
27 m_recentMenu = file->addMenu(tr("Open recent"));
28 file->addAction(tr("Save"),
29 this, SLOT(saveConfig()), Qt::CTRL+Qt::Key_S);
30 file->addAction(tr("Save as..."),
31 this, SLOT(saveConfigAs()), Qt::SHIFT+Qt::CTRL+Qt::Key_S);
32 file->addAction(tr("Quit"),
33 this, SLOT(quit()), Qt::CTRL+Qt::Key_Q);
34
35 QMenu *settings = menuBar()->addMenu(tr("Settings"));
36 settings->addAction(tr("Reset to factory defaults"),
37 this,SLOT(resetToDefaults()));
38 settings->addAction(tr("Use current settings at startup"),
39 this,SLOT(makeDefaults()));
40 settings->addAction(tr("Clear recent list"),
41 this,SLOT(clearRecent()));
42
43 QMenu *help = menuBar()->addMenu(tr("Help"));
44 help->addAction(tr("Online manual"),
45 this, SLOT(manual()), Qt::Key_F1);
46 help->addAction(tr("About"),
47 this, SLOT(about()) );
48
49 m_expert = new Expert;
50 m_wizard = new Wizard(m_expert->modelData());
51
52 // ----------- top part ------------------
53 QWidget *topPart = new QWidget;
54 QVBoxLayout *rowLayout = new QVBoxLayout(topPart);
55
56 // select working directory
57 QHBoxLayout *dirLayout = new QHBoxLayout;
58 m_workingDir = new QLineEdit;
59 m_selWorkingDir = new QPushButton(tr("Select..."));
60 dirLayout->addWidget(m_workingDir);
61 dirLayout->addWidget(m_selWorkingDir);
62
63 //------------- bottom part --------------
64 QWidget *runTab = new QWidget;
65 QVBoxLayout *runTabLayout = new QVBoxLayout(runTab);
66
67 // run doxygen
68 QHBoxLayout *runLayout = new QHBoxLayout;
69 m_run = new QPushButton(tr("Run doxygen"));
70 m_run->setEnabled(false);
71 m_runStatus = new QLabel(tr("Status: not running"));
72 m_saveLog = new QPushButton(tr("Save log..."));
73 m_saveLog->setEnabled(false);
74 QPushButton *showSettings = new QPushButton(tr("Show configuration"));
75 runLayout->addWidget(m_run);
76 runLayout->addWidget(m_runStatus);
77 runLayout->addStretch(1);
78 runLayout->addWidget(showSettings);
79 runLayout->addWidget(m_saveLog);
80
81 // output produced by doxygen
82 runTabLayout->addLayout(runLayout);
83 runTabLayout->addWidget(new QLabel(tr("Output produced by doxygen")));
84 QGridLayout *grid = new QGridLayout;
85 m_outputLog = new QTextEdit;
86 m_outputLog->setReadOnly(true);
87 m_outputLog->setFontFamily(QString::fromAscii("courier"));
88 m_outputLog->setMinimumWidth(600);
89 grid->addWidget(m_outputLog,0,0);
90 grid->setColumnStretch(0,1);
91 grid->setRowStretch(0,1);
92 QHBoxLayout *launchLayout = new QHBoxLayout;
93 m_launchHtml = new QPushButton(tr("Show HTML output"));
94 launchLayout->addWidget(m_launchHtml);
95
96 launchLayout->addStretch(1);
97 grid->addLayout(launchLayout,1,0);
98 runTabLayout->addLayout(grid);
99
100 QTabWidget *tabs = new QTabWidget;
101 tabs->addTab(m_wizard,tr("Wizard"));
102 tabs->addTab(m_expert,tr("Expert"));
103 tabs->addTab(runTab,tr("Run"));
104
105 rowLayout->addWidget(new QLabel(tr("Step 1: Specify the working directory from which doxygen will run")));
106 rowLayout->addLayout(dirLayout);
107 rowLayout->addWidget(new QLabel(tr("Step 2: Configure doxygen using the Wizard and/or Expert tab, then switch to the Run tab to generate the documentation")));
108 rowLayout->addWidget(tabs);
109
110 setCentralWidget(topPart);
111 statusBar()->showMessage(tr("Welcome to Doxygen"),messageTimeout);
112
113 m_runProcess = new QProcess;
114 m_running = false;
115 m_timer = new QTimer;
116
117 // connect signals and slots
118 connect(tabs,SIGNAL(currentChanged(int)),SLOT(selectTab(int)));
119 connect(m_selWorkingDir,SIGNAL(clicked()),SLOT(selectWorkingDir()));
120 connect(m_recentMenu,SIGNAL(triggered(QAction*)),SLOT(openRecent(QAction*)));
121 connect(m_workingDir,SIGNAL(returnPressed()),SLOT(updateWorkingDir()));
122 connect(m_runProcess,SIGNAL(readyReadStandardOutput()),SLOT(readStdout()));
123 connect(m_runProcess,SIGNAL(finished(int, QProcess::ExitStatus)),SLOT(runComplete()));
124 connect(m_timer,SIGNAL(timeout()),SLOT(readStdout()));
125 connect(m_run,SIGNAL(clicked()),SLOT(runDoxygen()));
126 connect(m_launchHtml,SIGNAL(clicked()),SLOT(showHtmlOutput()));
127 connect(m_saveLog,SIGNAL(clicked()),SLOT(saveLog()));
128 connect(showSettings,SIGNAL(clicked()),SLOT(showSettings()));
129 connect(m_expert,SIGNAL(changed()),SLOT(configChanged()));
130
131 loadSettings();
132 updateLaunchButtonState();
133 m_modified = false;
134 updateTitle();
135 m_wizard->refresh();
136}
137
138void MainWindow::closeEvent(QCloseEvent *event)
139{
140 if (discardUnsavedChanges())
141 {
142 saveSettings();
143 event->accept();
144 }
145 else
146 {
147 event->ignore();
148 }
149}
150
151void MainWindow::quit()
152{
153 if (discardUnsavedChanges())
154 {
155 saveSettings();
156 }
157 QApplication::exit(0);
158}
159
160void MainWindow::setWorkingDir(const QString &dirName)
161{
162 QDir::setCurrent(dirName);
163 m_workingDir->setText(dirName);
164 m_run->setEnabled(!dirName.isEmpty());
165}
166
167void MainWindow::selectWorkingDir()
168{
169 QString dirName = QFileDialog::getExistingDirectory(this,
170 tr("Select working directory"),m_workingDir->text());
171 if (!dirName.isEmpty())
172 {
173 setWorkingDir(dirName);
174 }
175}
176
177void MainWindow::updateWorkingDir()
178{
179 setWorkingDir(m_workingDir->text());
180}
181
182void MainWindow::manual()
183{
184 QDesktopServices::openUrl(QUrl(QString::fromAscii("http://www.doxygen.org/manual.html")));
185}
186
187void MainWindow::about()
188{
189 QString msg;
190 QTextStream t(&msg,QIODevice::WriteOnly);
191 t << QString::fromAscii("<qt><center>A tool to configure and run doxygen version ")+
192 QString::fromAscii(versionString)+
193 QString::fromAscii(" on your source files.</center><p><br>"
194 "<center>Written by<br> Dimitri van Heesch<br>&copy; 2000-2010</center><p>"
195 "</qt>");
196 QMessageBox::about(this,tr("Doxygen GUI"),msg);
197}
198
199void MainWindow::openConfig()
200{
201 if (discardUnsavedChanges(false))
202 {
203 QString fn = QFileDialog::getOpenFileName(this,
204 tr("Open configuration file"),
205 m_workingDir->text());
206 if (!fn.isEmpty())
207 {
208 loadConfigFromFile(fn);
209 }
210 }
211}
212
213void MainWindow::updateConfigFileName(const QString &fileName)
214{
215 if (m_fileName!=fileName)
216 {
217 m_fileName = fileName;
218 QString curPath = QFileInfo(fileName).path();
219 setWorkingDir(curPath);
220 addRecentFile(fileName);
221 updateTitle();
222 }
223}
224
225void MainWindow::loadConfigFromFile(const QString & fileName)
226{
227 m_expert->loadConfig(fileName);
228 m_wizard->refresh();
229 updateConfigFileName(fileName);
230 updateLaunchButtonState();
231 m_modified = false;
232 updateTitle();
233}
234
235void MainWindow::saveConfig(const QString &fileName)
236{
237 if (fileName.isEmpty()) return;
238 QFile f(fileName);
239 if (!f.open(QIODevice::WriteOnly))
240 {
241 QMessageBox::warning(this,
242 tr("Error saving"),
243 tr("Error: cannot open the file ")+fileName+tr(" for writing!\n")+
244 tr("Reason given: ")+f.error());
245 return;
246 }
247 QTextStream t(&f);
248 m_expert->writeConfig(t,false);
249 updateConfigFileName(fileName);
250 m_modified = false;
251 updateTitle();
252}
253
254bool MainWindow::saveConfig()
255{
256 if (m_fileName.isEmpty())
257 {
258 return saveConfigAs();
259 }
260 else
261 {
262 saveConfig(m_fileName);
263 return true;
264 }
265}
266
267bool MainWindow::saveConfigAs()
268{
269 QString fileName = QFileDialog::getSaveFileName(this, QString(),
270 m_workingDir->text()+QString::fromAscii("/Doxyfile"));
271 if (fileName.isEmpty()) return false;
272 saveConfig(fileName);
273 return true;
274}
275
276void MainWindow::makeDefaults()
277{
278 if (QMessageBox::question(this,tr("Use current setting at startup?"),
279 tr("Do you want to save the current settings "
280 "and use them next time Doxywizard starts?"),
281 QMessageBox::Save|
282 QMessageBox::Cancel)==QMessageBox::Save)
283 {
284 //printf("MainWindow:makeDefaults()\n");
285 m_expert->saveSettings(&m_settings);
286 m_settings.setValue(QString::fromAscii("wizard/loadsettings"), true);
287 m_settings.sync();
288 }
289}
290
291void MainWindow::clearRecent()
292{
293 if (QMessageBox::question(this,tr("Clear the list of recent files?"),
294 tr("Do you want to clear the list of recently "
295 "loaded configuration files?"),
296 QMessageBox::Yes|
297 QMessageBox::Cancel)==QMessageBox::Yes)
298 {
299 m_recentMenu->clear();
300 m_recentFiles.clear();
301 for (int i=0;i<MAX_RECENT_FILES;i++)
302 {
303 m_settings.setValue(QString().sprintf("recent/config%d",i++),QString::fromAscii(""));
304 }
305 m_settings.sync();
306 }
307
308}
309
310void MainWindow::resetToDefaults()
311{
312 if (QMessageBox::question(this,tr("Reset settings to their default values?"),
313 tr("Do you want to revert all settings back "
314 "to their original values?"),
315 QMessageBox::Reset|
316 QMessageBox::Cancel)==QMessageBox::Reset)
317 {
318 //printf("MainWindow:resetToDefaults()\n");
319 m_expert->resetToDefaults();
320 m_settings.setValue(QString::fromAscii("wizard/loadsettings"), false);
321 m_settings.sync();
322 m_wizard->refresh();
323 }
324}
325
326void MainWindow::loadSettings()
327{
328 QVariant geometry = m_settings.value(QString::fromAscii("main/geometry"), QVariant::Invalid);
329 QVariant state = m_settings.value(QString::fromAscii("main/state"), QVariant::Invalid);
330 QVariant wizState = m_settings.value(QString::fromAscii("wizard/state"), QVariant::Invalid);
331 QVariant loadSettings = m_settings.value(QString::fromAscii("wizard/loadsettings"), QVariant::Invalid);
332 QVariant workingDir = m_settings.value(QString::fromAscii("wizard/workingdir"), QVariant::Invalid);
333
334 if (geometry !=QVariant::Invalid) restoreGeometry(geometry.toByteArray());
335 if (state !=QVariant::Invalid) restoreState (state.toByteArray());
336 if (wizState !=QVariant::Invalid) m_wizard->restoreState(wizState.toByteArray());
337 if (loadSettings!=QVariant::Invalid && loadSettings.toBool())
338 {
339 m_expert->loadSettings(&m_settings);
340 if (workingDir!=QVariant::Invalid && QDir(workingDir.toString()).exists())
341 {
342 setWorkingDir(workingDir.toString());
343 }
344 }
345
346 for (int i=0;i<MAX_RECENT_FILES;i++)
347 {
348 QString entry = m_settings.value(QString().sprintf("recent/config%d",i)).toString();
349 if (!entry.isEmpty() && QFileInfo(entry).exists())
350 {
351 addRecentFile(entry);
352 }
353 }
354
355}
356
357void MainWindow::saveSettings()
358{
359 QSettings settings(QString::fromAscii("Doxygen.org"), QString::fromAscii("Doxywizard"));
360
361 m_settings.setValue(QString::fromAscii("main/geometry"), saveGeometry());
362 m_settings.setValue(QString::fromAscii("main/state"), saveState());
363 m_settings.setValue(QString::fromAscii("wizard/state"), m_wizard->saveState());
364 m_settings.setValue(QString::fromAscii("wizard/workingdir"), m_workingDir->text());
365}
366
367void MainWindow::selectTab(int id)
368{
369 if (id==0) m_wizard->refresh();
370}
371
372void MainWindow::addRecentFile(const QString &fileName)
373{
374 int i=m_recentFiles.indexOf(fileName);
375 if (i!=-1) m_recentFiles.removeAt(i);
376
377 // not found
378 if (m_recentFiles.count() < MAX_RECENT_FILES) // append
379 {
380 m_recentFiles.prepend(fileName);
381 }
382 else // add + drop last item
383 {
384 m_recentFiles.removeLast();
385 m_recentFiles.prepend(fileName);
386 }
387 m_recentMenu->clear();
388 i=0;
389 foreach( QString str, m_recentFiles )
390 {
391 m_recentMenu->addAction(str);
392 m_settings.setValue(QString().sprintf("recent/config%d",i++),str);
393 }
394 for (;i<MAX_RECENT_FILES;i++)
395 {
396 m_settings.setValue(QString().sprintf("recent/config%d",i++),QString::fromAscii(""));
397 }
398}
399
400void MainWindow::openRecent(QAction *action)
401{
402 if (discardUnsavedChanges(false))
403 {
404 loadConfigFromFile(action->text());
405 }
406}
407
408void MainWindow::runDoxygen()
409{
410 if (!m_running)
411 {
412 QString doxygenPath;
413#if defined(Q_OS_MACX)
414 doxygenPath = qApp->applicationDirPath()+QString::fromAscii("/../Resources/");
415 qDebug() << tr("Doxygen path: ") << doxygenPath;
416 if ( !QFile(doxygenPath + QString::fromAscii("doxygen")).exists() )
417 {
418 // No doygen binary in the resources, if there is a system doxygen binary, use that instead
419 if ( QFile(QString::fromAscii("/usr/local/bin/doxygen")).exists() )
420 {
421 doxygenPath = QString::fromAscii("/usr/local/bin/");
422 }
423 else
424 {
425 qDebug() << tr("Can't find the doxygen command, make sure it's in your $$PATH");
426 doxygenPath = QString::fromAscii("");
427 }
428 }
429 qDebug() << tr("Getting doxygen from: ") << doxygenPath;
430#endif
431
432 m_runProcess->setReadChannel(QProcess::StandardOutput);
433 m_runProcess->setProcessChannelMode(QProcess::MergedChannels);
434 m_runProcess->setWorkingDirectory(m_workingDir->text());
435 QStringList env=QProcess::systemEnvironment();
436 // set PWD environment variable to m_workingDir
437 env.replaceInStrings(QRegExp(QString::fromAscii("^PWD=(.*)"),Qt::CaseInsensitive),
438 QString::fromAscii("PWD=")+m_workingDir->text());
439 m_runProcess->setEnvironment(env);
440
441 QStringList args;
442 args << QString::fromAscii("-b"); // make stdout unbuffered
443 args << QString::fromAscii("-"); // read config from stdin
444
445 m_outputLog->clear();
446 m_runProcess->start(doxygenPath + QString::fromAscii("doxygen"), args);
447
448 if (!m_runProcess->waitForStarted())
449 {
450 m_outputLog->append(QString::fromAscii("*** Failed to run doxygen\n"));
451 return;
452 }
453 QTextStream t(m_runProcess);
454 m_expert->writeConfig(t,false);
455 m_runProcess->closeWriteChannel();
456
457 if (m_runProcess->state() == QProcess::NotRunning)
458 {
459 m_outputLog->append(QString::fromAscii("*** Failed to run doxygen\n"));
460 }
461 else
462 {
463 m_saveLog->setEnabled(false);
464 m_running=true;
465 m_run->setText(tr("Stop doxygen"));
466 m_runStatus->setText(tr("Status: running"));
467 m_timer->start(1000);
468 }
469 }
470 else
471 {
472 m_running=false;
473 m_run->setText(tr("Run doxygen"));
474 m_runStatus->setText(tr("Status: not running"));
475 m_runProcess->kill();
476 m_timer->stop();
477 //updateRunnable(m_workingDir->text());
478 }
479}
480
481void MainWindow::readStdout()
482{
483 if (m_running)
484 {
485 QByteArray data = m_runProcess->readAllStandardOutput();
486 QString text = QString::fromLocal8Bit(data);
487 if (!text.isEmpty())
488 {
489 m_outputLog->append(text.trimmed());
490 }
491 }
492}
493
494void MainWindow::runComplete()
495{
496 if (m_running)
497 {
498 m_outputLog->append(tr("*** Doxygen has finished\n"));
499 }
500 else
501 {
502 m_outputLog->append(tr("*** Cancelled by user\n"));
503 }
504 m_outputLog->ensureCursorVisible();
505 m_run->setText(tr("Run doxygen"));
506 m_runStatus->setText(tr("Status: not running"));
507 m_running=false;
508 updateLaunchButtonState();
509 //updateRunnable(m_workingDir->text());
510 m_saveLog->setEnabled(true);
511}
512
513void MainWindow::updateLaunchButtonState()
514{
515 m_launchHtml->setEnabled(m_expert->htmlOutputPresent(m_workingDir->text()));
516#if 0
517 m_launchPdf->setEnabled(m_expert->pdfOutputPresent(m_workingDir->text()));
518#endif
519}
520
521void MainWindow::showHtmlOutput()
522{
523 QString indexFile = m_expert->getHtmlOutputIndex(m_workingDir->text());
524 QFileInfo fi(indexFile);
525 // TODO: the following doesn't seem to work with IE
526#ifdef WIN32
527 //QString indexUrl(QString::fromAscii("file:///"));
528 ShellExecute(NULL, L"open", fi.absoluteFilePath().utf16(), NULL, NULL, SW_SHOWNORMAL);
529#else
530 QString indexUrl(QString::fromAscii("file://"));
531 indexUrl+=fi.absoluteFilePath();
532 QDesktopServices::openUrl(QUrl(indexUrl));
533#endif
534}
535
536void MainWindow::saveLog()
537{
538 QString fn = QFileDialog::getSaveFileName(this, tr("Save log file"),
539 m_workingDir->text()+
540 QString::fromAscii("/doxygen_log.txt"));
541 if (!fn.isEmpty())
542 {
543 QFile f(fn);
544 if (f.open(QIODevice::WriteOnly))
545 {
546 QTextStream t(&f);
547 t << m_outputLog->toPlainText();
548 statusBar()->showMessage(tr("Output log saved"),messageTimeout);
549 }
550 else
551 {
552 QMessageBox::warning(0,tr("Warning"),
553 tr("Cannot open file ")+fn+tr(" for writing. Nothing saved!"),tr("ok"));
554 }
555 }
556}
557
558void MainWindow::showSettings()
559{
560 QString text;
561 QTextStream t(&text);
562 m_expert->writeConfig(t,true);
563 m_outputLog->clear();
564 m_outputLog->append(text);
565 m_outputLog->ensureCursorVisible();
566 m_saveLog->setEnabled(true);
567}
568
569void MainWindow::configChanged()
570{
571 m_modified = true;
572 updateTitle();
573}
574
575void MainWindow::updateTitle()
576{
577 QString title = tr("Doxygen GUI frontend");
578 if (m_modified)
579 {
580 title+=QString::fromAscii(" +");
581 }
582 if (!m_fileName.isEmpty())
583 {
584 title+=QString::fromAscii(" (")+m_fileName+QString::fromAscii(")");
585 }
586 setWindowTitle(title);
587}
588
589bool MainWindow::discardUnsavedChanges(bool saveOption)
590{
591 if (m_modified)
592 {
593 QMessageBox::StandardButton button;
594 if (saveOption)
595 {
596 button = QMessageBox::question(this,
597 tr("Unsaved changes"),
598 tr("Unsaved changes will be lost! Do you want to save the configuration file?"),
599 QMessageBox::Save |
600 QMessageBox::Discard |
601 QMessageBox::Cancel
602 );
603 if (button==QMessageBox::Save)
604 {
605 return saveConfig();
606 }
607 }
608 else
609 {
610 button = QMessageBox::question(this,
611 tr("Unsaved changes"),
612 tr("Unsaved changes will be lost! Do you want to continue?"),
613 QMessageBox::Discard |
614 QMessageBox::Cancel
615 );
616 }
617 return button==QMessageBox::Discard;
618 }
619 return true;
620}
621
622//-----------------------------------------------------------------------
623
624int main(int argc,char **argv)
625{
626 QApplication a(argc,argv);
627 MainWindow &main = MainWindow::instance();
628 if (argc==2 && argv[1][0]!='-') // name of config file as an argument
629 {
630 main.loadConfigFromFile(QString::fromLocal8Bit(argv[1]));
631 }
632 else if (argc>1)
633 {
634 printf("Usage: %s [config file]\n",argv[0]);
635 exit(1);
636 }
637 main.show();
638 return a.exec();
639}
640

Archive Download this file

Revision: 1406