source: tspsg/src/mainwindow.cpp @ 134a9158bd

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