| 95 |
david |
1 |
#include "qmconfclass.h"
|
| 174 |
- |
2 |
#include "qmconfig.h"
|
| 380 |
david |
3 |
#include <QtCore/QVariant>
|
|
|
4 |
#include <QtGui/QAction>
|
|
|
5 |
#include <QApplication>
|
|
|
6 |
#include <QButtonGroup>
|
|
|
7 |
#include <QGroupBox>
|
|
|
8 |
#include <QHeaderView>
|
|
|
9 |
#include <QPushButton>
|
|
|
10 |
#include <QTableWidget>
|
|
|
11 |
#include <QVBoxLayout>
|
|
|
12 |
#include <QWidget>
|
| 99 |
david |
13 |
#include "consts.h"
|
|
|
14 |
#include "structs.h"
|
|
|
15 |
#include "proto.h"
|
| 180 |
- |
16 |
#include "mainwindow.h"
|
| 380 |
david |
17 |
#include "qmTableWidgetItem.h"
|
| 95 |
david |
18 |
|
| 380 |
david |
19 |
#include <QDialogButtonBox>
|
| 99 |
david |
20 |
#include "QTableWidgetItem"
|
| 107 |
david |
21 |
#include "spinboxdelegate.h"
|
|
|
22 |
#include "timedelegate.h"
|
| 111 |
david |
23 |
#include "textdelegate.h"
|
| 180 |
- |
24 |
#include <QMenu>
|
| 99 |
david |
25 |
|
| 227 |
- |
26 |
#define COL_ABR 0
|
|
|
27 |
#define COL_CLASS 1
|
|
|
28 |
#define COL_TIME 2
|
|
|
29 |
#define COL_WINNERS 3
|
|
|
30 |
#define COL_NE 4
|
|
|
31 |
#define COL_NE_WINNERS 5
|
|
|
32 |
#define COL_ST_TOTAL 6
|
| 228 |
- |
33 |
#define COL_ST_VALID 7
|
|
|
34 |
#define COL_ST_DISQ 8
|
|
|
35 |
#define COL_ST_NONEQ 9
|
|
|
36 |
#define COL_ST_VET 10
|
| 380 |
david |
37 |
#define COL_ST_CEV 11
|
|
|
38 |
#define COL_ST_CNE 12
|
|
|
39 |
#define COL_INDEX 13
|
| 227 |
- |
40 |
|
| 380 |
david |
41 |
#define COL_COUNT 14
|
| 227 |
- |
42 |
|
| 380 |
david |
43 |
|
| 104 |
- |
44 |
QmConfClass::QmConfClass(QWidget *parent) :
|
| 380 |
david |
45 |
QWidget(parent)
|
| 95 |
david |
46 |
{
|
| 181 |
- |
47 |
populating = false;
|
| 380 |
david |
48 |
dirty = false;
|
| 99 |
david |
49 |
|
| 380 |
david |
50 |
QVBoxLayout *verticalLayout = new QVBoxLayout(this);
|
|
|
51 |
verticalLayout->setContentsMargins(0, 0, 0, 0);
|
|
|
52 |
|
|
|
53 |
QGroupBox *groupBox = new QGroupBox("Class");
|
|
|
54 |
verticalLayout->addWidget(groupBox);
|
|
|
55 |
QVBoxLayout *verticalLayout2 = new QVBoxLayout(groupBox);
|
|
|
56 |
tableWidget = new QTableWidget(groupBox);
|
|
|
57 |
tableWidget->setAlternatingRowColors(true);
|
|
|
58 |
tableWidget->setRowCount(config.num_class + 1);
|
|
|
59 |
tableWidget->setColumnCount(COL_COUNT);
|
|
|
60 |
tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
61 |
tableWidget->horizontalHeader()->setVisible(true);
|
|
|
62 |
tableWidget->horizontalHeader()->setDefaultSectionSize(70);
|
|
|
63 |
tableWidget->horizontalHeader()->setHighlightSections(true);
|
|
|
64 |
//tableWidget->horizontalHeader()->setStretchLastSection(true);
|
|
|
65 |
tableWidget->verticalHeader()->setVisible(true);
|
|
|
66 |
tableWidget->verticalHeader()->setDefaultSectionSize(20);
|
|
|
67 |
//tableWidget->setSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::MinimumExpanding );
|
|
|
68 |
//tableWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
|
|
69 |
verticalLayout2->addWidget(tableWidget);
|
|
|
70 |
|
|
|
71 |
//QSpacerItem *verticalSpacer1;
|
|
|
72 |
//verticalSpacer1 = new QSpacerItem(0, 10, QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
73 |
//verticalLayout2->addItem(verticalSpacer1);
|
|
|
74 |
|
|
|
75 |
QHBoxLayout *horizontalLayout;
|
|
|
76 |
horizontalLayout = new QHBoxLayout();
|
|
|
77 |
horizontalLayout->setContentsMargins(0, 0, 5, 5);
|
|
|
78 |
verticalLayout->addLayout(horizontalLayout);
|
|
|
79 |
|
|
|
80 |
QDialogButtonBox *buttonBox = new QDialogButtonBox();
|
|
|
81 |
pushButtonRestore = buttonBox->addButton("Restore",QDialogButtonBox::ActionRole );
|
|
|
82 |
pushButtonSave = buttonBox->addButton("Save",QDialogButtonBox::ActionRole );
|
|
|
83 |
horizontalLayout->addWidget(buttonBox);
|
|
|
84 |
|
|
|
85 |
|
|
|
86 |
connect(pushButtonSave, SIGNAL(clicked(bool)), this, SLOT(save()) );
|
|
|
87 |
connect(pushButtonRestore, SIGNAL(clicked(bool)), this, SLOT(cancel()) );
|
|
|
88 |
|
| 109 |
david |
89 |
QStringList labels;
|
| 228 |
- |
90 |
labels << "Abr" << "Full Name" << "Start Time" << "Winners" << "NE" << "NE Winners";
|
| 109 |
david |
91 |
|
| 380 |
david |
92 |
labels << "Total" << "Valid" <<"Disqual" << "NonEq" << "VetCheck" << "Comp Ev" << " Comp NE";
|
| 107 |
david |
93 |
|
| 380 |
david |
94 |
labels << "Index";
|
| 180 |
- |
95 |
|
| 380 |
david |
96 |
tableWidget->setHorizontalHeaderLabels(labels);
|
| 180 |
- |
97 |
|
| 380 |
david |
98 |
connect(tableWidget, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(ctxMenu(const QPoint &)));
|
|
|
99 |
connect(tableWidget, SIGNAL(cellChanged(int,int)), this, SLOT(cellChanged(int,int)));
|
|
|
100 |
|
| 107 |
david |
101 |
/*
|
|
|
102 |
** Setup delegated for specialised editing
|
|
|
103 |
*/
|
| 380 |
david |
104 |
tableWidget->setItemDelegateForColumn(COL_ABR, new textDelegate(2));
|
|
|
105 |
tableWidget->setItemDelegateForColumn(COL_CLASS, new textDelegate(LEN_CLASS_NAME));
|
|
|
106 |
tableWidget->setItemDelegateForColumn(COL_TIME, new timeDelegate());
|
|
|
107 |
tableWidget->setItemDelegateForColumn(COL_WINNERS, new SpinBoxDelegate(0,50));
|
|
|
108 |
tableWidget->setItemDelegateForColumn(COL_NE_WINNERS, new SpinBoxDelegate(0,50));
|
|
|
109 |
}
|
| 107 |
david |
110 |
|
| 380 |
david |
111 |
/*----------------------------------------------------------------------------
|
|
|
112 |
** FUNCTION : showEvent
|
|
|
113 |
**
|
|
|
114 |
** DESCRIPTION : Called when the page is shown
|
|
|
115 |
** Used to refresh the contents of the display as well
|
|
|
116 |
** as show them for the first time
|
|
|
117 |
**
|
|
|
118 |
----------------------------------------------------------------------------*/
|
| 180 |
- |
119 |
|
| 380 |
david |
120 |
void QmConfClass::showEvent ( QShowEvent * event )
|
|
|
121 |
{
|
|
|
122 |
//qDebug("populate::showEvent");
|
|
|
123 |
if ( ! event->spontaneous() && !dirty )
|
|
|
124 |
{
|
|
|
125 |
populate();
|
|
|
126 |
}
|
|
|
127 |
}
|
| 180 |
- |
128 |
|
| 380 |
david |
129 |
/*----------------------------------------------------------------------------
|
|
|
130 |
** FUNCTION : populate
|
|
|
131 |
**
|
|
|
132 |
** DESCRIPTION : Populate the display with information
|
|
|
133 |
**
|
|
|
134 |
----------------------------------------------------------------------------*/
|
| 180 |
- |
135 |
|
| 104 |
- |
136 |
void QmConfClass::populate(void)
|
| 99 |
david |
137 |
{
|
| 380 |
david |
138 |
bool reportDataLoaded = false;
|
|
|
139 |
t_class_summary data;
|
|
|
140 |
|
| 181 |
- |
141 |
populating = true;
|
| 380 |
david |
142 |
tableWidget->clearContents();
|
|
|
143 |
tableWidget->setRowCount(0);
|
|
|
144 |
tableWidget->setSortingEnabled(false);
|
|
|
145 |
|
|
|
146 |
/*
|
|
|
147 |
** Load Report Data if we can
|
|
|
148 |
*/
|
|
|
149 |
if( load_report_data() )
|
| 99 |
david |
150 |
{
|
| 380 |
david |
151 |
calc_class_summary( & data );
|
|
|
152 |
reportDataLoaded = true;
|
|
|
153 |
}
|
| 105 |
- |
154 |
|
| 380 |
david |
155 |
/*
|
|
|
156 |
** Add all the information
|
|
|
157 |
*/
|
|
|
158 |
int ii = 0;
|
|
|
159 |
int entryIndex = 0;
|
|
|
160 |
for ( ii = 0; ii < MAX_CLASS; ii++)
|
|
|
161 |
{
|
|
|
162 |
if ( config.team_class[ii].abr[0] )
|
| 111 |
david |
163 |
{
|
| 380 |
david |
164 |
// Keep the config item index entry
|
|
|
165 |
// Will need it when we write stiff out
|
|
|
166 |
tableWidget->setRowCount(tableWidget->rowCount() + 1);
|
|
|
167 |
|
|
|
168 |
tableWidget->setItem(entryIndex, COL_INDEX, new qmTwiNumber(ii));
|
|
|
169 |
|
|
|
170 |
tableWidget->setItem(entryIndex, COL_ABR, new qmTwiEditString(config.team_class[ii].abr ));
|
|
|
171 |
tableWidget->setItem(entryIndex, COL_CLASS, new qmTwiEditString(config.team_class[ii].full_name ));
|
|
|
172 |
|
| 111 |
david |
173 |
QTableWidgetItem *item;
|
|
|
174 |
item = new QTableWidgetItem();
|
|
|
175 |
item->setData(Qt::EditRole,QTime().addSecs(config.team_class[ii].start) );
|
| 380 |
david |
176 |
tableWidget->setItem(entryIndex, COL_TIME, item);
|
| 107 |
david |
177 |
|
| 380 |
david |
178 |
tableWidget->setItem(entryIndex, COL_WINNERS, new qmTwiEditNumber(config.class_winners[ii]));
|
|
|
179 |
tableWidget->setItem(entryIndex, COL_NE, new qmTwiEditFlag("",config.nonequestrian_class == 1 + ii));
|
|
|
180 |
tableWidget->setItem(entryIndex, COL_NE_WINNERS, new qmTwiEditNumber(config.class_ne_winners[ii]));
|
| 181 |
- |
181 |
|
| 380 |
david |
182 |
if (reportDataLoaded)
|
|
|
183 |
{
|
|
|
184 |
tableWidget->setItem(entryIndex,COL_ST_TOTAL, new qmTwiNumber(data.teamclass[ii+1].total) );
|
|
|
185 |
tableWidget->setItem(entryIndex,COL_ST_VALID, new qmTwiNumber(data.teamclass[ii+1].valid) );
|
|
|
186 |
tableWidget->setItem(entryIndex,COL_ST_DISQ, new qmTwiNumber(data.teamclass[ii+1].disqualified));
|
|
|
187 |
tableWidget->setItem(entryIndex,COL_ST_NONEQ, new qmTwiNumber(data.teamclass[ii+1].non_equestrian));
|
|
|
188 |
tableWidget->setItem(entryIndex,COL_ST_VET, new qmTwiNumber(data.teamclass[ii+1].vet_check));
|
|
|
189 |
tableWidget->setItem(entryIndex,COL_ST_CEV, new qmTwiNumber(data.teamclass[ii+1].valid_ev));
|
|
|
190 |
tableWidget->setItem(entryIndex,COL_ST_CNE, new qmTwiNumber(data.teamclass[ii+1].valid_ne));
|
|
|
191 |
}
|
|
|
192 |
entryIndex++;
|
| 111 |
david |
193 |
}
|
| 99 |
david |
194 |
}
|
| 380 |
david |
195 |
|
|
|
196 |
// Insert Totals
|
|
|
197 |
// Flag that items on this this row is not to be sorted - or at least
|
|
|
198 |
// sorted at the end
|
|
|
199 |
//
|
|
|
200 |
if (reportDataLoaded)
|
|
|
201 |
{
|
|
|
202 |
tableWidget->setRowCount(tableWidget->rowCount() + 1);
|
|
|
203 |
tableWidget->setItem(entryIndex,COL_ABR, new qmTwiString("Totals", 1));
|
|
|
204 |
|
|
|
205 |
tableWidget->setItem(entryIndex, COL_CLASS, new qmTwiString("",1));
|
|
|
206 |
tableWidget->setItem(entryIndex, COL_TIME, new qmTwiString("",1));
|
|
|
207 |
tableWidget->setItem(entryIndex, COL_WINNERS, new qmTwiString("",1));
|
|
|
208 |
tableWidget->setItem(entryIndex, COL_NE, new qmTwiString("",1));
|
|
|
209 |
tableWidget->setItem(entryIndex, COL_NE_WINNERS, new qmTwiString("",1));
|
|
|
210 |
tableWidget->setItem(entryIndex, COL_INDEX, new qmTwiString("",1));
|
|
|
211 |
|
|
|
212 |
tableWidget->setItem(entryIndex,COL_ST_TOTAL, new qmTwiNumber(data.total.total, 1));
|
|
|
213 |
tableWidget->setItem(entryIndex,COL_ST_VALID, new qmTwiNumber(data.total.valid, 1));
|
|
|
214 |
tableWidget->setItem(entryIndex,COL_ST_DISQ, new qmTwiNumber(data.total.disqualified, 1));
|
|
|
215 |
tableWidget->setItem(entryIndex,COL_ST_NONEQ, new qmTwiNumber(data.total.non_equestrian, 1));
|
|
|
216 |
tableWidget->setItem(entryIndex,COL_ST_VET, new qmTwiNumber(data.total.vet_check, 1));
|
|
|
217 |
tableWidget->setItem(entryIndex,COL_ST_CEV, new qmTwiNumber(data.total.valid_ev, 1));
|
|
|
218 |
tableWidget->setItem(entryIndex,COL_ST_CNE, new qmTwiNumber(data.total.valid_ne, 1));
|
|
|
219 |
|
|
|
220 |
// Debug
|
|
|
221 |
// tableWidget->setItem(entryIndex, COL_INDEX, new qmTwiNumber(5,2));
|
|
|
222 |
|
|
|
223 |
}
|
|
|
224 |
|
|
|
225 |
checkNeClass();
|
|
|
226 |
|
|
|
227 |
tableWidget->sortByColumn ( COL_INDEX, Qt::AscendingOrder );
|
|
|
228 |
tableWidget->setSortingEnabled(true);
|
|
|
229 |
tableWidget->resizeColumnsToContents();
|
|
|
230 |
tableWidget->resizeRowsToContents();
|
|
|
231 |
|
| 181 |
- |
232 |
updateChanged(false);
|
|
|
233 |
populating = false;
|
| 99 |
david |
234 |
}
|
|
|
235 |
|
| 380 |
david |
236 |
void QmConfClass::checkNeClass(void)
|
|
|
237 |
{
|
|
|
238 |
QString tip = "Unexpected value. The NE winners are configured on a per-class basis";
|
|
|
239 |
|
|
|
240 |
for ( int ii = 0; ii < MAX_CLASS; ii++)
|
|
|
241 |
{
|
|
|
242 |
int indexEntry = 0;
|
|
|
243 |
QTableWidgetItem *item = tableWidget->item ( ii, COL_INDEX );
|
|
|
244 |
const QBrush *goldBrush = new QBrush(QColor(255,204,203));
|
|
|
245 |
|
|
|
246 |
if (!item)
|
|
|
247 |
{
|
|
|
248 |
//qDebug("Ignore row:%d", entryIndex);
|
|
|
249 |
continue;
|
|
|
250 |
}
|
|
|
251 |
if ( item->text().length() == 0)
|
|
|
252 |
{
|
|
|
253 |
//qDebug("Ignore empty row:%d", entryIndex);
|
|
|
254 |
continue;
|
|
|
255 |
}
|
|
|
256 |
|
|
|
257 |
indexEntry = item->text().toInt();
|
|
|
258 |
//qDebug("Processing: %d", ii);
|
|
|
259 |
|
|
|
260 |
item = tableWidget->item( ii, COL_NE );
|
|
|
261 |
if ( item )
|
|
|
262 |
{
|
|
|
263 |
if ( item->checkState() == Qt::Checked) {
|
|
|
264 |
|
|
|
265 |
item = tableWidget->item( ii, COL_WINNERS );
|
|
|
266 |
if (item && item->text().length() && item->text().toInt() ) {
|
|
|
267 |
tableWidget->item(ii,COL_WINNERS)->setBackground(*goldBrush);
|
|
|
268 |
tableWidget->item(ii,COL_WINNERS)->setToolTip(tip);
|
|
|
269 |
MainWindow::showMessage(tip);
|
|
|
270 |
} else {
|
|
|
271 |
tableWidget->item(ii,COL_WINNERS)->setBackground(Qt::transparent);
|
|
|
272 |
tableWidget->item(ii,COL_WINNERS)->setToolTip("");
|
|
|
273 |
|
|
|
274 |
}
|
|
|
275 |
|
|
|
276 |
item = tableWidget->item( ii, COL_NE_WINNERS );
|
|
|
277 |
if (item && item->text().length() && item->text().toInt() ) {
|
|
|
278 |
tableWidget->item(ii,COL_NE_WINNERS)->setBackground(*goldBrush);
|
|
|
279 |
tableWidget->item(ii,COL_NE_WINNERS)->setToolTip(tip);
|
|
|
280 |
MainWindow::showMessage(tip);
|
|
|
281 |
|
|
|
282 |
} else {
|
|
|
283 |
tableWidget->item(ii,COL_NE_WINNERS)->setBackground(Qt::transparent);
|
|
|
284 |
tableWidget->item(ii,COL_NE_WINNERS)->setToolTip("");
|
|
|
285 |
|
|
|
286 |
}
|
|
|
287 |
|
|
|
288 |
} else {
|
|
|
289 |
tableWidget->item(ii,COL_WINNERS)->setBackground(Qt::transparent);
|
|
|
290 |
tableWidget->item(ii,COL_WINNERS)->setToolTip("");
|
|
|
291 |
|
|
|
292 |
tableWidget->item(ii,COL_NE_WINNERS)->setBackground(Qt::transparent);
|
|
|
293 |
tableWidget->item(ii,COL_NE_WINNERS)->setToolTip("");
|
|
|
294 |
|
|
|
295 |
}
|
|
|
296 |
}
|
|
|
297 |
}
|
|
|
298 |
}
|
|
|
299 |
|
| 104 |
- |
300 |
void QmConfClass::save(void)
|
| 99 |
david |
301 |
{
|
| 104 |
- |
302 |
/*
|
|
|
303 |
** Copy original data
|
|
|
304 |
*/
|
| 176 |
- |
305 |
QmConfig newcfg(config);
|
| 104 |
- |
306 |
|
|
|
307 |
/*
|
|
|
308 |
** Extract the data from the Widgets
|
| 380 |
david |
309 |
** Trap: The Class info is cross ref by index into the table
|
|
|
310 |
** Thus we need to maintain the order in the config.
|
| 104 |
- |
311 |
*/
|
| 380 |
david |
312 |
for (int entryIndex = 0; entryIndex < tableWidget->rowCount(); entryIndex++)
|
| 104 |
- |
313 |
{
|
| 380 |
david |
314 |
|
|
|
315 |
// Check that this is a real Entry or the 'Totals' header
|
|
|
316 |
// Real rows have a COL_INDEX entry that is not empty
|
|
|
317 |
//
|
|
|
318 |
QTableWidgetItem *item = tableWidget->item ( entryIndex, COL_INDEX );
|
|
|
319 |
if (! item)
|
|
|
320 |
{
|
|
|
321 |
//qDebug("Ignore row:%d", entryIndex);
|
|
|
322 |
continue;
|
|
|
323 |
}
|
|
|
324 |
if ( item->text().length() == 0)
|
|
|
325 |
{
|
|
|
326 |
//qDebug("Ignore empty row:%d", entryIndex);
|
|
|
327 |
continue;
|
|
|
328 |
}
|
|
|
329 |
int ii = item->text().toInt();
|
|
|
330 |
//qDebug("Processing: %d", ii);
|
|
|
331 |
|
|
|
332 |
/*
|
|
|
333 |
** This is a new entry - allocate a new index
|
|
|
334 |
** Scan the entire available space looking for the first empty slot
|
|
|
335 |
*/
|
|
|
336 |
if (ii < 0)
|
|
|
337 |
{
|
|
|
338 |
for (ii = 0; ii < MAX_CLASS ; ii++)
|
|
|
339 |
{
|
|
|
340 |
if (newcfg.team_class[ii].abr[0] == 0)
|
|
|
341 |
{
|
|
|
342 |
break;
|
|
|
343 |
}
|
|
|
344 |
}
|
|
|
345 |
}
|
|
|
346 |
|
|
|
347 |
if (ii >= MAX_CLASS )
|
|
|
348 |
{
|
|
|
349 |
qDebug("Ignore row:%d. Class out of range", entryIndex);
|
|
|
350 |
continue;
|
|
|
351 |
}
|
|
|
352 |
|
|
|
353 |
item = tableWidget->item ( entryIndex, COL_ABR );
|
| 111 |
david |
354 |
if ( item )
|
|
|
355 |
{
|
|
|
356 |
strncpy(newcfg.team_class[ii].abr, qPrintable(item->text()), sizeof(newcfg.team_class[ii].abr)-1);
|
|
|
357 |
}
|
|
|
358 |
else
|
|
|
359 |
{
|
|
|
360 |
*newcfg.team_class[ii].abr = 0;
|
|
|
361 |
}
|
| 104 |
- |
362 |
|
| 380 |
david |
363 |
item = tableWidget->item ( entryIndex, COL_CLASS );
|
| 111 |
david |
364 |
if ( item )
|
|
|
365 |
{
|
|
|
366 |
strncpy(newcfg.team_class[ii].full_name, qPrintable(item->text()), sizeof(newcfg.team_class[ii].full_name)-1);
|
|
|
367 |
}
|
|
|
368 |
else
|
|
|
369 |
{
|
|
|
370 |
*newcfg.team_class[ii].full_name = 0;
|
|
|
371 |
}
|
| 108 |
david |
372 |
|
| 380 |
david |
373 |
item = tableWidget->item( entryIndex, COL_TIME );
|
| 111 |
david |
374 |
if ( item )
|
|
|
375 |
{
|
| 195 |
david |
376 |
QVariant data = item->data(Qt::EditRole);
|
|
|
377 |
if (data.isValid())
|
|
|
378 |
{
|
|
|
379 |
newcfg.team_class[ii].start = QTime(0,0,0).secsTo(item->data(Qt::EditRole).toTime());
|
|
|
380 |
}
|
|
|
381 |
else
|
|
|
382 |
{
|
|
|
383 |
newcfg.team_class[ii].start = -1;
|
|
|
384 |
}
|
| 111 |
david |
385 |
}
|
|
|
386 |
else
|
|
|
387 |
{
|
| 195 |
david |
388 |
newcfg.team_class[ii].start = -1;
|
| 111 |
david |
389 |
}
|
|
|
390 |
|
| 380 |
david |
391 |
item = tableWidget->item( entryIndex, COL_WINNERS );
|
| 111 |
david |
392 |
if ( item )
|
|
|
393 |
{
|
|
|
394 |
newcfg.class_winners[ii] = item->data(Qt::EditRole).toInt();
|
|
|
395 |
}
|
|
|
396 |
else
|
|
|
397 |
{
|
|
|
398 |
newcfg.class_winners[ii] = 0;
|
|
|
399 |
}
|
| 227 |
- |
400 |
|
| 380 |
david |
401 |
item = tableWidget->item( entryIndex, COL_NE );
|
| 181 |
- |
402 |
if ( item )
|
|
|
403 |
{
|
|
|
404 |
if ( item->checkState() == Qt::Checked)
|
|
|
405 |
{
|
|
|
406 |
newcfg.nonequestrian_class = ii;
|
|
|
407 |
strncpy(newcfg.nonequestrian_class_abr, newcfg.team_class[ii].abr, sizeof(newcfg.team_class[ii].abr)-1);
|
|
|
408 |
}
|
|
|
409 |
}
|
| 227 |
- |
410 |
|
| 380 |
david |
411 |
item = tableWidget->item( entryIndex, COL_NE_WINNERS );
|
| 227 |
- |
412 |
if ( item )
|
|
|
413 |
{
|
|
|
414 |
newcfg.class_ne_winners[ii] = item->data(Qt::EditRole).toInt();
|
|
|
415 |
}
|
|
|
416 |
else
|
|
|
417 |
{
|
|
|
418 |
newcfg.class_ne_winners[ii] = 0;
|
|
|
419 |
}
|
| 104 |
- |
420 |
}
|
|
|
421 |
|
| 181 |
- |
422 |
// Validate the data
|
|
|
423 |
try
|
| 104 |
- |
424 |
{
|
| 181 |
- |
425 |
MainWindow::showMessage( "Saving Config");
|
| 104 |
- |
426 |
|
| 181 |
- |
427 |
/*
|
|
|
428 |
** Now do the Class definitions
|
|
|
429 |
*/
|
|
|
430 |
|
|
|
431 |
for( int i = 0; i < MAX_CLASS; i++ )
|
| 104 |
- |
432 |
{
|
| 181 |
- |
433 |
compact( newcfg.team_class[i].abr );
|
|
|
434 |
compact( newcfg.team_class[i].full_name );
|
| 104 |
- |
435 |
}
|
| 181 |
- |
436 |
|
|
|
437 |
for( int i = 0; i < MAX_CLASS; i++ )
|
| 104 |
- |
438 |
{
|
| 181 |
- |
439 |
if( ( newcfg.team_class[i].abr[0] == '\0' ) != ( newcfg.team_class[i].full_name[0] == '\0' ) )
|
|
|
440 |
{
|
|
|
441 |
throw( "Configuration error. Class without description" );
|
|
|
442 |
|
|
|
443 |
}
|
|
|
444 |
if( newcfg.team_class[i].abr[0] != '\0' && newcfg.team_class[i].start < 0L )
|
|
|
445 |
{
|
|
|
446 |
throw( "Configuration error. Bad start time on class" );
|
|
|
447 |
|
|
|
448 |
}
|
| 104 |
- |
449 |
}
|
|
|
450 |
|
| 380 |
david |
451 |
// Calculate new max number of classes
|
|
|
452 |
// Scan from the end looking for the last one used
|
|
|
453 |
//
|
|
|
454 |
for (int i = MAX_CLASS-1; i >= 0; i--)
|
|
|
455 |
{
|
|
|
456 |
if (newcfg.team_class[i].abr[0])
|
|
|
457 |
{
|
|
|
458 |
//qDebug("num_class:%d -> %d", newcfg.num_class, 1+i);
|
|
|
459 |
newcfg.num_class = 1 + i;
|
|
|
460 |
break;
|
|
|
461 |
}
|
|
|
462 |
}
|
| 104 |
- |
463 |
|
| 181 |
- |
464 |
for( int i = newcfg.num_class; i < MAX_CLASS; i++ )
|
|
|
465 |
if( newcfg.team_class[i].full_name[0] )
|
|
|
466 |
{
|
| 380 |
david |
467 |
qDebug( "Configuration error: Missing Class name. Gaps not allowed" );
|
| 181 |
- |
468 |
}
|
|
|
469 |
|
|
|
470 |
if( newcfg.num_class == 0 )
|
| 104 |
- |
471 |
{
|
| 181 |
- |
472 |
throw( "Error: No categories defined" );
|
|
|
473 |
|
| 104 |
- |
474 |
}
|
|
|
475 |
|
| 380 |
david |
476 |
/*
|
|
|
477 |
** Test for duplicate abbreviations
|
|
|
478 |
** I know its a slow agorithm, but its only a small set
|
|
|
479 |
*/
|
|
|
480 |
for( int i = 0; i < MAX_CLASS; i++ )
|
|
|
481 |
{
|
|
|
482 |
if (newcfg.team_class[i].abr[0] != '\0')
|
|
|
483 |
{
|
|
|
484 |
for (int j = i+1; j < MAX_CLASS; j++)
|
|
|
485 |
{
|
|
|
486 |
if (newcfg.team_class[j].abr[0] != '\0')
|
|
|
487 |
{
|
|
|
488 |
if ( newcfg.team_class[i].abr[0] == newcfg.team_class[j].abr[0]
|
|
|
489 |
&& newcfg.team_class[i].abr[1] == newcfg.team_class[j].abr[1]
|
|
|
490 |
)
|
|
|
491 |
{
|
|
|
492 |
qDebug("Duplicate abr: %s", newcfg.team_class[i].abr);
|
|
|
493 |
throw( "Error: Duplicate abbreviations detected");
|
|
|
494 |
}
|
|
|
495 |
}
|
|
|
496 |
}
|
|
|
497 |
}
|
|
|
498 |
}
|
|
|
499 |
|
|
|
500 |
/*
|
|
|
501 |
** Sanity Test
|
|
|
502 |
*/
|
| 181 |
- |
503 |
newcfg.nonequestrian_class = newcfg.lookup_class( newcfg.nonequestrian_class_abr );
|
|
|
504 |
if( newcfg.equestrian_leg && newcfg.nonequestrian_class == 0 )
|
|
|
505 |
MainWindow::showMessage( "WARNING: Non-equestrian class not found" );
|
| 380 |
david |
506 |
//qDebug("NE Index is: %d", newcfg.nonequestrian_class );
|
| 181 |
- |
507 |
/*
|
|
|
508 |
** Sanity test of the data
|
|
|
509 |
*/
|
|
|
510 |
for( int i = 0; i < MAX_CLASS; i++ )
|
|
|
511 |
{
|
|
|
512 |
if( newcfg.team_class[i].abr[0] != '\0' && newcfg.class_winners[i] == 0 )
|
|
|
513 |
{
|
| 380 |
david |
514 |
if (newcfg.nonequestrian_class != i+1)
|
|
|
515 |
{
|
|
|
516 |
MainWindow::showMessage(QString("Warning: Class without winners:")+ newcfg.team_class[i].abr);
|
|
|
517 |
}
|
| 181 |
- |
518 |
}
|
| 111 |
david |
519 |
}
|
|
|
520 |
|
| 227 |
- |
521 |
/*
|
|
|
522 |
** Cannot mix winners for NE class and NE Winners for each class
|
|
|
523 |
*/
|
|
|
524 |
if (newcfg.nonequestrian_class)
|
|
|
525 |
{
|
|
|
526 |
newcfg.class_ne_winners_by_class = false;
|
|
|
527 |
for( int i = 0; i < MAX_CLASS; i++ )
|
|
|
528 |
{
|
| 228 |
- |
529 |
if ( newcfg.class_ne_winners[i])
|
|
|
530 |
{
|
|
|
531 |
newcfg.class_ne_winners_by_class = true;
|
|
|
532 |
break;
|
|
|
533 |
}
|
| 227 |
- |
534 |
}
|
|
|
535 |
if (newcfg.class_winners[newcfg.nonequestrian_class - 1] && newcfg.class_ne_winners_by_class )
|
|
|
536 |
{
|
|
|
537 |
MainWindow::showMessage( QString("Should not mix NE winners by each class and by NE Class"));
|
|
|
538 |
//throw( "Error: Cannot mix NE winners by each class and by NE Class" );
|
|
|
539 |
}
|
|
|
540 |
}
|
|
|
541 |
|
|
|
542 |
|
| 104 |
- |
543 |
config = newcfg;
|
| 176 |
- |
544 |
config.write_config();
|
| 181 |
- |
545 |
updateChanged(false);
|
|
|
546 |
|
| 380 |
david |
547 |
// Force re-populate so that the index field is now correct
|
|
|
548 |
populate();
|
|
|
549 |
|
|
|
550 |
|
| 104 |
- |
551 |
}
|
| 181 |
- |
552 |
catch (const char * str )
|
|
|
553 |
{
|
|
|
554 |
MainWindow::showMessage(str);
|
|
|
555 |
}
|
| 104 |
- |
556 |
|
| 99 |
david |
557 |
}
|
|
|
558 |
|
| 104 |
- |
559 |
void QmConfClass::cancel(void)
|
| 99 |
david |
560 |
{
|
|
|
561 |
populate();
|
|
|
562 |
}
|
|
|
563 |
|
| 104 |
- |
564 |
QmConfClass::~QmConfClass()
|
| 95 |
david |
565 |
{
|
| 380 |
david |
566 |
|
| 95 |
david |
567 |
}
|
|
|
568 |
|
| 180 |
- |
569 |
void QmConfClass::ctxMenu(const QPoint & pos)
|
|
|
570 |
{
|
| 380 |
david |
571 |
//qDebug("Context Menu");
|
| 180 |
- |
572 |
QMenu *menu = new QMenu;
|
|
|
573 |
menu->addAction(tr("New Category"), this, SLOT(ctxMenuAddRow()));
|
| 380 |
david |
574 |
|
|
|
575 |
/*
|
|
|
576 |
** Determine if we can delete an item
|
|
|
577 |
** Can delete a category we added in this session
|
|
|
578 |
** Can delete one if it has no teams using it.
|
|
|
579 |
*/
|
|
|
580 |
QTableWidgetItem *item = tableWidget->itemAt(pos);
|
| 180 |
- |
581 |
if (item)
|
|
|
582 |
{
|
| 380 |
david |
583 |
int row = item->row();
|
|
|
584 |
//qDebug("Item is at row:%d", row);
|
|
|
585 |
QTableWidgetItem *indexItem = tableWidget->item ( row, COL_INDEX );
|
|
|
586 |
if (indexItem)
|
|
|
587 |
{
|
|
|
588 |
int index = indexItem->text().toInt();
|
|
|
589 |
//qDebug("Item is at row:%d, Index: %d", row, index);
|
|
|
590 |
if (index < 0)
|
|
|
591 |
{
|
|
|
592 |
menu->addAction(tr("Delete Newly added Category"), this, SLOT(ctxMenuDeleteRow()));
|
|
|
593 |
}
|
|
|
594 |
else
|
|
|
595 |
{
|
|
|
596 |
QTableWidgetItem *itemTotalCount = tableWidget->item ( row, COL_ST_TOTAL );
|
|
|
597 |
if (itemTotalCount)
|
|
|
598 |
{
|
|
|
599 |
int count = itemTotalCount->text().toInt();
|
|
|
600 |
if (count == 0)
|
|
|
601 |
{
|
|
|
602 |
menu->addAction(tr("Delete Category - its not used"), this, SLOT(ctxMenuDeleteRow()));
|
|
|
603 |
}
|
|
|
604 |
}
|
|
|
605 |
|
|
|
606 |
}
|
|
|
607 |
}
|
| 180 |
- |
608 |
}
|
| 380 |
david |
609 |
menu->exec(tableWidget->mapToGlobal(pos));
|
| 180 |
- |
610 |
}
|
|
|
611 |
|
|
|
612 |
void QmConfClass::ctxMenuDeleteRow(void)
|
|
|
613 |
{
|
| 380 |
david |
614 |
//
|
|
|
615 |
// Assume that if the menu was shown, then we can delete it
|
|
|
616 |
//
|
|
|
617 |
//qDebug ("DELETE ROW: %d", tableWidget->currentRow () );
|
|
|
618 |
//tableWidget->removeCellWidget(tableWidget->currentRow (), COL_ABR);
|
|
|
619 |
//tableWidget->removeRow(tableWidget->currentRow ());
|
|
|
620 |
tableWidget->item(tableWidget->currentRow (), COL_ABR)->setText("");
|
|
|
621 |
tableWidget->item(tableWidget->currentRow (), COL_CLASS)->setText("");
|
|
|
622 |
tableWidget->hideRow(tableWidget->currentRow ());
|
| 189 |
- |
623 |
updateChanged(true);
|
| 180 |
- |
624 |
}
|
|
|
625 |
|
|
|
626 |
void QmConfClass::ctxMenuAddRow(void)
|
|
|
627 |
{
|
| 380 |
david |
628 |
tableWidget->setSortingEnabled(false);
|
|
|
629 |
tableWidget->setRowCount( 1+ tableWidget->rowCount());
|
| 180 |
- |
630 |
|
| 380 |
david |
631 |
/*
|
|
|
632 |
** Insert non-editable fields in the status part of the table
|
|
|
633 |
*/
|
|
|
634 |
tableWidget->setItem(tableWidget->rowCount() - 1, COL_INDEX, new qmTwiNumber(-1));
|
|
|
635 |
for (int ii= COL_ST_TOTAL; ii < COL_INDEX; ii++)
|
| 180 |
- |
636 |
{
|
| 380 |
david |
637 |
tableWidget->setItem(tableWidget->rowCount() - 1, ii, new qmTwiString(""));
|
| 180 |
- |
638 |
}
|
|
|
639 |
}
|
|
|
640 |
|
| 181 |
- |
641 |
void QmConfClass::cellChanged(int row,int col)
|
|
|
642 |
{
|
|
|
643 |
if ( populating )
|
|
|
644 |
return;
|
| 380 |
david |
645 |
if (col == COL_INDEX)
|
|
|
646 |
return;
|
|
|
647 |
|
|
|
648 |
updateChanged(true);
|
| 181 |
- |
649 |
populating = true;
|
|
|
650 |
//qDebug("Cell changed: %d, %d", row, col);
|
| 227 |
- |
651 |
if (col == COL_NE)
|
| 181 |
- |
652 |
{
|
| 380 |
david |
653 |
for (int ii = 0; ii < tableWidget->rowCount(); ii++)
|
| 181 |
- |
654 |
{
|
| 380 |
david |
655 |
QTableWidgetItem *item = tableWidget->item(ii, COL_NE);
|
| 181 |
- |
656 |
if (item)
|
|
|
657 |
{
|
|
|
658 |
item->setCheckState(ii == row ? Qt::Checked : Qt::Unchecked);
|
|
|
659 |
}
|
|
|
660 |
}
|
|
|
661 |
}
|
| 380 |
david |
662 |
|
|
|
663 |
// Highlight wonky config
|
|
|
664 |
if (col == COL_NE || col == COL_NE_WINNERS || col == COL_WINNERS) {
|
|
|
665 |
checkNeClass();
|
|
|
666 |
}
|
|
|
667 |
|
| 181 |
- |
668 |
populating = false;
|
|
|
669 |
}
|
|
|
670 |
|
|
|
671 |
void QmConfClass::updateChanged(bool newDirty)
|
|
|
672 |
{
|
|
|
673 |
if (newDirty != dirty)
|
|
|
674 |
{
|
|
|
675 |
dirty = newDirty;
|
|
|
676 |
if (dirty)
|
|
|
677 |
{
|
| 380 |
david |
678 |
pushButtonSave->setEnabled(true);
|
|
|
679 |
pushButtonSave->setStyleSheet("background-color: rgb(255, 0, 0);");
|
| 181 |
- |
680 |
}
|
|
|
681 |
else
|
|
|
682 |
{
|
| 380 |
david |
683 |
pushButtonSave->setEnabled(false);
|
|
|
684 |
pushButtonSave->setStyleSheet("");
|
| 181 |
- |
685 |
}
|
|
|
686 |
}
|
|
|
687 |
}
|
|
|
688 |
|
| 104 |
- |
689 |
void QmConfClass::changeEvent(QEvent *e)
|
| 95 |
david |
690 |
{
|
|
|
691 |
QWidget::changeEvent(e);
|
|
|
692 |
switch (e->type()) {
|
| 380 |
david |
693 |
|
| 95 |
david |
694 |
default:
|
|
|
695 |
break;
|
|
|
696 |
}
|
|
|
697 |
}
|