source: tspsg-svn/trunk/src/mainwindow.cpp @ 37

Last change on this file since 37 was 37, checked in by laleppa, 15 years ago

+ Task save prompt before creating or opening task and closing application if current task was modified.

  • Translation updates.
  • Property svn:keywords set to Id URL
File size: 13.3 KB
RevLine 
[1]1/*
[6]2 *  TSPSG - TSP Solver and Generator
[17]3 *  Copyright (C) 2007-2009 Lёppa <contacts[at]oleksii[dot]name>
[1]4 *
[6]5 *  $Id: mainwindow.cpp 37 2009-07-16 16:00:27Z laleppa $
6 *  $URL: https://tspsg.svn.sourceforge.net/svnroot/tspsg/trunk/src/mainwindow.cpp $
[4]7 *
[6]8 *  This file is part of TSPSG.
[1]9 *
[6]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.
[1]14 *
[6]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.
[1]19 *
[6]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/>.
[1]22 */
23
24#include "mainwindow.h"
25
26MainWindow::MainWindow(QWidget *parent)
[21]27        : QMainWindow(parent)
[1]28{
[29]29        settings = new QSettings(QSettings::IniFormat,QSettings::UserScope,"TSPSG","tspsg");
30        loadLanguage();
[1]31        setupUi(this);
[29]32#ifndef Q_OS_WINCE
33        printer = new QPrinter();
34#endif // Q_OS_WINCE
35        groupSettingsLanguageList = new QActionGroup(this);
[30]36        actionSettingsLanguageEnglish->setData("en");
37        actionSettingsLanguageEnglish->setActionGroup(groupSettingsLanguageList);
[29]38        loadLangList();
[23]39        spinCities->setValue(settings->value("NumCities",5).toInt());
[29]40        actionSettingsLanguageAutodetect->setChecked(settings->value("Language","").toString().isEmpty());
41        connect(actionFileNew,SIGNAL(triggered()),this,SLOT(actionFileNewTriggered()));
[31]42        connect(actionFileOpen,SIGNAL(triggered()),this,SLOT(actionFileOpenTriggered()));
43        connect(actionFileSaveTask,SIGNAL(triggered()),this,SLOT(actionFileSaveTaskTriggered()));
[29]44        connect(actionSettingsPreferences,SIGNAL(triggered()),this,SLOT(actionSettingsPreferencesTriggered()));
45        connect(actionSettingsLanguageAutodetect,SIGNAL(triggered(bool)),this,SLOT(actionSettingsLanguageAutodetectTriggered(bool)));
46        connect(groupSettingsLanguageList,SIGNAL(triggered(QAction *)),this,SLOT(groupSettingsLanguageListTriggered(QAction *)));
[37]47        connect(actionHelpAboutQt,SIGNAL(triggered()),qApp,SLOT(aboutQt()));
[29]48        connect(actionHelpAbout,SIGNAL(triggered()),this,SLOT(actionHelpAboutTriggered()));
[17]49#ifndef Q_OS_WINCE
[29]50        connect(actionFilePrintSetup,SIGNAL(triggered()),this,SLOT(actionFilePrintSetupTriggered()));
[17]51#endif // Q_OS_WINCE
[29]52        connect(buttonSolve,SIGNAL(clicked()),this,SLOT(buttonSolveClicked()));
53        connect(buttonRandom,SIGNAL(clicked()),this,SLOT(buttonRandomClicked()));
54        connect(spinCities,SIGNAL(valueChanged(int)),this,SLOT(spinCitiesValueChanged(int)));
[17]55QRect rect = geometry();
56#ifdef Q_OS_WINCE
57        // HACK: Fix for all tabWidget elements becoming "unclickable" if making it central widget.
58        rect.setSize(QApplication::desktop()->availableGeometry().size());
59        rect.setHeight(rect.height() - (QApplication::desktop()->screenGeometry().height() - QApplication::desktop()->availableGeometry().height()));
60        tabWidget->resize(rect.width(),rect.height() - toolBar->size().height());
61#else
[23]62        if (settings->value("SavePos",false).toBool()) {
[21]63                // Loading of saved window state
[23]64                settings->beginGroup("MainWindow");
65                resize(settings->value("Size",size()).toSize());
66                move(settings->value("Position",pos()).toPoint());
67                if (settings->value("Maximized",false).toBool())
[21]68                        setWindowState(windowState() | Qt::WindowMaximized);
[23]69                settings->endGroup();
[21]70        } else {
71                // Centering main window
72                rect.moveCenter(QApplication::desktop()->availableGeometry(this).center());
73                setGeometry(rect);
74        }
[17]75#endif // Q_OS_WINCE
[11]76        qsrand(QDateTime().currentDateTime().toTime_t());
[15]77        tspmodel = new CTSPModel();
78        tspmodel->setNumCities(spinCities->value());
79        taskView->setModel(tspmodel);
[31]80        connect(tspmodel,SIGNAL(numCitiesChanged(int)),this,SLOT(numCitiesChanged(int)));
[37]81        connect(tspmodel,SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),this,SLOT(dataChanged()));
82        connect(tspmodel,SIGNAL(layoutChanged()),this,SLOT(dataChanged()));
[21]83#ifdef Q_OS_WINCE
84        taskView->resizeColumnsToContents();
85        taskView->resizeRowsToContents();
86#endif // Q_OS_WINCE
[6]87}
88
[30]89bool MainWindow::loadLanguage(QString lang)
[4]90{
[29]91// i18n
[30]92bool ad = false;
93        if (lang.isEmpty()) {
94                ad = settings->value("Language","").toString().isEmpty();
95                lang = settings->value("Language",QLocale::system().name()).toString();
96        }
[29]97static QTranslator *qtTranslator;
98        if (qtTranslator) {
99                qApp->removeTranslator(qtTranslator);
100                delete qtTranslator;
101                qtTranslator = NULL;
102        }
103        qtTranslator = new QTranslator();
[30]104static QTranslator *translator;
105        if (translator) {
106                qApp->removeTranslator(translator);
107                delete translator;
108        }
109        translator = new QTranslator();
[29]110        if (lang.compare("en") && !lang.startsWith("en_")) {
111                // Trying to load system Qt library translation...
112                if (qtTranslator->load("qt_" + lang,QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
113                        qApp->installTranslator(qtTranslator);
114                else
115                        // No luck. Let's try to load bundled one.
116                        if (qtTranslator->load("qt_" + lang,"i18n"))
117                                qApp->installTranslator(qtTranslator);
118                        else {
119                                delete qtTranslator;
120                                qtTranslator = NULL;
121                        }
[30]122                // Now let's load application translation.
[29]123                if (translator->load(lang,"i18n"))
124                        qApp->installTranslator(translator);
125                else {
126                        if (!ad)
127                                QMessageBox(QMessageBox::Warning,trUtf8("Language change"),trUtf8("Unable to load translation language."),QMessageBox::Ok,this).exec();
128                        delete translator;
129                        translator = NULL;
130                        return false;
131                }
132        }
133        return true;
134}
135
136void MainWindow::spinCitiesValueChanged(int n)
137{
[21]138#ifdef Q_OS_WINCE
139int count = tspmodel->numCities();
140#endif // Q_OS_WINCE
[15]141        tspmodel->setNumCities(n);
[21]142#ifdef Q_OS_WINCE
143        if (n > count)
144                for (int k = count; k < n; k++) {
145                        taskView->resizeColumnToContents(k);
146                        taskView->resizeRowToContents(k);
147                }
148#endif // Q_OS_WINCE
[1]149}
150
[29]151
152void MainWindow::actionFileNewTriggered()
[1]153{
[37]154        if (isWindowModified()) {
155int res = QMessageBox(QMessageBox::Warning,trUtf8("New Task"),trUtf8("Would you like to save changes in current task?"),QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,this).exec();
156                if ((res == QMessageBox::Cancel) || ((res == QMessageBox::Yes) && !saveTask()))
157                        return;
158        }
[29]159        tspmodel->clear();
[37]160        setWindowModified(false);
[29]161}
162
[31]163void MainWindow::actionFileOpenTriggered()
164{
[37]165        if (isWindowModified()) {
166int res = QMessageBox(QMessageBox::Warning,trUtf8("Task Open"),trUtf8("Would you like to save changes in current task?"),QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,this).exec();
167                if ((res == QMessageBox::Cancel) || ((res == QMessageBox::Yes) && !saveTask()))
168                        return;
169        }
[31]170QFileDialog od(this);
171        od.setAcceptMode(QFileDialog::AcceptOpen);
172        od.setFileMode(QFileDialog::ExistingFile);
173QStringList filters(trUtf8("All Supported Formats") + " (*.tspt *.zkt)");
174        filters.append(QString(trUtf8("%1 Task Files")).arg("TSPSG") + " (*.tspt)");
175        filters.append(QString(trUtf8("%1 Task Files")).arg("ZKomModRd") + " (*.zkt)");
176        filters.append(trUtf8("All Files") + " (*)");
177        od.setNameFilters(filters);
178        if (od.exec() != QDialog::Accepted)
179                return;
180QStringList files = od.selectedFiles();
181        if (files.size() < 1)
182                return;
183        tspmodel->loadTask(files.first());
[37]184        setWindowModified(false);
[31]185}
186
187void MainWindow::actionFileSaveTaskTriggered()
188{
[37]189        saveTask();
190}
191
192bool MainWindow::saveTask() {
[31]193QFileDialog sd(this);
194        sd.setAcceptMode(QFileDialog::AcceptSave);
195QStringList filters(QString(trUtf8("%1 Task File")).arg("TSPSG") + " (*.tspt)");
196        filters.append(trUtf8("All Files") + " (*)");
197        sd.setNameFilters(filters);
198        sd.setDefaultSuffix("tspt");
199        if (sd.exec() != QDialog::Accepted)
[37]200                return false;
[31]201QStringList files = sd.selectedFiles();
202        if (files.size() < 1)
[37]203                return false;
204        if (tspmodel->saveTask(files.first())) {
205                setWindowModified(false);
206                return true;
207        } else
208                return false;
[31]209}
210
[29]211void MainWindow::actionSettingsPreferencesTriggered()
212{
[1]213SettingsDialog sd(this);
[21]214        sd.exec();
[1]215}
[6]216
[17]217#ifndef Q_OS_WINCE
[29]218void MainWindow::actionFilePrintSetupTriggered()
[17]219{
[29]220QPrintDialog pd(printer,this);
[33]221#if QT_VERSION >= 0x040500
222        // No such methods in Qt < 4.5
[29]223        pd.setOption(QAbstractPrintDialog::PrintSelection,false);
224        pd.setOption(QAbstractPrintDialog::PrintPageRange,false);
[33]225#endif
[17]226        pd.exec();
227}
228#endif // Q_OS_WINCE
229
[29]230void MainWindow::buttonRandomClicked()
[6]231{
[15]232        tspmodel->randomize();
[37]233        setWindowModified(true);
[21]234#ifdef Q_OS_WINCE
235        taskView->resizeColumnsToContents();
236        taskView->resizeRowsToContents();
237#endif // Q_OS_WINCE
[6]238}
239
[29]240void MainWindow::buttonSolveClicked()
[6]241{
[13]242        // TODO: Task solving goes here :-)
243tMatrix matrix;
244double *row;
[15]245int n = spinCities->value();
[13]246bool ok;
[15]247        for (int r = 0; r < n; r++) {
248                row = new double[n];
249                for (int c = 0; c < n; c++) {
250                        row[c] = tspmodel->index(r,c).data(Qt::UserRole).toDouble(&ok);
251                        if (!ok) {
[27]252                                QMessageBox(QMessageBox::Critical,trUtf8("Data error"),QString(trUtf8("Error in cell [Row %1; Column %2]: Invalid data format.")).arg(r + 1).arg(c + 1),QMessageBox::Ok,this).exec();
[15]253                                return;
[13]254                        }
255                }
256                matrix.append(row);
257        }
258CTSPSolver solver;
259sStep *root = solver.solve(spinCities->value(),matrix);
260        if (!root)
[27]261                QMessageBox(QMessageBox::Critical,trUtf8("Solution error"),trUtf8("There was an error while solving the task."),QMessageBox::Ok,this).exec();
[12]262        // tabWidget->setCurrentIndex(1);
[6]263}
[21]264
[29]265void MainWindow::actionHelpAboutTriggered()
[21]266{
267        // TODO: Normal about window :-)
[30]268QString about = QString::fromUtf8("TSPSG - TSP Solver and Generator\n");
269about += QString::fromUtf8("    Copyright (C) 2007-%1 Lёppa <contacts[at]oleksii[dot]name>\n").arg(QDate::currentDate().toString("yyyy"));
[37]270        about += QString::fromUtf8("Target OS: %1\n").arg(OS);
271        about += "Qt library:\n";
[30]272        about += QString::fromUtf8("    Compile time: %1\n").arg(QT_VERSION_STR);
273        about += QString::fromUtf8("    Runtime: %1\n").arg(qVersion());
274        about += "\n";
275        about += "TSPSG is licensed under the terms of the GNU General Public License. You should have received a copy of the GNU General Public License along with TSPSG.";
[27]276        QMessageBox(QMessageBox::Information,"About",about,QMessageBox::Ok,this).exec();
[21]277}
278
[29]279void MainWindow::loadLangList()
280{
281QSettings langinfo("i18n/languages.ini",QSettings::IniFormat);
[33]282#if QT_VERSION >= 0x040500
283        // In Qt < 4.5 QSettings doesn't have method setIniCodec.
[29]284        langinfo.setIniCodec("UTF-8");
[33]285#endif
[29]286QDir dir("i18n","*.qm",QDir::Name | QDir::IgnoreCase,QDir::Files);
287        if (!dir.exists())
288                return;
289QFileInfoList langs = dir.entryInfoList();
290        if (langs.size() <= 0)
291                return;
292QAction *a;
293        for (int k = 0; k < langs.size(); k++) {
294                QFileInfo lang = langs.at(k);
[30]295                if (!lang.completeBaseName().startsWith("qt_") && lang.completeBaseName().compare("en")) {
[33]296#if QT_VERSION >= 0x040500
[29]297                        a = menuSettingsLanguage->addAction(langinfo.value(lang.completeBaseName() + "/NativeName",lang.completeBaseName()).toString());
[33]298#else
299                        // We use Name if Qt < 4.5 because NativeName is in UTF-8, QSettings
300                        // reads .ini file as ASCII and there is no way to set file encoding.
301                        a = menuSettingsLanguage->addAction(langinfo.value(lang.completeBaseName() + "/Name",lang.completeBaseName()).toString());
302#endif
[29]303                        a->setData(lang.completeBaseName());
304                        a->setCheckable(true);
305                        a->setActionGroup(groupSettingsLanguageList);
306                        if (settings->value("Language",QLocale::system().name()).toString().startsWith(lang.completeBaseName()))
307                                a->setChecked(true);
308                }
309        }
310}
311
312void MainWindow::actionSettingsLanguageAutodetectTriggered(bool checked)
313{
314        if (checked) {
315                settings->remove("Language");
316                QMessageBox(QMessageBox::Information,trUtf8("Language change"),trUtf8("Language will be autodetected on next application start."),QMessageBox::Ok,this).exec();
317        } else
318                settings->setValue("Language",groupSettingsLanguageList->checkedAction()->data().toString());
319}
320
321void MainWindow::groupSettingsLanguageListTriggered(QAction *action)
322{
323        if (actionSettingsLanguageAutodetect->isChecked()) {
324                // We have language autodetection. It needs to be disabled to change language.
325                if (QMessageBox(QMessageBox::Question,trUtf8("Language change"),trUtf8("You have language autodetection turned on.\nIt needs to be off.\nDo you wish to turn it off?"),QMessageBox::Yes | QMessageBox::No,this).exec() == QMessageBox::Yes) {
326                        actionSettingsLanguageAutodetect->trigger();
327                } else
328                        return;
329        }
[30]330        if (loadLanguage(action->data().toString())) {
[29]331                settings->setValue("Language",action->data().toString());
332                retranslateUi(this);
333        }
334}
335
[21]336void MainWindow::closeEvent(QCloseEvent *event)
337{
[37]338        if (isWindowModified()) {
339int res = QMessageBox(QMessageBox::Warning,trUtf8("Application Close"),trUtf8("Would you like to save changes in current task?"),QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,this).exec();
340                if ((res == QMessageBox::Cancel) || ((res == QMessageBox::Yes) && !saveTask())) {
341                        event->ignore();
342                        return;
343                }
344        }
[26]345        settings->setValue("NumCities",spinCities->value());
346#ifndef Q_OS_WINCE
[21]347        // Saving windows state
[23]348        if (settings->value("SavePos",false).toBool()) {
349                settings->beginGroup("MainWindow");
350                settings->setValue("Maximized",isMaximized());
[21]351                if (!isMaximized()) {
[23]352                        settings->setValue("Size",size());
353                        settings->setValue("Position",pos());
[21]354                }
[23]355                settings->endGroup();
[21]356        }
[26]357#endif // Q_OS_WINCE
[21]358        QMainWindow::closeEvent(event);
359}
[31]360
[37]361void MainWindow::dataChanged()
362{
363        setWindowModified(true);
364}
365
[31]366void MainWindow::numCitiesChanged(int nCities)
367{
368        spinCities->setValue(nCities);
369}
Note: See TracBrowser for help on using the repository browser.