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