source: tspsg-svn/trunk/src/tspmodel.cpp @ 34

Last change on this file since 34 was 34, checked in by laleppa, 16 years ago

Explicit braces to avoid ambiguous ‘else’.

  • Property svn:keywords set to Id URL
File size: 6.8 KB
Line 
1/*
2 *  TSPSG - TSP Solver and Generator
3 *  Copyright (C) 2007-2009 Lёppa <contacts[at]oleksii[dot]name>
4 *
5 *  $Id: tspmodel.cpp 34 2009-06-30 17:22:29Z laleppa $
6 *  $URL: https://tspsg.svn.sourceforge.net/svnroot/tspsg/trunk/src/tspmodel.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 "tspmodel.h"
25
26CTSPModel::CTSPModel(QObject *parent)
27        : QAbstractTableModel(parent), nCities(0)
28{
29        settings = new QSettings(QSettings::IniFormat,QSettings::UserScope,"TSPSG","tspsg");
30}
31
32int CTSPModel::rand(int min, int max)
33{
34        return min + (int)(((float)qrand() / RAND_MAX) * max);
35}
36
37int CTSPModel::rowCount(const QModelIndex &) const
38{
39        return nCities;
40}
41
42int CTSPModel::columnCount(const QModelIndex &) const
43{
44        return nCities;
45}
46
47QVariant CTSPModel::headerData(int section, Qt::Orientation orientation, int role) const
48{
49        if (role == Qt::DisplayRole) {
50                if (orientation == Qt::Vertical)
51                        return trUtf8("City %1").arg(section + 1);
52                else
53                        return trUtf8("%1").arg(section + 1);
54        }
55        return QVariant();
56}
57
58QVariant CTSPModel::data(const QModelIndex &index, int role) const
59{
60        if (!index.isValid())
61                return QVariant();
62        if (role == Qt::TextAlignmentRole)
63                return int(Qt::AlignCenter);
64        else if (role == Qt::FontRole) {
65QFont font;
66                font.setBold(true);
67                return font;
68        } else if (role == Qt::DisplayRole || role == Qt::EditRole) {
69                if (index.row() < nCities && index.column() < nCities)
70                        if (table[index.row()][index.column()] == INFINITY)
71                                return trUtf8(INFSTR);
72                        else
73                                // HACK: Converting to string to prevent spinbox in edit mode
74                                return QVariant(table[index.row()][index.column()]).toString();
75                else
76                        return QVariant();
77        } else if (role == Qt::UserRole)
78                return table[index.row()][index.column()];
79        return QVariant();
80}
81
82bool CTSPModel::setData(const QModelIndex &index, const QVariant &value, int role)
83{
84        if (!index.isValid())
85                return false;
86        if (role == Qt::EditRole && index.row() != index.column()) {
87                if (value.toString().compare(INFSTR) == 0)
88                        table[index.row()][index.column()] = INFINITY;
89                else {
90bool ok;
91double tmp = value.toDouble(&ok);
92                        if (!ok || tmp < 0)
93                                return false;
94                        else
95                                table[index.row()][index.column()] = tmp;
96                }
97                emit dataChanged(index,index);
98                return true;
99        }
100        return false;
101}
102
103Qt::ItemFlags CTSPModel::flags(const QModelIndex &index) const
104{
105Qt::ItemFlags flags = QAbstractItemModel::flags(index);
106        if (index.row() != index.column())
107                flags |= Qt::ItemIsEditable;
108        return flags;
109}
110
111quint16 CTSPModel::numCities() const
112{
113        return nCities;
114}
115
116void CTSPModel::setNumCities(int n)
117{
118// int randMin = settings->value("MinCost",DEF_RAND_MIN).toInt();
119// int randMax = settings->value("MaxCost",DEF_RAND_MAX).toInt();
120        if (n == nCities)
121                return;
122        emit layoutAboutToBeChanged();
123        if (n > nCities) {
124                for (int r = 0; r < nCities; r++) {
125                        for (int c = nCities; c < n; c++)
126                                if (r == c)
127                                        table[r][c] = INFINITY;
128                                else
129                                        table[r][c] = 0; // rand(randMin,randMax);
130                }
131                for (int r = nCities; r < n; r++) {
132                        for (int c = 0; c < n; c++)
133                                if (r == c)
134                                        table[r][c] = INFINITY;
135                                else
136                                        table[r][c] = 0; // rand(randMin,randMax);
137                }
138        }
139        nCities = n;
140        emit layoutChanged();
141}
142
143void CTSPModel::clear()
144{
145        for (int r = 0; r < nCities; r++)
146                for (int c = 0; c < nCities; c++)
147                        if (r != c)
148                                table[r][c] = 0;
149        emit dataChanged(index(0,0),index(nCities - 1,nCities - 1));
150}
151
152void CTSPModel::loadTask(QString fname)
153{
154QFile f(fname);
155        f.open(QIODevice::ReadOnly);
156QDataStream ds(&f);
157        ds.setVersion(QDataStream::Qt_4_4);
158quint32 sig;
159        ds >> sig;
160        ds.device()->reset();
161        if (sig == TSPT)
162                loadTSPT(&ds);
163        else if ((sig >> 16) == ZKT)
164                loadZKT(&ds);
165        else
166                QMessageBox(QMessageBox::Critical,trUtf8("Task Load"),trUtf8("Unable to load task:\nUnknown file format or file is corrupted."),QMessageBox::Ok).exec();
167        f.close();
168}
169
170void CTSPModel::loadTSPT(QDataStream *ds)
171{
172        // Skipping signature
173        ds->skipRawData(sizeof(TSPT));
174        // File version
175quint8 version;
176        *ds >> version;
177        if (version > TSPT_VERSION) {
178                QMessageBox(QMessageBox::Critical,trUtf8("Task Load"),trUtf8("Unable to load task:\nFile version is newer than application supports.\nPlease, try to update application."),QMessageBox::Ok).exec();
179                return;
180        }
181        // Skipping metadata
182        ds->skipRawData(TSPT_META_SIZE);
183        // Cities number
184quint16 size;
185        *ds >> size;
186        if (nCities != size)
187                emit numCitiesChanged(size);
188        // Costs
189        for (int r = 0; r < size; r++)
190                for (int c = 0; c < size; c++)
191                        if (r != c)
192                                *ds >> table[r][c];
193        emit dataChanged(index(0,0),index(nCities - 1,nCities - 1));
194}
195
196void CTSPModel::loadZKT(QDataStream *ds)
197{
198        // Skipping signature
199        ds->skipRawData(sizeof(ZKT));
200        // File version
201quint16 version;
202        ds->readRawData(reinterpret_cast<char *>(&version),2);
203        if (version > ZKT_VERSION) {
204                QMessageBox(QMessageBox::Critical,trUtf8("Task Load"),trUtf8("Unable to load task:\nFile version is newer than application supports.\nPlease, try to update application."),QMessageBox::Ok).exec();
205                return;
206        }
207        // Cities number
208quint8 size;
209        ds->readRawData(reinterpret_cast<char *>(&size),1);
210        if (nCities != size)
211                emit numCitiesChanged(size);
212        // Costs
213double val;
214        for (int r = 0; r < size; r++)
215                for (int c = 0; c < size; c++)
216                        if (r != c) {
217                                ds->readRawData(reinterpret_cast<char *>(&val),8);
218                                table[r][c] = val;
219                        } else
220                                ds->skipRawData(8);
221        emit dataChanged(index(0,0),index(nCities - 1,nCities - 1));
222}
223
224void CTSPModel::saveTask(QString fname)
225{
226QFile f(fname);
227        f.open(QIODevice::WriteOnly);
228QDataStream ds(&f);
229        ds.setVersion(QDataStream::Qt_4_4);
230        // File signature
231        ds << TSPT;
232        // File version
233        ds << TSPT_VERSION;
234        // File metadata version
235        ds << TSPT_META_VERSION;
236        // Metadata
237        ds << OSID;
238        // Number of cities
239        ds << nCities;
240        // Costs
241        for (int r = 0; r < nCities; r++)
242                for (int c = 0; c < nCities; c++)
243                        if (r != c)
244                                ds << table[r][c];
245        f.close();
246}
247
248void CTSPModel::randomize()
249{
250int randMin = settings->value("MinCost",DEF_RAND_MIN).toInt();
251int randMax = settings->value("MaxCost",DEF_RAND_MAX).toInt();
252        for (int r = 0; r < nCities; r++)
253                for (int c = 0; c < nCities; c++)
254                        if (r != c)
255                                table[r][c] = rand(randMin,randMax);
256        emit dataChanged(index(0,0),index(nCities - 1,nCities - 1));
257}
Note: See TracBrowser for help on using the repository browser.