Index: src/mainwindow.cpp
===================================================================
--- src/mainwindow.cpp	(revision d2820c3a1f10ce51a7d40efd3ecc98eeb0949ada)
+++ src/mainwindow.cpp	(revision 43c29c04ba146d9b12f2aa85a216d9536a546555)
@@ -23,4 +23,8 @@
 
 #include "mainwindow.h"
+
+#ifdef Q_OS_WIN32
+	#include "shobjidl.h"
+#endif
 
 #ifdef _T_T_L_
@@ -436,4 +440,6 @@
 void MainWindow::actionHelpAboutTriggered()
 {
+	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+
 QString title;
 #ifdef HANDHELD
@@ -462,25 +468,49 @@
 	about += QString("%1: <b>%2</b><br>").arg(tr("Algorithm"), CTSPSolver::getVersionId());
 	about += "<br>";
-	about += tr("TSPSG is free software: you can redistribute it and/or modify it<br>"
-		"under the terms of the GNU General Public License as published<br>"
-		"by the Free Software Foundation, either version 3 of the License,<br>"
-		"or (at your option) any later version.<br>"
-		"<br>"
-		"TSPSG is distributed in the hope that it will be useful, but<br>"
-		"WITHOUT ANY WARRANTY; without even the implied warranty of<br>"
-		"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>"
-		"GNU General Public License for more details.<br>"
-		"<br>"
-		"You should have received a copy of the GNU General Public License<br>"
-		"along with TSPSG.  If not, see <a href=\"http://www.gnu.org/licenses/\">http://www.gnu.org/licenses/</a>.");
+	about += tr("This program is free software: you can redistribute it and/or modify<br>\n"
+		"it under the terms of the GNU General Public License as published by<br>\n"
+		"the Free Software Foundation, either version 3 of the License, or<br>\n"
+		"(at your option) any later version.<br>\n"
+		"<br>\n"
+		"This program is distributed in the hope that it will be useful,<br>\n"
+		"but WITHOUT ANY WARRANTY; without even the implied warranty of<br>\n"
+		"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>\n"
+		"GNU General Public License for more details.<br>\n"
+		"<br>\n"
+		"You should have received a copy of the GNU General Public License<br>\n"
+		"along with TSPSG.  If not, see <a href=\"http://www.gnu.org/licenses/\">www.gnu.org/licenses/</a>.");
+
+QString credits;
+	credits += tr("This software was created using LGPL version of <b>Qt framework</b>,<br>\n"
+		"see <a href=\"http://qt.nokia.com/\">qt.nokia.com</a><br>\n"
+		"<br>\n"
+		"Most icons used in this software are part of <b>Oxygen Icons</b> project "
+		"licensed according to the GNU Lesser General Public License,<br>\n"
+		"see <a href=\"http://www.oxygen-icons.org/\">www.oxygen-icons.org</a><br>\n"
+		"<br>\n"
+		"Country flag icons used in this software are part of the free "
+		"<b>Flag Icons</b> collection created by <b>IconDrawer</b>,<br>\n"
+		"see <a href=\"http://www.icondrawer.com/\">www.icondrawer.com</a>");
+
+QFile f(":/files/COPYING");
+	f.open(QIODevice::ReadOnly);
+
+QString translation = QApplication::translate("--------", "AUTHORS %1", "Please, provide translator credits here. %1 will be replaced with VERSION");
+	if ((translation != "AUTHORS %1") && (translation.contains("%1"))) {
+QString about = QApplication::translate("--------", "VERSION", "Please, provide your translation version here.");
+		if (about != "VERSION")
+			translation = translation.arg(about);
+	}
 
 QDialog *dlg = new QDialog(this);
 QLabel *lblIcon = new QLabel(dlg),
-	*lblTitle = new QLabel(dlg),
-	*lblTranslated = new QLabel(dlg);
+	*lblTitle = new QLabel(dlg);
 #ifdef HANDHELD
 QLabel *lblSubTitle = new QLabel(QString("<b>&copy; 2007-%1 <a href=\"http://%2/\">%3</a></b>").arg(QDate::currentDate().toString("yyyy"), QApplication::organizationDomain(), QApplication::organizationName()), dlg);
 #endif // HANDHELD
+QTabWidget *tabs = new QTabWidget(dlg);
 QTextBrowser *txtAbout = new QTextBrowser(dlg);
+QTextBrowser *txtLicense = new QTextBrowser(dlg);
+QTextBrowser *txtCredits = new QTextBrowser(dlg);
 QVBoxLayout *vb = new QVBoxLayout();
 QHBoxLayout *hb1 = new QHBoxLayout(),
@@ -509,23 +539,19 @@
 	txtAbout->setHtml(about);
 	txtAbout->moveCursor(QTextCursor::Start);
-#ifndef HANDHELD
-	txtAbout->setStyleSheet(QString("QTextBrowser {background-color: %1; border-color: %2; border-width: 1px; border-style: solid; border-radius: 4px; padding: 1px;}").arg(palette().base().color().name(), palette().shadow().color().name()));
-#endif // HANDHELD
+	txtAbout->setFrameShape(QFrame::NoFrame);
+
+//	txtCredits->setWordWrapMode(QTextOption::NoWrap);
+	txtCredits->setOpenExternalLinks(true);
+	txtCredits->setHtml(credits);
+	txtCredits->moveCursor(QTextCursor::Start);
+	txtCredits->setFrameShape(QFrame::NoFrame);
+
+	txtLicense->setWordWrapMode(QTextOption::NoWrap);
+	txtLicense->setOpenExternalLinks(true);
+	txtLicense->setText(f.readAll());
+	txtLicense->moveCursor(QTextCursor::Start);
+	txtLicense->setFrameShape(QFrame::NoFrame);
 
 	bb->button(QDialogButtonBox::Ok)->setCursor(QCursor(Qt::PointingHandCursor));
-
-	lblTranslated->setText(QApplication::translate("--------", "AUTHORS", "Please, provide translator credits here."));
-	if (lblTranslated->text() == "AUTHORS")
-		lblTranslated->hide();
-	else {
-		lblTranslated->setOpenExternalLinks(true);
-#ifndef HANDHELD
-		lblTranslated->setStyleSheet(QString("QLabel {background-color: %1; border-color: %2; border-width: 1px; border-style: solid; border-radius: 3px; padding: 1px;}").arg(palette().alternateBase().color().name(), palette().shadow().color().name()));
-#endif // HANDHELD
-		hb2->addWidget(lblTranslated);
-	}
-
-	// This one isn't displayed anywhere, yet. Provided as a placeholder for future use.
-	QApplication::translate("--------", "VERSION", "Please, provide your translation version here.");
 
 	hb2->addWidget(bb);
@@ -538,5 +564,23 @@
 	vb->addWidget(lblSubTitle);
 #endif // HANDHELD
-	vb->addWidget(txtAbout);
+
+	tabs->addTab(txtAbout, tr("About"));
+	tabs->addTab(txtLicense, tr("License"));
+	tabs->addTab(txtCredits, tr("Credits"));
+	if (translation != "AUTHORS %1") {
+QTextBrowser *txtTranslation = new QTextBrowser(dlg);
+//		txtTranslation->setWordWrapMode(QTextOption::NoWrap);
+		txtTranslation->setOpenExternalLinks(true);
+		txtTranslation->setText(translation);
+		txtTranslation->moveCursor(QTextCursor::Start);
+		txtTranslation->setFrameShape(QFrame::NoFrame);
+
+		tabs->addTab(txtTranslation, tr("Translation"));
+	}
+#ifndef HANDHELD
+	tabs->setStyleSheet(QString("QTabWidget::pane {background-color: %1; border-color: %3; border-width: 1px; border-style: solid; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; padding: 1px;} QTabBar::tab {background-color: %2; border-color: %3; border-width: 1px; border-style: solid; border-bottom: none; border-top-left-radius: 4px; border-top-right-radius: 4px; padding: 2px 6px;} QTabBar::tab:selected {background-color: %4;} QTabBar::tab:!selected {margin-top: 1px;}").arg(palette().base().color().name(), palette().button().color().name(), palette().shadow().color().name(), palette().light().color().name()));
+#endif // HANDHELD
+
+	vb->addWidget(tabs);
 	vb->addLayout(hb2);
 
@@ -556,4 +600,5 @@
 
 	dlg->resize(450, 350);
+	QApplication::restoreOverrideCursor();
 
 	dlg->exec();
@@ -597,4 +642,8 @@
 	pb->setFormat(tr("%v of %1 parts found").arg(n));
 	pd.setBar(pb);
+QPushButton *cancel = new QPushButton(&pd);
+	cancel->setIcon(QIcon::fromTheme("dialog-cancel", QIcon(":/images/icons/dialog-cancel.png")));
+	cancel->setText(QApplication::translate("QProgressDialog", "Cancel", "No need to translate this. This translation will be taken from Qt translation files."));
+	pd.setCancelButton(cancel);
 	pd.setMaximum(n);
 	pd.setAutoReset(false);
@@ -605,14 +654,67 @@
 	pd.show();
 
+#ifdef Q_OS_WIN32
+HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (LPVOID*)&tl);
+	if (SUCCEEDED(hr)) {
+		hr = tl->HrInit();
+		if (FAILED(hr)) {
+			tl->Release();
+			tl = NULL;
+		} else {
+//			tl->SetProgressState(winId(), TBPF_INDETERMINATE);
+			tl->SetProgressValue(winId(), 0, n * 2);
+		}
+	}
+#endif
+
 CTSPSolver solver;
+	solver.setCleanupOnCancel(false);
 	connect(&solver, SIGNAL(routePartFound(int)), &pd, SLOT(setValue(int)));
 	connect(&pd, SIGNAL(canceled()), &solver, SLOT(cancel()));
+#ifdef Q_OS_WIN32
+	if (tl != NULL)
+		connect(&solver, SIGNAL(routePartFound(int)), SLOT(solverRoutePartFound(int)));
+#endif
 SStep *root = solver.solve(n, matrix);
+#ifdef Q_OS_WIN32
+	if (tl != NULL)
+		disconnect(&solver, SIGNAL(routePartFound(int)), this, SLOT(solverRoutePartFound(int)));
+#endif
 	disconnect(&solver, SIGNAL(routePartFound(int)), &pd, SLOT(setValue(int)));
 	disconnect(&pd, SIGNAL(canceled()), &solver, SLOT(cancel()));
 	if (!root) {
 		pd.reset();
-		if (!solver.wasCanceled())
+		if (!solver.wasCanceled()) {
+#ifdef Q_OS_WIN32
+			if (tl != NULL) {
+//				tl->SetProgressValue(winId(), n, n * 2);
+				tl->SetProgressState(winId(), TBPF_ERROR);
+			}
+#endif
+			QApplication::alert(this);
 			QMessageBox::warning(this, tr("Solution Result"), tr("Unable to find a solution.\nMaybe, this task has no solution."));
+		}
+		pd.setLabelText(tr("Cleaning up..."));
+		pd.setMaximum(0);
+		pd.setCancelButton(NULL);
+		pd.show();
+#ifdef Q_OS_WIN32
+		if (tl != NULL)
+			tl->SetProgressState(winId(), TBPF_INDETERMINATE);
+#endif
+		QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+
+QFuture<void> f = QtConcurrent::run(&solver, &CTSPSolver::cleanup, false);
+		while (!f.isFinished()) {
+			QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+		}
+		pd.reset();
+#ifdef Q_OS_WIN32
+		if (tl != NULL) {
+			tl->SetProgressState(winId(), TBPF_NOPROGRESS);
+			tl->Release();
+			tl = NULL;
+		}
+#endif
 		return;
 	}
@@ -621,4 +723,9 @@
 	pd.setMaximum(solver.getTotalSteps() + 1);
 	pd.setValue(0);
+
+#ifdef Q_OS_WIN32
+	if (tl != NULL)
+		tl->SetProgressValue(winId(), spinCities->value(), spinCities->value() + solver.getTotalSteps() + 1);
+#endif
 
 	solutionText->clear();
@@ -665,10 +772,28 @@
 			pd.show();
 			QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
-			solver.cleanup(true);
+#ifdef Q_OS_WIN32
+			if (tl != NULL)
+				tl->SetProgressState(winId(), TBPF_INDETERMINATE);
+#endif
+QFuture<void> f = QtConcurrent::run(&solver, &CTSPSolver::cleanup, false);
+			while (!f.isFinished()) {
+				QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+			}
 			solutionText->clear();
 			toggleSolutionActions(false);
+#ifdef Q_OS_WIN32
+			if (tl != NULL) {
+				tl->SetProgressState(winId(), TBPF_NOPROGRESS);
+				tl->Release();
+				tl = NULL;
+			}
+#endif
 			return;
 		}
 		pd.setValue(n);
+#ifdef Q_OS_WIN32
+		if (tl != NULL)
+			tl->SetProgressValue(winId(), spinCities->value() + n, spinCities->value() + solver.getTotalSteps() + 1);
+#endif
 
 		cur.beginEditBlock();
@@ -713,4 +838,8 @@
 	pb->setFormat(tr("Generating footer"));
 	pd.setValue(n);
+#ifdef Q_OS_WIN32
+	if (tl != NULL)
+		tl->SetProgressValue(winId(), spinCities->value() + n, spinCities->value() + solver.getTotalSteps() + 1);
+#endif
 
 	cur.beginEditBlock();
@@ -764,7 +893,24 @@
 	pd.setCancelButton(NULL);
 	QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
-	solver.cleanup(true);
+#ifdef Q_OS_WIN32
+	if (tl != NULL)
+		tl->SetProgressState(winId(), TBPF_INDETERMINATE);
+#endif
+QFuture<void> f = QtConcurrent::run(&solver, &CTSPSolver::cleanup, false);
+	while (!f.isFinished()) {
+		QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+	}
 	toggleSolutionActions();
 	tabWidget->setCurrentIndex(1);
+#ifdef Q_OS_WIN32
+	if (tl != NULL) {
+		tl->SetProgressState(winId(), TBPF_NOPROGRESS);
+		tl->Release();
+		tl = NULL;
+	}
+#endif
+
+	pd.reset();
+	QApplication::alert(this, 3000);
 }
 
@@ -833,4 +979,15 @@
 }
 #endif // QT_NO_PRINTER
+
+#ifdef Q_OS_WIN32
+void MainWindow::solverRoutePartFound(int n)
+{
+#ifdef Q_OS_WIN32
+	tl->SetProgressValue(winId(), n, spinCities->value() * 2);
+#else
+	Q_UNUSED(n);
+#endif // Q_OS_WIN32
+}
+#endif // Q_OS_WIN32
 
 void MainWindow::spinCitiesValueChanged(int n)
Index: src/mainwindow.h
===================================================================
--- src/mainwindow.h	(revision d2820c3a1f10ce51a7d40efd3ecc98eeb0949ada)
+++ src/mainwindow.h	(revision 43c29c04ba146d9b12f2aa85a216d9536a546555)
@@ -35,4 +35,9 @@
 
 #include "tspmodel.h"
+
+#ifdef Q_OS_WIN32
+	// Forward declaration. A real one is in shobjidl.h
+	struct ITaskbarList3;
+#endif
 
 using namespace TSPSolver;
@@ -88,4 +93,7 @@
 	void printPreview(QPrinter *printer);
 #endif // QT_NO_PRINTER
+#ifdef Q_OS_WIN32
+	void solverRoutePartFound(int n);
+#endif // Q_OS_WIN32
 	void spinCitiesValueChanged(int nCities);
 
@@ -111,4 +119,8 @@
 	QRect currentGeometry;
 #endif // Q_OS_WINCE_WM
+
+#ifdef Q_OS_WIN32
+	ITaskbarList3 *tl;
+#endif // Q_OS_WIN32
 
 	// The solution graph SVG
Index: src/shobjidl.h
===================================================================
--- src/shobjidl.h	(revision 43c29c04ba146d9b12f2aa85a216d9536a546555)
+++ src/shobjidl.h	(revision 43c29c04ba146d9b12f2aa85a216d9536a546555)
@@ -0,0 +1,94 @@
+/*!
+ * \file shobjidl.h
+ * \author Copyright &copy; Microsoft Corporation
+ * \author Extracted and documented by Lёppa <contacts[at]oleksii[dot]name>
+ * \version Microsoft Windows SDK v7.0A
+ *
+ *  $Id$
+ *  $URL$
+ *
+ * \brief This file is a minimal required part of \c %shobjidl.h from <b>Microsoft Windows SDK v7.0A</b>.
+ *
+ *  This file is an extract of \c %shobjidl.h from <b>Microsoft Windows SDK v7.0A</b>.
+ *  It is needed to support <b>Windows 7 Taskbar Extensions</b> (namely, <em>Progress Bars</em>)
+ *  and contains minimal required definition of \c ITaskbarList3 interface.
+ *
+ *  Tested with \b MSVC and \b mingw32. Doesn't need <b>Windows 7 SDK</b> itself.
+ *
+ * \note Don't forget to link to \b ole32 library when using this file (usually \c -lole32 linker flag is enough).
+ */
+
+#ifndef _SHOBJIDL_H
+#define _SHOBJIDL_H
+
+#include <windows.h>
+
+#ifndef DOXYGEN_EXCLUDE
+DEFINE_GUID(CLSID_TaskbarList, 0x56fdf344,0xfd6d,0x11d0,0x95,0x8a,0x00,0x60,0x97,0xc9,0xa0,0x90);
+DEFINE_GUID(IID_ITaskbarList3, 0xea1afb91,0x9e28,0x4b86,0x90,0xe9,0x9e,0x9f,0x8a,0x5e,0xef,0xaf);
+#endif
+
+enum TBPFLAG {
+	/*! Stops displaying progress and returns the button to its normal state. Call this method with this flag to dismiss the progress bar when the operation is complete or cancelled. */
+	TBPF_NOPROGRESS		= 0,
+
+	/*! The progress indicator does not grow in size, but cycles repeatedly along the length of the taskbar button. This indicates activity without specifying what proportion of the progress is complete. Progress is taking place, but there is no prediction as to how long the operation will take. */
+	TBPF_INDETERMINATE	= 0x1,
+
+	/*! The progress indicator grows in size from left to right in proportion to the estimated amount of the operation completed. This is a determinate progress indicator; a prediction is being made as to the duration of the operation. */
+	TBPF_NORMAL			= 0x2,
+
+	/*! The progress indicator turns red to show that an error has occurred in one of the windows that is broadcasting progress. This is a determinate state. If the progress indicator is in the indeterminate state, it switches to a red determinate display of a generic percentage not indicative of actual progress. */
+	TBPF_ERROR			= 0x4,
+
+	/*! The progress indicator turns yellow to show that progress is currently stopped in one of the windows but can be resumed by the user. No error condition exists and nothing is preventing the progress from continuing. This is a determinate state. If the progress indicator is in the indeterminate state, it switches to a yellow determinate display of a generic percentage not indicative of actual progress. */
+	TBPF_PAUSED			= 0x8
+};
+
+#ifndef DOXYGEN_EXCLUDE
+DECLARE_INTERFACE_(ITaskbarList3, IUnknown)
+{
+	/*** IUnknown methods ***/
+	STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **ppv) PURE;
+	STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+	STDMETHOD_(ULONG, Release) (THIS) PURE;
+	/*** ITaskbarList specific methods ***/
+	STDMETHOD(HrInit) (THIS) PURE;
+	STDMETHOD(AddTab) (THIS_ HWND hwnd) PURE;
+	STDMETHOD(DeleteTab) (THIS_ HWND hwnd) PURE;
+	STDMETHOD(ActivateTab) (THIS_ HWND hwnd) PURE;
+	STDMETHOD(SetActiveAlt) (THIS_ HWND hwnd) PURE;
+	/*** ITaskbarList2 specific methods ***/
+	STDMETHOD(MarkFullscreenWindow) (THIS_ HWND hwnd, BOOL fFullscreen) PURE;
+	/*** ITaskbarList3 specific methods (only used ones) ***/
+	STDMETHOD(SetProgressValue) (THIS_ HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal) PURE;
+	STDMETHOD(SetProgressState) (THIS_ HWND hwnd, TBPFLAG tbpFlags) PURE;
+};
+#else
+// This block is strictly for doxygen.
+/*!
+ * \brief Exposes methods that control the taskbar.
+ *
+ *  Extends ITaskbarList2 by exposing methods that support the unified launching and switching taskbar button functionality added in Windows 7. This functionality includes thumbnail representations and switch targets based on individual tabs in a tabbed application, thumbnail toolbars, notification and status overlays, and progress indicators. This interface also provides the methods of the ITaskbarList and ITaskbarList2 interfaces, from which it inherits.
+ */
+public interface class ITaskbarList3: public ITaskbarList2 {
+	/*!
+	 * \brief Sets the type and state of the progress indicator displayed on a taskbar button.
+	 * \param hwnd The handle of the window in which the progress of an operation is being shown. This window's associated taskbar button will display the progress bar.
+	 * \param tbpFlags Flags that control the current state of the progress button.
+	 * \return Returns S_OK if successful, or an error value otherwise.
+	 *
+	 * \note A call to SetProgressValue() will switch a progress indicator currently in an indeterminate mode (#TBPF_INDETERMINATE) to a normal (determinate) display and clear the #TBPF_INDETERMINATE flag.
+	 */
+	HRESULT SetProgressState(HWND hwnd, TBPFLAG tbpFlags);
+	/*!
+	 * \brief Displays or updates a progress bar hosted in a taskbar button to show the specific percentage completed of the full operation.
+	 * \param hwnd The handle of the window whose associated taskbar button is being used as a progress indicator.
+	 * \param ullCompleted An application-defined value that indicates the proportion of the operation that has been completed at the time the method is called.
+	 * \param ullTotal An application-defined value that specifies the value \a ullCompleted will have when the operation is complete.
+	 */
+	HRESULT SetProgressValue(HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal);
+};
+#endif
+
+#endif /* _SHOBJIDL_H */
Index: src/tspsolver.cpp
===================================================================
--- src/tspsolver.cpp	(revision d2820c3a1f10ce51a7d40efd3ecc98eeb0949ada)
+++ src/tspsolver.cpp	(revision 43c29c04ba146d9b12f2aa85a216d9536a546555)
@@ -43,5 +43,5 @@
  */
 CTSPSolver::CTSPSolver(QObject *parent)
-	: QObject(parent), nCities(0), total(0), root(NULL) {}
+	: QObject(parent), cc(true), nCities(0), total(0), root(NULL) {}
 
 /*!
@@ -51,20 +51,12 @@
  * \note It is not required to call this function manually. This function is always called by solve() at the beginning of the solution process.
  *
- * \sa solve()
+ * \sa solve(), setCleanupOnCancel()
  */
 void CTSPSolver::cleanup(bool processEvents)
 {
-#ifdef QAPPLICATION_H
-	if (!processEvents)
-		QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-#endif
 	route.clear();
 	mayNotBeOptimal = false;
 	if (root != NULL)
 		deleteTree(root, processEvents);
-#ifdef QAPPLICATION_H
-	if (!processEvents)
-		QApplication::restoreOverrideCursor();
-#endif
 }
 
@@ -115,4 +107,19 @@
 {
 	return !mayNotBeOptimal;
+}
+
+/*!
+ * \brief Sets whether or not to call cleanup() on solution cancel.
+ * \param enable Set to \c true to enable clenup (default).
+ *
+ *  This may be useful if you want to make cleanup yourself or provide indication of clenup to user.
+ *
+ * \note Please, note that cleanup() is explicitly called at the start of each solution.
+ *       Disabling cleanup and forgetting to do it manually may considerably increase the solution time for large tasks (with more than 15 cities).
+ * \sa cleanup()
+ */
+void CTSPSolver::setCleanupOnCancel(bool enable)
+{
+	cc = enable;
 }
 
@@ -174,5 +181,6 @@
 		locker.relock();
 		if ((nRow == -1) || (nCol == -1) || canceled) {
-			cleanup();
+			if (canceled && cc)
+				cleanup();
 			return NULL;
 		}
Index: src/tspsolver.h
===================================================================
--- src/tspsolver.h	(revision d2820c3a1f10ce51a7d40efd3ecc98eeb0949ada)
+++ src/tspsolver.h	(revision 43c29c04ba146d9b12f2aa85a216d9536a546555)
@@ -113,7 +113,8 @@
 	CTSPSolver(QObject *parent = NULL);
 	void cleanup(bool processEvents = false);
-	QString getSortedPath(const QString &city, const QString &separator = " -> ") const;
+	QString getSortedPath(const QString &city, const QString &separator = QString(" -> ")) const;
 	int getTotalSteps() const;
 	bool isOptimal() const;
+	void setCleanupOnCancel(bool enable = true);
 	SStep *solve(int numCities, const TMatrix &task);
 	bool wasCanceled() const;
@@ -131,5 +132,5 @@
 
 private:
-	bool mayNotBeOptimal, canceled;
+	bool mayNotBeOptimal, canceled, cc;
 	int nCities, total;
 	SStep *root;
