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

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

+ Opening task file
+ Saving task file

  • Translations update to reflect recent changes.
  • 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 31 2009-06-29 23:02:31Z 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        return QVariant();
55}
56
57QVariant CTSPModel::data(const QModelIndex &index, int role) const
58{
59        if (!index.isValid())
60                return QVariant();
61        if (role == Qt::TextAlignmentRole)
62                return int(Qt::AlignCenter);
63        else if (role == Qt::FontRole) {
64QFont font;
65                font.setBold(true);
66                return font;
67        } else if (role == Qt::DisplayRole || role == Qt::EditRole) {
68                if (index.row() < nCities && index.column() < nCities)
69                        if (table[index.row()][index.column()] == INFINITY)
70                                return trUtf8(INFSTR);
71                        else
72                                // HACK: Converting to string to prevent spinbox in edit mode
73                                return QVariant(table[index.row()][index.column()]).toString();
74                else
75                        return QVariant();
76        } else if (role == Qt::UserRole)
77                return table[index.row()][index.column()];
78        return QVariant();
79}
80
81bool CTSPModel::setData(const QModelIndex &index, const QVariant &value, int role)
82{
83        if (!index.isValid())
84                return false;
85        if (role == Qt::EditRole && index.row() != index.column()) {
86                if (value.toString().compare(INFSTR) == 0)
87                        table[index.row()][index.column()] = INFINITY;
88                else {
89bool ok;
90double tmp = value.toDouble(&ok);
91                        if (!ok || tmp < 0)
92                                return false;
93                        else
94                                table[index.row()][index.column()] = tmp;
95                }
96                emit dataChanged(index,index);
97                return true;
98        }
99        return false;
100}
101
102Qt::ItemFlags CTSPModel::flags(const QModelIndex &index) const
103{
104Qt::ItemFlags flags = QAbstractItemModel::flags(index);
105        if (index.row() != index.column())
106                flags |= Qt::ItemIsEditable;
107        return flags;
108}
109
110quint16 CTSPModel::numCities() const
111{
112        return nCities;
113}
114
115void CTSPModel::setNumCities(int n)
116{
117// int randMin = settings->value("MinCost",DEF_RAND_MIN).toInt();
118// int randMax = settings->value("MaxCost",DEF_RAND_MAX).toInt();
119        if (n == nCities)
120                return;
121        emit layoutAboutToBeChanged();
122        if (n > nCities) {
123                for (int r = 0; r < nCities; r++) {
124                        for (int c = nCities; c < n; c++)
125                                if (r == c)
126                                        table[r][c] = INFINITY;
127                                else
128                                        table[r][c] = 0; // rand(randMin,randMax);
129                }
130                for (int r = nCities; r < n; r++) {
131                        for (int c = 0; c < n; c++)
132                                if (r == c)
133                                        table[r][c] = INFINITY;
134                                else
135                                        table[r][c] = 0; // rand(randMin,randMax);
136                }
137        }
138        nCities = n;
139        emit layoutChanged();
140}
141
142void CTSPModel::clear()
143{
144        for (int r = 0; r < nCities; r++)
145                for (int c = 0; c < nCities; c++)
146                        if (r != c)
147                                table[r][c] = 0;
148        emit dataChanged(index(0,0),index(nCities - 1,nCities - 1));
149}
150
151void CTSPModel::loadTask(QString fname)
152{
153QFile f(fname);
154        f.open(QIODevice::ReadOnly);
155QDataStream ds(&f);
156        ds.setVersion(QDataStream::Qt_4_4);
157quint32 sig;
158        ds >> sig;
159        ds.device()->reset();
160        if (sig == TSPT)
161                loadTSPT(&ds);
162        else if ((sig >> 16) == ZKT)
163                loadZKT(&ds);
164        else
165                QMessageBox(QMessageBox::Critical,trUtf8("Task Load"),trUtf8("Unable to load task:\nUnknown file format or file is corrupted."),QMessageBox::Ok).exec();
166        f.close();
167}
168
169void CTSPModel::loadTSPT(QDataStream *ds)
170{
171        // Skipping signature
172        ds->skipRawData(sizeof(TSPT));
173        // File version
174quint8 version;
175        *ds >> version;
176        if (version > TSPT_VERSION) {
177                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();
178                return;
179        }
180        // Skipping metadata
181        ds->skipRawData(TSPT_META_SIZE);
182        // Cities number
183quint16 size;
184        *ds >> size;
185        if (nCities != size)
186                emit numCitiesChanged(size);
187        // Costs
188        for (int r = 0; r < size; r++)
189                for (int c = 0; c < size; c++)
190                        if (r != c)
191                                *ds >> table[r][c];
192        emit dataChanged(index(0,0),index(nCities - 1,nCities - 1));
193}
194
195void CTSPModel::loadZKT(QDataStream *ds)
196{
197        // Skipping signature
198        ds->skipRawData(sizeof(ZKT));
199        // File version
200quint16 version;
201        ds->readRawData(reinterpret_cast<char *>(&version),2);
202        if (version > ZKT_VERSION) {
203                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();
204                return;
205        }
206        // Cities number
207quint8 size;
208        ds->readRawData(reinterpret_cast<char *>(&size),1);
209        if (nCities != size)
210                emit numCitiesChanged(size);
211        // Costs
212double val;
213        for (int r = 0; r < size; r++)
214                for (int c = 0; c < size; c++)
215                        if (r != c) {
216                                ds->readRawData(reinterpret_cast<char *>(&val),8);
217                                table[r][c] = val;
218                        } else
219                                ds->skipRawData(8);
220        emit dataChanged(index(0,0),index(nCities - 1,nCities - 1));
221}
222
223void CTSPModel::saveTask(QString fname)
224{
225QFile f(fname);
226        f.open(QIODevice::WriteOnly);
227QDataStream ds(&f);
228        ds.setVersion(QDataStream::Qt_4_4);
229        // File signature
230        ds << TSPT;
231        // File version
232        ds << TSPT_VERSION;
233        // File metadata version
234        ds << TSPT_META_VERSION;
235        // Metadata
236        ds << OSID;
237        // Number of cities
238        ds << nCities;
239        // Costs
240        for (int r = 0; r < nCities; r++)
241                for (int c = 0; c < nCities; c++)
242                        if (r != c)
243                                ds << table[r][c];
244        f.close();
245}
246
247void CTSPModel::randomize()
248{
249int randMin = settings->value("MinCost",DEF_RAND_MIN).toInt();
250int randMax = settings->value("MaxCost",DEF_RAND_MAX).toInt();
251        for (int r = 0; r < nCities; r++)
252                for (int c = 0; c < nCities; c++)
253                        if (r != c)
254                                table[r][c] = rand(randMin,randMax);
255        emit dataChanged(index(0,0),index(nCities - 1,nCities - 1));
256}
Note: See TracBrowser for help on using the repository browser.