Changeset e0fcac5f2c in tspsg for src/mainwindow.cpp


Ignore:
Timestamp:
Oct 24, 2009, 3:37:48 PM (15 years ago)
Author:
Oleksii Serdiuk
Branches:
0.1.3.145-beta1-symbian, 0.1.4.170-beta2-bb10, appveyor, imgbot, master, readme
Children:
8af59c4aa3
Parents:
85ad815b0b
Message:
  • Finished documentation.
  • Sorted all functions in .cpp files according to order of their declaration in .h files.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/mainwindow.cpp

    r85ad815b0b re0fcac5f2c  
    115115}
    116116
     117/*!
     118 * \brief Handles Main Window close event.
     119 * \param event Close event.
     120 *
     121 *  Checks whether or not a current task was saved and asks for saving if not.
     122 *  Saves TSPSG settings.
     123 */
     124void MainWindow::closeEvent(QCloseEvent *event)
     125{
     126        if (!maybeSave()) {
     127                event->ignore();
     128                return;
     129        }
     130        settings->setValue("NumCities",spinCities->value());
     131#ifndef Q_OS_WINCE
     132        // Saving windows state
     133        if (settings->value("SavePos",false).toBool()) {
     134                settings->beginGroup("MainWindow");
     135                settings->setValue("Maximized",isMaximized());
     136                if (!isMaximized()) {
     137                        settings->setValue("Size",size());
     138                        settings->setValue("Position",pos());
     139                }
     140                settings->endGroup();
     141        }
     142#endif // Q_OS_WINCE
     143        QMainWindow::closeEvent(event);
     144}
     145
     146/* Privates **********************************************************/
     147
     148void MainWindow::actionFileNewTriggered()
     149{
     150        if (!maybeSave())
     151                return;
     152        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
     153        tspmodel->clear();
     154        setFileName();
     155        setWindowModified(false);
     156        tabWidget->setCurrentIndex(0);
     157        solutionText->clear();
     158        enableSolutionActions(false);
     159        QApplication::restoreOverrideCursor();
     160}
     161
     162void MainWindow::actionFileOpenTriggered()
     163{
     164        if (!maybeSave())
     165                return;
     166QFileDialog od(this);
     167        od.setAcceptMode(QFileDialog::AcceptOpen);
     168        od.setFileMode(QFileDialog::ExistingFile);
     169QStringList filters(trUtf8("All Supported Formats") + " (*.tspt *.zkt)");
     170        filters.append(trUtf8("%1 Task Files").arg("TSPSG") + " (*.tspt)");
     171        filters.append(trUtf8("%1 Task Files").arg("ZKomModRd") + " (*.zkt)");
     172        filters.append(trUtf8("All Files") + " (*)");
     173        od.setNameFilters(filters);
     174        if (od.exec() != QDialog::Accepted)
     175                return;
     176QStringList files = od.selectedFiles();
     177        if (files.empty())
     178                return;
     179        if (!tspmodel->loadTask(files.first()))
     180                return;
     181        setFileName(files.first());
     182        tabWidget->setCurrentIndex(0);
     183        setWindowModified(false);
     184        solutionText->clear();
     185        enableSolutionActions(false);
     186}
     187
     188void MainWindow::actionFileSaveTriggered()
     189{
     190        if ((fileName == trUtf8("Untitled") + ".tspt") || (!fileName.endsWith(".tspt",Qt::CaseInsensitive)))
     191                saveTask();
     192        else
     193                if (tspmodel->saveTask(fileName))
     194                        setWindowModified(false);
     195}
     196
     197void MainWindow::actionFileSaveAsTaskTriggered()
     198{
     199        saveTask();
     200}
     201
     202void MainWindow::actionFileSaveAsSolutionTriggered()
     203{
     204static QString selectedFile;
     205        if (selectedFile.isEmpty())
     206#ifndef QT_NO_PRINTER
     207                selectedFile = "solution.pdf";
     208#else
     209                selectedFile = "solution.html";
     210#endif // QT_NO_PRINTER
     211QFileDialog sd(this);
     212        sd.setAcceptMode(QFileDialog::AcceptSave);
     213QStringList filters;
     214#ifndef QT_NO_PRINTER
     215        filters.append(trUtf8("PDF Files") + "(*.pdf)");
     216#endif
     217        filters.append(trUtf8("HTML Files") + " (*.html *.htm)");
     218#if QT_VERSION >= 0x040500
     219        filters.append(trUtf8("OpenDocument Files") + " (*.odt)");
     220#endif // QT_VERSION >= 0x040500
     221        filters.append(trUtf8("All Files") + " (*)");
     222        sd.setNameFilters(filters);
     223        sd.selectFile(selectedFile);
     224        if (sd.exec() != QDialog::Accepted)
     225                return;
     226QStringList files = sd.selectedFiles();
     227        if (files.empty())
     228                return;
     229        selectedFile = files.first();
     230        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
     231#ifndef QT_NO_PRINTER
     232        if (selectedFile.endsWith(".pdf",Qt::CaseInsensitive)) {
     233QPrinter printer(QPrinter::HighResolution);
     234                printer.setOutputFormat(QPrinter::PdfFormat);
     235                printer.setOutputFileName(selectedFile);
     236                solutionText->document()->print(&printer);
     237                QApplication::restoreOverrideCursor();
     238                return;
     239        }
     240#endif
     241#if QT_VERSION >= 0x040500
     242QTextDocumentWriter dw(selectedFile);
     243        if (!(selectedFile.endsWith(".htm",Qt::CaseInsensitive) || selectedFile.endsWith(".html",Qt::CaseInsensitive) || selectedFile.endsWith(".odt",Qt::CaseInsensitive) || selectedFile.endsWith(".txt",Qt::CaseInsensitive)))
     244                dw.setFormat("plaintext");
     245        dw.write(solutionText->document());
     246#else
     247        // Qt < 4.5 has no QTextDocumentWriter class
     248QFile file(selectedFile);
     249        if (!file.open(QFile::WriteOnly)) {
     250                QApplication::restoreOverrideCursor();
     251                return;
     252        }
     253QTextStream ts(&file);
     254        ts.setCodec(QTextCodec::codecForName("UTF-8"));
     255        ts << solutionText->document()->toHtml("UTF-8");
     256        file.close();
     257#endif // QT_VERSION >= 0x040500
     258        QApplication::restoreOverrideCursor();
     259}
     260
     261#ifndef QT_NO_PRINTER
     262void MainWindow::actionFilePrintPreviewTriggered()
     263{
     264QPrintPreviewDialog ppd(printer, this);
     265    connect(&ppd,SIGNAL(paintRequested(QPrinter *)),SLOT(printPreview(QPrinter *)));
     266    ppd.exec();
     267}
     268
     269void MainWindow::actionFilePrintTriggered()
     270{
     271QPrintDialog pd(printer,this);
     272#if QT_VERSION >= 0x040500
     273        // No such methods in Qt < 4.5
     274        pd.setOption(QAbstractPrintDialog::PrintSelection,false);
     275        pd.setOption(QAbstractPrintDialog::PrintPageRange,false);
     276#endif
     277        if (pd.exec() != QDialog::Accepted)
     278                return;
     279        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
     280        solutionText->document()->print(printer);
     281        QApplication::restoreOverrideCursor();
     282}
     283#endif // QT_NO_PRINTER
     284
     285void MainWindow::actionSettingsPreferencesTriggered()
     286{
     287SettingsDialog sd(this);
     288        if (sd.exec() != QDialog::Accepted)
     289                return;
     290        if (sd.colorChanged() || sd.fontChanged()) {
     291                initDocStyleSheet();
     292                if (!output.isEmpty() && sd.colorChanged() && (QMessageBox(QMessageBox::Question,trUtf8("Settings Changed"),trUtf8("You have changed color settings.\nDo you wish to apply them to current solution text?"),QMessageBox::Yes | QMessageBox::No,this).exec() == QMessageBox::Yes)) {
     293                        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
     294                        solutionText->clear();
     295                        solutionText->setHtml(output.join(""));
     296                        QApplication::restoreOverrideCursor();
     297                }
     298        }
     299}
     300
     301void MainWindow::actionSettingsLanguageAutodetectTriggered(bool checked)
     302{
     303        if (checked) {
     304                settings->remove("Language");
     305                QMessageBox(QMessageBox::Information,trUtf8("Language change"),trUtf8("Language will be autodetected on next application start."),QMessageBox::Ok,this).exec();
     306        } else
     307                settings->setValue("Language",groupSettingsLanguageList->checkedAction()->data().toString());
     308}
     309
     310void MainWindow::groupSettingsLanguageListTriggered(QAction *action)
     311{
     312        if (actionSettingsLanguageAutodetect->isChecked()) {
     313                // We have language autodetection. It needs to be disabled to change language.
     314                if (QMessageBox(QMessageBox::Question,trUtf8("Language change"),trUtf8("You have language autodetection turned on.\nIt needs to be off.\nDo you wish to turn it off?"),QMessageBox::Yes | QMessageBox::No,this).exec() == QMessageBox::Yes) {
     315                        actionSettingsLanguageAutodetect->trigger();
     316                } else
     317                        return;
     318        }
     319bool untitled = (fileName == trUtf8("Untitled") + ".tspt");
     320        if (loadLanguage(action->data().toString())) {
     321                settings->setValue("Language",action->data().toString());
     322                retranslateUi(this);
     323                if (untitled)
     324                        setFileName();
     325        }
     326}
     327
     328void MainWindow::actionHelpAboutTriggered()
     329{
     330//! \todo TODO: Normal about window :-)
     331QString about = QString::fromUtf8("TSPSG: TSP Solver and Generator\n");
     332        about += QString::fromUtf8("    Version: "BUILD_VERSION"\n");
     333        about += QString::fromUtf8("    Copyright (C) 2007-%1 Lёppa <contacts[at]oleksii[dot]name>\n").arg(QDate::currentDate().toString("yyyy"));
     334        about += QString::fromUtf8("Target OS: %1\n").arg(OS);
     335        about += "Qt library:\n";
     336        about += QString::fromUtf8("    Compile time: %1\n").arg(QT_VERSION_STR);
     337        about += QString::fromUtf8("    Runtime: %1\n").arg(qVersion());
     338        about += QString::fromUtf8("Built on %1 at %2\n").arg(__DATE__).arg(__TIME__);
     339        about += QString::fromUtf8(VERSIONID"\n\n");
     340        about += QString::fromUtf8("Algorithm: %1\n").arg(CTSPSolver::getVersionId());
     341        about += "\n";
     342        about += "TSPSG is licensed under the terms of the GNU General Public License. You should have received a copy of the GNU General Public License along with TSPSG.";
     343        QMessageBox(QMessageBox::Information,"About",about,QMessageBox::Ok,this).exec();
     344}
     345
     346void MainWindow::buttonBackToTaskClicked()
     347{
     348        tabWidget->setCurrentIndex(0);
     349}
     350
     351void MainWindow::buttonRandomClicked()
     352{
     353        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
     354        tspmodel->randomize();
     355        QApplication::restoreOverrideCursor();
     356}
     357
     358void MainWindow::buttonSolveClicked()
     359{
     360tMatrix matrix;
     361QList<double> row;
     362int n = spinCities->value();
     363bool ok;
     364        for (int r = 0; r < n; r++) {
     365                row.clear();
     366                for (int c = 0; c < n; c++) {
     367                        row.append(tspmodel->index(r,c).data(Qt::UserRole).toDouble(&ok));
     368                        if (!ok) {
     369                                QMessageBox(QMessageBox::Critical,trUtf8("Data error"),trUtf8("Error in cell [Row %1; Column %2]: Invalid data format.").arg(r + 1).arg(c + 1),QMessageBox::Ok,this).exec();
     370                                return;
     371                        }
     372                }
     373                matrix.append(row);
     374        }
     375CTSPSolver solver;
     376sStep *root = solver.solve(n,matrix,this);
     377        if (!root)
     378                return;
     379        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
     380QColor color = settings->value("Output/Color",DEF_FONT_COLOR).value<QColor>();
     381        output.clear();
     382        output.append("<p>" + trUtf8("Variant #%1").arg(spinVariant->value()) + "</p>");
     383        output.append("<p>" + trUtf8("Task:") + "</p>");
     384        outputMatrix(matrix,output);
     385        output.append("<hr>");
     386        output.append("<p>" + trUtf8("Solution of Variant #%1 task").arg(spinVariant->value()) + "</p>");
     387sStep *step = root;
     388        n = 1;
     389        while (n <= spinCities->value()) {
     390                if (step->prNode->prNode != NULL || (step->prNode->prNode == NULL && step->plNode->prNode == NULL)) {
     391                        if (n != spinCities->value()) {
     392                                output.append("<p>" + trUtf8("Step #%1").arg(n++) + "</p>");
     393                                outputMatrix(step->matrix,output,step->candidate.nRow,step->candidate.nCol);
     394                                if (step->alts)
     395                                        output.append("<p class=\"hasalts\">" + trUtf8("This step has alternate candidates for branching.") + "</p>");
     396                                output.append("<p>&nbsp;</p>");
     397                        }
     398                }
     399                if (step->prNode->prNode != NULL)
     400                        step = step->prNode;
     401                else if (step->plNode->prNode != NULL)
     402                        step = step->plNode;
     403                else
     404                        break;
     405        }
     406        if (solver.isOptimal())
     407                output.append("<p>" + trUtf8("Optimal path:") + "</p>");
     408        else
     409                output.append("<p>" + trUtf8("Resulting path:") + "</p>");
     410        output.append("<p>&nbsp;&nbsp;" + solver.getSortedPath() + "</p>");
     411        output.append("<p>" + trUtf8("The price is <b>%1</b> units.").arg(step->price) + "</p>");
     412        if (!solver.isOptimal()) {
     413                output.append("<p>&nbsp;</p>");
     414                output.append("<p>" + trUtf8("<b>WARNING!!!</b><br>This result is a record, but it may not be optimal.<br>Iterations need to be continued to check whether this result is optimal or get an optimal one.") + "</p>");
     415        }
     416        output.append("<p></p>");
     417        solutionText->setHtml(output.join(""));
     418        solutionText->setDocumentTitle(trUtf8("Solution of Variant #%1 task").arg(spinVariant->value()));
     419
     420        // Scrolling to the end of text.
     421QTextCursor cursor(solutionText->textCursor());
     422        cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
     423        solutionText->setTextCursor(cursor);
     424
     425        enableSolutionActions();
     426        tabWidget->setCurrentIndex(1);
     427        QApplication::restoreOverrideCursor();
     428}
     429
     430void MainWindow::dataChanged()
     431{
     432        setWindowModified(true);
     433}
     434
     435void MainWindow::dataChanged(const QModelIndex &tl, const QModelIndex &br)
     436{
     437        setWindowModified(true);
     438        if (settings->value("Autosize",true).toBool()) {
     439                for (int k = tl.row(); k <= br.row(); k++)
     440                        taskView->resizeRowToContents(k);
     441                for (int k = tl.column(); k <= br.column(); k++)
     442                        taskView->resizeColumnToContents(k);
     443        }
     444}
     445
     446void MainWindow::numCitiesChanged(int nCities)
     447{
     448        blockSignals(true);
     449        spinCities->setValue(nCities);
     450        blockSignals(false);
     451}
     452
     453#ifndef QT_NO_PRINTER
     454void MainWindow::printPreview(QPrinter *printer)
     455{
     456        solutionText->print(printer);
     457}
     458#endif // QT_NO_PRINTER
     459
     460void MainWindow::spinCitiesValueChanged(int n)
     461{
     462int count = tspmodel->numCities();
     463        tspmodel->setNumCities(n);
     464        if ((n > count) && settings->value("Autosize",true).toBool())
     465                for (int k = count; k < n; k++) {
     466                        taskView->resizeColumnToContents(k);
     467                        taskView->resizeRowToContents(k);
     468                }
     469}
     470
    117471void MainWindow::enableSolutionActions(bool enable)
    118472{
     
    126480        actionFilePrintPreview->setEnabled(enable);
    127481#endif // QT_NO_PRINTER
     482}
     483
     484void MainWindow::initDocStyleSheet()
     485{
     486QColor color = settings->value("Output/Color",DEF_FONT_COLOR).value<QColor>();
     487QColor hilight;
     488        if (color.value() < 192)
     489                hilight.setHsv(color.hue(),color.saturation(),127 + qRound(color.value() / 2));
     490        else
     491                hilight.setHsv(color.hue(),color.saturation(),color.value() / 2);
     492        solutionText->document()->setDefaultStyleSheet("* {color: " + color.name() +";} p {margin: 0px 10px;} table {margin: 5px;} td {padding: 1px 5px;} .hasalts {color: " + hilight.name() + ";} .selected {color: #A00000; font-weight: bold;} .alternate {color: #008000; font-weight: bold;}");
     493        solutionText->document()->setDefaultFont(settings->value("Output/Font",QFont(DEF_FONT_FAMILY,DEF_FONT_SIZE)).value<QFont>());
     494}
     495
     496void MainWindow::loadLangList()
     497{
     498QSettings langinfo(PATH_I18N"/languages.ini",QSettings::IniFormat);
     499#if QT_VERSION >= 0x040500
     500        // In Qt < 4.5 QSettings doesn't have method setIniCodec.
     501        langinfo.setIniCodec("UTF-8");
     502#endif
     503QDir dir(PATH_I18N,"*.qm",QDir::Name | QDir::IgnoreCase,QDir::Files);
     504        if (!dir.exists())
     505                return;
     506QFileInfoList langs = dir.entryInfoList();
     507        if (langs.size() <= 0)
     508                return;
     509QAction *a;
     510        for (int k = 0; k < langs.size(); k++) {
     511                QFileInfo lang = langs.at(k);
     512                if (!lang.completeBaseName().startsWith("qt_") && lang.completeBaseName().compare("en")) {
     513#if QT_VERSION >= 0x040500
     514                        a = menuSettingsLanguage->addAction(langinfo.value(lang.completeBaseName() + "/NativeName",lang.completeBaseName()).toString());
     515#else
     516                        // We use Name if Qt < 4.5 because NativeName is in UTF-8, QSettings
     517                        // reads .ini file as ASCII and there is no way to set file encoding.
     518                        a = menuSettingsLanguage->addAction(langinfo.value(lang.completeBaseName() + "/Name",lang.completeBaseName()).toString());
     519#endif
     520                        a->setData(lang.completeBaseName());
     521                        a->setCheckable(true);
     522                        a->setActionGroup(groupSettingsLanguageList);
     523                        if (settings->value("Language",QLocale::system().name()).toString().startsWith(lang.completeBaseName()))
     524                                a->setChecked(true);
     525                }
     526        }
    128527}
    129528
     
    176575}
    177576
    178 void MainWindow::initDocStyleSheet()
    179 {
    180 QColor color = settings->value("Output/Color",DEF_FONT_COLOR).value<QColor>();
    181 QColor hilight;
    182         if (color.value() < 192)
    183                 hilight.setHsv(color.hue(),color.saturation(),127 + qRound(color.value() / 2));
    184         else
    185                 hilight.setHsv(color.hue(),color.saturation(),color.value() / 2);
    186         solutionText->document()->setDefaultStyleSheet("* {color: " + color.name() +";} p {margin: 0px 10px;} table {margin: 5px;} td {padding: 1px 5px;} .hasalts {color: " + hilight.name() + ";} .selected {color: #A00000; font-weight: bold;} .alternate {color: #008000; font-weight: bold;}");
    187         solutionText->document()->setDefaultFont(settings->value("Output/Font",QFont(DEF_FONT_FAMILY,DEF_FONT_SIZE)).value<QFont>());
    188 }
    189 
    190 void MainWindow::setFileName(QString fileName)
    191 {
    192         this->fileName = fileName;
    193         setWindowTitle(QString("%1[*] - %2").arg(QFileInfo(fileName).completeBaseName()).arg(trUtf8("Travelling Salesman Problem")));
    194 }
    195 
    196 void MainWindow::spinCitiesValueChanged(int n)
    197 {
    198 int count = tspmodel->numCities();
    199         tspmodel->setNumCities(n);
    200         if ((n > count) && settings->value("Autosize",true).toBool())
    201                 for (int k = count; k < n; k++) {
    202                         taskView->resizeColumnToContents(k);
    203                         taskView->resizeRowToContents(k);
    204                 }
    205 }
    206 
    207577bool MainWindow::maybeSave()
    208578{
     
    218588}
    219589
    220 void MainWindow::actionFileNewTriggered()
    221 {
    222         if (!maybeSave())
    223                 return;
    224         QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
    225         tspmodel->clear();
    226         setFileName();
    227         setWindowModified(false);
    228         tabWidget->setCurrentIndex(0);
    229         solutionText->clear();
    230         enableSolutionActions(false);
    231         QApplication::restoreOverrideCursor();
    232 }
    233 
    234 void MainWindow::actionFileOpenTriggered()
    235 {
    236         if (!maybeSave())
    237                 return;
    238 QFileDialog od(this);
    239         od.setAcceptMode(QFileDialog::AcceptOpen);
    240         od.setFileMode(QFileDialog::ExistingFile);
    241 QStringList filters(trUtf8("All Supported Formats") + " (*.tspt *.zkt)");
    242         filters.append(trUtf8("%1 Task Files").arg("TSPSG") + " (*.tspt)");
    243         filters.append(trUtf8("%1 Task Files").arg("ZKomModRd") + " (*.zkt)");
    244         filters.append(trUtf8("All Files") + " (*)");
    245         od.setNameFilters(filters);
    246         if (od.exec() != QDialog::Accepted)
    247                 return;
    248 QStringList files = od.selectedFiles();
    249         if (files.empty())
    250                 return;
    251         if (!tspmodel->loadTask(files.first()))
    252                 return;
    253         setFileName(files.first());
    254         tabWidget->setCurrentIndex(0);
    255         setWindowModified(false);
    256         solutionText->clear();
    257         enableSolutionActions(false);
    258 }
    259 
    260 void MainWindow::actionFileSaveTriggered()
    261 {
    262         if ((fileName == trUtf8("Untitled") + ".tspt") || (!fileName.endsWith(".tspt",Qt::CaseInsensitive)))
    263                 saveTask();
    264         else
    265                 if (tspmodel->saveTask(fileName))
    266                         setWindowModified(false);
    267 }
    268 
    269 void MainWindow::actionFileSaveAsTaskTriggered()
    270 {
    271         saveTask();
    272 }
    273 
    274 void MainWindow::actionFileSaveAsSolutionTriggered()
    275 {
    276 static QString selectedFile;
    277         if (selectedFile.isEmpty())
    278 #ifndef QT_NO_PRINTER
    279                 selectedFile = "solution.pdf";
    280 #else
    281                 selectedFile = "solution.html";
    282 #endif // QT_NO_PRINTER
    283 QFileDialog sd(this);
    284         sd.setAcceptMode(QFileDialog::AcceptSave);
    285 QStringList filters;
    286 #ifndef QT_NO_PRINTER
    287         filters.append(trUtf8("PDF Files") + "(*.pdf)");
    288 #endif
    289         filters.append(trUtf8("HTML Files") + " (*.html *.htm)");
    290 #if QT_VERSION >= 0x040500
    291         filters.append(trUtf8("OpenDocument Files") + " (*.odt)");
    292 #endif // QT_VERSION >= 0x040500
    293         filters.append(trUtf8("All Files") + " (*)");
    294         sd.setNameFilters(filters);
    295         sd.selectFile(selectedFile);
    296         if (sd.exec() != QDialog::Accepted)
    297                 return;
    298 QStringList files = sd.selectedFiles();
    299         if (files.empty())
    300                 return;
    301         selectedFile = files.first();
    302         QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
    303 #ifndef QT_NO_PRINTER
    304         if (selectedFile.endsWith(".pdf",Qt::CaseInsensitive)) {
    305 QPrinter printer(QPrinter::HighResolution);
    306                 printer.setOutputFormat(QPrinter::PdfFormat);
    307                 printer.setOutputFileName(selectedFile);
    308                 solutionText->document()->print(&printer);
    309                 QApplication::restoreOverrideCursor();
    310                 return;
    311         }
    312 #endif
    313 #if QT_VERSION >= 0x040500
    314 QTextDocumentWriter dw(selectedFile);
    315         if (!(selectedFile.endsWith(".htm",Qt::CaseInsensitive) || selectedFile.endsWith(".html",Qt::CaseInsensitive) || selectedFile.endsWith(".odt",Qt::CaseInsensitive) || selectedFile.endsWith(".txt",Qt::CaseInsensitive)))
    316                 dw.setFormat("plaintext");
    317         dw.write(solutionText->document());
    318 #else
    319         // Qt < 4.5 has no QTextDocumentWriter class
    320 QFile file(selectedFile);
    321         if (!file.open(QFile::WriteOnly)) {
    322                 QApplication::restoreOverrideCursor();
    323                 return;
    324         }
    325 QTextStream ts(&file);
    326         ts.setCodec(QTextCodec::codecForName("UTF-8"));
    327         ts << solutionText->document()->toHtml("UTF-8");
    328         file.close();
    329 #endif // QT_VERSION >= 0x040500
    330         QApplication::restoreOverrideCursor();
     590void MainWindow::outputMatrix(tMatrix matrix, QStringList &output, int nRow, int nCol)
     591{
     592int n = spinCities->value();
     593QString line="";
     594        output.append("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">");
     595        for (int r = 0; r < n; r++) {
     596                line = "<tr>";
     597                for (int c = 0; c < n; c++) {
     598                        if (matrix[r][c] == INFINITY)
     599                                line += "<td align=\"center\">"INFSTR"</td>";
     600                        else if ((r == nRow) && (c == nCol))
     601                                line += "<td align=\"center\" class=\"selected\">" + QVariant(matrix[r][c]).toString() + "</td>";
     602                        else
     603                                line += "<td align=\"center\">" + QVariant(matrix[r][c]).toString() + "</td>";
     604                }
     605                line += "</tr>";
     606                output.append(line);
     607        }
     608        output.append("</table>");
    331609}
    332610
     
    355633}
    356634
    357 void MainWindow::actionSettingsPreferencesTriggered()
    358 {
    359 SettingsDialog sd(this);
    360         if (sd.exec() != QDialog::Accepted)
    361                 return;
    362         if (sd.colorChanged() || sd.fontChanged()) {
    363                 initDocStyleSheet();
    364                 if (!output.isEmpty() && sd.colorChanged() && (QMessageBox(QMessageBox::Question,trUtf8("Settings Changed"),trUtf8("You have changed color settings.\nDo you wish to apply them to current solution text?"),QMessageBox::Yes | QMessageBox::No,this).exec() == QMessageBox::Yes)) {
    365                         QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
    366                         solutionText->clear();
    367                         solutionText->setHtml(output.join(""));
    368                         QApplication::restoreOverrideCursor();
    369                 }
    370         }
    371 }
    372 
    373 #ifndef QT_NO_PRINTER
    374 void MainWindow::printPreview(QPrinter *printer)
    375 {
    376         solutionText->print(printer);
    377 }
    378 
    379 void MainWindow::actionFilePrintPreviewTriggered()
    380 {
    381 QPrintPreviewDialog ppd(printer, this);
    382     connect(&ppd,SIGNAL(paintRequested(QPrinter *)),SLOT(printPreview(QPrinter *)));
    383     ppd.exec();
    384 }
    385 
    386 void MainWindow::actionFilePrintTriggered()
    387 {
    388 QPrintDialog pd(printer,this);
    389 #if QT_VERSION >= 0x040500
    390         // No such methods in Qt < 4.5
    391         pd.setOption(QAbstractPrintDialog::PrintSelection,false);
    392         pd.setOption(QAbstractPrintDialog::PrintPageRange,false);
    393 #endif
    394         if (pd.exec() != QDialog::Accepted)
    395                 return;
    396         QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
    397         solutionText->document()->print(printer);
    398         QApplication::restoreOverrideCursor();
    399 }
    400 #endif // QT_NO_PRINTER
    401 
    402 void MainWindow::buttonRandomClicked()
    403 {
    404         QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
    405         tspmodel->randomize();
    406         QApplication::restoreOverrideCursor();
    407 }
    408 
    409 void MainWindow::buttonBackToTaskClicked()
    410 {
    411         tabWidget->setCurrentIndex(0);
    412 }
    413 
    414 void MainWindow::outputMatrix(tMatrix matrix, QStringList &output, int nRow, int nCol)
    415 {
    416 int n = spinCities->value();
    417 QString line="";
    418         output.append("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">");
    419         for (int r = 0; r < n; r++) {
    420                 line = "<tr>";
    421                 for (int c = 0; c < n; c++) {
    422                         if (matrix[r][c] == INFINITY)
    423                                 line += "<td align=\"center\">"INFSTR"</td>";
    424                         else if ((r == nRow) && (c == nCol))
    425                                 line += "<td align=\"center\" class=\"selected\">" + QVariant(matrix[r][c]).toString() + "</td>";
    426                         else
    427                                 line += "<td align=\"center\">" + QVariant(matrix[r][c]).toString() + "</td>";
    428                 }
    429                 line += "</tr>";
    430                 output.append(line);
    431         }
    432         output.append("</table>");
    433 }
    434 
    435 void MainWindow::buttonSolveClicked()
    436 {
    437 tMatrix matrix;
    438 QList<double> row;
    439 int n = spinCities->value();
    440 bool ok;
    441         for (int r = 0; r < n; r++) {
    442                 row.clear();
    443                 for (int c = 0; c < n; c++) {
    444                         row.append(tspmodel->index(r,c).data(Qt::UserRole).toDouble(&ok));
    445                         if (!ok) {
    446                                 QMessageBox(QMessageBox::Critical,trUtf8("Data error"),trUtf8("Error in cell [Row %1; Column %2]: Invalid data format.").arg(r + 1).arg(c + 1),QMessageBox::Ok,this).exec();
    447                                 return;
    448                         }
    449                 }
    450                 matrix.append(row);
    451         }
    452 CTSPSolver solver;
    453 sStep *root = solver.solve(n,matrix,this);
    454         if (!root)
    455                 return;
    456         QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
    457 QColor color = settings->value("Output/Color",DEF_FONT_COLOR).value<QColor>();
    458         output.clear();
    459         output.append("<p>" + trUtf8("Variant #%1").arg(spinVariant->value()) + "</p>");
    460         output.append("<p>" + trUtf8("Task:") + "</p>");
    461         outputMatrix(matrix,output);
    462         output.append("<hr>");
    463         output.append("<p>" + trUtf8("Solution of Variant #%1 task").arg(spinVariant->value()) + "</p>");
    464 sStep *step = root;
    465         n = 1;
    466         while (n <= spinCities->value()) {
    467                 if (step->prNode->prNode != NULL || (step->prNode->prNode == NULL && step->plNode->prNode == NULL)) {
    468                         if (n != spinCities->value()) {
    469                                 output.append("<p>" + trUtf8("Step #%1").arg(n++) + "</p>");
    470                                 outputMatrix(step->matrix,output,step->candidate.nRow,step->candidate.nCol);
    471                                 if (step->alts)
    472                                         output.append("<p class=\"hasalts\">" + trUtf8("This step has alternate candidates for branching.") + "</p>");
    473                                 output.append("<p>&nbsp;</p>");
    474                         }
    475                 }
    476                 if (step->prNode->prNode != NULL)
    477                         step = step->prNode;
    478                 else if (step->plNode->prNode != NULL)
    479                         step = step->plNode;
    480                 else
    481                         break;
    482         }
    483         if (solver.isOptimal())
    484                 output.append("<p>" + trUtf8("Optimal path:") + "</p>");
    485         else
    486                 output.append("<p>" + trUtf8("Resulting path:") + "</p>");
    487         output.append("<p>&nbsp;&nbsp;" + solver.getSortedPath() + "</p>");
    488         output.append("<p>" + trUtf8("The price is <b>%1</b> units.").arg(step->price) + "</p>");
    489         if (!solver.isOptimal()) {
    490                 output.append("<p>&nbsp;</p>");
    491                 output.append("<p>" + trUtf8("<b>WARNING!!!</b><br>This result is a record, but it may not be optimal.<br>Iterations need to be continued to check whether this result is optimal or get an optimal one.") + "</p>");
    492         }
    493         output.append("<p></p>");
    494         solutionText->setHtml(output.join(""));
    495         solutionText->setDocumentTitle(trUtf8("Solution of Variant #%1 task").arg(spinVariant->value()));
    496 
    497         // Scrolling to the end of text.
    498 QTextCursor cursor(solutionText->textCursor());
    499         cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
    500         solutionText->setTextCursor(cursor);
    501 
    502         enableSolutionActions();
    503         tabWidget->setCurrentIndex(1);
    504         QApplication::restoreOverrideCursor();
    505 }
    506 
    507 void MainWindow::actionHelpAboutTriggered()
    508 {
    509 //! \todo TODO: Normal about window :-)
    510 QString about = QString::fromUtf8("TSPSG: TSP Solver and Generator\n");
    511         about += QString::fromUtf8("    Version: "BUILD_VERSION"\n");
    512         about += QString::fromUtf8("    Copyright (C) 2007-%1 Lёppa <contacts[at]oleksii[dot]name>\n").arg(QDate::currentDate().toString("yyyy"));
    513         about += QString::fromUtf8("Target OS: %1\n").arg(OS);
    514         about += "Qt library:\n";
    515         about += QString::fromUtf8("    Compile time: %1\n").arg(QT_VERSION_STR);
    516         about += QString::fromUtf8("    Runtime: %1\n").arg(qVersion());
    517         about += QString::fromUtf8("Built on %1 at %2\n").arg(__DATE__).arg(__TIME__);
    518         about += QString::fromUtf8(VERSIONID"\n\n");
    519         about += QString::fromUtf8("Algorithm: %1\n").arg(CTSPSolver::getVersionId());
    520         about += "\n";
    521         about += "TSPSG is licensed under the terms of the GNU General Public License. You should have received a copy of the GNU General Public License along with TSPSG.";
    522         QMessageBox(QMessageBox::Information,"About",about,QMessageBox::Ok,this).exec();
    523 }
    524 
    525 void MainWindow::loadLangList()
    526 {
    527 QSettings langinfo(PATH_I18N"/languages.ini",QSettings::IniFormat);
    528 #if QT_VERSION >= 0x040500
    529         // In Qt < 4.5 QSettings doesn't have method setIniCodec.
    530         langinfo.setIniCodec("UTF-8");
    531 #endif
    532 QDir dir(PATH_I18N,"*.qm",QDir::Name | QDir::IgnoreCase,QDir::Files);
    533         if (!dir.exists())
    534                 return;
    535 QFileInfoList langs = dir.entryInfoList();
    536         if (langs.size() <= 0)
    537                 return;
    538 QAction *a;
    539         for (int k = 0; k < langs.size(); k++) {
    540                 QFileInfo lang = langs.at(k);
    541                 if (!lang.completeBaseName().startsWith("qt_") && lang.completeBaseName().compare("en")) {
    542 #if QT_VERSION >= 0x040500
    543                         a = menuSettingsLanguage->addAction(langinfo.value(lang.completeBaseName() + "/NativeName",lang.completeBaseName()).toString());
    544 #else
    545                         // We use Name if Qt < 4.5 because NativeName is in UTF-8, QSettings
    546                         // reads .ini file as ASCII and there is no way to set file encoding.
    547                         a = menuSettingsLanguage->addAction(langinfo.value(lang.completeBaseName() + "/Name",lang.completeBaseName()).toString());
    548 #endif
    549                         a->setData(lang.completeBaseName());
    550                         a->setCheckable(true);
    551                         a->setActionGroup(groupSettingsLanguageList);
    552                         if (settings->value("Language",QLocale::system().name()).toString().startsWith(lang.completeBaseName()))
    553                                 a->setChecked(true);
    554                 }
    555         }
    556 }
    557 
    558 void MainWindow::actionSettingsLanguageAutodetectTriggered(bool checked)
    559 {
    560         if (checked) {
    561                 settings->remove("Language");
    562                 QMessageBox(QMessageBox::Information,trUtf8("Language change"),trUtf8("Language will be autodetected on next application start."),QMessageBox::Ok,this).exec();
    563         } else
    564                 settings->setValue("Language",groupSettingsLanguageList->checkedAction()->data().toString());
    565 }
    566 
    567 void MainWindow::groupSettingsLanguageListTriggered(QAction *action)
    568 {
    569         if (actionSettingsLanguageAutodetect->isChecked()) {
    570                 // We have language autodetection. It needs to be disabled to change language.
    571                 if (QMessageBox(QMessageBox::Question,trUtf8("Language change"),trUtf8("You have language autodetection turned on.\nIt needs to be off.\nDo you wish to turn it off?"),QMessageBox::Yes | QMessageBox::No,this).exec() == QMessageBox::Yes) {
    572                         actionSettingsLanguageAutodetect->trigger();
    573                 } else
    574                         return;
    575         }
    576 bool untitled = (fileName == trUtf8("Untitled") + ".tspt");
    577         if (loadLanguage(action->data().toString())) {
    578                 settings->setValue("Language",action->data().toString());
    579                 retranslateUi(this);
    580                 if (untitled)
    581                         setFileName();
    582         }
    583 }
    584 
    585 /*!
    586  * \brief Handles Main Window close event.
    587  * \param event Close event.
    588  *
    589  *  Checks whether or not a current task was saved and asks for saving if not.
    590  *  Saves TSPSG settings.
    591  */
    592 void MainWindow::closeEvent(QCloseEvent *event)
    593 {
    594         if (!maybeSave()) {
    595                 event->ignore();
    596                 return;
    597         }
    598         settings->setValue("NumCities",spinCities->value());
    599 #ifndef Q_OS_WINCE
    600         // Saving windows state
    601         if (settings->value("SavePos",false).toBool()) {
    602                 settings->beginGroup("MainWindow");
    603                 settings->setValue("Maximized",isMaximized());
    604                 if (!isMaximized()) {
    605                         settings->setValue("Size",size());
    606                         settings->setValue("Position",pos());
    607                 }
    608                 settings->endGroup();
    609         }
    610 #endif // Q_OS_WINCE
    611         QMainWindow::closeEvent(event);
    612 }
    613 
    614 void MainWindow::dataChanged()
    615 {
    616         setWindowModified(true);
    617 }
    618 
    619 void MainWindow::dataChanged(const QModelIndex &tl, const QModelIndex &br)
    620 {
    621         setWindowModified(true);
    622         if (settings->value("Autosize",true).toBool()) {
    623                 for (int k = tl.row(); k <= br.row(); k++)
    624                         taskView->resizeRowToContents(k);
    625                 for (int k = tl.column(); k <= br.column(); k++)
    626                         taskView->resizeColumnToContents(k);
    627         }
    628 }
    629 
    630 void MainWindow::numCitiesChanged(int nCities)
    631 {
    632         blockSignals(true);
    633         spinCities->setValue(nCities);
    634         blockSignals(false);
    635 }
     635void MainWindow::setFileName(QString fileName)
     636{
     637        this->fileName = fileName;
     638        setWindowTitle(QString("%1[*] - %2").arg(QFileInfo(fileName).completeBaseName()).arg(trUtf8("Travelling Salesman Problem")));
     639}
Note: See TracChangeset for help on using the changeset viewer.