/* * TSPSG: TSP Solver and Generator * Copyright (C) 2007-2010 Lёppa * * $Id: mainwindow.cpp 122 2010-06-22 20:19:42Z laleppa $ * $URL: https://tspsg.svn.sourceforge.net/svnroot/tspsg/trunk/src/mainwindow.cpp $ * * This file is part of TSPSG. * * TSPSG is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * TSPSG is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with TSPSG. If not, see . */ #include "mainwindow.h" #ifdef _T_T_L_ #include "_.h" _C_ _R_ _Y_ _P_ _T_ #endif /*! * \brief Class constructor. * \param parent Main Window parent widget. * * Initializes Main Window and creates its layout based on target OS. * Loads TSPSG settings and opens a task file if it was specified as a commandline parameter. */ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, "TSPSG", "tspsg", this); if (settings->contains("Style")) { QStyle *s = QStyleFactory::create(settings->value("Style").toString()); if (s != NULL) QApplication::setStyle(s); else settings->remove("Style"); } loadLanguage(); setupUi(); setAcceptDrops(true); initDocStyleSheet(); #ifndef QT_NO_PRINTER printer = new QPrinter(QPrinter::HighResolution); #endif // QT_NO_PRINTER #ifdef Q_OS_WINCE_WM currentGeometry = QApplication::desktop()->availableGeometry(0); // We need to react to SIP show/hide and resize the window appropriately connect(QApplication::desktop(), SIGNAL(workAreaResized(int)), SLOT(desktopResized(int))); #endif // Q_OS_WINCE_WM connect(actionFileNew, SIGNAL(triggered()), SLOT(actionFileNewTriggered())); connect(actionFileOpen, SIGNAL(triggered()), SLOT(actionFileOpenTriggered())); connect(actionFileSave, SIGNAL(triggered()), SLOT(actionFileSaveTriggered())); connect(actionFileSaveAsTask, SIGNAL(triggered()), SLOT(actionFileSaveAsTaskTriggered())); connect(actionFileSaveAsSolution, SIGNAL(triggered()), SLOT(actionFileSaveAsSolutionTriggered())); #ifndef QT_NO_PRINTER connect(actionFilePrintPreview, SIGNAL(triggered()), SLOT(actionFilePrintPreviewTriggered())); connect(actionFilePrint, SIGNAL(triggered()), SLOT(actionFilePrintTriggered())); #endif // QT_NO_PRINTER #ifndef HANDHELD connect(actionSettingsToolbarsConfigure, SIGNAL(triggered()), SLOT(actionSettingsToolbarsConfigureTriggered())); #endif // HANDHELD connect(actionSettingsPreferences, SIGNAL(triggered()), SLOT(actionSettingsPreferencesTriggered())); #ifdef Q_OS_WIN32 connect(actionHelpCheck4Updates, SIGNAL(triggered()), SLOT(actionHelpCheck4UpdatesTriggered())); #endif // Q_OS_WIN32 connect(actionSettingsLanguageAutodetect, SIGNAL(triggered(bool)), SLOT(actionSettingsLanguageAutodetectTriggered(bool))); connect(groupSettingsLanguageList, SIGNAL(triggered(QAction *)), SLOT(groupSettingsLanguageListTriggered(QAction *))); connect(actionSettingsStyleSystem, SIGNAL(triggered(bool)), SLOT(actionSettingsStyleSystemTriggered(bool))); connect(groupSettingsStyleList, SIGNAL(triggered(QAction*)), SLOT(groupSettingsStyleListTriggered(QAction*))); connect(actionHelpAboutQt, SIGNAL(triggered()), qApp, SLOT(aboutQt())); connect(actionHelpAbout, SIGNAL(triggered()), SLOT(actionHelpAboutTriggered())); connect(buttonSolve, SIGNAL(clicked()), SLOT(buttonSolveClicked())); connect(buttonRandom, SIGNAL(clicked()), SLOT(buttonRandomClicked())); connect(buttonBackToTask, SIGNAL(clicked()), SLOT(buttonBackToTaskClicked())); connect(spinCities, SIGNAL(valueChanged(int)), SLOT(spinCitiesValueChanged(int))); #ifndef HANDHELD // Centering main window QRect rect = geometry(); rect.moveCenter(QApplication::desktop()->availableGeometry(this).center()); setGeometry(rect); if (settings->value("SavePos", DEF_SAVEPOS).toBool()) { // Loading of saved window state settings->beginGroup("MainWindow"); restoreGeometry(settings->value("Geometry").toByteArray()); restoreState(settings->value("State").toByteArray()); settings->endGroup(); } #endif // HANDHELD tspmodel = new CTSPModel(this); taskView->setModel(tspmodel); connect(tspmodel, SIGNAL(numCitiesChanged(int)), SLOT(numCitiesChanged(int))); connect(tspmodel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), SLOT(dataChanged(const QModelIndex &, const QModelIndex &))); connect(tspmodel, SIGNAL(layoutChanged()), SLOT(dataChanged())); if ((QCoreApplication::arguments().count() > 1) && (tspmodel->loadTask(QCoreApplication::arguments().at(1)))) setFileName(QCoreApplication::arguments().at(1)); else { setFileName(); spinCities->setValue(settings->value("NumCities",DEF_NUM_CITIES).toInt()); spinCitiesValueChanged(spinCities->value()); } setWindowModified(false); } MainWindow::~MainWindow() { #ifndef QT_NO_PRINTER delete printer; #endif } /* Privates **********************************************************/ void MainWindow::actionFileNewTriggered() { if (!maybeSave()) return; QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); tspmodel->clear(); setFileName(); setWindowModified(false); tabWidget->setCurrentIndex(0); solutionText->clear(); toggleSolutionActions(false); QApplication::restoreOverrideCursor(); } void MainWindow::actionFileOpenTriggered() { if (!maybeSave()) return; QStringList filters(tr("All Supported Formats") + " (*.tspt *.zkt)"); filters.append(tr("%1 Task Files").arg("TSPSG") + " (*.tspt)"); filters.append(tr("%1 Task Files").arg("ZKomModRd") + " (*.zkt)"); filters.append(tr("All Files") + " (*)"); QString file = QFileInfo(fileName).canonicalPath(); QFileDialog::Options opts = settings->value("UseNativeDialogs", DEF_USE_NATIVE_DIALOGS).toBool() ? QFileDialog::Options() : QFileDialog::DontUseNativeDialog; file = QFileDialog::getOpenFileName(this, tr("Task Load"), file, filters.join(";;"), NULL, opts); if (file.isEmpty() || !QFileInfo(file).isFile()) return; if (!tspmodel->loadTask(file)) return; setFileName(file); tabWidget->setCurrentIndex(0); setWindowModified(false); solutionText->clear(); toggleSolutionActions(false); } bool MainWindow::actionFileSaveTriggered() { if ((fileName == tr("Untitled") + ".tspt") || (!fileName.endsWith(".tspt", Qt::CaseInsensitive))) return saveTask(); else if (tspmodel->saveTask(fileName)) { setWindowModified(false); return true; } else return false; } void MainWindow::actionFileSaveAsTaskTriggered() { saveTask(); } void MainWindow::actionFileSaveAsSolutionTriggered() { static QString selectedFile; if (selectedFile.isEmpty()) selectedFile = QFileInfo(fileName).canonicalPath(); else selectedFile = QFileInfo(selectedFile).canonicalPath(); if (!selectedFile.isEmpty()) selectedFile += "/"; if (fileName == tr("Untitled") + ".tspt") { #ifndef QT_NO_PRINTER selectedFile += "solution.pdf"; #else selectedFile += "solution.html"; #endif // QT_NO_PRINTER } else { #ifndef QT_NO_PRINTER selectedFile += QFileInfo(fileName).completeBaseName() + ".pdf"; #else selectedFile += QFileInfo(fileName).completeBaseName() + ".html"; #endif // QT_NO_PRINTER } QStringList filters; #ifndef QT_NO_PRINTER filters.append(tr("PDF Files") + " (*.pdf)"); #endif filters.append(tr("HTML Files") + " (*.html *.htm)"); #if QT_VERSION >= 0x040500 filters.append(tr("OpenDocument Files") + " (*.odt)"); #endif // QT_VERSION >= 0x040500 filters.append(tr("All Files") + " (*)"); QFileDialog::Options opts(settings->value("UseNativeDialogs", DEF_USE_NATIVE_DIALOGS).toBool() ? QFileDialog::Options() : QFileDialog::DontUseNativeDialog); QString file = QFileDialog::getSaveFileName(this, QString(), selectedFile, filters.join(";;"), NULL, opts); if (file.isEmpty()) return; selectedFile = file; QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); #ifndef QT_NO_PRINTER if (selectedFile.endsWith(".pdf",Qt::CaseInsensitive)) { QPrinter printer(QPrinter::HighResolution); printer.setOutputFormat(QPrinter::PdfFormat); printer.setOutputFileName(selectedFile); solutionText->document()->print(&printer); QApplication::restoreOverrideCursor(); return; } #endif if (selectedFile.endsWith(".htm", Qt::CaseInsensitive) || selectedFile.endsWith(".html", Qt::CaseInsensitive)) { QFile file(selectedFile); if (!file.open(QFile::WriteOnly)) { QApplication::restoreOverrideCursor(); QMessageBox::critical(this, tr("Solution Save"), tr("Unable to save the solution.\nError: %1").arg(file.errorString())); return; } QFileInfo fi(selectedFile); QString format = settings->value("Output/GraphImageFormat", DEF_GRAPH_IMAGE_FORMAT).toString(); #if !defined(NOSVG) && (QT_VERSION >= 0x040500) if (!QImageWriter::supportedImageFormats().contains(format.toAscii()) && (format != "svg")) { #else // NOSVG && QT_VERSION >= 0x040500 if (!QImageWriter::supportedImageFormats().contains(format.toAscii())) { #endif // NOSVG && QT_VERSION >= 0x040500 format = DEF_GRAPH_IMAGE_FORMAT; settings->remove("Output/GraphImageFormat"); } QString html = solutionText->document()->toHtml("UTF-8"), img = fi.completeBaseName() + "." + format; html.replace(QRegExp("= 0x040500) if (format == "svg") { QSvgGenerator svg; svg.setSize(QSize(graph.width(), graph.height())); svg.setResolution(graph.logicalDpiX()); svg.setFileName(fi.path() + "/" + img); svg.setTitle(tr("Solution Graph")); svg.setDescription(tr("Generated with %1").arg(QApplication::applicationName())); QPainter p; p.begin(&svg); p.drawPicture(1, 1, graph); p.end(); } else { #endif // NOSVG && QT_VERSION >= 0x040500 QImage i(graph.width() + 2, graph.height() + 2, QImage::Format_ARGB32); i.fill(0x00FFFFFF); QPainter p; p.begin(&i); p.drawPicture(1, 1, graph); p.end(); QImageWriter pic(fi.path() + "/" + img); if (pic.supportsOption(QImageIOHandler::Description)) { pic.setText("Title", "Solution Graph"); pic.setText("Software", QApplication::applicationName()); } if (format == "png") pic.setQuality(5); else if (format == "jpeg") pic.setQuality(80); if (!pic.write(i)) { QApplication::restoreOverrideCursor(); QMessageBox::critical(this, tr("Solution Save"), tr("Unable to save the solution graph.\nError: %1").arg(pic.errorString())); return; } #if !defined(NOSVG) && (QT_VERSION >= 0x040500) } #endif // NOSVG && QT_VERSION >= 0x040500 // Qt < 4.5 has no QTextDocumentWriter class #if QT_VERSION >= 0x040500 } else { QTextDocumentWriter dw(selectedFile); if (!selectedFile.endsWith(".odt",Qt::CaseInsensitive)) dw.setFormat("plaintext"); if (!dw.write(solutionText->document())) QMessageBox::critical(this, tr("Solution Save"), tr("Unable to save the solution.\nError: %1").arg(dw.device()->errorString())); #endif // QT_VERSION >= 0x040500 } QApplication::restoreOverrideCursor(); } #ifndef QT_NO_PRINTER void MainWindow::actionFilePrintPreviewTriggered() { QPrintPreviewDialog ppd(printer, this); connect(&ppd,SIGNAL(paintRequested(QPrinter *)),SLOT(printPreview(QPrinter *))); ppd.exec(); } void MainWindow::actionFilePrintTriggered() { QPrintDialog pd(printer,this); if (pd.exec() != QDialog::Accepted) return; QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); solutionText->print(printer); QApplication::restoreOverrideCursor(); } #endif // QT_NO_PRINTER void MainWindow::actionSettingsPreferencesTriggered() { SettingsDialog sd(this); if (sd.exec() != QDialog::Accepted) return; if (sd.colorChanged() || sd.fontChanged()) { if (!solutionText->document()->isEmpty() && sd.colorChanged()) QMessageBox::information(this, tr("Settings Changed"), tr("You have changed color settings.\nThey will be applied to the next solution output.")); initDocStyleSheet(); } if (sd.translucencyChanged() != 0) toggleTranclucency(sd.translucencyChanged() == 1); } void MainWindow::actionSettingsLanguageAutodetectTriggered(bool checked) { if (checked) { settings->remove("Language"); QMessageBox::information(this, tr("Language change"), tr("Language will be autodetected on the next %1 start.").arg(QApplication::applicationName())); } else settings->setValue("Language", groupSettingsLanguageList->checkedAction()->data().toString()); } void MainWindow::groupSettingsLanguageListTriggered(QAction *action) { if (actionSettingsLanguageAutodetect->isChecked()) { // We have language autodetection. It needs to be disabled to change language. if (QMessageBox::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) { actionSettingsLanguageAutodetect->trigger(); } else return; } bool untitled = (fileName == tr("Untitled") + ".tspt"); if (loadLanguage(action->data().toString())) { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); settings->setValue("Language",action->data().toString()); retranslateUi(); if (untitled) setFileName(); #ifdef Q_OS_WIN32 if (QtWin::isCompositionEnabled() && settings->value("UseTranslucency", DEF_USE_TRANSLUCENCY).toBool()) { toggleStyle(labelVariant, true); toggleStyle(labelCities, true); } #endif QApplication::restoreOverrideCursor(); if (!solutionText->document()->isEmpty()) 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.")); } } void MainWindow::actionSettingsStyleSystemTriggered(bool checked) { if (checked) { settings->remove("Style"); QMessageBox::information(this, tr("Style Change"), tr("To apply the default style you need to restart %1.").arg(QApplication::applicationName())); } else { settings->setValue("Style", groupSettingsStyleList->checkedAction()->text()); } } void MainWindow::groupSettingsStyleListTriggered(QAction *action) { QStyle *s = QStyleFactory::create(action->text()); if (s != NULL) { QApplication::setStyle(s); settings->setValue("Style", action->text()); actionSettingsStyleSystem->setChecked(false); } } #ifndef HANDHELD void MainWindow::actionSettingsToolbarsConfigureTriggered() { QtToolBarDialog dlg(this); dlg.setToolBarManager(toolBarManager); dlg.exec(); QToolButton *tb = static_cast(toolBarMain->widgetForAction(actionFileSave)); if (tb != NULL) { tb->setMenu(menuFileSaveAs); tb->setPopupMode(QToolButton::MenuButtonPopup); tb->resize(tb->sizeHint()); } loadToolbarList(); } #endif // HANDHELD #ifdef Q_OS_WIN32 void MainWindow::actionHelpCheck4UpdatesTriggered() { if (!hasUpdater()) { 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.")); return; } QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); QProcess::execute("updater/Update.exe -name=\"TSPSG: TSP Solver and Generator\" -check=\"freeupdate\""); QApplication::restoreOverrideCursor(); } #endif // Q_OS_WIN32 void MainWindow::actionHelpAboutTriggered() { QString title; #ifdef HANDHELD title += QString("TSPSG
TSP Solver and Generator

"); #else title += QString("%1
").arg(QApplication::applicationName()); #endif // HANDHELD title += QString("%1: %2
").arg(tr("Version"), QApplication::applicationVersion()); #ifndef HANDHELD title += QString("© 2007-%1 %3
").arg(QDate::currentDate().toString("yyyy"), QApplication::organizationDomain(), QApplication::organizationName()); title += QString("http://tspsg.sourceforge.net/"); #else title += QString("http://tspsg.sf.net/"); #endif // HANDHELD QString about; about += QString("%1: %2
").arg(tr("Target OS (ARCH)"), OS); #ifndef STATIC_BUILD about += QString("%1 (%2):
").arg(tr("Qt library"), tr("shared")); about += QString("    %1: %2
").arg(tr("Build time"), QT_VERSION_STR); about += QString("    %1: %2
").arg(tr("Runtime"), qVersion()); #else about += QString("%1: %2 (%3)
").arg(tr("Qt library"), QT_VERSION_STR, tr("static")); #endif // STATIC_BUILD about += tr("Buid %1, built on %2 at %3").arg(BUILD_NUMBER).arg(__DATE__).arg(__TIME__) + "
"; about += QString("%1: %2
").arg(tr("Algorithm"), CTSPSolver::getVersionId()); about += "
"; about += tr("TSPSG is free software: you can redistribute it and/or modify it
" "under the terms of the GNU General Public License as published
" "by the Free Software Foundation, either version 3 of the License,
" "or (at your option) any later version.
" "
" "TSPSG is distributed in the hope that it will be useful, but
" "WITHOUT ANY WARRANTY; without even the implied warranty of
" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
" "GNU General Public License for more details.
" "
" "You should have received a copy of the GNU General Public License
" "along with TSPSG. If not, see http://www.gnu.org/licenses/."); QDialog *dlg = new QDialog(this); QLabel *lblIcon = new QLabel(dlg), *lblTitle = new QLabel(dlg), *lblTranslated = new QLabel(dlg); #ifdef HANDHELD QLabel *lblSubTitle = new QLabel(QString("© 2007-%1 %3").arg(QDate::currentDate().toString("yyyy"), QApplication::organizationDomain(), QApplication::organizationName()), dlg); #endif // HANDHELD QTextBrowser *txtAbout = new QTextBrowser(dlg); QVBoxLayout *vb = new QVBoxLayout(); QHBoxLayout *hb1 = new QHBoxLayout(), *hb2 = new QHBoxLayout(); QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok, Qt::Horizontal, dlg); lblTitle->setOpenExternalLinks(true); lblTitle->setText(title); lblTitle->setAlignment(Qt::AlignTop); lblTitle->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); #ifndef HANDHELD 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())); #endif // HANDHELD lblIcon->setPixmap(QPixmap(":/images/tspsg.png").scaledToHeight(lblTitle->sizeHint().height(), Qt::SmoothTransformation)); lblIcon->setAlignment(Qt::AlignVCenter); #ifndef HANDHELD 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())); #endif // HANDHELD hb1->addWidget(lblIcon); hb1->addWidget(lblTitle); txtAbout->setWordWrapMode(QTextOption::NoWrap); txtAbout->setOpenExternalLinks(true); 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 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); #ifdef Q_OS_WINCE_WM vb->setMargin(3); #endif // Q_OS_WINCE_WM vb->addLayout(hb1); #ifdef HANDHELD vb->addWidget(lblSubTitle); #endif // HANDHELD vb->addWidget(txtAbout); vb->addLayout(hb2); dlg->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint); dlg->setWindowTitle(tr("About %1").arg(QApplication::applicationName())); dlg->setWindowIcon(QIcon::fromTheme("help-about", QIcon(":/images/icons/help-about.png"))); dlg->setLayout(vb); connect(bb, SIGNAL(accepted()), dlg, SLOT(accept())); #ifdef Q_OS_WIN32 // Adding some eyecandy in Vista and 7 :-) if (QtWin::isCompositionEnabled()) { QtWin::enableBlurBehindWindow(dlg, true); } #endif // Q_OS_WIN32 dlg->resize(450, 350); dlg->exec(); delete dlg; } void MainWindow::buttonBackToTaskClicked() { tabWidget->setCurrentIndex(0); } void MainWindow::buttonRandomClicked() { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); tspmodel->randomize(); QApplication::restoreOverrideCursor(); } void MainWindow::buttonSolveClicked() { TMatrix matrix; QList row; int n = spinCities->value(); bool ok; for (int r = 0; r < n; r++) { row.clear(); for (int c = 0; c < n; c++) { row.append(tspmodel->index(r,c).data(Qt::UserRole).toDouble(&ok)); if (!ok) { QMessageBox::critical(this, tr("Data error"), tr("Error in cell [Row %1; Column %2]: Invalid data format.").arg(r + 1).arg(c + 1)); return; } } matrix.append(row); } QProgressDialog pd(this); QProgressBar *pb = new QProgressBar(&pd); pb->setAlignment(Qt::AlignCenter); pb->setFormat(tr("%v of %1 parts found").arg(n)); pd.setBar(pb); pd.setMaximum(n); pd.setAutoReset(false); pd.setLabelText(tr("Calculating optimal route...")); pd.setWindowTitle(tr("Solution Progress")); pd.setWindowModality(Qt::ApplicationModal); pd.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint); pd.show(); CTSPSolver solver; connect(&solver, SIGNAL(routePartFound(int)), &pd, SLOT(setValue(int))); connect(&pd, SIGNAL(canceled()), &solver, SLOT(cancel())); SStep *root = solver.solve(n, matrix); disconnect(&solver, SIGNAL(routePartFound(int)), &pd, SLOT(setValue(int))); disconnect(&pd, SIGNAL(canceled()), &solver, SLOT(cancel())); if (!root) { pd.reset(); if (!solver.wasCanceled()) QMessageBox::warning(this, tr("Solution Result"), tr("Unable to find a solution.\nMaybe, this task has no solution.")); return; } pb->setFormat(tr("Generating header")); pd.setLabelText(tr("Generating solution output...")); pd.setMaximum(solver.getTotalSteps() + 1); pd.setValue(0); solutionText->clear(); solutionText->setDocumentTitle(tr("Solution of Variant #%1 Task").arg(spinVariant->value())); QPainter pic; if (settings->value("Output/ShowGraph", DEF_SHOW_GRAPH).toBool()) { pic.begin(&graph); pic.setRenderHint(QPainter::Antialiasing); pic.setFont(settings->value("Output/Font", QFont(getDefaultFont(), 9)).value()); pic.setBrush(QBrush(QColor(Qt::white))); pic.setBackgroundMode(Qt::OpaqueMode); } QTextDocument *doc = solutionText->document(); QTextCursor cur(doc); cur.beginEditBlock(); cur.setBlockFormat(fmt_paragraph); cur.insertText(tr("Variant #%1 Task").arg(spinVariant->value()), fmt_default); cur.insertBlock(fmt_paragraph); cur.insertText(tr("Task:")); outputMatrix(cur, matrix); if (settings->value("Output/ShowGraph", DEF_SHOW_GRAPH).toBool()) { #ifdef _T_T_L_ _b_ _i_ _z_ _a_ _r_ _r_ _e_ #endif drawNode(pic, 0); } cur.insertHtml("
"); cur.insertBlock(fmt_paragraph); int imgpos = cur.position(); cur.insertText(tr("Variant #%1 Solution").arg(spinVariant->value()), fmt_default); cur.endEditBlock(); SStep *step = root; int c = n = 1; pb->setFormat(tr("Generating step %v")); while ((step->next != SStep::NoNextStep) && (c < spinCities->value())) { if (pd.wasCanceled()) { pd.setLabelText(tr("Cleaning up...")); pd.setMaximum(0); pd.setCancelButton(NULL); pd.show(); QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); solver.cleanup(true); solutionText->clear(); toggleSolutionActions(false); return; } pd.setValue(n); cur.beginEditBlock(); cur.insertBlock(fmt_paragraph); cur.insertText(tr("Step #%1").arg(n)); 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())))) { outputMatrix(cur, *step); } cur.insertBlock(fmt_paragraph); 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); if (!step->alts.empty()) { SStep::SCandidate cand; QString alts; foreach(cand, step->alts) { if (!alts.isEmpty()) alts += ", "; alts += tr("(%1;%2)").arg(cand.nRow + 1).arg(cand.nCol + 1); } cur.insertBlock(fmt_paragraph); cur.insertText(tr("%n alternate candidate(s) for branching: %1.", "", step->alts.count()).arg(alts), fmt_altlist); } cur.insertBlock(fmt_paragraph); cur.insertText(" ", fmt_default); cur.endEditBlock(); if (settings->value("Output/ShowGraph", DEF_SHOW_GRAPH).toBool()) { if (step->prNode != NULL) drawNode(pic, n, false, step->prNode); if (step->plNode != NULL) drawNode(pic, n, true, step->plNode); } n++; if (step->next == SStep::RightBranch) { c++; step = step->prNode; } else if (step->next == SStep::LeftBranch) { step = step->plNode; } else break; } pb->setFormat(tr("Generating footer")); pd.setValue(n); cur.beginEditBlock(); cur.insertBlock(fmt_paragraph); if (solver.isOptimal()) cur.insertText(tr("Optimal path:")); else cur.insertText(tr("Resulting path:")); cur.insertBlock(fmt_paragraph); cur.insertText(" " + solver.getSortedPath(tr("City %1"))); cur.insertBlock(fmt_paragraph); if (isInteger(step->price)) cur.insertHtml("

" + tr("The price is %n unit(s).", "", qRound(step->price)) + "

"); else cur.insertHtml("

" + tr("The price is %1 units.").arg(step->price, 0, 'f', settings->value("Task/FractionalAccuracy", DEF_FRACTIONAL_ACCURACY).toInt()) + "

"); if (!solver.isOptimal()) { cur.insertBlock(fmt_paragraph); cur.insertText(" "); cur.insertBlock(fmt_paragraph); cur.insertHtml("

" + tr("WARNING!!!
This result is a record, but it may not be optimal.
Iterations need to be continued to check whether this result is optimal or get an optimal one.") + "

"); } cur.endEditBlock(); if (settings->value("Output/ShowGraph", DEF_SHOW_GRAPH).toBool()) { pic.end(); QImage i(graph.width() + 2, graph.height() + 2, QImage::Format_ARGB32); i.fill(0); pic.begin(&i); pic.drawPicture(1, 1, graph); pic.end(); doc->addResource(QTextDocument::ImageResource, QUrl("tspsg://graph.pic"), i); QTextImageFormat img; img.setName("tspsg://graph.pic"); cur.setPosition(imgpos); cur.insertImage(img, QTextFrameFormat::FloatRight); } if (settings->value("Output/ScrollToEnd", DEF_SCROLL_TO_END).toBool()) { // Scrolling to the end of the text. solutionText->moveCursor(QTextCursor::End); } else solutionText->moveCursor(QTextCursor::Start); pd.setLabelText(tr("Cleaning up...")); pd.setMaximum(0); pd.setCancelButton(NULL); QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); solver.cleanup(true); toggleSolutionActions(); tabWidget->setCurrentIndex(1); } void MainWindow::dataChanged() { setWindowModified(true); } void MainWindow::dataChanged(const QModelIndex &tl, const QModelIndex &br) { setWindowModified(true); if (settings->value("Autosize", DEF_AUTOSIZE).toBool()) { for (int k = tl.row(); k <= br.row(); k++) taskView->resizeRowToContents(k); for (int k = tl.column(); k <= br.column(); k++) taskView->resizeColumnToContents(k); } } #ifdef Q_OS_WINCE_WM void MainWindow::changeEvent(QEvent *ev) { if ((ev->type() == QEvent::ActivationChange) && isActiveWindow()) desktopResized(0); QWidget::changeEvent(ev); } void MainWindow::desktopResized(int screen) { if ((screen != 0) || !isActiveWindow()) return; QRect availableGeometry = QApplication::desktop()->availableGeometry(0); if (currentGeometry != availableGeometry) { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); /*! * \hack HACK: This hack checks whether \link QDesktopWidget::availableGeometry() availableGeometry()\endlink's \c top + \c hegiht = \link QDesktopWidget::screenGeometry() screenGeometry()\endlink's \c height. * If \c true, the window gets maximized. If we used \c setGeometry() in this case, the bottom of the * window would end up being behind the soft buttons. Is this a bug in Qt or Windows Mobile? */ if ((availableGeometry.top() + availableGeometry.height()) == QApplication::desktop()->screenGeometry().height()) { setWindowState(windowState() | Qt::WindowMaximized); } else { if (windowState() & Qt::WindowMaximized) setWindowState(windowState() ^ Qt::WindowMaximized); setGeometry(availableGeometry); } currentGeometry = availableGeometry; QApplication::restoreOverrideCursor(); } } #endif // Q_OS_WINCE_WM void MainWindow::numCitiesChanged(int nCities) { blockSignals(true); spinCities->setValue(nCities); blockSignals(false); } #ifndef QT_NO_PRINTER void MainWindow::printPreview(QPrinter *printer) { solutionText->print(printer); } #endif // QT_NO_PRINTER void MainWindow::spinCitiesValueChanged(int n) { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); int count = tspmodel->numCities(); tspmodel->setNumCities(n); if ((n > count) && settings->value("Autosize", DEF_AUTOSIZE).toBool()) for (int k = count; k < n; k++) { taskView->resizeColumnToContents(k); taskView->resizeRowToContents(k); } QApplication::restoreOverrideCursor(); } void MainWindow::closeEvent(QCloseEvent *ev) { if (!maybeSave()) { ev->ignore(); return; } if (!settings->value("SettingsReset", false).toBool()) { settings->setValue("NumCities", spinCities->value()); // Saving Main Window state #ifndef HANDHELD if (settings->value("SavePos", DEF_SAVEPOS).toBool()) { settings->beginGroup("MainWindow"); settings->setValue("Geometry", saveGeometry()); settings->setValue("State", saveState()); settings->setValue("Toolbars", toolBarManager->saveState()); settings->endGroup(); } #endif // HANDHELD } else { settings->remove("SettingsReset"); } QMainWindow::closeEvent(ev); } void MainWindow::dragEnterEvent(QDragEnterEvent *ev) { if (ev->mimeData()->hasUrls() && (ev->mimeData()->urls().count() == 1)) { QFileInfo fi(ev->mimeData()->urls().first().toLocalFile()); if ((fi.suffix() == "tspt") || (fi.suffix() == "zkt")) ev->acceptProposedAction(); } } void MainWindow::drawNode(QPainter &pic, int nstep, bool left, SStep *step) { const int r = 35; qreal x, y; if (step != NULL) x = left ? r : r * 3.5; else x = r * 2.25; y = r * (3 * nstep + 1); #ifdef _T_T_L_ if (nstep == -481124) { _t_t_l_(pic, r, x); return; } #endif pic.drawEllipse(QPointF(x, y), r, r); if (step != NULL) { QFont font; if (left) { font = pic.font(); font.setStrikeOut(true); pic.setFont(font); } 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"); if (left) { font.setStrikeOut(false); pic.setFont(font); } if (step->price != INFINITY) { 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())); } else { pic.drawText(QRectF(x - r, y - r, r * 2, r * 2), Qt::AlignCenter, "\n"INFSTR); } } else { pic.drawText(QRectF(x - r, y - r, r * 2, r * 2), Qt::AlignCenter, tr("Root")); } if (nstep == 1) { pic.drawLine(QPointF(x, y - r), QPointF(r * 2.25, y - 2 * r)); } else if (nstep > 1) { pic.drawLine(QPointF(x, y - r), QPointF((step->pNode->pNode->next == SStep::RightBranch) ? r * 3.5 : r, y - 2 * r)); } } void MainWindow::dropEvent(QDropEvent *ev) { if (maybeSave() && tspmodel->loadTask(ev->mimeData()->urls().first().toLocalFile())) { setFileName(ev->mimeData()->urls().first().toLocalFile()); tabWidget->setCurrentIndex(0); setWindowModified(false); solutionText->clear(); toggleSolutionActions(false); ev->setDropAction(Qt::CopyAction); ev->accept(); } } bool MainWindow::hasUpdater() const { #ifdef Q_OS_WIN32 return QFile::exists("updater/Update.exe"); #else // Q_OS_WIN32 return false; #endif // Q_OS_WIN32 } void MainWindow::initDocStyleSheet() { solutionText->document()->setDefaultFont(settings->value("Output/Font", QFont(getDefaultFont(), DEF_FONT_SIZE)).value()); fmt_paragraph.setTopMargin(0); fmt_paragraph.setRightMargin(10); fmt_paragraph.setBottomMargin(0); fmt_paragraph.setLeftMargin(10); fmt_table.setTopMargin(5); fmt_table.setRightMargin(10); fmt_table.setBottomMargin(5); fmt_table.setLeftMargin(10); fmt_table.setBorder(0); fmt_table.setBorderStyle(QTextFrameFormat::BorderStyle_None); fmt_table.setCellSpacing(5); fmt_cell.setAlignment(Qt::AlignHCenter); settings->beginGroup("Output/Colors"); QColor color = settings->value("Text", DEF_TEXT_COLOR).value(); QColor hilight; if (color.value() < 192) hilight.setHsv(color.hue(), color.saturation(), 127 + qRound(color.value() / 2)); else hilight.setHsv(color.hue(), color.saturation(), color.value() / 2); solutionText->document()->setDefaultStyleSheet(QString("* {color: %1;}").arg(color.name())); fmt_default.setForeground(QBrush(color)); fmt_selected.setForeground(QBrush(settings->value("Selected", DEF_SELECTED_COLOR).value())); fmt_selected.setFontWeight(QFont::Bold); fmt_alternate.setForeground(QBrush(settings->value("Alternate", DEF_ALTERNATE_COLOR).value())); fmt_alternate.setFontWeight(QFont::Bold); fmt_altlist.setForeground(QBrush(hilight)); settings->endGroup(); solutionText->setTextColor(color); } void MainWindow::loadLangList() { QMap langlist; QFileInfoList langs; QFileInfo lang; QString name; QStringList language, dirs; QTranslator t; QDir dir; dir.setFilter(QDir::Files); dir.setNameFilters(QStringList("tspsg_*.qm")); dir.setSorting(QDir::NoSort); dirs << PATH_L10N << ":/l10n"; foreach (QString dirname, dirs) { dir.setPath(dirname); if (dir.exists()) { langs = dir.entryInfoList(); for (int k = 0; k < langs.size(); k++) { lang = langs.at(k); if (lang.completeBaseName().compare("tspsg_en", Qt::CaseInsensitive) && !langlist.contains(lang.completeBaseName().mid(6)) && t.load(lang.completeBaseName(), dirname)) { language.clear(); language.append(lang.completeBaseName().mid(6)); language.append(t.translate("--------", "COUNTRY", "Please, provide an ISO 3166-1 alpha-2 country code for this translation language here (eg., UA).").toLower()); language.append(t.translate("--------", "LANGNAME", "Please, provide a native name of your translation language here.")); language.append(t.translate("MainWindow", "Set application language to %1", "").arg(name)); langlist.insert(language.at(0), language); } } } } QAction *a; foreach (language, langlist) { a = menuSettingsLanguage->addAction(language.at(2)); a->setStatusTip(language.at(3)); a->setIcon(QIcon::fromTheme(QString("flag-%1").arg(language.at(1))/*, QIcon(QString(":/images/icons/l10n/%1.png").arg(language.at(1)))*/)); a->setData(language.at(0)); a->setCheckable(true); a->setActionGroup(groupSettingsLanguageList); if (settings->value("Language", QLocale::system().name()).toString().startsWith(language.at(0))) a->setChecked(true); } } bool MainWindow::loadLanguage(const QString &lang) { // i18n bool ad = false; QString lng = lang; if (lng.isEmpty()) { ad = settings->value("Language", "").toString().isEmpty(); lng = settings->value("Language", QLocale::system().name()).toString(); } static QTranslator *qtTranslator; // Qt library translator if (qtTranslator) { qApp->removeTranslator(qtTranslator); delete qtTranslator; qtTranslator = NULL; } static QTranslator *translator; // Application translator if (translator) { qApp->removeTranslator(translator); delete translator; translator = NULL; } if (lng == "en") return true; // Trying to load system Qt library translation... qtTranslator = new QTranslator(this); if (qtTranslator->load("qt_" + lng, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) qApp->installTranslator(qtTranslator); else { // No luck. Let's try to load a bundled one. if (qtTranslator->load("qt_" + lng, PATH_L10N)) { // We have a translation in the localization direcotry. qApp->installTranslator(qtTranslator); } else if (qtTranslator->load("qt_" + lng, ":/l10n")) { // We have a translation "built-in" into application resources. qApp->installTranslator(qtTranslator); } else { // Qt library translation unavailable for this language. delete qtTranslator; qtTranslator = NULL; } } // Now let's load application translation. translator = new QTranslator(this); if (translator->load("tspsg_" + lng, PATH_L10N)) { // We have a translation in the localization directory. qApp->installTranslator(translator); } else if (translator->load("tspsg_" + lng, ":/l10n")) { // We have a translation "built-in" into application resources. qApp->installTranslator(translator); } else { delete translator; translator = NULL; if (!ad) { settings->remove("Language"); QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); QMessageBox::warning(isVisible() ? this : NULL, tr("Language Change"), tr("Unable to load the translation language.\nFalling back to autodetection.")); QApplication::restoreOverrideCursor(); } return false; } return true; } void MainWindow::loadStyleList() { menuSettingsStyle->clear(); QStringList styles = QStyleFactory::keys(); menuSettingsStyle->insertAction(NULL, actionSettingsStyleSystem); actionSettingsStyleSystem->setChecked(!settings->contains("Style")); menuSettingsStyle->addSeparator(); QAction *a; foreach (QString style, styles) { a = menuSettingsStyle->addAction(style); a->setData(false); a->setStatusTip(tr("Set application style to %1").arg(style)); a->setCheckable(true); a->setActionGroup(groupSettingsStyleList); if ((style == settings->value("Style").toString()) || QString(QApplication::style()->metaObject()->className()).contains(QRegExp(QString("^Q?%1(Style)?$").arg(QRegExp::escape(style)), Qt::CaseInsensitive))) { a->setChecked(true); } } } void MainWindow::loadToolbarList() { menuSettingsToolbars->clear(); #ifndef HANDHELD menuSettingsToolbars->insertAction(NULL, actionSettingsToolbarsConfigure); menuSettingsToolbars->addSeparator(); QList list = toolBarManager->toolBars(); foreach (QToolBar *t, list) { menuSettingsToolbars->insertAction(NULL, t->toggleViewAction()); } #else // HANDHELD menuSettingsToolbars->insertAction(NULL, toolBarMain->toggleViewAction()); #endif // HANDHELD } bool MainWindow::maybeSave() { if (!isWindowModified()) return true; int res = QMessageBox::warning(this, tr("Unsaved Changes"), tr("Would you like to save changes in the current task?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); if (res == QMessageBox::Save) return actionFileSaveTriggered(); else if (res == QMessageBox::Cancel) return false; else return true; } void MainWindow::outputMatrix(QTextCursor &cur, const TMatrix &matrix) { int n = spinCities->value(); QTextTable *table = cur.insertTable(n, n, fmt_table); for (int r = 0; r < n; r++) { for (int c = 0; c < n; c++) { cur = table->cellAt(r, c).firstCursorPosition(); cur.setBlockFormat(fmt_cell); cur.setBlockCharFormat(fmt_default); if (matrix.at(r).at(c) == INFINITY) cur.insertText(INFSTR); else 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())); } QApplication::processEvents(); } cur.movePosition(QTextCursor::End); } void MainWindow::outputMatrix(QTextCursor &cur, const SStep &step) { int n = spinCities->value(); QTextTable *table = cur.insertTable(n, n, fmt_table); for (int r = 0; r < n; r++) { for (int c = 0; c < n; c++) { cur = table->cellAt(r, c).firstCursorPosition(); cur.setBlockFormat(fmt_cell); if (step.matrix.at(r).at(c) == INFINITY) cur.insertText(INFSTR, fmt_default); else if ((r == step.candidate.nRow) && (c == step.candidate.nCol)) 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); else { SStep::SCandidate cand; cand.nRow = r; cand.nCol = c; if (step.alts.contains(cand)) 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); else 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); } } QApplication::processEvents(); } cur.movePosition(QTextCursor::End); } void MainWindow::retranslateUi(bool all) { if (all) Ui::MainWindow::retranslateUi(this); loadStyleList(); loadToolbarList(); #ifndef QT_NO_PRINTER actionFilePrintPreview->setText(tr("P&rint Preview...")); #ifndef QT_NO_TOOLTIP actionFilePrintPreview->setToolTip(tr("Preview solution results")); #endif // QT_NO_TOOLTIP #ifndef QT_NO_STATUSTIP actionFilePrintPreview->setStatusTip(tr("Preview current solution results before printing")); #endif // QT_NO_STATUSTIP actionFilePrint->setText(tr("&Print...")); #ifndef QT_NO_TOOLTIP actionFilePrint->setToolTip(tr("Print solution")); #endif // QT_NO_TOOLTIP #ifndef QT_NO_STATUSTIP actionFilePrint->setStatusTip(tr("Print current solution results")); #endif // QT_NO_STATUSTIP actionFilePrint->setShortcut(tr("Ctrl+P")); #endif // QT_NO_PRINTER #ifndef HANDHELD actionSettingsToolbarsConfigure->setText(tr("Configure...")); #ifndef QT_NO_STATUSTIP actionSettingsToolbarsConfigure->setStatusTip(tr("Customize toolbars")); #endif // QT_NO_STATUSTIP #endif // HANDHELD #ifdef Q_OS_WIN32 actionHelpCheck4Updates->setText(tr("Check for &Updates...")); #ifndef QT_NO_STATUSTIP actionHelpCheck4Updates->setStatusTip(tr("Check for %1 updates").arg(QApplication::applicationName())); #endif // QT_NO_STATUSTIP #endif // Q_OS_WIN32 } bool MainWindow::saveTask() { QStringList filters(tr("%1 Task File").arg("TSPSG") + " (*.tspt)"); filters.append(tr("All Files") + " (*)"); QString file; if (fileName.endsWith(".tspt", Qt::CaseInsensitive)) file = fileName; else file = QFileInfo(fileName).canonicalPath() + "/" + QFileInfo(fileName).completeBaseName() + ".tspt"; QFileDialog::Options opts = settings->value("UseNativeDialogs", DEF_USE_NATIVE_DIALOGS).toBool() ? QFileDialog::Options() : QFileDialog::DontUseNativeDialog; file = QFileDialog::getSaveFileName(this, tr("Task Save"), file, filters.join(";;"), NULL, opts); if (file.isEmpty()) return false; if (tspmodel->saveTask(file)) { setFileName(file); setWindowModified(false); return true; } return false; } void MainWindow::setFileName(const QString &fileName) { this->fileName = fileName; setWindowTitle(QString("%1[*] - %2").arg(QFileInfo(fileName).completeBaseName()).arg(QApplication::applicationName())); } void MainWindow::setupUi() { Ui::MainWindow::setupUi(this); // File Menu actionFileNew->setIcon(QIcon::fromTheme("document-new", QIcon(":/images/icons/document-new.png"))); actionFileOpen->setIcon(QIcon::fromTheme("document-open", QIcon(":/images/icons/document-open.png"))); actionFileSave->setIcon(QIcon::fromTheme("document-save", QIcon(":/images/icons/document-save.png"))); menuFileSaveAs->setIcon(QIcon::fromTheme("document-save-as", QIcon(":/images/icons/document-save-as.png"))); actionFileExit->setIcon(QIcon::fromTheme("application-exit", QIcon(":/images/icons/application-exit.png"))); // Settings Menu menuSettingsLanguage->setIcon(QIcon::fromTheme("preferences-desktop-locale", QIcon(":/images/icons/preferences-desktop-locale.png"))); actionSettingsLanguageEnglish->setIcon(QIcon::fromTheme("flag-gb"/*, QIcon(":/images/icons/l10n/gb.png")*/)); menuSettingsStyle->setIcon(QIcon::fromTheme("preferences-desktop-theme", QIcon(":/images/icons/preferences-desktop-theme.png"))); actionSettingsPreferences->setIcon(QIcon::fromTheme("preferences-system", QIcon(":/images/icons/preferences-system.png"))); // Help Menu actionHelpContents->setIcon(QIcon::fromTheme("help-contents", QIcon(":/images/icons/help-contents.png"))); actionHelpContextual->setIcon(QIcon::fromTheme("help-contextual", QIcon(":/images/icons/help-contextual.png"))); actionHelpAbout->setIcon(QIcon::fromTheme("help-about", QIcon(":/images/icons/help-about.png"))); // Buttons buttonRandom->setIcon(QIcon::fromTheme("roll", QIcon(":/images/icons/roll.png"))); buttonSolve->setIcon(QIcon::fromTheme("dialog-ok", QIcon(":/images/icons/dialog-ok.png"))); buttonSaveSolution->setIcon(QIcon::fromTheme("document-save-as", QIcon(":/images/icons/document-save-as.png"))); buttonBackToTask->setIcon(QIcon::fromTheme("go-previous", QIcon(":/images/icons/go-previous.png"))); // action->setIcon(QIcon::fromTheme("", QIcon(":/images/icons/.png"))); #if QT_VERSION >= 0x040600 setToolButtonStyle(Qt::ToolButtonFollowStyle); #endif #ifndef HANDHELD QStatusBar *statusbar = new QStatusBar(this); statusbar->setObjectName("statusbar"); setStatusBar(statusbar); #endif // HANDHELD #ifdef Q_OS_WINCE_WM menuBar()->setDefaultAction(menuFile->menuAction()); QScrollArea *scrollArea = new QScrollArea(this); scrollArea->setFrameShape(QFrame::NoFrame); scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); scrollArea->setWidgetResizable(true); scrollArea->setWidget(tabWidget); setCentralWidget(scrollArea); #else setCentralWidget(tabWidget); #endif // Q_OS_WINCE_WM //! \hack HACK: A little hack for toolbar icons to have a sane size. #ifdef HANDHELD toolBarMain->setIconSize(QSize(logicalDpiX() / 4, logicalDpiY() / 4)); #endif // HANDHELD QToolButton *tb = static_cast(toolBarMain->widgetForAction(actionFileSave)); if (tb != NULL) { tb->setMenu(menuFileSaveAs); tb->setPopupMode(QToolButton::MenuButtonPopup); } // solutionText->document()->setDefaultFont(settings->value("Output/Font", QFont(DEF_FONT_FAMILY, DEF_FONT_SIZE)).value()); solutionText->setWordWrapMode(QTextOption::WordWrap); #ifndef QT_NO_PRINTER actionFilePrintPreview = new QAction(this); actionFilePrintPreview->setObjectName("actionFilePrintPreview"); actionFilePrintPreview->setEnabled(false); actionFilePrintPreview->setIcon(QIcon::fromTheme("document-print-preview", QIcon(":/images/icons/document-print-preview.png"))); actionFilePrint = new QAction(this); actionFilePrint->setObjectName("actionFilePrint"); actionFilePrint->setEnabled(false); actionFilePrint->setIcon(QIcon::fromTheme("document-print", QIcon(":/images/icons/document-print.png"))); menuFile->insertAction(actionFileExit,actionFilePrintPreview); menuFile->insertAction(actionFileExit,actionFilePrint); menuFile->insertSeparator(actionFileExit); toolBarMain->insertAction(actionSettingsPreferences, actionFilePrint); #endif // QT_NO_PRINTER groupSettingsLanguageList = new QActionGroup(this); actionSettingsLanguageEnglish->setData("en"); actionSettingsLanguageEnglish->setActionGroup(groupSettingsLanguageList); loadLangList(); actionSettingsLanguageAutodetect->setChecked(settings->value("Language", "").toString().isEmpty()); actionSettingsStyleSystem->setData(true); groupSettingsStyleList = new QActionGroup(this); #ifndef HANDHELD actionSettingsToolbarsConfigure = new QAction(this); actionSettingsToolbarsConfigure->setIcon(QIcon::fromTheme("configure-toolbars", QIcon(":/images/icons/configure-toolbars.png"))); #endif // HANDHELD #ifdef Q_OS_WIN32 actionHelpCheck4Updates = new QAction(this); actionHelpCheck4Updates->setIcon(QIcon::fromTheme("system-software-update", QIcon(":/images/icons/system-software-update.png"))); actionHelpCheck4Updates->setEnabled(hasUpdater()); menuHelp->insertAction(actionHelpAboutQt, actionHelpCheck4Updates); menuHelp->insertSeparator(actionHelpAboutQt); #endif // Q_OS_WIN32 spinCities->setMaximum(MAX_NUM_CITIES); #ifndef HANDHELD toolBarManager = new QtToolBarManager; toolBarManager->setMainWindow(this); QString cat = toolBarMain->windowTitle(); toolBarManager->addToolBar(toolBarMain, cat); #ifndef QT_NO_PRINTER toolBarManager->addAction(actionFilePrintPreview, cat); #endif // QT_NO_PRINTER toolBarManager->addAction(actionHelpContents, cat); toolBarManager->addAction(actionHelpContextual, cat); // toolBarManager->addAction(action, cat); toolBarManager->restoreState(settings->value("MainWindow/Toolbars").toByteArray()); #endif // HANDHELD retranslateUi(false); #ifdef Q_OS_WIN32 // Adding some eyecandy in Vista and 7 :-) if (QtWin::isCompositionEnabled() && settings->value("UseTranslucency", DEF_USE_TRANSLUCENCY).toBool()) { toggleTranclucency(true); } #endif // Q_OS_WIN32 } void MainWindow::toggleSolutionActions(bool enable) { buttonSaveSolution->setEnabled(enable); actionFileSaveAsSolution->setEnabled(enable); solutionText->setEnabled(enable); #ifndef QT_NO_PRINTER actionFilePrint->setEnabled(enable); actionFilePrintPreview->setEnabled(enable); #endif // QT_NO_PRINTER } void MainWindow::toggleTranclucency(bool enable) { #ifdef Q_OS_WIN32 toggleStyle(labelVariant, enable); toggleStyle(labelCities, enable); toggleStyle(statusBar(), enable); tabWidget->setDocumentMode(enable); QtWin::enableBlurBehindWindow(this, enable); #else Q_UNUSED(enable); #endif // Q_OS_WIN32 }