Index: src/mainwindow.cpp
===================================================================
--- src/mainwindow.cpp	(revision caef58b531b15aae84d82e4151b605f89a9b7877)
+++ src/mainwindow.cpp	(revision e0fcac5f2c6ab0bd37fa7a8c63ea43347c13fb7c)
@@ -115,4 +115,358 @@
 }
 
+/*!
+ * \brief Handles Main Window close event.
+ * \param event Close event.
+ *
+ *  Checks whether or not a current task was saved and asks for saving if not.
+ *  Saves TSPSG settings.
+ */
+void MainWindow::closeEvent(QCloseEvent *event)
+{
+	if (!maybeSave()) {
+		event->ignore();
+		return;
+	}
+	settings->setValue("NumCities",spinCities->value());
+#ifndef Q_OS_WINCE
+	// Saving windows state
+	if (settings->value("SavePos",false).toBool()) {
+		settings->beginGroup("MainWindow");
+		settings->setValue("Maximized",isMaximized());
+		if (!isMaximized()) {
+			settings->setValue("Size",size());
+			settings->setValue("Position",pos());
+		}
+		settings->endGroup();
+	}
+#endif // Q_OS_WINCE
+	QMainWindow::closeEvent(event);
+}
+
+/* Privates **********************************************************/
+
+void MainWindow::actionFileNewTriggered()
+{
+	if (!maybeSave())
+		return;
+	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+	tspmodel->clear();
+	setFileName();
+	setWindowModified(false);
+	tabWidget->setCurrentIndex(0);
+	solutionText->clear();
+	enableSolutionActions(false);
+	QApplication::restoreOverrideCursor();
+}
+
+void MainWindow::actionFileOpenTriggered()
+{
+	if (!maybeSave())
+		return;
+QFileDialog od(this);
+	od.setAcceptMode(QFileDialog::AcceptOpen);
+	od.setFileMode(QFileDialog::ExistingFile);
+QStringList filters(trUtf8("All Supported Formats") + " (*.tspt *.zkt)");
+	filters.append(trUtf8("%1 Task Files").arg("TSPSG") + " (*.tspt)");
+	filters.append(trUtf8("%1 Task Files").arg("ZKomModRd") + " (*.zkt)");
+	filters.append(trUtf8("All Files") + " (*)");
+	od.setNameFilters(filters);
+	if (od.exec() != QDialog::Accepted)
+		return;
+QStringList files = od.selectedFiles();
+	if (files.empty())
+		return;
+	if (!tspmodel->loadTask(files.first()))
+		return;
+	setFileName(files.first());
+	tabWidget->setCurrentIndex(0);
+	setWindowModified(false);
+	solutionText->clear();
+	enableSolutionActions(false);
+}
+
+void MainWindow::actionFileSaveTriggered()
+{
+	if ((fileName == trUtf8("Untitled") + ".tspt") || (!fileName.endsWith(".tspt",Qt::CaseInsensitive)))
+		saveTask();
+	else
+		if (tspmodel->saveTask(fileName))
+			setWindowModified(false);
+}
+
+void MainWindow::actionFileSaveAsTaskTriggered()
+{
+	saveTask();
+}
+
+void MainWindow::actionFileSaveAsSolutionTriggered()
+{
+static QString selectedFile;
+	if (selectedFile.isEmpty())
+#ifndef QT_NO_PRINTER
+		selectedFile = "solution.pdf";
+#else
+		selectedFile = "solution.html";
+#endif // QT_NO_PRINTER
+QFileDialog sd(this);
+	sd.setAcceptMode(QFileDialog::AcceptSave);
+QStringList filters;
+#ifndef QT_NO_PRINTER
+	filters.append(trUtf8("PDF Files") + "(*.pdf)");
+#endif
+	filters.append(trUtf8("HTML Files") + " (*.html *.htm)");
+#if QT_VERSION >= 0x040500
+	filters.append(trUtf8("OpenDocument Files") + " (*.odt)");
+#endif // QT_VERSION >= 0x040500
+	filters.append(trUtf8("All Files") + " (*)");
+	sd.setNameFilters(filters);
+	sd.selectFile(selectedFile);
+	if (sd.exec() != QDialog::Accepted)
+		return;
+QStringList files = sd.selectedFiles();
+	if (files.empty())
+		return;
+	selectedFile = files.first();
+	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+#ifndef QT_NO_PRINTER
+	if (selectedFile.endsWith(".pdf",Qt::CaseInsensitive)) {
+QPrinter printer(QPrinter::HighResolution);
+		printer.setOutputFormat(QPrinter::PdfFormat);
+		printer.setOutputFileName(selectedFile);
+		solutionText->document()->print(&printer);
+		QApplication::restoreOverrideCursor();
+		return;
+	}
+#endif
+#if QT_VERSION >= 0x040500
+QTextDocumentWriter dw(selectedFile);
+	if (!(selectedFile.endsWith(".htm",Qt::CaseInsensitive) || selectedFile.endsWith(".html",Qt::CaseInsensitive) || selectedFile.endsWith(".odt",Qt::CaseInsensitive) || selectedFile.endsWith(".txt",Qt::CaseInsensitive)))
+		dw.setFormat("plaintext");
+	dw.write(solutionText->document());
+#else
+	// Qt < 4.5 has no QTextDocumentWriter class
+QFile file(selectedFile);
+	if (!file.open(QFile::WriteOnly)) {
+		QApplication::restoreOverrideCursor();
+		return;
+	}
+QTextStream ts(&file);
+	ts.setCodec(QTextCodec::codecForName("UTF-8"));
+	ts << solutionText->document()->toHtml("UTF-8");
+	file.close();
+#endif // QT_VERSION >= 0x040500
+	QApplication::restoreOverrideCursor();
+}
+
+#ifndef QT_NO_PRINTER
+void MainWindow::actionFilePrintPreviewTriggered()
+{
+QPrintPreviewDialog ppd(printer, this);
+    connect(&ppd,SIGNAL(paintRequested(QPrinter *)),SLOT(printPreview(QPrinter *)));
+    ppd.exec();
+}
+
+void MainWindow::actionFilePrintTriggered()
+{
+QPrintDialog pd(printer,this);
+#if QT_VERSION >= 0x040500
+	// No such methods in Qt < 4.5
+	pd.setOption(QAbstractPrintDialog::PrintSelection,false);
+	pd.setOption(QAbstractPrintDialog::PrintPageRange,false);
+#endif
+	if (pd.exec() != QDialog::Accepted)
+		return;
+	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+	solutionText->document()->print(printer);
+	QApplication::restoreOverrideCursor();
+}
+#endif // QT_NO_PRINTER
+
+void MainWindow::actionSettingsPreferencesTriggered()
+{
+SettingsDialog sd(this);
+	if (sd.exec() != QDialog::Accepted)
+		return;
+	if (sd.colorChanged() || sd.fontChanged()) {
+		initDocStyleSheet();
+		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)) {
+			QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+			solutionText->clear();
+			solutionText->setHtml(output.join(""));
+			QApplication::restoreOverrideCursor();
+		}
+	}
+}
+
+void MainWindow::actionSettingsLanguageAutodetectTriggered(bool checked)
+{
+	if (checked) {
+		settings->remove("Language");
+		QMessageBox(QMessageBox::Information,trUtf8("Language change"),trUtf8("Language will be autodetected on next application start."),QMessageBox::Ok,this).exec();
+	} else
+		settings->setValue("Language",groupSettingsLanguageList->checkedAction()->data().toString());
+}
+
+void MainWindow::groupSettingsLanguageListTriggered(QAction *action)
+{
+	if (actionSettingsLanguageAutodetect->isChecked()) {
+		// We have language autodetection. It needs to be disabled to change language.
+		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) {
+			actionSettingsLanguageAutodetect->trigger();
+		} else
+			return;
+	}
+bool untitled = (fileName == trUtf8("Untitled") + ".tspt");
+	if (loadLanguage(action->data().toString())) {
+		settings->setValue("Language",action->data().toString());
+		retranslateUi(this);
+		if (untitled)
+			setFileName();
+	}
+}
+
+void MainWindow::actionHelpAboutTriggered()
+{
+//! \todo TODO: Normal about window :-)
+QString about = QString::fromUtf8("TSPSG: TSP Solver and Generator\n");
+	about += QString::fromUtf8("    Version: "BUILD_VERSION"\n");
+	about += QString::fromUtf8("    Copyright (C) 2007-%1 Lёppa <contacts[at]oleksii[dot]name>\n").arg(QDate::currentDate().toString("yyyy"));
+	about += QString::fromUtf8("Target OS: %1\n").arg(OS);
+	about += "Qt library:\n";
+	about += QString::fromUtf8("    Compile time: %1\n").arg(QT_VERSION_STR);
+	about += QString::fromUtf8("    Runtime: %1\n").arg(qVersion());
+	about += QString::fromUtf8("Built on %1 at %2\n").arg(__DATE__).arg(__TIME__);
+	about += QString::fromUtf8(VERSIONID"\n\n");
+	about += QString::fromUtf8("Algorithm: %1\n").arg(CTSPSolver::getVersionId());
+	about += "\n";
+	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.";
+	QMessageBox(QMessageBox::Information,"About",about,QMessageBox::Ok,this).exec();
+}
+
+void MainWindow::buttonBackToTaskClicked()
+{
+	tabWidget->setCurrentIndex(0);
+}
+
+void MainWindow::buttonRandomClicked()
+{
+	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+	tspmodel->randomize();
+	QApplication::restoreOverrideCursor();
+}
+
+void MainWindow::buttonSolveClicked()
+{
+tMatrix matrix;
+QList<double> row;
+int n = spinCities->value();
+bool ok;
+	for (int r = 0; r < n; r++) {
+		row.clear();
+		for (int c = 0; c < n; c++) {
+			row.append(tspmodel->index(r,c).data(Qt::UserRole).toDouble(&ok));
+			if (!ok) {
+				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();
+				return;
+			}
+		}
+		matrix.append(row);
+	}
+CTSPSolver solver;
+sStep *root = solver.solve(n,matrix,this);
+	if (!root)
+		return;
+	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+QColor color = settings->value("Output/Color",DEF_FONT_COLOR).value<QColor>();
+	output.clear();
+	output.append("<p>" + trUtf8("Variant #%1").arg(spinVariant->value()) + "</p>");
+	output.append("<p>" + trUtf8("Task:") + "</p>");
+	outputMatrix(matrix,output);
+	output.append("<hr>");
+	output.append("<p>" + trUtf8("Solution of Variant #%1 task").arg(spinVariant->value()) + "</p>");
+sStep *step = root;
+	n = 1;
+	while (n <= spinCities->value()) {
+		if (step->prNode->prNode != NULL || (step->prNode->prNode == NULL && step->plNode->prNode == NULL)) {
+			if (n != spinCities->value()) {
+				output.append("<p>" + trUtf8("Step #%1").arg(n++) + "</p>");
+				outputMatrix(step->matrix,output,step->candidate.nRow,step->candidate.nCol);
+				if (step->alts)
+					output.append("<p class=\"hasalts\">" + trUtf8("This step has alternate candidates for branching.") + "</p>");
+				output.append("<p>&nbsp;</p>");
+			}
+		}
+		if (step->prNode->prNode != NULL)
+			step = step->prNode;
+		else if (step->plNode->prNode != NULL)
+			step = step->plNode;
+		else
+			break;
+	}
+	if (solver.isOptimal())
+		output.append("<p>" + trUtf8("Optimal path:") + "</p>");
+	else
+		output.append("<p>" + trUtf8("Resulting path:") + "</p>");
+	output.append("<p>&nbsp;&nbsp;" + solver.getSortedPath() + "</p>");
+	output.append("<p>" + trUtf8("The price is <b>%1</b> units.").arg(step->price) + "</p>");
+	if (!solver.isOptimal()) {
+		output.append("<p>&nbsp;</p>");
+		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>");
+	}
+	output.append("<p></p>");
+	solutionText->setHtml(output.join(""));
+	solutionText->setDocumentTitle(trUtf8("Solution of Variant #%1 task").arg(spinVariant->value()));
+
+	// Scrolling to the end of text.
+QTextCursor cursor(solutionText->textCursor());
+	cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
+	solutionText->setTextCursor(cursor);
+
+	enableSolutionActions();
+	tabWidget->setCurrentIndex(1);
+	QApplication::restoreOverrideCursor();
+}
+
+void MainWindow::dataChanged()
+{
+	setWindowModified(true);
+}
+
+void MainWindow::dataChanged(const QModelIndex &tl, const QModelIndex &br)
+{
+	setWindowModified(true);
+	if (settings->value("Autosize",true).toBool()) {
+		for (int k = tl.row(); k <= br.row(); k++)
+			taskView->resizeRowToContents(k);
+		for (int k = tl.column(); k <= br.column(); k++)
+			taskView->resizeColumnToContents(k);
+	}
+}
+
+void MainWindow::numCitiesChanged(int nCities)
+{
+	blockSignals(true);
+	spinCities->setValue(nCities);
+	blockSignals(false);
+}
+
+#ifndef QT_NO_PRINTER
+void MainWindow::printPreview(QPrinter *printer)
+{
+	solutionText->print(printer);
+}
+#endif // QT_NO_PRINTER
+
+void MainWindow::spinCitiesValueChanged(int n)
+{
+int count = tspmodel->numCities();
+	tspmodel->setNumCities(n);
+	if ((n > count) && settings->value("Autosize",true).toBool())
+		for (int k = count; k < n; k++) {
+			taskView->resizeColumnToContents(k);
+			taskView->resizeRowToContents(k);
+		}
+}
+
 void MainWindow::enableSolutionActions(bool enable)
 {
@@ -126,4 +480,49 @@
 	actionFilePrintPreview->setEnabled(enable);
 #endif // QT_NO_PRINTER
+}
+
+void MainWindow::initDocStyleSheet()
+{
+QColor color = settings->value("Output/Color",DEF_FONT_COLOR).value<QColor>();
+QColor hilight;
+	if (color.value() < 192)
+		hilight.setHsv(color.hue(),color.saturation(),127 + qRound(color.value() / 2));
+	else
+		hilight.setHsv(color.hue(),color.saturation(),color.value() / 2);
+	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;}");
+	solutionText->document()->setDefaultFont(settings->value("Output/Font",QFont(DEF_FONT_FAMILY,DEF_FONT_SIZE)).value<QFont>());
+}
+
+void MainWindow::loadLangList()
+{
+QSettings langinfo(PATH_I18N"/languages.ini",QSettings::IniFormat);
+#if QT_VERSION >= 0x040500
+	// In Qt < 4.5 QSettings doesn't have method setIniCodec.
+	langinfo.setIniCodec("UTF-8");
+#endif
+QDir dir(PATH_I18N,"*.qm",QDir::Name | QDir::IgnoreCase,QDir::Files);
+	if (!dir.exists())
+		return;
+QFileInfoList langs = dir.entryInfoList();
+	if (langs.size() <= 0)
+		return;
+QAction *a;
+	for (int k = 0; k < langs.size(); k++) {
+		QFileInfo lang = langs.at(k);
+		if (!lang.completeBaseName().startsWith("qt_") && lang.completeBaseName().compare("en")) {
+#if QT_VERSION >= 0x040500
+			a = menuSettingsLanguage->addAction(langinfo.value(lang.completeBaseName() + "/NativeName",lang.completeBaseName()).toString());
+#else
+			// We use Name if Qt < 4.5 because NativeName is in UTF-8, QSettings
+			// reads .ini file as ASCII and there is no way to set file encoding.
+			a = menuSettingsLanguage->addAction(langinfo.value(lang.completeBaseName() + "/Name",lang.completeBaseName()).toString());
+#endif
+			a->setData(lang.completeBaseName());
+			a->setCheckable(true);
+			a->setActionGroup(groupSettingsLanguageList);
+			if (settings->value("Language",QLocale::system().name()).toString().startsWith(lang.completeBaseName()))
+				a->setChecked(true);
+		}
+	}
 }
 
@@ -176,33 +575,4 @@
 }
 
-void MainWindow::initDocStyleSheet()
-{
-QColor color = settings->value("Output/Color",DEF_FONT_COLOR).value<QColor>();
-QColor hilight;
-	if (color.value() < 192)
-		hilight.setHsv(color.hue(),color.saturation(),127 + qRound(color.value() / 2));
-	else
-		hilight.setHsv(color.hue(),color.saturation(),color.value() / 2);
-	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;}");
-	solutionText->document()->setDefaultFont(settings->value("Output/Font",QFont(DEF_FONT_FAMILY,DEF_FONT_SIZE)).value<QFont>());
-}
-
-void MainWindow::setFileName(QString fileName)
-{
-	this->fileName = fileName;
-	setWindowTitle(QString("%1[*] - %2").arg(QFileInfo(fileName).completeBaseName()).arg(trUtf8("Travelling Salesman Problem")));
-}
-
-void MainWindow::spinCitiesValueChanged(int n)
-{
-int count = tspmodel->numCities();
-	tspmodel->setNumCities(n);
-	if ((n > count) && settings->value("Autosize",true).toBool())
-		for (int k = count; k < n; k++) {
-			taskView->resizeColumnToContents(k);
-			taskView->resizeRowToContents(k);
-		}
-}
-
 bool MainWindow::maybeSave()
 {
@@ -218,115 +588,23 @@
 }
 
-void MainWindow::actionFileNewTriggered()
-{
-	if (!maybeSave())
-		return;
-	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-	tspmodel->clear();
-	setFileName();
-	setWindowModified(false);
-	tabWidget->setCurrentIndex(0);
-	solutionText->clear();
-	enableSolutionActions(false);
-	QApplication::restoreOverrideCursor();
-}
-
-void MainWindow::actionFileOpenTriggered()
-{
-	if (!maybeSave())
-		return;
-QFileDialog od(this);
-	od.setAcceptMode(QFileDialog::AcceptOpen);
-	od.setFileMode(QFileDialog::ExistingFile);
-QStringList filters(trUtf8("All Supported Formats") + " (*.tspt *.zkt)");
-	filters.append(trUtf8("%1 Task Files").arg("TSPSG") + " (*.tspt)");
-	filters.append(trUtf8("%1 Task Files").arg("ZKomModRd") + " (*.zkt)");
-	filters.append(trUtf8("All Files") + " (*)");
-	od.setNameFilters(filters);
-	if (od.exec() != QDialog::Accepted)
-		return;
-QStringList files = od.selectedFiles();
-	if (files.empty())
-		return;
-	if (!tspmodel->loadTask(files.first()))
-		return;
-	setFileName(files.first());
-	tabWidget->setCurrentIndex(0);
-	setWindowModified(false);
-	solutionText->clear();
-	enableSolutionActions(false);
-}
-
-void MainWindow::actionFileSaveTriggered()
-{
-	if ((fileName == trUtf8("Untitled") + ".tspt") || (!fileName.endsWith(".tspt",Qt::CaseInsensitive)))
-		saveTask();
-	else
-		if (tspmodel->saveTask(fileName))
-			setWindowModified(false);
-}
-
-void MainWindow::actionFileSaveAsTaskTriggered()
-{
-	saveTask();
-}
-
-void MainWindow::actionFileSaveAsSolutionTriggered()
-{
-static QString selectedFile;
-	if (selectedFile.isEmpty())
-#ifndef QT_NO_PRINTER
-		selectedFile = "solution.pdf";
-#else
-		selectedFile = "solution.html";
-#endif // QT_NO_PRINTER
-QFileDialog sd(this);
-	sd.setAcceptMode(QFileDialog::AcceptSave);
-QStringList filters;
-#ifndef QT_NO_PRINTER
-	filters.append(trUtf8("PDF Files") + "(*.pdf)");
-#endif
-	filters.append(trUtf8("HTML Files") + " (*.html *.htm)");
-#if QT_VERSION >= 0x040500
-	filters.append(trUtf8("OpenDocument Files") + " (*.odt)");
-#endif // QT_VERSION >= 0x040500
-	filters.append(trUtf8("All Files") + " (*)");
-	sd.setNameFilters(filters);
-	sd.selectFile(selectedFile);
-	if (sd.exec() != QDialog::Accepted)
-		return;
-QStringList files = sd.selectedFiles();
-	if (files.empty())
-		return;
-	selectedFile = files.first();
-	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-#ifndef QT_NO_PRINTER
-	if (selectedFile.endsWith(".pdf",Qt::CaseInsensitive)) {
-QPrinter printer(QPrinter::HighResolution);
-		printer.setOutputFormat(QPrinter::PdfFormat);
-		printer.setOutputFileName(selectedFile);
-		solutionText->document()->print(&printer);
-		QApplication::restoreOverrideCursor();
-		return;
-	}
-#endif
-#if QT_VERSION >= 0x040500
-QTextDocumentWriter dw(selectedFile);
-	if (!(selectedFile.endsWith(".htm",Qt::CaseInsensitive) || selectedFile.endsWith(".html",Qt::CaseInsensitive) || selectedFile.endsWith(".odt",Qt::CaseInsensitive) || selectedFile.endsWith(".txt",Qt::CaseInsensitive)))
-		dw.setFormat("plaintext");
-	dw.write(solutionText->document());
-#else
-	// Qt < 4.5 has no QTextDocumentWriter class
-QFile file(selectedFile);
-	if (!file.open(QFile::WriteOnly)) {
-		QApplication::restoreOverrideCursor();
-		return;
-	}
-QTextStream ts(&file);
-	ts.setCodec(QTextCodec::codecForName("UTF-8"));
-	ts << solutionText->document()->toHtml("UTF-8");
-	file.close();
-#endif // QT_VERSION >= 0x040500
-	QApplication::restoreOverrideCursor();
+void MainWindow::outputMatrix(tMatrix matrix, QStringList &output, int nRow, int nCol)
+{
+int n = spinCities->value();
+QString line="";
+	output.append("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">");
+	for (int r = 0; r < n; r++) {
+		line = "<tr>";
+		for (int c = 0; c < n; c++) {
+			if (matrix[r][c] == INFINITY)
+				line += "<td align=\"center\">"INFSTR"</td>";
+			else if ((r == nRow) && (c == nCol))
+				line += "<td align=\"center\" class=\"selected\">" + QVariant(matrix[r][c]).toString() + "</td>";
+			else
+				line += "<td align=\"center\">" + QVariant(matrix[r][c]).toString() + "</td>";
+		}
+		line += "</tr>";
+		output.append(line);
+	}
+	output.append("</table>");
 }
 
@@ -355,281 +633,7 @@
 }
 
-void MainWindow::actionSettingsPreferencesTriggered()
-{
-SettingsDialog sd(this);
-	if (sd.exec() != QDialog::Accepted)
-		return;
-	if (sd.colorChanged() || sd.fontChanged()) {
-		initDocStyleSheet();
-		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)) {
-			QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-			solutionText->clear();
-			solutionText->setHtml(output.join(""));
-			QApplication::restoreOverrideCursor();
-		}
-	}
-}
-
-#ifndef QT_NO_PRINTER
-void MainWindow::printPreview(QPrinter *printer)
-{
-	solutionText->print(printer);
-}
-
-void MainWindow::actionFilePrintPreviewTriggered()
-{
-QPrintPreviewDialog ppd(printer, this);
-    connect(&ppd,SIGNAL(paintRequested(QPrinter *)),SLOT(printPreview(QPrinter *)));
-    ppd.exec();
-}
-
-void MainWindow::actionFilePrintTriggered()
-{
-QPrintDialog pd(printer,this);
-#if QT_VERSION >= 0x040500
-	// No such methods in Qt < 4.5
-	pd.setOption(QAbstractPrintDialog::PrintSelection,false);
-	pd.setOption(QAbstractPrintDialog::PrintPageRange,false);
-#endif
-	if (pd.exec() != QDialog::Accepted)
-		return;
-	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-	solutionText->document()->print(printer);
-	QApplication::restoreOverrideCursor();
-}
-#endif // QT_NO_PRINTER
-
-void MainWindow::buttonRandomClicked()
-{
-	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-	tspmodel->randomize();
-	QApplication::restoreOverrideCursor();
-}
-
-void MainWindow::buttonBackToTaskClicked()
-{
-	tabWidget->setCurrentIndex(0);
-}
-
-void MainWindow::outputMatrix(tMatrix matrix, QStringList &output, int nRow, int nCol)
-{
-int n = spinCities->value();
-QString line="";
-	output.append("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">");
-	for (int r = 0; r < n; r++) {
-		line = "<tr>";
-		for (int c = 0; c < n; c++) {
-			if (matrix[r][c] == INFINITY)
-				line += "<td align=\"center\">"INFSTR"</td>";
-			else if ((r == nRow) && (c == nCol))
-				line += "<td align=\"center\" class=\"selected\">" + QVariant(matrix[r][c]).toString() + "</td>";
-			else
-				line += "<td align=\"center\">" + QVariant(matrix[r][c]).toString() + "</td>";
-		}
-		line += "</tr>";
-		output.append(line);
-	}
-	output.append("</table>");
-}
-
-void MainWindow::buttonSolveClicked()
-{
-tMatrix matrix;
-QList<double> row;
-int n = spinCities->value();
-bool ok;
-	for (int r = 0; r < n; r++) {
-		row.clear();
-		for (int c = 0; c < n; c++) {
-			row.append(tspmodel->index(r,c).data(Qt::UserRole).toDouble(&ok));
-			if (!ok) {
-				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();
-				return;
-			}
-		}
-		matrix.append(row);
-	}
-CTSPSolver solver;
-sStep *root = solver.solve(n,matrix,this);
-	if (!root)
-		return;
-	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-QColor color = settings->value("Output/Color",DEF_FONT_COLOR).value<QColor>();
-	output.clear();
-	output.append("<p>" + trUtf8("Variant #%1").arg(spinVariant->value()) + "</p>");
-	output.append("<p>" + trUtf8("Task:") + "</p>");
-	outputMatrix(matrix,output);
-	output.append("<hr>");
-	output.append("<p>" + trUtf8("Solution of Variant #%1 task").arg(spinVariant->value()) + "</p>");
-sStep *step = root;
-	n = 1;
-	while (n <= spinCities->value()) {
-		if (step->prNode->prNode != NULL || (step->prNode->prNode == NULL && step->plNode->prNode == NULL)) {
-			if (n != spinCities->value()) {
-				output.append("<p>" + trUtf8("Step #%1").arg(n++) + "</p>");
-				outputMatrix(step->matrix,output,step->candidate.nRow,step->candidate.nCol);
-				if (step->alts)
-					output.append("<p class=\"hasalts\">" + trUtf8("This step has alternate candidates for branching.") + "</p>");
-				output.append("<p>&nbsp;</p>");
-			}
-		}
-		if (step->prNode->prNode != NULL)
-			step = step->prNode;
-		else if (step->plNode->prNode != NULL)
-			step = step->plNode;
-		else
-			break;
-	}
-	if (solver.isOptimal())
-		output.append("<p>" + trUtf8("Optimal path:") + "</p>");
-	else
-		output.append("<p>" + trUtf8("Resulting path:") + "</p>");
-	output.append("<p>&nbsp;&nbsp;" + solver.getSortedPath() + "</p>");
-	output.append("<p>" + trUtf8("The price is <b>%1</b> units.").arg(step->price) + "</p>");
-	if (!solver.isOptimal()) {
-		output.append("<p>&nbsp;</p>");
-		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>");
-	}
-	output.append("<p></p>");
-	solutionText->setHtml(output.join(""));
-	solutionText->setDocumentTitle(trUtf8("Solution of Variant #%1 task").arg(spinVariant->value()));
-
-	// Scrolling to the end of text.
-QTextCursor cursor(solutionText->textCursor());
-	cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
-	solutionText->setTextCursor(cursor);
-
-	enableSolutionActions();
-	tabWidget->setCurrentIndex(1);
-	QApplication::restoreOverrideCursor();
-}
-
-void MainWindow::actionHelpAboutTriggered()
-{
-//! \todo TODO: Normal about window :-)
-QString about = QString::fromUtf8("TSPSG: TSP Solver and Generator\n");
-	about += QString::fromUtf8("    Version: "BUILD_VERSION"\n");
-	about += QString::fromUtf8("    Copyright (C) 2007-%1 Lёppa <contacts[at]oleksii[dot]name>\n").arg(QDate::currentDate().toString("yyyy"));
-	about += QString::fromUtf8("Target OS: %1\n").arg(OS);
-	about += "Qt library:\n";
-	about += QString::fromUtf8("    Compile time: %1\n").arg(QT_VERSION_STR);
-	about += QString::fromUtf8("    Runtime: %1\n").arg(qVersion());
-	about += QString::fromUtf8("Built on %1 at %2\n").arg(__DATE__).arg(__TIME__);
-	about += QString::fromUtf8(VERSIONID"\n\n");
-	about += QString::fromUtf8("Algorithm: %1\n").arg(CTSPSolver::getVersionId());
-	about += "\n";
-	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.";
-	QMessageBox(QMessageBox::Information,"About",about,QMessageBox::Ok,this).exec();
-}
-
-void MainWindow::loadLangList()
-{
-QSettings langinfo(PATH_I18N"/languages.ini",QSettings::IniFormat);
-#if QT_VERSION >= 0x040500
-	// In Qt < 4.5 QSettings doesn't have method setIniCodec.
-	langinfo.setIniCodec("UTF-8");
-#endif
-QDir dir(PATH_I18N,"*.qm",QDir::Name | QDir::IgnoreCase,QDir::Files);
-	if (!dir.exists())
-		return;
-QFileInfoList langs = dir.entryInfoList();
-	if (langs.size() <= 0)
-		return;
-QAction *a;
-	for (int k = 0; k < langs.size(); k++) {
-		QFileInfo lang = langs.at(k);
-		if (!lang.completeBaseName().startsWith("qt_") && lang.completeBaseName().compare("en")) {
-#if QT_VERSION >= 0x040500
-			a = menuSettingsLanguage->addAction(langinfo.value(lang.completeBaseName() + "/NativeName",lang.completeBaseName()).toString());
-#else
-			// We use Name if Qt < 4.5 because NativeName is in UTF-8, QSettings
-			// reads .ini file as ASCII and there is no way to set file encoding.
-			a = menuSettingsLanguage->addAction(langinfo.value(lang.completeBaseName() + "/Name",lang.completeBaseName()).toString());
-#endif
-			a->setData(lang.completeBaseName());
-			a->setCheckable(true);
-			a->setActionGroup(groupSettingsLanguageList);
-			if (settings->value("Language",QLocale::system().name()).toString().startsWith(lang.completeBaseName()))
-				a->setChecked(true);
-		}
-	}
-}
-
-void MainWindow::actionSettingsLanguageAutodetectTriggered(bool checked)
-{
-	if (checked) {
-		settings->remove("Language");
-		QMessageBox(QMessageBox::Information,trUtf8("Language change"),trUtf8("Language will be autodetected on next application start."),QMessageBox::Ok,this).exec();
-	} else
-		settings->setValue("Language",groupSettingsLanguageList->checkedAction()->data().toString());
-}
-
-void MainWindow::groupSettingsLanguageListTriggered(QAction *action)
-{
-	if (actionSettingsLanguageAutodetect->isChecked()) {
-		// We have language autodetection. It needs to be disabled to change language.
-		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) {
-			actionSettingsLanguageAutodetect->trigger();
-		} else
-			return;
-	}
-bool untitled = (fileName == trUtf8("Untitled") + ".tspt");
-	if (loadLanguage(action->data().toString())) {
-		settings->setValue("Language",action->data().toString());
-		retranslateUi(this);
-		if (untitled)
-			setFileName();
-	}
-}
-
-/*!
- * \brief Handles Main Window close event.
- * \param event Close event.
- *
- *  Checks whether or not a current task was saved and asks for saving if not.
- *  Saves TSPSG settings.
- */
-void MainWindow::closeEvent(QCloseEvent *event)
-{
-	if (!maybeSave()) {
-		event->ignore();
-		return;
-	}
-	settings->setValue("NumCities",spinCities->value());
-#ifndef Q_OS_WINCE
-	// Saving windows state
-	if (settings->value("SavePos",false).toBool()) {
-		settings->beginGroup("MainWindow");
-		settings->setValue("Maximized",isMaximized());
-		if (!isMaximized()) {
-			settings->setValue("Size",size());
-			settings->setValue("Position",pos());
-		}
-		settings->endGroup();
-	}
-#endif // Q_OS_WINCE
-	QMainWindow::closeEvent(event);
-}
-
-void MainWindow::dataChanged()
-{
-	setWindowModified(true);
-}
-
-void MainWindow::dataChanged(const QModelIndex &tl, const QModelIndex &br)
-{
-	setWindowModified(true);
-	if (settings->value("Autosize",true).toBool()) {
-		for (int k = tl.row(); k <= br.row(); k++)
-			taskView->resizeRowToContents(k);
-		for (int k = tl.column(); k <= br.column(); k++)
-			taskView->resizeColumnToContents(k);
-	}
-}
-
-void MainWindow::numCitiesChanged(int nCities)
-{
-	blockSignals(true);
-	spinCities->setValue(nCities);
-	blockSignals(false);
-}
+void MainWindow::setFileName(QString fileName)
+{
+	this->fileName = fileName;
+	setWindowTitle(QString("%1[*] - %2").arg(QFileInfo(fileName).completeBaseName()).arg(trUtf8("Travelling Salesman Problem")));
+}
