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

Last change on this file since 39 was 38, checked in by laleppa, 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 svn:keywords set to Id URL
File size: 13.6 KB
Line 
1/*
2 *  TSPSG - TSP Solver and Generator
3 *  Copyright (C) 2007-2009 Lёppa <contacts[at]oleksii[dot]name>
4 *
5 *  $Id: mainwindow.cpp 38 2009-07-20 18:47:40Z laleppa $
6 *  $URL: https://tspsg.svn.sourceforge.net/svnroot/tspsg/trunk/src/mainwindow.cpp $
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
26MainWindow::MainWindow(QWidget *parent)
27        : QMainWindow(parent)
28{
29        settings = new QSettings(QSettings::IniFormat,QSettings::UserScope,"TSPSG","tspsg");
30        loadLanguage();
31        setupUi(this);
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
37#ifndef Q_OS_WINCE
38        printer = new QPrinter();
39#endif // Q_OS_WINCE
40        groupSettingsLanguageList = new QActionGroup(this);
41        actionSettingsLanguageEnglish->setData("en");
42        actionSettingsLanguageEnglish->setActionGroup(groupSettingsLanguageList);
43        loadLangList();
44        spinCities->setValue(settings->value("NumCities",5).toInt());
45        actionSettingsLanguageAutodetect->setChecked(settings->value("Language","").toString().isEmpty());
46        connect(actionFileNew,SIGNAL(triggered()),this,SLOT(actionFileNewTriggered()));
47        connect(actionFileOpen,SIGNAL(triggered()),this,SLOT(actionFileOpenTriggered()));
48        connect(actionFileSaveTask,SIGNAL(triggered()),this,SLOT(actionFileSaveTaskTriggered()));
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 *)));
52        connect(actionHelpAboutQt,SIGNAL(triggered()),qApp,SLOT(aboutQt()));
53        connect(actionHelpAbout,SIGNAL(triggered()),this,SLOT(actionHelpAboutTriggered()));
54#ifndef Q_OS_WINCE
55        connect(actionFilePrintSetup,SIGNAL(triggered()),this,SLOT(actionFilePrintSetupTriggered()));
56#endif // Q_OS_WINCE
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)));
60QRect rect = geometry();
61#ifdef Q_OS_WINCE
62        // HACK: Fix for all tabWidget elements becoming "unclickable" if making it central widget.
63/*      rect.setSize(QApplication::desktop()->availableGeometry().size());
64        rect.setHeight(rect.height() - (QApplication::desktop()->screenGeometry().height() - QApplication::desktop()->availableGeometry().height()));
65        tabWidget->resize(rect.width(),rect.height() - toolBar->iconSize().height());*/
66        // Somehow, this works now. No more "unclickable" elements :-\
67        setCentralWidget(tabWidget);
68#else
69        if (settings->value("SavePos",false).toBool()) {
70                // Loading of saved window state
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())
75                        setWindowState(windowState() | Qt::WindowMaximized);
76                settings->endGroup();
77        } else {
78                // Centering main window
79                rect.moveCenter(QApplication::desktop()->availableGeometry(this).center());
80                setGeometry(rect);
81        }
82#endif // Q_OS_WINCE
83        qsrand(QDateTime().currentDateTime().toTime_t());
84        tspmodel = new CTSPModel();
85        tspmodel->setNumCities(spinCities->value());
86        taskView->setModel(tspmodel);
87        connect(tspmodel,SIGNAL(numCitiesChanged(int)),this,SLOT(numCitiesChanged(int)));
88        connect(tspmodel,SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),this,SLOT(dataChanged()));
89        connect(tspmodel,SIGNAL(layoutChanged()),this,SLOT(dataChanged()));
90#ifdef Q_OS_WINCE
91        taskView->resizeColumnsToContents();
92        taskView->resizeRowsToContents();
93#endif // Q_OS_WINCE
94}
95
96bool MainWindow::loadLanguage(QString lang)
97{
98// i18n
99bool ad = false;
100        if (lang.isEmpty()) {
101                ad = settings->value("Language","").toString().isEmpty();
102                lang = settings->value("Language",QLocale::system().name()).toString();
103        }
104static QTranslator *qtTranslator;
105        if (qtTranslator) {
106                qApp->removeTranslator(qtTranslator);
107                delete qtTranslator;
108                qtTranslator = NULL;
109        }
110        qtTranslator = new QTranslator();
111static QTranslator *translator;
112        if (translator) {
113                qApp->removeTranslator(translator);
114                delete translator;
115        }
116        translator = new QTranslator();
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                        }
129                // Now let's load application translation.
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)
144{
145#ifdef Q_OS_WINCE
146int count = tspmodel->numCities();
147#endif // Q_OS_WINCE
148        tspmodel->setNumCities(n);
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
156}
157
158
159void MainWindow::actionFileNewTriggered()
160{
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        }
166        tspmodel->clear();
167        setWindowModified(false);
168}
169
170void MainWindow::actionFileOpenTriggered()
171{
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        }
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());
191        setWindowModified(false);
192}
193
194void MainWindow::actionFileSaveTaskTriggered()
195{
196        saveTask();
197}
198
199bool MainWindow::saveTask() {
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)
207                return false;
208QStringList files = sd.selectedFiles();
209        if (files.size() < 1)
210                return false;
211        if (tspmodel->saveTask(files.first())) {
212                setWindowModified(false);
213                return true;
214        } else
215                return false;
216}
217
218void MainWindow::actionSettingsPreferencesTriggered()
219{
220SettingsDialog sd(this);
221        sd.exec();
222}
223
224#ifndef Q_OS_WINCE
225void MainWindow::actionFilePrintSetupTriggered()
226{
227QPrintDialog pd(printer,this);
228#if QT_VERSION >= 0x040500
229        // No such methods in Qt < 4.5
230        pd.setOption(QAbstractPrintDialog::PrintSelection,false);
231        pd.setOption(QAbstractPrintDialog::PrintPageRange,false);
232#endif
233        pd.exec();
234}
235#endif // Q_OS_WINCE
236
237void MainWindow::buttonRandomClicked()
238{
239        tspmodel->randomize();
240        setWindowModified(true);
241#ifdef Q_OS_WINCE
242        taskView->resizeColumnsToContents();
243        taskView->resizeRowsToContents();
244#endif // Q_OS_WINCE
245}
246
247void MainWindow::buttonSolveClicked()
248{
249        // TODO: Task solving goes here :-)
250tMatrix matrix;
251double *row;
252int n = spinCities->value();
253bool ok;
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) {
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();
260                                return;
261                        }
262                }
263                matrix.append(row);
264        }
265CTSPSolver solver;
266sStep *root = solver.solve(spinCities->value(),matrix);
267        if (!root)
268                QMessageBox(QMessageBox::Critical,trUtf8("Solution error"),trUtf8("There was an error while solving the task."),QMessageBox::Ok,this).exec();
269        // tabWidget->setCurrentIndex(1);
270}
271
272void MainWindow::actionHelpAboutTriggered()
273{
274        // TODO: Normal about window :-)
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"));
277        about += QString::fromUtf8("Target OS: %1\n").arg(OS);
278        about += "Qt library:\n";
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.";
283        QMessageBox(QMessageBox::Information,"About",about,QMessageBox::Ok,this).exec();
284}
285
286void MainWindow::loadLangList()
287{
288QSettings langinfo("i18n/languages.ini",QSettings::IniFormat);
289#if QT_VERSION >= 0x040500
290        // In Qt < 4.5 QSettings doesn't have method setIniCodec.
291        langinfo.setIniCodec("UTF-8");
292#endif
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);
302                if (!lang.completeBaseName().startsWith("qt_") && lang.completeBaseName().compare("en")) {
303#if QT_VERSION >= 0x040500
304                        a = menuSettingsLanguage->addAction(langinfo.value(lang.completeBaseName() + "/NativeName",lang.completeBaseName()).toString());
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
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        }
337        if (loadLanguage(action->data().toString())) {
338                settings->setValue("Language",action->data().toString());
339                retranslateUi(this);
340        }
341}
342
343void MainWindow::closeEvent(QCloseEvent *event)
344{
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        }
352        settings->setValue("NumCities",spinCities->value());
353#ifndef Q_OS_WINCE
354        // Saving windows state
355        if (settings->value("SavePos",false).toBool()) {
356                settings->beginGroup("MainWindow");
357                settings->setValue("Maximized",isMaximized());
358                if (!isMaximized()) {
359                        settings->setValue("Size",size());
360                        settings->setValue("Position",pos());
361                }
362                settings->endGroup();
363        }
364#endif // Q_OS_WINCE
365        QMainWindow::closeEvent(event);
366}
367
368void MainWindow::dataChanged()
369{
370        setWindowModified(true);
371}
372
373void MainWindow::numCitiesChanged(int nCities)
374{
375        spinCities->setValue(nCities);
376}
Note: See TracBrowser for help on using the repository browser.