source: tspsg/src/mainwindow.cpp @ e26679937d

0.1.3.145-beta1-symbian0.1.4.170-beta2-bb10appveyorimgbotreadme
Last change on this file since e26679937d was e26679937d, checked in by Oleksii Serdiuk, 14 years ago

Added an option to select graph quality, because higher graph quality looked uglier on the screen while looked nicer when printing.

  • Property mode set to 100644
File size: 56.0 KB
Line 
1/*
2 *  TSPSG: TSP Solver and Generator
3 *  Copyright (C) 2007-2010 Lёppa <contacts[at]oleksii[dot]name>
4 *
5 *  $Id$
6 *  $URL$
7 *
8 *  This file is part of TSPSG.
9 *
10 *  TSPSG is free software: you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License as published by
12 *  the Free Software Foundation, either version 3 of the License, or
13 *  (at your option) any later version.
14 *
15 *  TSPSG is distributed in the hope that it will be useful,
16 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 *  GNU General Public License for more details.
19 *
20 *  You should have received a copy of the GNU General Public License
21 *  along with TSPSG.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24#include "mainwindow.h"
25
26#ifdef Q_OS_WIN32
27        #include "shobjidl.h"
28#endif
29
30#ifdef _T_T_L_
31#include "_.h"
32_C_ _R_ _Y_ _P_ _T_
33#endif
34
35/*!
36 * \brief Class constructor.
37 * \param parent Main Window parent widget.
38 *
39 *  Initializes Main Window and creates its layout based on target OS.
40 *  Loads TSPSG settings and opens a task file if it was specified as a commandline parameter.
41 */
42MainWindow::MainWindow(QWidget *parent)
43        : QMainWindow(parent)
44{
45        settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, "TSPSG", "tspsg", this);
46
47        if (settings->contains("Style")) {
48QStyle *s = QStyleFactory::create(settings->value("Style").toString());
49                if (s != NULL)
50                        QApplication::setStyle(s);
51                else
52                        settings->remove("Style");
53        }
54
55        loadLanguage();
56        setupUi();
57        setAcceptDrops(true);
58
59        initDocStyleSheet();
60
61#ifndef QT_NO_PRINTER
62        printer = new QPrinter(QPrinter::HighResolution);
63#endif // QT_NO_PRINTER
64
65#ifdef Q_OS_WINCE_WM
66        currentGeometry = QApplication::desktop()->availableGeometry(0);
67        // We need to react to SIP show/hide and resize the window appropriately
68        connect(QApplication::desktop(), SIGNAL(workAreaResized(int)), SLOT(desktopResized(int)));
69#endif // Q_OS_WINCE_WM
70        connect(actionFileNew, SIGNAL(triggered()), SLOT(actionFileNewTriggered()));
71        connect(actionFileOpen, SIGNAL(triggered()), SLOT(actionFileOpenTriggered()));
72        connect(actionFileSave, SIGNAL(triggered()), SLOT(actionFileSaveTriggered()));
73        connect(actionFileSaveAsTask, SIGNAL(triggered()), SLOT(actionFileSaveAsTaskTriggered()));
74        connect(actionFileSaveAsSolution, SIGNAL(triggered()), SLOT(actionFileSaveAsSolutionTriggered()));
75#ifndef QT_NO_PRINTER
76        connect(actionFilePrintPreview, SIGNAL(triggered()), SLOT(actionFilePrintPreviewTriggered()));
77        connect(actionFilePrint, SIGNAL(triggered()), SLOT(actionFilePrintTriggered()));
78#endif // QT_NO_PRINTER
79#ifndef HANDHELD
80        connect(actionSettingsToolbarsConfigure, SIGNAL(triggered()), SLOT(actionSettingsToolbarsConfigureTriggered()));
81#endif // HANDHELD
82        connect(actionSettingsPreferences, SIGNAL(triggered()), SLOT(actionSettingsPreferencesTriggered()));
83#ifdef Q_OS_WIN32
84        connect(actionHelpCheck4Updates, SIGNAL(triggered()), SLOT(actionHelpCheck4UpdatesTriggered()));
85#endif // Q_OS_WIN32
86        connect(actionSettingsLanguageAutodetect, SIGNAL(triggered(bool)), SLOT(actionSettingsLanguageAutodetectTriggered(bool)));
87        connect(groupSettingsLanguageList, SIGNAL(triggered(QAction *)), SLOT(groupSettingsLanguageListTriggered(QAction *)));
88        connect(actionSettingsStyleSystem, SIGNAL(triggered(bool)), SLOT(actionSettingsStyleSystemTriggered(bool)));
89        connect(groupSettingsStyleList, SIGNAL(triggered(QAction*)), SLOT(groupSettingsStyleListTriggered(QAction*)));
90        connect(actionHelpAboutQt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
91        connect(actionHelpAbout, SIGNAL(triggered()), SLOT(actionHelpAboutTriggered()));
92
93        connect(buttonSolve, SIGNAL(clicked()), SLOT(buttonSolveClicked()));
94        connect(buttonRandom, SIGNAL(clicked()), SLOT(buttonRandomClicked()));
95        connect(buttonBackToTask, SIGNAL(clicked()), SLOT(buttonBackToTaskClicked()));
96        connect(spinCities, SIGNAL(valueChanged(int)), SLOT(spinCitiesValueChanged(int)));
97
98#ifndef HANDHELD
99        // Centering main window
100QRect rect = geometry();
101        rect.moveCenter(QApplication::desktop()->availableGeometry(this).center());
102        setGeometry(rect);
103        if (settings->value("SavePos", DEF_SAVEPOS).toBool()) {
104                // Loading of saved window state
105                settings->beginGroup("MainWindow");
106                restoreGeometry(settings->value("Geometry").toByteArray());
107                restoreState(settings->value("State").toByteArray());
108                settings->endGroup();
109        }
110#endif // HANDHELD
111
112        tspmodel = new CTSPModel(this);
113        taskView->setModel(tspmodel);
114        connect(tspmodel, SIGNAL(numCitiesChanged(int)), SLOT(numCitiesChanged(int)));
115        connect(tspmodel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), SLOT(dataChanged(const QModelIndex &, const QModelIndex &)));
116        connect(tspmodel, SIGNAL(layoutChanged()), SLOT(dataChanged()));
117        if ((QCoreApplication::arguments().count() > 1) && (tspmodel->loadTask(QCoreApplication::arguments().at(1))))
118                setFileName(QCoreApplication::arguments().at(1));
119        else {
120                setFileName();
121                spinCities->setValue(settings->value("NumCities",DEF_NUM_CITIES).toInt());
122                spinCitiesValueChanged(spinCities->value());
123        }
124        setWindowModified(false);
125}
126
127MainWindow::~MainWindow()
128{
129#ifndef QT_NO_PRINTER
130        delete printer;
131#endif
132}
133
134/* Privates **********************************************************/
135
136void MainWindow::actionFileNewTriggered()
137{
138        if (!maybeSave())
139                return;
140        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
141        tspmodel->clear();
142        setFileName();
143        setWindowModified(false);
144        tabWidget->setCurrentIndex(0);
145        solutionText->clear();
146        toggleSolutionActions(false);
147        QApplication::restoreOverrideCursor();
148}
149
150void MainWindow::actionFileOpenTriggered()
151{
152        if (!maybeSave())
153                return;
154
155QStringList filters(tr("All Supported Formats") + " (*.tspt *.zkt)");
156        filters.append(tr("%1 Task Files").arg("TSPSG") + " (*.tspt)");
157        filters.append(tr("%1 Task Files").arg("ZKomModRd") + " (*.zkt)");
158        filters.append(tr("All Files") + " (*)");
159
160QString file = QFileInfo(fileName).canonicalPath();
161QFileDialog::Options opts = settings->value("UseNativeDialogs", DEF_USE_NATIVE_DIALOGS).toBool() ? QFileDialog::Options() : QFileDialog::DontUseNativeDialog;
162        file = QFileDialog::getOpenFileName(this, tr("Task Load"), file, filters.join(";;"), NULL, opts);
163        if (file.isEmpty() || !QFileInfo(file).isFile())
164                return;
165        if (!tspmodel->loadTask(file))
166                return;
167        setFileName(file);
168        tabWidget->setCurrentIndex(0);
169        setWindowModified(false);
170        solutionText->clear();
171        toggleSolutionActions(false);
172}
173
174bool MainWindow::actionFileSaveTriggered()
175{
176        if ((fileName == tr("Untitled") + ".tspt") || (!fileName.endsWith(".tspt", Qt::CaseInsensitive)))
177                return saveTask();
178        else
179                if (tspmodel->saveTask(fileName)) {
180                        setWindowModified(false);
181                        return true;
182                } else
183                        return false;
184}
185
186void MainWindow::actionFileSaveAsTaskTriggered()
187{
188        saveTask();
189}
190
191void MainWindow::actionFileSaveAsSolutionTriggered()
192{
193static QString selectedFile;
194        if (selectedFile.isEmpty())
195                selectedFile = QFileInfo(fileName).canonicalPath();
196        else
197                selectedFile = QFileInfo(selectedFile).canonicalPath();
198        if (!selectedFile.isEmpty())
199                selectedFile += "/";
200        if (fileName == tr("Untitled") + ".tspt") {
201#ifndef QT_NO_PRINTER
202                selectedFile += "solution.pdf";
203#else
204                selectedFile += "solution.html";
205#endif // QT_NO_PRINTER
206        } else {
207#ifndef QT_NO_PRINTER
208                selectedFile += QFileInfo(fileName).completeBaseName() + ".pdf";
209#else
210                selectedFile += QFileInfo(fileName).completeBaseName() + ".html";
211#endif // QT_NO_PRINTER
212        }
213
214QStringList filters;
215#ifndef QT_NO_PRINTER
216        filters.append(tr("PDF Files") + " (*.pdf)");
217#endif
218        filters.append(tr("HTML Files") + " (*.html *.htm)");
219#if QT_VERSION >= 0x040500
220        filters.append(tr("OpenDocument Files") + " (*.odt)");
221#endif // QT_VERSION >= 0x040500
222        filters.append(tr("All Files") + " (*)");
223
224QFileDialog::Options opts(settings->value("UseNativeDialogs", DEF_USE_NATIVE_DIALOGS).toBool() ? QFileDialog::Options() : QFileDialog::DontUseNativeDialog);
225QString file = QFileDialog::getSaveFileName(this, QString(), selectedFile, filters.join(";;"), NULL, opts);
226        if (file.isEmpty())
227                return;
228        selectedFile = file;
229        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
230#ifndef QT_NO_PRINTER
231        if (selectedFile.endsWith(".pdf",Qt::CaseInsensitive)) {
232QPrinter printer(QPrinter::HighResolution);
233                printer.setOutputFormat(QPrinter::PdfFormat);
234                printer.setOutputFileName(selectedFile);
235                solutionText->document()->print(&printer);
236                QApplication::restoreOverrideCursor();
237                return;
238        }
239#endif
240        if (selectedFile.endsWith(".htm", Qt::CaseInsensitive) || selectedFile.endsWith(".html", Qt::CaseInsensitive)) {
241QFile file(selectedFile);
242                if (!file.open(QFile::WriteOnly)) {
243                        QApplication::restoreOverrideCursor();
244                        QMessageBox::critical(this, tr("Solution Save"), tr("Unable to save the solution.\nError: %1").arg(file.errorString()));
245                        return;
246                }
247QFileInfo fi(selectedFile);
248QString format = settings->value("Output/GraphImageFormat", DEF_GRAPH_IMAGE_FORMAT).toString();
249#if !defined(NOSVG) && (QT_VERSION >= 0x040500)
250        if (!QImageWriter::supportedImageFormats().contains(format.toAscii()) && (format != "svg")) {
251#else // NOSVG && QT_VERSION >= 0x040500
252        if (!QImageWriter::supportedImageFormats().contains(format.toAscii())) {
253#endif // NOSVG && QT_VERSION >= 0x040500
254                format = DEF_GRAPH_IMAGE_FORMAT;
255                settings->remove("Output/GraphImageFormat");
256        }
257QString html = solutionText->document()->toHtml("UTF-8"),
258                img =  fi.completeBaseName() + "." + format;
259                html.replace(QRegExp("<img\\s+src=\"tspsg://graph.pic\""), QString("<img src=\"%1\" alt=\"%2\"").arg(img, tr("Solution Graph")));
260
261                // Saving solution text as HTML
262QTextStream ts(&file);
263                ts.setCodec(QTextCodec::codecForName("UTF-8"));
264                ts << html;
265                file.close();
266
267                // Saving solution graph as SVG or PNG (depending on settings and SVG support)
268#if !defined(NOSVG) && (QT_VERSION >= 0x040500)
269                if (format == "svg") {
270QSvgGenerator svg;
271                        svg.setSize(QSize(graph.width(), graph.height()));
272                        svg.setResolution(graph.logicalDpiX());
273                        svg.setFileName(fi.path() + "/" + img);
274                        svg.setTitle(tr("Solution Graph"));
275                        svg.setDescription(tr("Generated with %1").arg(QApplication::applicationName()));
276QPainter p;
277                        p.begin(&svg);
278                        p.drawPicture(1, 1, graph);
279                        p.end();
280                } else {
281#endif // NOSVG && QT_VERSION >= 0x040500
282QImage i(graph.width(), graph.height(), QImage::Format_ARGB32);
283                        i.fill(0x00FFFFFF);
284QPainter p;
285                        p.begin(&i);
286                        p.drawPicture(1, 1, graph);
287                        p.end();
288QImageWriter pic(fi.path() + "/" + img);
289                        if (pic.supportsOption(QImageIOHandler::Description)) {
290                                pic.setText("Title", "Solution Graph");
291                                pic.setText("Software", QApplication::applicationName());
292                        }
293                        if (format == "png")
294                                pic.setQuality(5);
295                        else if (format == "jpeg")
296                                pic.setQuality(80);
297                        if (!pic.write(i)) {
298                                QApplication::restoreOverrideCursor();
299                                QMessageBox::critical(this, tr("Solution Save"), tr("Unable to save the solution graph.\nError: %1").arg(pic.errorString()));
300                                return;
301                        }
302#if !defined(NOSVG) && (QT_VERSION >= 0x040500)
303                }
304#endif // NOSVG && QT_VERSION >= 0x040500
305
306// Qt < 4.5 has no QTextDocumentWriter class
307#if QT_VERSION >= 0x040500
308        } else {
309QTextDocumentWriter dw(selectedFile);
310                if (!selectedFile.endsWith(".odt",Qt::CaseInsensitive))
311                        dw.setFormat("plaintext");
312                if (!dw.write(solutionText->document()))
313                        QMessageBox::critical(this, tr("Solution Save"), tr("Unable to save the solution.\nError: %1").arg(dw.device()->errorString()));
314#endif // QT_VERSION >= 0x040500
315        }
316        QApplication::restoreOverrideCursor();
317}
318
319#ifndef QT_NO_PRINTER
320void MainWindow::actionFilePrintPreviewTriggered()
321{
322QPrintPreviewDialog ppd(printer, this);
323        connect(&ppd,SIGNAL(paintRequested(QPrinter *)),SLOT(printPreview(QPrinter *)));
324        ppd.exec();
325}
326
327void MainWindow::actionFilePrintTriggered()
328{
329QPrintDialog pd(printer,this);
330        if (pd.exec() != QDialog::Accepted)
331                return;
332        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
333        solutionText->print(printer);
334        QApplication::restoreOverrideCursor();
335}
336#endif // QT_NO_PRINTER
337
338void MainWindow::actionSettingsPreferencesTriggered()
339{
340SettingsDialog sd(this);
341        if (sd.exec() != QDialog::Accepted)
342                return;
343        if (sd.colorChanged() || sd.fontChanged()) {
344                if (!solutionText->document()->isEmpty() && sd.colorChanged())
345                        QMessageBox::information(this, tr("Settings Changed"), tr("You have changed color settings.\nThey will be applied to the next solution output."));
346                initDocStyleSheet();
347        }
348        if (sd.translucencyChanged() != 0)
349                toggleTranclucency(sd.translucencyChanged() == 1);
350}
351
352void MainWindow::actionSettingsLanguageAutodetectTriggered(bool checked)
353{
354        if (checked) {
355                settings->remove("Language");
356                QMessageBox::information(this, tr("Language change"), tr("Language will be autodetected on the next %1 start.").arg(QApplication::applicationName()));
357        } else
358                settings->setValue("Language", groupSettingsLanguageList->checkedAction()->data().toString());
359}
360
361void MainWindow::groupSettingsLanguageListTriggered(QAction *action)
362{
363        if (actionSettingsLanguageAutodetect->isChecked()) {
364                // We have language autodetection. It needs to be disabled to change language.
365                if (QMessageBox::question(this, tr("Language change"), tr("You have language autodetection turned on.\nIt needs to be off.\nDo you wish to turn it off?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
366                        actionSettingsLanguageAutodetect->trigger();
367                } else
368                        return;
369        }
370bool untitled = (fileName == tr("Untitled") + ".tspt");
371        if (loadLanguage(action->data().toString())) {
372                QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
373                settings->setValue("Language",action->data().toString());
374                retranslateUi();
375                if (untitled)
376                        setFileName();
377#ifdef Q_OS_WIN32
378                if (QtWin::isCompositionEnabled() && settings->value("UseTranslucency", DEF_USE_TRANSLUCENCY).toBool())  {
379                        toggleStyle(labelVariant, true);
380                        toggleStyle(labelCities, true);
381                }
382#endif
383                QApplication::restoreOverrideCursor();
384                if (!solutionText->document()->isEmpty())
385                        QMessageBox::information(this, tr("Settings Changed"), tr("You have changed the application language.\nTo get current solution output in the new language\nyou need to re-run the solution process."));
386        }
387}
388
389void MainWindow::actionSettingsStyleSystemTriggered(bool checked)
390{
391        if (checked) {
392                settings->remove("Style");
393                QMessageBox::information(this, tr("Style Change"), tr("To apply the default style you need to restart %1.").arg(QApplication::applicationName()));
394        } else {
395                settings->setValue("Style", groupSettingsStyleList->checkedAction()->text());
396        }
397}
398
399void MainWindow::groupSettingsStyleListTriggered(QAction *action)
400{
401QStyle *s = QStyleFactory::create(action->text());
402        if (s != NULL) {
403                QApplication::setStyle(s);
404                settings->setValue("Style", action->text());
405                actionSettingsStyleSystem->setChecked(false);
406        }
407}
408
409#ifndef HANDHELD
410void MainWindow::actionSettingsToolbarsConfigureTriggered()
411{
412QtToolBarDialog dlg(this);
413        dlg.setToolBarManager(toolBarManager);
414        dlg.exec();
415QToolButton *tb = static_cast<QToolButton *>(toolBarMain->widgetForAction(actionFileSave));
416        if (tb != NULL) {
417                tb->setMenu(menuFileSaveAs);
418                tb->setPopupMode(QToolButton::MenuButtonPopup);
419                tb->resize(tb->sizeHint());
420        }
421
422        loadToolbarList();
423}
424#endif // HANDHELD
425
426#ifdef Q_OS_WIN32
427void MainWindow::actionHelpCheck4UpdatesTriggered()
428{
429        if (!hasUpdater()) {
430                QMessageBox::warning(this, tr("Unsupported Feature"), tr("Sorry, but this feature is not supported on your platform\nor support for this feature was not installed."));
431                return;
432        }
433
434        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
435        QProcess::execute("updater/Update.exe -name=\"TSPSG: TSP Solver and Generator\" -check=\"freeupdate\"");
436        QApplication::restoreOverrideCursor();
437}
438#endif // Q_OS_WIN32
439
440void MainWindow::actionHelpAboutTriggered()
441{
442        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
443
444QString title;
445#ifdef HANDHELD
446        title += QString("<b>TSPSG<br>TSP Solver and Generator</b><br>");
447#else
448        title += QString("<b>%1</b><br>").arg(QApplication::applicationName());
449#endif // HANDHELD
450        title += QString("%1: <b>%2</b><br>").arg(tr("Version"), QApplication::applicationVersion());
451#ifndef HANDHELD
452        title += QString("<b>&copy; 2007-%1 <a href=\"http://%2/\">%3</a></b><br>").arg(QDate::currentDate().toString("yyyy"), QApplication::organizationDomain(), QApplication::organizationName());
453#endif // HANDHELD
454        title += QString("<b><a href=\"http://tspsg.info/\">http://tspsg.info/</a></b>");
455
456QString about;
457        about += QString("%1: <b>%2</b><br>").arg(tr("Target OS (ARCH)"), OS);
458#ifndef STATIC_BUILD
459        about += QString("%1 (%2):<br>").arg(tr("Qt library"), tr("shared"));
460        about += QString("&nbsp;&nbsp;&nbsp;&nbsp;%1: <b>%2</b><br>").arg(tr("Build time"), QT_VERSION_STR);
461        about += QString("&nbsp;&nbsp;&nbsp;&nbsp;%1: <b>%2</b><br>").arg(tr("Runtime"), qVersion());
462#else
463        about += QString("%1: <b>%2</b> (%3)<br>").arg(tr("Qt library"), QT_VERSION_STR, tr("static"));
464#endif // STATIC_BUILD
465        about += tr("Buid <b>%1</b>, built on <b>%2</b> at <b>%3</b>").arg(BUILD_NUMBER).arg(__DATE__).arg(__TIME__) + "<br>";
466        about += QString("%1: <b>%2</b><br>").arg(tr("Algorithm"), CTSPSolver::getVersionId());
467        about += "<br>";
468        about += tr("This program is free software: you can redistribute it and/or modify<br>\n"
469                "it under the terms of the GNU General Public License as published by<br>\n"
470                "the Free Software Foundation, either version 3 of the License, or<br>\n"
471                "(at your option) any later version.<br>\n"
472                "<br>\n"
473                "This program is distributed in the hope that it will be useful,<br>\n"
474                "but WITHOUT ANY WARRANTY; without even the implied warranty of<br>\n"
475                "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>\n"
476                "GNU General Public License for more details.<br>\n"
477                "<br>\n"
478                "You should have received a copy of the GNU General Public License<br>\n"
479                "along with TSPSG.  If not, see <a href=\"http://www.gnu.org/licenses/\">www.gnu.org/licenses/</a>.");
480
481QString credits;
482        credits += tr("%1 was created using <b>Qt&nbsp;framework</b> licensed "
483                "under the terms of the GNU Lesser General Public License,<br>\n"
484                "see <a href=\"http://qt.nokia.com/\">qt.nokia.com</a><br>\n"
485                "<br>\n"
486                "Most icons used in %1 are part of <b>Oxygen&nbsp;Icons</b> project "
487                "licensed according to the GNU Lesser General Public License,<br>\n"
488                "see <a href=\"http://www.oxygen-icons.org/\">www.oxygen-icons.org</a><br>\n"
489                "<br>\n"
490                "Country flag icons used in %1 are part of the free "
491                "<b>Flag&nbsp;Icons</b> collection created by <b>IconDrawer</b>,<br>\n"
492                "see <a href=\"http://www.icondrawer.com/\">www.icondrawer.com</a>")
493                        .arg(QApplication::applicationName());
494
495QFile f(":/files/COPYING");
496        f.open(QIODevice::ReadOnly);
497
498QString translation = QApplication::translate("--------", "AUTHORS %1", "Please, provide translator credits here. %1 will be replaced with VERSION");
499        if ((translation != "AUTHORS %1") && (translation.contains("%1"))) {
500QString about = QApplication::translate("--------", "VERSION", "Please, provide your translation version here.");
501                if (about != "VERSION")
502                        translation = translation.arg(about);
503        }
504
505QDialog *dlg = new QDialog(this);
506QLabel *lblIcon = new QLabel(dlg),
507        *lblTitle = new QLabel(dlg);
508#ifdef HANDHELD
509QLabel *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);
510#endif // HANDHELD
511QTabWidget *tabs = new QTabWidget(dlg);
512QTextBrowser *txtAbout = new QTextBrowser(dlg);
513QTextBrowser *txtLicense = new QTextBrowser(dlg);
514QTextBrowser *txtCredits = new QTextBrowser(dlg);
515QVBoxLayout *vb = new QVBoxLayout();
516QHBoxLayout *hb1 = new QHBoxLayout(),
517        *hb2 = new QHBoxLayout();
518QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok, Qt::Horizontal, dlg);
519
520        lblTitle->setOpenExternalLinks(true);
521        lblTitle->setText(title);
522        lblTitle->setAlignment(Qt::AlignTop);
523        lblTitle->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
524#ifndef HANDHELD
525        lblTitle->setStyleSheet(QString("QLabel {background-color: %1; border-color: %2; border-width: 1px; border-style: solid; border-radius: 4px; padding: 1px;}").arg(palette().alternateBase().color().name(), palette().shadow().color().name()));
526#endif // HANDHELD
527
528        lblIcon->setPixmap(QPixmap(":/images/tspsg.png").scaledToHeight(lblTitle->sizeHint().height(), Qt::SmoothTransformation));
529        lblIcon->setAlignment(Qt::AlignVCenter);
530#ifndef HANDHELD
531        lblIcon->setStyleSheet(QString("QLabel {background-color: white; border-color: %1; border-width: 1px; border-style: solid; border-radius: 4px; padding: 1px;}").arg(palette().windowText().color().name()));
532#endif // HANDHELD
533
534        hb1->addWidget(lblIcon);
535        hb1->addWidget(lblTitle);
536
537        txtAbout->setWordWrapMode(QTextOption::NoWrap);
538        txtAbout->setOpenExternalLinks(true);
539        txtAbout->setHtml(about);
540        txtAbout->moveCursor(QTextCursor::Start);
541        txtAbout->setFrameShape(QFrame::NoFrame);
542
543//      txtCredits->setWordWrapMode(QTextOption::NoWrap);
544        txtCredits->setOpenExternalLinks(true);
545        txtCredits->setHtml(credits);
546        txtCredits->moveCursor(QTextCursor::Start);
547        txtCredits->setFrameShape(QFrame::NoFrame);
548
549        txtLicense->setWordWrapMode(QTextOption::NoWrap);
550        txtLicense->setOpenExternalLinks(true);
551        txtLicense->setText(f.readAll());
552        txtLicense->moveCursor(QTextCursor::Start);
553        txtLicense->setFrameShape(QFrame::NoFrame);
554
555        bb->button(QDialogButtonBox::Ok)->setCursor(QCursor(Qt::PointingHandCursor));
556        bb->button(QDialogButtonBox::Ok)->setIcon(QIcon::fromTheme("dialog-ok", QIcon(":/images/icons/dialog-ok.png")));
557
558        hb2->addWidget(bb);
559
560#ifdef Q_OS_WINCE_WM
561        vb->setMargin(3);
562#endif // Q_OS_WINCE_WM
563        vb->addLayout(hb1);
564#ifdef HANDHELD
565        vb->addWidget(lblSubTitle);
566#endif // HANDHELD
567
568        tabs->addTab(txtAbout, tr("About"));
569        tabs->addTab(txtLicense, tr("License"));
570        tabs->addTab(txtCredits, tr("Credits"));
571        if (translation != "AUTHORS %1") {
572QTextBrowser *txtTranslation = new QTextBrowser(dlg);
573//              txtTranslation->setWordWrapMode(QTextOption::NoWrap);
574                txtTranslation->setOpenExternalLinks(true);
575                txtTranslation->setText(translation);
576                txtTranslation->moveCursor(QTextCursor::Start);
577                txtTranslation->setFrameShape(QFrame::NoFrame);
578
579                tabs->addTab(txtTranslation, tr("Translation"));
580        }
581#ifndef HANDHELD
582        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()));
583#endif // HANDHELD
584
585        vb->addWidget(tabs);
586        vb->addLayout(hb2);
587
588        dlg->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint);
589        dlg->setWindowTitle(tr("About %1").arg(QApplication::applicationName()));
590        dlg->setWindowIcon(QIcon::fromTheme("help-about", QIcon(":/images/icons/help-about.png")));
591        dlg->setLayout(vb);
592
593        connect(bb, SIGNAL(accepted()), dlg, SLOT(accept()));
594
595#ifdef Q_OS_WIN32
596        // Adding some eyecandy in Vista and 7 :-)
597        if (QtWin::isCompositionEnabled())  {
598                QtWin::enableBlurBehindWindow(dlg, true);
599        }
600#endif // Q_OS_WIN32
601
602        dlg->resize(450, 350);
603        QApplication::restoreOverrideCursor();
604
605        dlg->exec();
606
607        delete dlg;
608}
609
610void MainWindow::buttonBackToTaskClicked()
611{
612        tabWidget->setCurrentIndex(0);
613}
614
615void MainWindow::buttonRandomClicked()
616{
617        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
618        tspmodel->randomize();
619        QApplication::restoreOverrideCursor();
620}
621
622void MainWindow::buttonSolveClicked()
623{
624TMatrix matrix;
625QList<double> row;
626int n = spinCities->value();
627bool ok;
628        for (int r = 0; r < n; r++) {
629                row.clear();
630                for (int c = 0; c < n; c++) {
631                        row.append(tspmodel->index(r,c).data(Qt::UserRole).toDouble(&ok));
632                        if (!ok) {
633                                QMessageBox::critical(this, tr("Data error"), tr("Error in cell [Row %1; Column %2]: Invalid data format.").arg(r + 1).arg(c + 1));
634                                return;
635                        }
636                }
637                matrix.append(row);
638        }
639
640QProgressDialog pd(this);
641QProgressBar *pb = new QProgressBar(&pd);
642        pb->setAlignment(Qt::AlignCenter);
643        pb->setFormat(tr("%v of %1 parts found").arg(n));
644        pd.setBar(pb);
645QPushButton *cancel = new QPushButton(&pd);
646        cancel->setIcon(QIcon::fromTheme("dialog-cancel", QIcon(":/images/icons/dialog-cancel.png")));
647        cancel->setText(QApplication::translate("QProgressDialog", "Cancel", "No need to translate this. This translation will be taken from Qt translation files."));
648        pd.setCancelButton(cancel);
649        pd.setMaximum(n);
650        pd.setAutoReset(false);
651        pd.setLabelText(tr("Calculating optimal route..."));
652        pd.setWindowTitle(tr("Solution Progress"));
653        pd.setWindowModality(Qt::ApplicationModal);
654        pd.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
655        pd.show();
656
657#ifdef Q_OS_WIN32
658HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (LPVOID*)&tl);
659        if (SUCCEEDED(hr)) {
660                hr = tl->HrInit();
661                if (FAILED(hr)) {
662                        tl->Release();
663                        tl = NULL;
664                } else {
665//                      tl->SetProgressState(winId(), TBPF_INDETERMINATE);
666                        tl->SetProgressValue(winId(), 0, n * 2);
667                }
668        }
669#endif
670
671CTSPSolver solver;
672        solver.setCleanupOnCancel(false);
673        connect(&solver, SIGNAL(routePartFound(int)), &pd, SLOT(setValue(int)));
674        connect(&pd, SIGNAL(canceled()), &solver, SLOT(cancel()));
675#ifdef Q_OS_WIN32
676        if (tl != NULL)
677                connect(&solver, SIGNAL(routePartFound(int)), SLOT(solverRoutePartFound(int)));
678#endif
679SStep *root = solver.solve(n, matrix);
680#ifdef Q_OS_WIN32
681        if (tl != NULL)
682                disconnect(&solver, SIGNAL(routePartFound(int)), this, SLOT(solverRoutePartFound(int)));
683#endif
684        disconnect(&solver, SIGNAL(routePartFound(int)), &pd, SLOT(setValue(int)));
685        disconnect(&pd, SIGNAL(canceled()), &solver, SLOT(cancel()));
686        if (!root) {
687                pd.reset();
688                if (!solver.wasCanceled()) {
689#ifdef Q_OS_WIN32
690                        if (tl != NULL) {
691//                              tl->SetProgressValue(winId(), n, n * 2);
692                                tl->SetProgressState(winId(), TBPF_ERROR);
693                        }
694#endif
695                        QApplication::alert(this);
696                        QMessageBox::warning(this, tr("Solution Result"), tr("Unable to find a solution.\nMaybe, this task has no solution."));
697                }
698                pd.setLabelText(tr("Cleaning up..."));
699                pd.setMaximum(0);
700                pd.setCancelButton(NULL);
701                pd.show();
702#ifdef Q_OS_WIN32
703                if (tl != NULL)
704                        tl->SetProgressState(winId(), TBPF_INDETERMINATE);
705#endif
706                QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
707
708QFuture<void> f = QtConcurrent::run(&solver, &CTSPSolver::cleanup, false);
709                while (!f.isFinished()) {
710                        QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
711                }
712                pd.reset();
713#ifdef Q_OS_WIN32
714                if (tl != NULL) {
715                        tl->SetProgressState(winId(), TBPF_NOPROGRESS);
716                        tl->Release();
717                        tl = NULL;
718                }
719#endif
720                return;
721        }
722        pb->setFormat(tr("Generating header"));
723        pd.setLabelText(tr("Generating solution output..."));
724        pd.setMaximum(solver.getTotalSteps() + 1);
725        pd.setValue(0);
726
727#ifdef Q_OS_WIN32
728        if (tl != NULL)
729                tl->SetProgressValue(winId(), spinCities->value(), spinCities->value() + solver.getTotalSteps() + 1);
730#endif
731
732        solutionText->clear();
733        solutionText->setDocumentTitle(tr("Solution of Variant #%1 Task").arg(spinVariant->value()));
734
735QPainter pic;
736        if (settings->value("Output/ShowGraph", DEF_SHOW_GRAPH).toBool()) {
737                pic.begin(&graph);
738                pic.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
739QFont font = settings->value("Output/Font", QFont(getDefaultFont(), 9)).value<QFont>();
740                if (settings->value("Output/HQGraph", DEF_HQ_GRAPH).toBool()) {
741                        font.setWeight(QFont::DemiBold);
742                        font.setPointSizeF(font.pointSizeF() * 2);
743                }
744                pic.setFont(font);
745                pic.setBrush(QBrush(QColor(Qt::white)));
746                if (settings->value("Output/HQGraph", DEF_HQ_GRAPH).toBool()) {
747QPen pen = pic.pen();
748                        pen.setWidth(2);
749                        pic.setPen(pen);
750                }
751                pic.setBackgroundMode(Qt::OpaqueMode);
752        }
753
754QTextDocument *doc = solutionText->document();
755QTextCursor cur(doc);
756
757        cur.beginEditBlock();
758        cur.setBlockFormat(fmt_paragraph);
759        cur.insertText(tr("Variant #%1 Task").arg(spinVariant->value()), fmt_default);
760        cur.insertBlock(fmt_paragraph);
761        cur.insertText(tr("Task:"));
762        outputMatrix(cur, matrix);
763        if (settings->value("Output/ShowGraph", DEF_SHOW_GRAPH).toBool()) {
764#ifdef _T_T_L_
765                _b_ _i_ _z_ _a_ _r_ _r_ _e_
766#endif
767                drawNode(pic, 0);
768        }
769        cur.insertHtml("<hr>");
770        cur.insertBlock(fmt_paragraph);
771int imgpos = cur.position();
772        cur.insertText(tr("Variant #%1 Solution").arg(spinVariant->value()), fmt_default);
773        cur.endEditBlock();
774
775SStep *step = root;
776int c = n = 1;
777        pb->setFormat(tr("Generating step %v"));
778        while ((step->next != SStep::NoNextStep) && (c < spinCities->value())) {
779                if (pd.wasCanceled()) {
780                        pd.setLabelText(tr("Cleaning up..."));
781                        pd.setMaximum(0);
782                        pd.setCancelButton(NULL);
783                        pd.show();
784                        QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
785#ifdef Q_OS_WIN32
786                        if (tl != NULL)
787                                tl->SetProgressState(winId(), TBPF_INDETERMINATE);
788#endif
789QFuture<void> f = QtConcurrent::run(&solver, &CTSPSolver::cleanup, false);
790                        while (!f.isFinished()) {
791                                QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
792                        }
793                        solutionText->clear();
794                        toggleSolutionActions(false);
795#ifdef Q_OS_WIN32
796                        if (tl != NULL) {
797                                tl->SetProgressState(winId(), TBPF_NOPROGRESS);
798                                tl->Release();
799                                tl = NULL;
800                        }
801#endif
802                        return;
803                }
804                pd.setValue(n);
805#ifdef Q_OS_WIN32
806                if (tl != NULL)
807                        tl->SetProgressValue(winId(), spinCities->value() + n, spinCities->value() + solver.getTotalSteps() + 1);
808#endif
809
810                cur.beginEditBlock();
811                cur.insertBlock(fmt_paragraph);
812                cur.insertText(tr("Step #%1").arg(n));
813                if (settings->value("Output/ShowMatrix", DEF_SHOW_MATRIX).toBool() && (!settings->value("Output/UseShowMatrixLimit", DEF_USE_SHOW_MATRIX_LIMIT).toBool() || (settings->value("Output/UseShowMatrixLimit", DEF_USE_SHOW_MATRIX_LIMIT).toBool() && (spinCities->value() <= settings->value("Output/ShowMatrixLimit", DEF_SHOW_MATRIX_LIMIT).toInt())))) {
814                        outputMatrix(cur, *step);
815                }
816                cur.insertBlock(fmt_paragraph);
817                cur.insertText(tr("Selected route %1 %2 part.").arg((step->next == SStep::RightBranch) ? tr("with") : tr("without")).arg(tr("(%1;%2)").arg(step->candidate.nRow + 1).arg(step->candidate.nCol + 1)), fmt_default);
818                if (!step->alts.empty()) {
819                        SStep::SCandidate cand;
820                        QString alts;
821                        foreach(cand, step->alts) {
822                                if (!alts.isEmpty())
823                                        alts += ", ";
824                                alts += tr("(%1;%2)").arg(cand.nRow + 1).arg(cand.nCol + 1);
825                        }
826                        cur.insertBlock(fmt_paragraph);
827                        cur.insertText(tr("%n alternate candidate(s) for branching: %1.", "", step->alts.count()).arg(alts), fmt_altlist);
828                }
829                cur.insertBlock(fmt_paragraph);
830                cur.insertText(" ", fmt_default);
831                cur.endEditBlock();
832
833                if (settings->value("Output/ShowGraph", DEF_SHOW_GRAPH).toBool()) {
834                        if (step->prNode != NULL)
835                                drawNode(pic, n, false, step->prNode);
836                        if (step->plNode != NULL)
837                                drawNode(pic, n, true, step->plNode);
838                }
839                n++;
840
841                if (step->next == SStep::RightBranch) {
842                        c++;
843                        step = step->prNode;
844                } else if (step->next == SStep::LeftBranch) {
845                        step = step->plNode;
846                } else
847                        break;
848        }
849        pb->setFormat(tr("Generating footer"));
850        pd.setValue(n);
851#ifdef Q_OS_WIN32
852        if (tl != NULL)
853                tl->SetProgressValue(winId(), spinCities->value() + n, spinCities->value() + solver.getTotalSteps() + 1);
854#endif
855
856        cur.beginEditBlock();
857        cur.insertBlock(fmt_paragraph);
858        if (solver.isOptimal())
859                cur.insertText(tr("Optimal path:"));
860        else
861                cur.insertText(tr("Resulting path:"));
862
863        cur.insertBlock(fmt_paragraph);
864        cur.insertText("  " + solver.getSortedPath(tr("City %1")));
865
866        cur.insertBlock(fmt_paragraph);
867        if (isInteger(step->price))
868                cur.insertHtml("<p>" + tr("The price is <b>%n</b> unit(s).", "", qRound(step->price)) + "</p>");
869        else
870                cur.insertHtml("<p>" + tr("The price is <b>%1</b> units.").arg(step->price, 0, 'f', settings->value("Task/FractionalAccuracy", DEF_FRACTIONAL_ACCURACY).toInt()) + "</p>");
871        if (!solver.isOptimal()) {
872                cur.insertBlock(fmt_paragraph);
873                cur.insertText(" ");
874                cur.insertBlock(fmt_paragraph);
875                cur.insertHtml("<p>" + tr("<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>");
876        }
877        cur.endEditBlock();
878
879        if (settings->value("Output/ShowGraph", DEF_SHOW_GRAPH).toBool()) {
880                pic.end();
881
882QImage i(graph.width() + 1, graph.height() + 1, QImage::Format_RGB32);
883                i.fill(0xFFFFFF);
884                pic.begin(&i);
885                pic.drawPicture(1, 1, graph);
886                pic.end();
887                doc->addResource(QTextDocument::ImageResource, QUrl("tspsg://graph.pic"), i);
888
889QTextImageFormat img;
890                img.setName("tspsg://graph.pic");
891                if (settings->value("Output/HQGraph", DEF_HQ_GRAPH).toBool()) {
892                        img.setWidth(i.width() / 2);
893                        img.setHeight(i.height() / 2);
894                } else {
895                        img.setWidth(i.width());
896                        img.setHeight(i.height());
897                }
898
899                cur.setPosition(imgpos);
900                cur.insertImage(img, QTextFrameFormat::FloatRight);
901        }
902
903        if (settings->value("Output/ScrollToEnd", DEF_SCROLL_TO_END).toBool()) {
904                // Scrolling to the end of the text.
905                solutionText->moveCursor(QTextCursor::End);
906        } else
907                solutionText->moveCursor(QTextCursor::Start);
908
909        pd.setLabelText(tr("Cleaning up..."));
910        pd.setMaximum(0);
911        pd.setCancelButton(NULL);
912        QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
913#ifdef Q_OS_WIN32
914        if (tl != NULL)
915                tl->SetProgressState(winId(), TBPF_INDETERMINATE);
916#endif
917QFuture<void> f = QtConcurrent::run(&solver, &CTSPSolver::cleanup, false);
918        while (!f.isFinished()) {
919                QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
920        }
921        toggleSolutionActions();
922        tabWidget->setCurrentIndex(1);
923#ifdef Q_OS_WIN32
924        if (tl != NULL) {
925                tl->SetProgressState(winId(), TBPF_NOPROGRESS);
926                tl->Release();
927                tl = NULL;
928        }
929#endif
930
931        pd.reset();
932        QApplication::alert(this, 3000);
933}
934
935void MainWindow::dataChanged()
936{
937        setWindowModified(true);
938}
939
940void MainWindow::dataChanged(const QModelIndex &tl, const QModelIndex &br)
941{
942        setWindowModified(true);
943        if (settings->value("Autosize", DEF_AUTOSIZE).toBool()) {
944                for (int k = tl.row(); k <= br.row(); k++)
945                        taskView->resizeRowToContents(k);
946                for (int k = tl.column(); k <= br.column(); k++)
947                        taskView->resizeColumnToContents(k);
948        }
949}
950
951#ifdef Q_OS_WINCE_WM
952void MainWindow::changeEvent(QEvent *ev)
953{
954        if ((ev->type() == QEvent::ActivationChange) && isActiveWindow())
955                desktopResized(0);
956
957        QWidget::changeEvent(ev);
958}
959
960void MainWindow::desktopResized(int screen)
961{
962        if ((screen != 0) || !isActiveWindow())
963                return;
964
965QRect availableGeometry = QApplication::desktop()->availableGeometry(0);
966        if (currentGeometry != availableGeometry) {
967                QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
968                /*!
969                 * \hack HACK: This hack checks whether \link QDesktopWidget::availableGeometry() availableGeometry()\endlink's \c top + \c hegiht = \link QDesktopWidget::screenGeometry() screenGeometry()\endlink's \c height.
970                 *  If \c true, the window gets maximized. If we used \c setGeometry() in this case, the bottom of the
971                 *  window would end up being behind the soft buttons. Is this a bug in Qt or Windows Mobile?
972                 */
973                if ((availableGeometry.top() + availableGeometry.height()) == QApplication::desktop()->screenGeometry().height()) {
974                        setWindowState(windowState() | Qt::WindowMaximized);
975                } else {
976                        if (windowState() & Qt::WindowMaximized)
977                                setWindowState(windowState() ^ Qt::WindowMaximized);
978                        setGeometry(availableGeometry);
979                }
980                currentGeometry = availableGeometry;
981                QApplication::restoreOverrideCursor();
982        }
983}
984#endif // Q_OS_WINCE_WM
985
986void MainWindow::numCitiesChanged(int nCities)
987{
988        blockSignals(true);
989        spinCities->setValue(nCities);
990        blockSignals(false);
991}
992
993#ifndef QT_NO_PRINTER
994void MainWindow::printPreview(QPrinter *printer)
995{
996        solutionText->print(printer);
997}
998#endif // QT_NO_PRINTER
999
1000#ifdef Q_OS_WIN32
1001void MainWindow::solverRoutePartFound(int n)
1002{
1003#ifdef Q_OS_WIN32
1004        tl->SetProgressValue(winId(), n, spinCities->value() * 2);
1005#else
1006        Q_UNUSED(n);
1007#endif // Q_OS_WIN32
1008}
1009#endif // Q_OS_WIN32
1010
1011void MainWindow::spinCitiesValueChanged(int n)
1012{
1013        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1014int count = tspmodel->numCities();
1015        tspmodel->setNumCities(n);
1016        if ((n > count) && settings->value("Autosize", DEF_AUTOSIZE).toBool())
1017                for (int k = count; k < n; k++) {
1018                        taskView->resizeColumnToContents(k);
1019                        taskView->resizeRowToContents(k);
1020                }
1021        QApplication::restoreOverrideCursor();
1022}
1023
1024void MainWindow::closeEvent(QCloseEvent *ev)
1025{
1026        if (!maybeSave()) {
1027                ev->ignore();
1028                return;
1029        }
1030        if (!settings->value("SettingsReset", false).toBool()) {
1031                settings->setValue("NumCities", spinCities->value());
1032
1033                // Saving Main Window state
1034#ifndef HANDHELD
1035                if (settings->value("SavePos", DEF_SAVEPOS).toBool()) {
1036                        settings->beginGroup("MainWindow");
1037                        settings->setValue("Geometry", saveGeometry());
1038                        settings->setValue("State", saveState());
1039                        settings->setValue("Toolbars", toolBarManager->saveState());
1040                        settings->endGroup();
1041                }
1042#endif // HANDHELD
1043        } else {
1044                settings->remove("SettingsReset");
1045        }
1046
1047        QMainWindow::closeEvent(ev);
1048}
1049
1050void MainWindow::dragEnterEvent(QDragEnterEvent *ev)
1051{
1052        if (ev->mimeData()->hasUrls() && (ev->mimeData()->urls().count() == 1)) {
1053QFileInfo fi(ev->mimeData()->urls().first().toLocalFile());
1054                if ((fi.suffix() == "tspt") || (fi.suffix() == "zkt"))
1055                        ev->acceptProposedAction();
1056        }
1057}
1058
1059void MainWindow::drawNode(QPainter &pic, int nstep, bool left, SStep *step)
1060{
1061int r;
1062        if (settings->value("Output/HQGraph", DEF_HQ_GRAPH).toBool())
1063                r = 70;
1064        else
1065                r = 35;
1066qreal x, y;
1067        if (step != NULL)
1068                x = left ? r : r * 3.5;
1069        else
1070                x = r * 2.25;
1071        y = r * (3 * nstep + 1);
1072
1073#ifdef _T_T_L_
1074        if (nstep == -481124) {
1075                _t_t_l_(pic, r, x);
1076                return;
1077        }
1078#endif
1079
1080        pic.drawEllipse(QPointF(x, y), r, r);
1081
1082        if (step != NULL) {
1083QFont font;
1084                if (left) {
1085                        font = pic.font();
1086                        font.setStrikeOut(true);
1087                        pic.setFont(font);
1088                }
1089                pic.drawText(QRectF(x - r, y - r, r * 2, r * 2), Qt::AlignCenter, tr("(%1;%2)").arg(step->pNode->candidate.nRow + 1).arg(step->pNode->candidate.nCol + 1) + "\n");
1090                if (left) {
1091                        font.setStrikeOut(false);
1092                        pic.setFont(font);
1093                }
1094                if (step->price != INFINITY) {
1095                        pic.drawText(QRectF(x - r, y - r, r * 2, r * 2), Qt::AlignCenter, isInteger(step->price) ?  QString("\n%1").arg(step->price) : QString("\n%1").arg(step->price, 0, 'f', settings->value("Task/FractionalAccuracy", DEF_FRACTIONAL_ACCURACY).toInt()));
1096                } else {
1097                        pic.drawText(QRectF(x - r, y - r, r * 2, r * 2), Qt::AlignCenter, "\n"INFSTR);
1098                }
1099        } else {
1100                pic.drawText(QRectF(x - r, y - r, r * 2, r * 2), Qt::AlignCenter, tr("Root"));
1101        }
1102
1103        if (nstep == 1) {
1104                pic.drawLine(QPointF(x, y - r), QPointF(r * 2.25, y - 2 * r));
1105        } else if (nstep > 1) {
1106                pic.drawLine(QPointF(x, y - r), QPointF((step->pNode->pNode->next == SStep::RightBranch) ? r * 3.5 : r, y - 2 * r));
1107        }
1108
1109}
1110
1111void MainWindow::dropEvent(QDropEvent *ev)
1112{
1113        if (maybeSave() && tspmodel->loadTask(ev->mimeData()->urls().first().toLocalFile())) {
1114                setFileName(ev->mimeData()->urls().first().toLocalFile());
1115                tabWidget->setCurrentIndex(0);
1116                setWindowModified(false);
1117                solutionText->clear();
1118                toggleSolutionActions(false);
1119
1120                ev->setDropAction(Qt::CopyAction);
1121                ev->accept();
1122        }
1123}
1124
1125bool MainWindow::hasUpdater() const
1126{
1127#ifdef Q_OS_WIN32
1128        return QFile::exists("updater/Update.exe");
1129#else // Q_OS_WIN32
1130        return false;
1131#endif // Q_OS_WIN32
1132}
1133
1134void MainWindow::initDocStyleSheet()
1135{
1136        solutionText->document()->setDefaultFont(settings->value("Output/Font", QFont(getDefaultFont(), DEF_FONT_SIZE)).value<QFont>());
1137
1138        fmt_paragraph.setTopMargin(0);
1139        fmt_paragraph.setRightMargin(10);
1140        fmt_paragraph.setBottomMargin(0);
1141        fmt_paragraph.setLeftMargin(10);
1142
1143        fmt_table.setTopMargin(5);
1144        fmt_table.setRightMargin(10);
1145        fmt_table.setBottomMargin(5);
1146        fmt_table.setLeftMargin(10);
1147        fmt_table.setBorder(0);
1148        fmt_table.setBorderStyle(QTextFrameFormat::BorderStyle_None);
1149        fmt_table.setCellSpacing(5);
1150
1151        fmt_cell.setAlignment(Qt::AlignHCenter);
1152
1153        settings->beginGroup("Output/Colors");
1154
1155QColor color = settings->value("Text", DEF_TEXT_COLOR).value<QColor>();
1156QColor hilight;
1157        if (color.value() < 192)
1158                hilight.setHsv(color.hue(), color.saturation(), 127 + qRound(color.value() / 2));
1159        else
1160                hilight.setHsv(color.hue(), color.saturation(), color.value() / 2);
1161
1162        solutionText->document()->setDefaultStyleSheet(QString("* {color: %1;}").arg(color.name()));
1163        fmt_default.setForeground(QBrush(color));
1164
1165        fmt_selected.setForeground(QBrush(settings->value("Selected", DEF_SELECTED_COLOR).value<QColor>()));
1166        fmt_selected.setFontWeight(QFont::Bold);
1167
1168        fmt_alternate.setForeground(QBrush(settings->value("Alternate", DEF_ALTERNATE_COLOR).value<QColor>()));
1169        fmt_alternate.setFontWeight(QFont::Bold);
1170        fmt_altlist.setForeground(QBrush(hilight));
1171
1172        settings->endGroup();
1173
1174        solutionText->setTextColor(color);
1175}
1176
1177void MainWindow::loadLangList()
1178{
1179QMap<QString, QStringList> langlist;
1180QFileInfoList langs;
1181QFileInfo lang;
1182QString name;
1183QStringList language, dirs;
1184QTranslator t;
1185QDir dir;
1186        dir.setFilter(QDir::Files);
1187        dir.setNameFilters(QStringList("tspsg_*.qm"));
1188        dir.setSorting(QDir::NoSort);
1189
1190        dirs << PATH_L10N << ":/l10n";
1191        foreach (QString dirname, dirs) {
1192                dir.setPath(dirname);
1193                if (dir.exists()) {
1194                        langs = dir.entryInfoList();
1195                        for (int k = 0; k < langs.size(); k++) {
1196                                lang = langs.at(k);
1197                                if (lang.completeBaseName().compare("tspsg_en", Qt::CaseInsensitive) && !langlist.contains(lang.completeBaseName().mid(6)) && t.load(lang.completeBaseName(), dirname)) {
1198
1199                                        language.clear();
1200                                        language.append(lang.completeBaseName().mid(6));
1201                                        language.append(t.translate("--------", "COUNTRY", "Please, provide an ISO 3166-1 alpha-2 country code for this translation language here (eg., UA).").toLower());
1202                                        language.append(t.translate("--------", "LANGNAME", "Please, provide a native name of your translation language here."));
1203                                        language.append(t.translate("MainWindow", "Set application language to %1", "").arg(name));
1204
1205                                        langlist.insert(language.at(0), language);
1206                                }
1207                        }
1208                }
1209        }
1210
1211QAction *a;
1212        foreach (language, langlist) {
1213                a = menuSettingsLanguage->addAction(language.at(2));
1214                a->setStatusTip(language.at(3));
1215                a->setIcon(QIcon::fromTheme(QString("flag-%1").arg(language.at(1)), QIcon(QString(":/images/icons/l10n/flag-%1.png").arg(language.at(1)))));
1216                a->setData(language.at(0));
1217                a->setCheckable(true);
1218                a->setActionGroup(groupSettingsLanguageList);
1219                if (settings->value("Language", QLocale::system().name()).toString().startsWith(language.at(0)))
1220                        a->setChecked(true);
1221        }
1222}
1223
1224bool MainWindow::loadLanguage(const QString &lang)
1225{
1226// i18n
1227bool ad = false;
1228QString lng = lang;
1229        if (lng.isEmpty()) {
1230                ad = settings->value("Language", "").toString().isEmpty();
1231                lng = settings->value("Language", QLocale::system().name()).toString();
1232        }
1233static QTranslator *qtTranslator; // Qt library translator
1234        if (qtTranslator) {
1235                qApp->removeTranslator(qtTranslator);
1236                delete qtTranslator;
1237                qtTranslator = NULL;
1238        }
1239static QTranslator *translator; // Application translator
1240        if (translator) {
1241                qApp->removeTranslator(translator);
1242                delete translator;
1243                translator = NULL;
1244        }
1245
1246        if (lng == "en")
1247                return true;
1248
1249        // Trying to load system Qt library translation...
1250        qtTranslator = new QTranslator(this);
1251        if (qtTranslator->load("qt_" + lng, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
1252                qApp->installTranslator(qtTranslator);
1253        else {
1254                // No luck. Let's try to load a bundled one.
1255                if (qtTranslator->load("qt_" + lng, PATH_L10N)) {
1256                        // We have a translation in the localization direcotry.
1257                        qApp->installTranslator(qtTranslator);
1258                } else if (qtTranslator->load("qt_" + lng, ":/l10n")) {
1259                        // We have a translation "built-in" into application resources.
1260                        qApp->installTranslator(qtTranslator);
1261                } else {
1262                        // Qt library translation unavailable for this language.
1263                        delete qtTranslator;
1264                        qtTranslator = NULL;
1265                }
1266        }
1267
1268        // Now let's load application translation.
1269        translator = new QTranslator(this);
1270        if (translator->load("tspsg_" + lng, PATH_L10N)) {
1271                // We have a translation in the localization directory.
1272                qApp->installTranslator(translator);
1273        } else if (translator->load("tspsg_" + lng, ":/l10n")) {
1274                // We have a translation "built-in" into application resources.
1275                qApp->installTranslator(translator);
1276        } else {
1277                delete translator;
1278                translator = NULL;
1279                if (!ad) {
1280                        settings->remove("Language");
1281                        QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
1282                        QMessageBox::warning(isVisible() ? this : NULL, tr("Language Change"), tr("Unable to load the translation language.\nFalling back to autodetection."));
1283                        QApplication::restoreOverrideCursor();
1284                }
1285                return false;
1286        }
1287        return true;
1288}
1289
1290void MainWindow::loadStyleList()
1291{
1292        menuSettingsStyle->clear();
1293QStringList styles = QStyleFactory::keys();
1294        menuSettingsStyle->insertAction(NULL, actionSettingsStyleSystem);
1295        actionSettingsStyleSystem->setChecked(!settings->contains("Style"));
1296        menuSettingsStyle->addSeparator();
1297QAction *a;
1298        foreach (QString style, styles) {
1299                a = menuSettingsStyle->addAction(style);
1300                a->setData(false);
1301                a->setStatusTip(tr("Set application style to %1").arg(style));
1302                a->setCheckable(true);
1303                a->setActionGroup(groupSettingsStyleList);
1304                if ((style == settings->value("Style").toString())
1305                        || QString(QApplication::style()->metaObject()->className()).contains(QRegExp(QString("^Q?%1(Style)?$").arg(QRegExp::escape(style)), Qt::CaseInsensitive))) {
1306                        a->setChecked(true);
1307                }
1308        }
1309}
1310
1311void MainWindow::loadToolbarList()
1312{
1313        menuSettingsToolbars->clear();
1314#ifndef HANDHELD
1315        menuSettingsToolbars->insertAction(NULL, actionSettingsToolbarsConfigure);
1316        menuSettingsToolbars->addSeparator();
1317QList<QToolBar *> list = toolBarManager->toolBars();
1318        foreach (QToolBar *t, list) {
1319                menuSettingsToolbars->insertAction(NULL, t->toggleViewAction());
1320        }
1321#else // HANDHELD
1322        menuSettingsToolbars->insertAction(NULL, toolBarMain->toggleViewAction());
1323#endif // HANDHELD
1324}
1325
1326bool MainWindow::maybeSave()
1327{
1328        if (!isWindowModified())
1329                return true;
1330int res = QMessageBox::warning(this, tr("Unsaved Changes"), tr("Would you like to save changes in the current task?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
1331        if (res == QMessageBox::Save)
1332                return actionFileSaveTriggered();
1333        else if (res == QMessageBox::Cancel)
1334                return false;
1335        else
1336                return true;
1337}
1338
1339void MainWindow::outputMatrix(QTextCursor &cur, const TMatrix &matrix)
1340{
1341int n = spinCities->value();
1342QTextTable *table = cur.insertTable(n, n, fmt_table);
1343
1344        for (int r = 0; r < n; r++) {
1345                for (int c = 0; c < n; c++) {
1346                        cur = table->cellAt(r, c).firstCursorPosition();
1347                        cur.setBlockFormat(fmt_cell);
1348                        cur.setBlockCharFormat(fmt_default);
1349                        if (matrix.at(r).at(c) == INFINITY)
1350                                cur.insertText(INFSTR);
1351                        else
1352                                cur.insertText(isInteger(matrix.at(r).at(c)) ? QString("%1").arg(matrix.at(r).at(c)) : QString("%1").arg(matrix.at(r).at(c), 0, 'f', settings->value("Task/FractionalAccuracy", DEF_FRACTIONAL_ACCURACY).toInt()));
1353                }
1354                QApplication::processEvents();
1355        }
1356        cur.movePosition(QTextCursor::End);
1357}
1358
1359void MainWindow::outputMatrix(QTextCursor &cur, const SStep &step)
1360{
1361int n = spinCities->value();
1362QTextTable *table = cur.insertTable(n, n, fmt_table);
1363
1364        for (int r = 0; r < n; r++) {
1365                for (int c = 0; c < n; c++) {
1366                        cur = table->cellAt(r, c).firstCursorPosition();
1367                        cur.setBlockFormat(fmt_cell);
1368                        if (step.matrix.at(r).at(c) == INFINITY)
1369                                cur.insertText(INFSTR, fmt_default);
1370                        else if ((r == step.candidate.nRow) && (c == step.candidate.nCol))
1371                                cur.insertText(isInteger(step.matrix.at(r).at(c)) ? QString("%1").arg(step.matrix.at(r).at(c)) : QString("%1").arg(step.matrix.at(r).at(c), 0, 'f', settings->value("Task/FractionalAccuracy", DEF_FRACTIONAL_ACCURACY).toInt()), fmt_selected);
1372                        else {
1373SStep::SCandidate cand;
1374                                cand.nRow = r;
1375                                cand.nCol = c;
1376                                if (step.alts.contains(cand))
1377                                        cur.insertText(isInteger(step.matrix.at(r).at(c)) ? QString("%1").arg(step.matrix.at(r).at(c)) : QString("%1").arg(step.matrix.at(r).at(c), 0, 'f', settings->value("Task/FractionalAccuracy", DEF_FRACTIONAL_ACCURACY).toInt()), fmt_alternate);
1378                                else
1379                                        cur.insertText(isInteger(step.matrix.at(r).at(c)) ? QString("%1").arg(step.matrix.at(r).at(c)) : QString("%1").arg(step.matrix.at(r).at(c), 0, 'f', settings->value("Task/FractionalAccuracy", DEF_FRACTIONAL_ACCURACY).toInt()), fmt_default);
1380                        }
1381                }
1382                QApplication::processEvents();
1383        }
1384
1385        cur.movePosition(QTextCursor::End);
1386}
1387
1388void MainWindow::retranslateUi(bool all)
1389{
1390        if (all)
1391                Ui::MainWindow::retranslateUi(this);
1392
1393        loadStyleList();
1394        loadToolbarList();
1395
1396#ifndef QT_NO_PRINTER
1397        actionFilePrintPreview->setText(tr("P&rint Preview..."));
1398#ifndef QT_NO_TOOLTIP
1399        actionFilePrintPreview->setToolTip(tr("Preview solution results"));
1400#endif // QT_NO_TOOLTIP
1401#ifndef QT_NO_STATUSTIP
1402        actionFilePrintPreview->setStatusTip(tr("Preview current solution results before printing"));
1403#endif // QT_NO_STATUSTIP
1404
1405        actionFilePrint->setText(tr("&Print..."));
1406#ifndef QT_NO_TOOLTIP
1407        actionFilePrint->setToolTip(tr("Print solution"));
1408#endif // QT_NO_TOOLTIP
1409#ifndef QT_NO_STATUSTIP
1410        actionFilePrint->setStatusTip(tr("Print current solution results"));
1411#endif // QT_NO_STATUSTIP
1412        actionFilePrint->setShortcut(tr("Ctrl+P"));
1413#endif // QT_NO_PRINTER
1414
1415#ifndef HANDHELD
1416        actionSettingsToolbarsConfigure->setText(tr("Configure..."));
1417#ifndef QT_NO_STATUSTIP
1418        actionSettingsToolbarsConfigure->setStatusTip(tr("Customize toolbars"));
1419#endif // QT_NO_STATUSTIP
1420#endif // HANDHELD
1421
1422#ifdef Q_OS_WIN32
1423        actionHelpCheck4Updates->setText(tr("Check for &Updates..."));
1424#ifndef QT_NO_STATUSTIP
1425        actionHelpCheck4Updates->setStatusTip(tr("Check for %1 updates").arg(QApplication::applicationName()));
1426#endif // QT_NO_STATUSTIP
1427#endif // Q_OS_WIN32
1428}
1429
1430bool MainWindow::saveTask() {
1431QStringList filters(tr("%1 Task File").arg("TSPSG") + " (*.tspt)");
1432        filters.append(tr("All Files") + " (*)");
1433QString file;
1434        if (fileName.endsWith(".tspt", Qt::CaseInsensitive))
1435                file = fileName;
1436        else
1437                file = QFileInfo(fileName).canonicalPath() + "/" + QFileInfo(fileName).completeBaseName() + ".tspt";
1438
1439QFileDialog::Options opts = settings->value("UseNativeDialogs", DEF_USE_NATIVE_DIALOGS).toBool() ? QFileDialog::Options() : QFileDialog::DontUseNativeDialog;
1440        file = QFileDialog::getSaveFileName(this, tr("Task Save"), file, filters.join(";;"), NULL, opts);
1441
1442        if (file.isEmpty())
1443                return false;
1444        if (tspmodel->saveTask(file)) {
1445                setFileName(file);
1446                setWindowModified(false);
1447                return true;
1448        }
1449        return false;
1450}
1451
1452void MainWindow::setFileName(const QString &fileName)
1453{
1454        this->fileName = fileName;
1455        setWindowTitle(QString("%1[*] - %2").arg(QFileInfo(fileName).completeBaseName()).arg(QApplication::applicationName()));
1456}
1457
1458void MainWindow::setupUi()
1459{
1460        Ui::MainWindow::setupUi(this);
1461
1462        // File Menu
1463        actionFileNew->setIcon(QIcon::fromTheme("document-new", QIcon(":/images/icons/document-new.png")));
1464        actionFileOpen->setIcon(QIcon::fromTheme("document-open", QIcon(":/images/icons/document-open.png")));
1465        actionFileSave->setIcon(QIcon::fromTheme("document-save", QIcon(":/images/icons/document-save.png")));
1466        menuFileSaveAs->setIcon(QIcon::fromTheme("document-save-as", QIcon(":/images/icons/document-save-as.png")));
1467        actionFileExit->setIcon(QIcon::fromTheme("application-exit", QIcon(":/images/icons/application-exit.png")));
1468        // Settings Menu
1469        menuSettingsLanguage->setIcon(QIcon::fromTheme("preferences-desktop-locale", QIcon(":/images/icons/preferences-desktop-locale.png")));
1470        actionSettingsLanguageEnglish->setIcon(QIcon::fromTheme("flag-gb", QIcon(":/images/icons/l10n/flag-gb.png")));
1471        menuSettingsStyle->setIcon(QIcon::fromTheme("preferences-desktop-theme", QIcon(":/images/icons/preferences-desktop-theme.png")));
1472        actionSettingsPreferences->setIcon(QIcon::fromTheme("preferences-system", QIcon(":/images/icons/preferences-system.png")));
1473        // Help Menu
1474        actionHelpContents->setIcon(QIcon::fromTheme("help-contents", QIcon(":/images/icons/help-contents.png")));
1475        actionHelpContextual->setIcon(QIcon::fromTheme("help-contextual", QIcon(":/images/icons/help-contextual.png")));
1476        actionHelpAbout->setIcon(QIcon::fromTheme("help-about", QIcon(":/images/icons/help-about.png")));
1477        // Buttons
1478        buttonRandom->setIcon(QIcon::fromTheme("roll", QIcon(":/images/icons/roll.png")));
1479        buttonSolve->setIcon(QIcon::fromTheme("dialog-ok", QIcon(":/images/icons/dialog-ok.png")));
1480        buttonSaveSolution->setIcon(QIcon::fromTheme("document-save-as", QIcon(":/images/icons/document-save-as.png")));
1481        buttonBackToTask->setIcon(QIcon::fromTheme("go-previous", QIcon(":/images/icons/go-previous.png")));
1482
1483//      action->setIcon(QIcon::fromTheme("", QIcon(":/images/icons/.png")));
1484
1485#if QT_VERSION >= 0x040600
1486        setToolButtonStyle(Qt::ToolButtonFollowStyle);
1487#endif
1488
1489#ifndef HANDHELD
1490QStatusBar *statusbar = new QStatusBar(this);
1491        statusbar->setObjectName("statusbar");
1492        setStatusBar(statusbar);
1493#endif // HANDHELD
1494
1495#ifdef Q_OS_WINCE_WM
1496        menuBar()->setDefaultAction(menuFile->menuAction());
1497
1498QScrollArea *scrollArea = new QScrollArea(this);
1499        scrollArea->setFrameShape(QFrame::NoFrame);
1500        scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1501        scrollArea->setWidgetResizable(true);
1502        scrollArea->setWidget(tabWidget);
1503        setCentralWidget(scrollArea);
1504#else
1505        setCentralWidget(tabWidget);
1506#endif // Q_OS_WINCE_WM
1507
1508        //! \hack HACK: A little hack for toolbar icons to have a sane size.
1509#ifdef HANDHELD
1510        toolBarMain->setIconSize(QSize(logicalDpiX() / 4, logicalDpiY() / 4));
1511#endif // HANDHELD
1512QToolButton *tb = static_cast<QToolButton *>(toolBarMain->widgetForAction(actionFileSave));
1513        if (tb != NULL)  {
1514                tb->setMenu(menuFileSaveAs);
1515                tb->setPopupMode(QToolButton::MenuButtonPopup);
1516        }
1517
1518//      solutionText->document()->setDefaultFont(settings->value("Output/Font", QFont(DEF_FONT_FAMILY, DEF_FONT_SIZE)).value<QFont>());
1519        solutionText->setWordWrapMode(QTextOption::WordWrap);
1520
1521#ifndef QT_NO_PRINTER
1522        actionFilePrintPreview = new QAction(this);
1523        actionFilePrintPreview->setObjectName("actionFilePrintPreview");
1524        actionFilePrintPreview->setEnabled(false);
1525        actionFilePrintPreview->setIcon(QIcon::fromTheme("document-print-preview", QIcon(":/images/icons/document-print-preview.png")));
1526
1527        actionFilePrint = new QAction(this);
1528        actionFilePrint->setObjectName("actionFilePrint");
1529        actionFilePrint->setEnabled(false);
1530        actionFilePrint->setIcon(QIcon::fromTheme("document-print", QIcon(":/images/icons/document-print.png")));
1531
1532        menuFile->insertAction(actionFileExit,actionFilePrintPreview);
1533        menuFile->insertAction(actionFileExit,actionFilePrint);
1534        menuFile->insertSeparator(actionFileExit);
1535
1536        toolBarMain->insertAction(actionSettingsPreferences, actionFilePrint);
1537#endif // QT_NO_PRINTER
1538
1539        groupSettingsLanguageList = new QActionGroup(this);
1540        actionSettingsLanguageEnglish->setData("en");
1541        actionSettingsLanguageEnglish->setActionGroup(groupSettingsLanguageList);
1542        loadLangList();
1543        actionSettingsLanguageAutodetect->setChecked(settings->value("Language", "").toString().isEmpty());
1544
1545        actionSettingsStyleSystem->setData(true);
1546        groupSettingsStyleList = new QActionGroup(this);
1547
1548#ifndef HANDHELD
1549        actionSettingsToolbarsConfigure = new QAction(this);
1550        actionSettingsToolbarsConfigure->setIcon(QIcon::fromTheme("configure-toolbars", QIcon(":/images/icons/configure-toolbars.png")));
1551#endif // HANDHELD
1552
1553#ifdef Q_OS_WIN32
1554        actionHelpCheck4Updates = new QAction(this);
1555        actionHelpCheck4Updates->setIcon(QIcon::fromTheme("system-software-update", QIcon(":/images/icons/system-software-update.png")));
1556        actionHelpCheck4Updates->setEnabled(hasUpdater());
1557        menuHelp->insertAction(actionHelpAboutQt, actionHelpCheck4Updates);
1558        menuHelp->insertSeparator(actionHelpAboutQt);
1559#endif // Q_OS_WIN32
1560
1561        spinCities->setMaximum(MAX_NUM_CITIES);
1562
1563#ifndef HANDHELD
1564        toolBarManager = new QtToolBarManager;
1565        toolBarManager->setMainWindow(this);
1566QString cat = toolBarMain->windowTitle();
1567        toolBarManager->addToolBar(toolBarMain, cat);
1568#ifndef QT_NO_PRINTER
1569        toolBarManager->addAction(actionFilePrintPreview, cat);
1570#endif // QT_NO_PRINTER
1571        toolBarManager->addAction(actionHelpContents, cat);
1572        toolBarManager->addAction(actionHelpContextual, cat);
1573//      toolBarManager->addAction(action, cat);
1574        toolBarManager->restoreState(settings->value("MainWindow/Toolbars").toByteArray());
1575#endif // HANDHELD
1576
1577        retranslateUi(false);
1578
1579#ifdef Q_OS_WIN32
1580        // Adding some eyecandy in Vista and 7 :-)
1581        if (QtWin::isCompositionEnabled() && settings->value("UseTranslucency", DEF_USE_TRANSLUCENCY).toBool())  {
1582                toggleTranclucency(true);
1583        }
1584#endif // Q_OS_WIN32
1585}
1586
1587void MainWindow::toggleSolutionActions(bool enable)
1588{
1589        buttonSaveSolution->setEnabled(enable);
1590        actionFileSaveAsSolution->setEnabled(enable);
1591        solutionText->setEnabled(enable);
1592#ifndef QT_NO_PRINTER
1593        actionFilePrint->setEnabled(enable);
1594        actionFilePrintPreview->setEnabled(enable);
1595#endif // QT_NO_PRINTER
1596}
1597
1598void MainWindow::toggleTranclucency(bool enable)
1599{
1600#ifdef Q_OS_WIN32
1601        toggleStyle(labelVariant, enable);
1602        toggleStyle(labelCities, enable);
1603        toggleStyle(statusBar(), enable);
1604        tabWidget->setDocumentMode(enable);
1605        QtWin::enableBlurBehindWindow(this, enable);
1606#else
1607        Q_UNUSED(enable);
1608#endif // Q_OS_WIN32
1609}
Note: See TracBrowser for help on using the repository browser.