~ubuntu-branches/ubuntu/vivid/qgo/vivid-proposed

« back to all changes in this revision

Viewing changes to src/network/gamedialog.cpp

  • Committer: Package Import Robot
  • Author(s): Yann Dirson
  • Date: 2012-05-19 19:05:05 UTC
  • mfrom: (1.1.12)
  • Revision ID: package-import@ubuntu.com-20120519190505-b23f5tzx7y8cu946
Tags: 2~svn764-1
* The "Raise dead" release (Closes: #673520), new maintainer.
* New upstream snapshot with Qt4 support (Closes: #604589), adjusted
  build-deps.
* Switched to source format "3.0 (quilt)", adjusted build-deps.
* Switched to dh and debhelper compat level 9, adjusted build-deps.
* Build with -fpermissive.
* New build-dep libasound2-dev, remove obsolete build-dep on libxinerama-dev.
* Refreshed patches 01_gnugo and 04_desktop, leaving 20_kfreebsd away
  for this release, and removing the remaining ones, now obsolete.
* Added patch 02_usrgames for FHS-correct install location.
* Adjusted icon names in menu file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   Copyright (C) 2009 by The qGo Project                                 *
 
3
 *                                                                         *
 
4
 *   This file is part of qGo.                                             *
 
5
 *                                                                         *
 
6
 *   qGo is free software: you can redistribute it and/or modify           *
 
7
 *   it under the terms of the GNU General Public License as published by  *
 
8
 *   the Free Software Foundation; either version 2 of the License, or     *
 
9
 *   (at your option) any later version.                                   *
 
10
 *                                                                         *
 
11
 *   This program is distributed in the hope that it will be useful,       *
 
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 
14
 *   GNU General Public License for more details.                          *
 
15
 *                                                                         *
 
16
 *   You should have received a copy of the GNU General Public License     *
 
17
 *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
 
18
 *   or write to the Free Software Foundation, Inc.,                       *
 
19
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 
20
 ***************************************************************************/
 
21
 
 
22
 
 
23
#include "gamedialog.h"
 
24
#include "audio.h"
 
25
 
 
26
#include "defines.h"
 
27
//#include "komispinbox.h"
 
28
#include "network/networkconnection.h"
 
29
#include "network/messages.h"
 
30
#include "network/gamedialogflags.h"
 
31
#include "network/playergamelistings.h"
 
32
 
 
33
 
 
34
GameDialog::GameDialog(NetworkConnection * conn, const PlayerListing & opp)
 
35
        : QDialog(), Ui::GameDialog(), connection(conn), opponent(opp)
 
36
{
 
37
        ui.setupUi(this);
 
38
        gameSound = SoundFactory::newSound(SOUND_PATH_PREFIX"blip.wav");
 
39
        
 
40
        setWindowTitle(tr("New Game"));
 
41
 
 
42
        have_suggestdata = false;
 
43
//      komiSpin->setValue(55);
 
44
//      buttonOffer->setFocus();
 
45
        komi_request = false;
 
46
        is_nmatch = false;
 
47
        offered_and_unrefused = false;
 
48
  
 
49
        dialog_changed = 0;
 
50
        clearChangedFlags();
 
51
        
 
52
        current_match_request = new MatchRequest();
 
53
        
 
54
        /* FIXME, what about size 38 and larger boards ?? */
 
55
        ui.boardSizeSpin->setRange(1,19);
 
56
        ui.handicapSpin->setRange(1,9);
 
57
        
 
58
        we_are_challenger = false;
 
59
        
 
60
        /* Not sure what to do with these.  It would make sense to
 
61
        * just have a number instead of a time spin since no seconds are
 
62
        * allowed in two of the settings... but it would probably be better
 
63
        * to set something on the timeSpin so that it still has the :00
 
64
        * seconds reminder.  Unless we want to have "seconds" in the text. */
 
65
        
 
66
        ui.boardSizeSpin->setValue(connection->gd_verifyBoardSize(preferences.default_size));
 
67
        ui.komiSpin->setValue(preferences.default_komi);
 
68
        
 
69
        ui.timeSpin->setDisplayFormat("h:mm:ss");
 
70
        ui.BYTimeSpin->setDisplayFormat("h:mm:ss");
 
71
        ui.timeSpin->setTime(connection->gd_checkMainTime(canadian, qtimeFromSeconds(preferences.default_stonesmaintime)));
 
72
        ui.stonesTimeSpin->setTime(connection->gd_checkPeriodTime(canadian, QTime(0, preferences.default_stonestime/60, preferences.default_stonestime%60)));
 
73
        ui.stonesSpin->setValue(connection->gd_checkPeriods(canadian, preferences.default_stones));
 
74
        ui.BYTimeSpin->setTime(connection->gd_checkMainTime(byoyomi, QTime(0, preferences.default_byomaintime/60, preferences.default_byomaintime%60)));
 
75
        ui.BYPeriodTimeSpin->setTime(connection->gd_checkPeriodTime(byoyomi, QTime(0, preferences.default_byoperiodtime/60, preferences.default_byoperiodtime%60)));
 
76
        ui.BYPeriodsSpin->setValue(connection->gd_checkPeriods(byoyomi, preferences.default_byoperiods));
 
77
        ui.ASIATimeSpin->setTime(connection->gd_checkMainTime(tvasia, QTime(0, preferences.default_asiamaintime/60, preferences.default_asiamaintime%60)));
 
78
        ui.ASIAPeriodTimeSpin->setTime(connection->gd_checkPeriodTime(tvasia, QTime(0, preferences.default_asiaperiodtime/60, preferences.default_asiaperiodtime%60)));
 
79
        ui.ASIAPeriodsSpin->setValue(connection->gd_checkPeriods(tvasia, preferences.default_asiaperiods));
 
80
        
 
81
//      cb_free->setChecked(true);
 
82
 
 
83
        connect(ui.buttonCancel,SIGNAL(pressed()), SLOT(slot_cancel()));
 
84
        connect(ui.buttonDecline,SIGNAL(pressed()), SLOT(slot_decline()));
 
85
        connect(ui.buttonOffer,SIGNAL(clicked(bool)),SLOT( slot_offer(bool)));
 
86
        //connect(ui.buttonStats,SIGNAL(pressed()), SLOT(slot_statsOpponent()));
 
87
 
 
88
        // in order to check if anything changes
 
89
        connect(ui.play_black_button, SIGNAL(clicked(bool)), SLOT(slot_play_black_button()));
 
90
        connect(ui.play_white_button, SIGNAL(clicked(bool)), SLOT(slot_play_white_button()));
 
91
        connect(ui.play_nigiri_button, SIGNAL(clicked(bool)), SLOT(slot_play_nigiri_button()));
 
92
        
 
93
        connect(ui.ratedCB, SIGNAL(clicked(bool)), SLOT(ratedCB_changed(bool)));
 
94
        connect(ui.boardSizeSpin, SIGNAL(valueChanged(int)), SLOT(slot_boardSizeSpin(int)));
 
95
        connect(ui.handicapSpin, SIGNAL(valueChanged(int)), SLOT(slot_handicapSpin(int)));
 
96
        connect(ui.komiSpin, SIGNAL(valueChanged(int)), SLOT(slot_komiSpin(int)));
 
97
        
 
98
        connect(ui.timeTab, SIGNAL(currentChanged(int)), SLOT(slot_timeTab(int)));
 
99
        // Does below need seconds or really only minutes??!?!? FIXME
 
100
        connect(ui.timeSpin, SIGNAL(timeChanged(const QTime &)), SLOT(slot_timeSpin(const QTime &)));   //weird that this isn't QTimeEdit!!!
 
101
        connect(ui.stonesTimeSpin, SIGNAL(timeChanged(const QTime &)), SLOT(slot_stonesTimeSpin(const QTime &)));
 
102
        connect(ui.stonesSpin, SIGNAL(valueChanged(int)), SLOT(slot_stonesSpin(int)));
 
103
        connect(ui.BYTimeSpin, SIGNAL(timeChanged(const QTime &)), SLOT(slot_BYTimeSpin(const QTime &)));
 
104
        connect(ui.BYPeriodTimeSpin, SIGNAL(timeChanged(const QTime &)), SLOT(slot_BYPeriodTimeSpin(const QTime &)));
 
105
        connect(ui.BYPeriodsSpin, SIGNAL(valueChanged(int)), SLOT(slot_BYPeriodsSpin(int)));
 
106
        connect(ui.ASIATimeSpin, SIGNAL(timeChanged(const QTime &)), SLOT(slot_ASIATimeSpin(const QTime &)));
 
107
        connect(ui.ASIAPeriodTimeSpin, SIGNAL(timeChanged(const QTime &)), SLOT(slot_ASIAPeriodTimeSpin(const QTime &)));
 
108
        connect(ui.ASIAPeriodsSpin, SIGNAL(valueChanged(int)), SLOT(slot_ASIAPeriodsSpin(int)));
 
109
}
 
110
 
 
111
void GameDialog::slot_play_black_button(void)
 
112
{
 
113
        if(current_match_request->color_request == MatchRequest::BLACK)
 
114
        {
 
115
                dialog_changed--;
 
116
                color_request_changed = false;
 
117
                if(dialog_changed == 0 && !current_match_request->first_offer)
 
118
                        ui.buttonOffer->setText(tr("Accept"));
 
119
        }
 
120
        else if(!color_request_changed)
 
121
        {
 
122
                dialog_changed++;
 
123
                color_request_changed = true;
 
124
                ui.buttonOffer->setText(tr("Offer"));
 
125
        }
 
126
        qDebug("play black: %d", dialog_changed);
 
127
        if(flags & GDF_NIGIRI_EVEN)
 
128
                ui.handicapSpin->setEnabled(true);
 
129
}
 
130
 
 
131
void GameDialog::slot_play_white_button(void)
 
132
{
 
133
        if(current_match_request->color_request == MatchRequest::WHITE)
 
134
        {
 
135
                dialog_changed--;
 
136
                color_request_changed = false;
 
137
                if(dialog_changed == 0 && !current_match_request->first_offer)
 
138
                        ui.buttonOffer->setText(tr("Accept"));
 
139
        }
 
140
        else
 
141
        {
 
142
                dialog_changed++;
 
143
                color_request_changed = true;
 
144
                ui.buttonOffer->setText(tr("Offer"));
 
145
        }
 
146
        qDebug("play white: %d", dialog_changed);
 
147
        if(flags & GDF_NIGIRI_EVEN)
 
148
                ui.handicapSpin->setEnabled(true);
 
149
}
 
150
 
 
151
void GameDialog::slot_play_nigiri_button(void)
 
152
{
 
153
        if(current_match_request->color_request == MatchRequest::NIGIRI)
 
154
        {
 
155
                dialog_changed--;
 
156
                color_request_changed = false;
 
157
                if(dialog_changed == 0 && !current_match_request->first_offer)
 
158
                        ui.buttonOffer->setText(tr("Accept"));
 
159
        }
 
160
        else
 
161
        {
 
162
                dialog_changed++;
 
163
                color_request_changed = true;
 
164
                ui.buttonOffer->setText(tr("Offer"));
 
165
        }
 
166
        qDebug("play nigiri: %d", dialog_changed);      
 
167
        if(flags & GDF_NIGIRI_EVEN)
 
168
        {
 
169
                ui.handicapSpin->setValue(0);
 
170
                ui.handicapSpin->setEnabled(false);
 
171
        }
 
172
}
 
173
 
 
174
void GameDialog::ratedCB_changed(bool checked)
 
175
{       
 
176
        if((current_match_request->free_rated == RATED) == checked)     //must have changed to get here
 
177
        {
 
178
                dialog_changed--;
 
179
                ratedchanged = false;
 
180
                if(dialog_changed == 0 && !current_match_request->first_offer)
 
181
                        ui.buttonOffer->setText(tr("Accept"));
 
182
        }
 
183
        else if(!ratedchanged)
 
184
        {
 
185
                dialog_changed++;
 
186
                ui.buttonOffer->setText(tr("Offer"));
 
187
                ratedchanged = true;
 
188
        }
 
189
        
 
190
        if(flags & GDF_RATED_SIZE_FIXED)
 
191
        {
 
192
                if(checked)
 
193
                {
 
194
                        qDebug("set disabled boardsize");
 
195
                        ui.boardSizeSpin->setValue(19);
 
196
                        ui.boardSizeSpin->setEnabled(false);
 
197
                }
 
198
                else if(!(flags & GDF_ONLY_DISPUTE_TIME))
 
199
                        ui.boardSizeSpin->setEnabled(true);
 
200
        }
 
201
        if(flags & GDF_RATED_HANDICAP_FIXED)
 
202
        {
 
203
                if(checked)
 
204
                {
 
205
                        // We need to actually calculate the proper handicap
 
206
                        // FIXME
 
207
                        // with tygem its either 0 or 1 !!, anything else
 
208
                        // is automatically friendly
 
209
                        //ui.boardSizeSpin->setValue(19);
 
210
                        //ui.boardSizeSpin->setEnabled(false);
 
211
                        //for now
 
212
                        ui.handicapSpin->setEnabled(false);
 
213
                }
 
214
                else if(!(flags & GDF_ONLY_DISPUTE_TIME))
 
215
                        ui.handicapSpin->setEnabled(true);
 
216
        }
 
217
        if(flags & GDF_RATED_NO_HANDICAP)
 
218
        {
 
219
                if(checked)
 
220
                {
 
221
                        PlayerListing us = connection->getOurListing();
 
222
                        getProperKomiHandicap(us.rank, opponent.rank, &(current_match_request->komi), &(current_match_request->handicap));
 
223
                        ui.handicapSpin->setValue(current_match_request->handicap);
 
224
                        ui.komiSpin->setValue((int)(current_match_request->komi - 0.5));        //.5 is added by dialog ui
 
225
                        ui.komiSpin->setEnabled(false);
 
226
                        ui.handicapSpin->setEnabled(false);
 
227
                }
 
228
                else if(!(flags & GDF_ONLY_DISPUTE_TIME))
 
229
                {
 
230
                        ui.komiSpin->setEnabled(true);
 
231
                        ui.handicapSpin->setEnabled(true);
 
232
                }
 
233
        }
 
234
}
 
235
 
 
236
void GameDialog::slot_boardSizeSpin(int value)
 
237
{
 
238
        int bs = connection->gd_verifyBoardSize(value);
 
239
        if(bs != value)
 
240
        {
 
241
                value = bs;
 
242
                ui.boardSizeSpin->setValue(value);
 
243
        }
 
244
        if((int)current_match_request->board_size == value)     //must have changed to get here
 
245
        {
 
246
                dialog_changed--;
 
247
                boardSizechanged = false;
 
248
                if(dialog_changed == 0 && !current_match_request->first_offer)
 
249
                        ui.buttonOffer->setText(tr("Accept"));
 
250
        }
 
251
        else if(!boardSizechanged)
 
252
        {
 
253
                dialog_changed++;
 
254
                ui.buttonOffer->setText(tr("Offer"));
 
255
                boardSizechanged = true;
 
256
        }
 
257
}
 
258
 
 
259
/* Be careful!! there's a 1/0 issue here FIXME */
 
260
void GameDialog::slot_handicapSpin(int value)
 
261
{
 
262
        if((int)current_match_request->handicap == value)       //must have changed to get here
 
263
        {
 
264
                dialog_changed--;
 
265
                handicapchanged = false;
 
266
                if(dialog_changed == 0 && !current_match_request->first_offer)
 
267
                        ui.buttonOffer->setText(tr("Accept"));
 
268
        }
 
269
        else if(!handicapchanged)
 
270
        {
 
271
                dialog_changed++;
 
272
                ui.buttonOffer->setText(tr("Offer"));
 
273
                handicapchanged = true;
 
274
        }
 
275
        if(flags & GDF_KOMI_FIXED6)
 
276
        {
 
277
                if(value == 0)
 
278
                        ui.komiSpin->setValue(6);
 
279
                else
 
280
                        ui.komiSpin->setValue(0);
 
281
                //already disabled
 
282
                //ui.komiSpin->setEnabled(false);
 
283
        }
 
284
        else
 
285
        {
 
286
                /* We do this anyway, its just not disabled so it can be changed after */
 
287
                if(value == 0)
 
288
                        ui.komiSpin->setValue(6);
 
289
                else
 
290
                        ui.komiSpin->setValue(0);
 
291
        }
 
292
}
 
293
 
 
294
void GameDialog::slot_komiSpin(int value)
 
295
{
 
296
        float komi = (float)value;
 
297
        if(komi < 0)
 
298
                komi -= 0.5;
 
299
        else
 
300
                komi += 0.5;
 
301
        if(current_match_request->komi == komi) //must have changed to get here
 
302
        {
 
303
                dialog_changed--;
 
304
                komichanged = false;
 
305
                if(dialog_changed == 0 && !current_match_request->first_offer)
 
306
                        ui.buttonOffer->setText(tr("Accept"));
 
307
        }
 
308
        else if(!komichanged)
 
309
        {
 
310
                dialog_changed++;
 
311
                ui.buttonOffer->setText(tr("Offer"));
 
312
                komichanged = true;
 
313
        }
 
314
}
 
315
 
 
316
void GameDialog::slot_timeTab(int value)
 
317
{
 
318
        TimeSystem t;
 
319
        switch(value)
 
320
        {
 
321
                case 0:
 
322
                        t = canadian;
 
323
                        break;
 
324
                case 1:
 
325
                        t = byoyomi;
 
326
                        break;
 
327
                case 2:
 
328
                        t = tvasia;
 
329
                        break;
 
330
                default:
 
331
                        t = none;
 
332
                        break;
 
333
        }
 
334
        if(current_match_request->timeSystem == t)      //must have changed to get here
 
335
        {
 
336
                dialog_changed--;
 
337
                ttchanged = false;
 
338
                if(dialog_changed == 0 && !current_match_request->first_offer)
 
339
                        ui.buttonOffer->setText(tr("Accept"));
 
340
        }
 
341
        else if(!ttchanged)
 
342
        {
 
343
                dialog_changed++;
 
344
                ui.buttonOffer->setText(tr("Offer"));
 
345
                ttchanged = true;
 
346
        }
 
347
}
 
348
 
 
349
void GameDialog::slot_timeSpin(const QTime & v)
 
350
{
 
351
        //can't have seconds... ?
 
352
        //if(v.seconds() > 0)
 
353
        //      ui.timeSpin->setTime(QTime(v.minutes(), 0);
 
354
        QTime check = connection->gd_checkMainTime(canadian, v);
 
355
        if(check != v)
 
356
        {
 
357
                ui.timeSpin->blockSignals(true);
 
358
                ui.timeSpin->setTime(check);
 
359
                ui.timeSpin->blockSignals(false);
 
360
        }
 
361
        /*if(current_match_request->timeSystem == canadian)
 
362
        {*/
 
363
                int seconds = timeToSeconds(v);
 
364
                if(current_match_request->maintime == seconds)
 
365
                {
 
366
                        dialog_changed--;
 
367
                        timechanged = false;
 
368
                        if(dialog_changed == 0 && !current_match_request->first_offer)
 
369
                                ui.buttonOffer->setText(tr("Accept"));
 
370
                }
 
371
                else if(!timechanged)
 
372
                {
 
373
                        dialog_changed++;
 
374
                        ui.buttonOffer->setText(tr("Offer"));
 
375
                        timechanged = true;
 
376
                }
 
377
        //}
 
378
}
 
379
 
 
380
void GameDialog::slot_stonesTimeSpin(const QTime & v)
 
381
{
 
382
        QTime check = connection->gd_checkPeriodTime(canadian, v);
 
383
        if(check != v)
 
384
        {
 
385
                ui.stonesTimeSpin->blockSignals(true);
 
386
                ui.stonesTimeSpin->setTime(check);
 
387
                ui.stonesTimeSpin->blockSignals(false);
 
388
        }
 
389
        if(current_match_request->timeSystem == canadian)
 
390
        {
 
391
                int seconds = timeToSeconds(check);
 
392
                if(current_match_request->periodtime == seconds)
 
393
                {
 
394
                        dialog_changed--;
 
395
                        if(dialog_changed == 0 && !current_match_request->first_offer)
 
396
                                ui.buttonOffer->setText(tr("Accept"));
 
397
                        stonesTimechanged = false;
 
398
                }
 
399
                else if(!stonesTimechanged)
 
400
                {
 
401
                        dialog_changed++;
 
402
                        ui.buttonOffer->setText(tr("Offer"));
 
403
                        stonesTimechanged = true;
 
404
                }
 
405
        }
 
406
}
 
407
 
 
408
void GameDialog::slot_stonesSpin(int v)
 
409
{
 
410
        unsigned int check = connection->gd_checkPeriods(canadian, v);
 
411
        if(check != (unsigned)v)
 
412
        {
 
413
                ui.stonesSpin->blockSignals(true);
 
414
                ui.stonesSpin->setValue(check);
 
415
                ui.stonesSpin->blockSignals(false);
 
416
        }
 
417
        if(current_match_request->timeSystem == canadian)
 
418
        {
 
419
                if(current_match_request->stones_periods == v)
 
420
                {
 
421
                        dialog_changed--;
 
422
                        stoneschanged = false;
 
423
                        if(dialog_changed == 0 && !current_match_request->first_offer)
 
424
                                ui.buttonOffer->setText(tr("Accept"));
 
425
                }
 
426
                else if(!stoneschanged)
 
427
                {
 
428
                        dialog_changed++;
 
429
                        ui.buttonOffer->setText(tr("Offer"));
 
430
                        stoneschanged = true;
 
431
                }
 
432
        }
 
433
}
 
434
 
 
435
void GameDialog::slot_BYTimeSpin(const QTime & v)
 
436
{
 
437
        QTime check = connection->gd_checkMainTime(byoyomi, v);
 
438
        if(check != v)
 
439
        {
 
440
                ui.BYTimeSpin->blockSignals(true);
 
441
                ui.BYTimeSpin->setTime(check);
 
442
                ui.BYTimeSpin->blockSignals(false);
 
443
        }
 
444
        if(current_match_request->timeSystem == byoyomi)
 
445
        {
 
446
                int seconds = timeToSeconds(v);
 
447
                if(current_match_request->maintime == seconds)
 
448
                {
 
449
                        dialog_changed--;
 
450
                        timechanged = false;
 
451
                        if(dialog_changed == 0 && !current_match_request->first_offer)
 
452
                                ui.buttonOffer->setText(tr("Accept"));
 
453
                }
 
454
                else if(!timechanged)
 
455
                {
 
456
                        dialog_changed++;
 
457
                        timechanged = true;
 
458
                        ui.buttonOffer->setText(tr("Offer"));
 
459
                }
 
460
        }
 
461
}
 
462
 
 
463
void GameDialog::slot_BYPeriodTimeSpin(const QTime & v)
 
464
{
 
465
        QTime check = connection->gd_checkPeriodTime(byoyomi, v);
 
466
        if(check != v)
 
467
        {
 
468
                ui.BYPeriodTimeSpin->blockSignals(true);
 
469
                ui.BYPeriodTimeSpin->setTime(check);
 
470
                ui.BYPeriodTimeSpin->blockSignals(false);
 
471
        }
 
472
        if(current_match_request->timeSystem == byoyomi)
 
473
        {
 
474
                int seconds = timeToSeconds(v);
 
475
                if(current_match_request->periodtime == seconds)
 
476
                {
 
477
                        dialog_changed--;
 
478
                        BYPeriodTimechanged = false;
 
479
                        if(dialog_changed == 0 && !current_match_request->first_offer)
 
480
                                ui.buttonOffer->setText(tr("Accept"));
 
481
                }
 
482
                else if(!BYPeriodTimechanged)
 
483
                {
 
484
                        dialog_changed++;
 
485
                        ui.buttonOffer->setText(tr("Offer"));
 
486
                        BYPeriodTimechanged = true;
 
487
                }
 
488
        }
 
489
}
 
490
 
 
491
void GameDialog::slot_BYPeriodsSpin(int v)
 
492
{
 
493
        unsigned int check = connection->gd_checkPeriods(byoyomi, v);
 
494
        if(check != (unsigned)v)
 
495
        {
 
496
                ui.BYPeriodsSpin->blockSignals(true);
 
497
                ui.BYPeriodsSpin->setValue(check);
 
498
                ui.BYPeriodsSpin->blockSignals(false);
 
499
        }
 
500
        if(current_match_request->timeSystem == byoyomi)
 
501
        {
 
502
                if(current_match_request->stones_periods == v)
 
503
                {
 
504
                        dialog_changed--;
 
505
                        BYPeriodschanged = false;
 
506
                        if(dialog_changed == 0 && !current_match_request->first_offer)
 
507
                                ui.buttonOffer->setText(tr("Accept"));
 
508
                }
 
509
                else if(!BYPeriodschanged)
 
510
                {
 
511
                        dialog_changed++;
 
512
                        ui.buttonOffer->setText(tr("Offer"));
 
513
                        BYPeriodschanged = true;
 
514
                }
 
515
        }
 
516
}
 
517
 
 
518
void GameDialog::slot_ASIATimeSpin(const QTime & v)
 
519
{
 
520
        QTime check = connection->gd_checkMainTime(tvasia, v);
 
521
        if(check != v)
 
522
        {
 
523
                ui.ASIATimeSpin->blockSignals(true);
 
524
                ui.ASIATimeSpin->setTime(check);
 
525
                ui.ASIATimeSpin->blockSignals(false);
 
526
        }
 
527
        if(current_match_request->timeSystem == tvasia)
 
528
        {
 
529
                int seconds = timeToSeconds(v);
 
530
                if(current_match_request->maintime == seconds)
 
531
                {
 
532
                        dialog_changed--;
 
533
                        ASIATimechanged = false;
 
534
                        if(dialog_changed == 0 && !current_match_request->first_offer)
 
535
                                ui.buttonOffer->setText(tr("Accept"));
 
536
                }
 
537
                else if(!ASIATimechanged)
 
538
                {
 
539
                        dialog_changed++;
 
540
                        ui.buttonOffer->setText(tr("Offer"));
 
541
                        ASIATimechanged = true;
 
542
                }
 
543
        }
 
544
}
 
545
 
 
546
void GameDialog::slot_ASIAPeriodTimeSpin(const QTime & v)
 
547
{
 
548
        QTime check = connection->gd_checkPeriodTime(tvasia, v);
 
549
        if(check != v)
 
550
        {
 
551
                ui.ASIAPeriodTimeSpin->blockSignals(true);
 
552
                ui.ASIAPeriodTimeSpin->setTime(check);
 
553
                ui.ASIAPeriodTimeSpin->blockSignals(false);
 
554
        }
 
555
        if(current_match_request->timeSystem == tvasia)
 
556
        {
 
557
                int seconds = timeToSeconds(v);
 
558
                if(current_match_request->periodtime == seconds)
 
559
                {
 
560
                        dialog_changed--;
 
561
                        ASIAPeriodTimechanged = false;
 
562
                        if(dialog_changed == 0 && !current_match_request->first_offer)
 
563
                                ui.buttonOffer->setText(tr("Accept"));
 
564
                }
 
565
                else if(!ASIAPeriodTimechanged)
 
566
                {
 
567
                        dialog_changed++;
 
568
                        ui.buttonOffer->setText(tr("Offer"));
 
569
                        ASIAPeriodTimechanged = true;
 
570
                }
 
571
        }
 
572
}
 
573
 
 
574
void GameDialog::slot_ASIAPeriodsSpin(int v)
 
575
{
 
576
        unsigned int check = connection->gd_checkPeriods(tvasia, v);
 
577
        if(check != (unsigned)v)
 
578
        {
 
579
                ui.ASIAPeriodsSpin->blockSignals(true);
 
580
                ui.ASIAPeriodsSpin->setValue(check);
 
581
                ui.ASIAPeriodsSpin->blockSignals(false);
 
582
        }
 
583
        if(current_match_request->timeSystem == tvasia)
 
584
        {
 
585
                if(current_match_request->stones_periods == v)
 
586
                {
 
587
                        dialog_changed--;
 
588
                        ASIAPeriodschanged = false;
 
589
                        if(dialog_changed == 0 && !current_match_request->first_offer)
 
590
                                ui.buttonOffer->setText(tr("Accept"));
 
591
                }
 
592
                else if(!ASIAPeriodschanged)
 
593
                {
 
594
                        dialog_changed++;
 
595
                        ui.buttonOffer->setText(tr("Offer"));
 
596
                        ASIAPeriodschanged = true;
 
597
                }
 
598
        }
 
599
}       
 
600
 
 
601
void GameDialog::clearChangedFlags(void)
 
602
{       
 
603
        if(dialog_changed != 10000)     //for offers
 
604
                dialog_changed = 0;
 
605
        color_request_changed = false;
 
606
        ratedchanged = false;
 
607
        boardSizechanged = false;
 
608
        handicapchanged = false;
 
609
        komichanged = false;
 
610
        ttchanged = false;
 
611
        timechanged = false;
 
612
        stonesTimechanged = false;
 
613
        stoneschanged = false;
 
614
        BYPeriodTimechanged = false;
 
615
        BYPeriodschanged = false;
 
616
        ASIATimechanged = false;
 
617
        ASIAPeriodTimechanged = false;
 
618
        ASIAPeriodschanged = false;
 
619
}
 
620
 
 
621
GameDialog::~GameDialog()
 
622
{
 
623
        qDebug("deconstructing GameDialog");
 
624
        delete current_match_request;
 
625
}
 
626
 
 
627
void GameDialog::closeEvent(QCloseEvent *)
 
628
{
 
629
        qDebug("GameDialog::closeEvent");
 
630
        if(connection)
 
631
                connection->closeGameDialog(opponent);
 
632
}
 
633
 
 
634
/*
 
635
void GameDialog::slot_opponentopen(const QString &opp)
 
636
{
 
637
        qDebug("#### GameDialog::slot_opponentopen()");
 
638
        if (playerOpponentEdit->text() != opp)//(playerWhiteEdit->isReadOnly() && playerBlackEdit->text() != opp ||         playerBlackEdit->isReadOnly() && playerWhiteEdit->text() != opp)
 
639
            // not for me
 
640
            return;
 
641
 
 
642
        QString me;
 
643
        QString opponent = playerOpponentEdit->text();;
 
644
        // send match command, send tell:
 
645
 
 
646
        // 24 *xxxx*: CLIENT: <qGo 1.9.12> match xxxx wants handicap 0, komi 0.5[, free]
 
647
        // this command is not part of server preferences "use Komi" and "auto negotiation"
 
648
        QString send = "tell " + opponent + " CLIENT: <qGo " + VERSION + "> match " +
 
649
                me + " wants handicap " + ui.handicapSpin->text() + ", komi " +
 
650
                komiSpin->text();
 
651
        if (ComboBox_free->currentText() == QString(tr("yes")))
 
652
                send += ", free";
 
653
 
 
654
        emit signal_sendcommand(send, false);
 
655
}
 
656
*/
 
657
 
 
658
 
 
659
/* This is used for offering and accepting */
 
660
void GameDialog::slot_offer(bool active)
 
661
{
 
662
        qDebug("#### GameDialog::slot_offer()");
 
663
        // active serves for more in the future...
 
664
        // to clarify: active means the button is down and client is
 
665
        // waiting on server response to offer
 
666
        if (!active)
 
667
        {
 
668
                qDebug("Not sending game offer, already active");
 
669
                ui.buttonOffer->setChecked(true);       //since we just unchecked it
 
670
                return;
 
671
        }
 
672
        
 
673
        offered_and_unrefused = true;
 
674
        save_to_preferences();
 
675
        if(!dialog_changed)
 
676
        {
 
677
                if(current_match_request->first_offer)
 
678
                        connection->sendMatchRequest(current_match_request);
 
679
                else
 
680
                        connection->acceptMatchOffer(opponent, current_match_request);
 
681
                qDebug("Match request unchanged\n");
 
682
                return;
 
683
        }
 
684
        // if both names are identical -> teaching game
 
685
        if (ui.playerOpponentEdit->text() == myName)
 
686
        {
 
687
                /* FIXME I'm sure this teaching stuff is going to be buggy */
 
688
                emit signal_sendCommand("teach " + ui.boardSizeSpin->text(), false);
 
689
                // prepare for future use...
 
690
                //ui.buttonOffer->setDown(false);
 
691
                ui.buttonOffer->setChecked(false);
 
692
                ui.buttonDecline->setDisabled(true);
 
693
                ui.buttonCancel->setEnabled(true);
 
694
                ui.buttonOffer->setText(tr("Offer"));
 
695
 
 
696
                //emit accept();
 
697
                connection->acceptMatchOffer(opponent, current_match_request);
 
698
                return;
 
699
        }
 
700
 
 
701
        // send match command
 
702
        // below nigiri shouldn't be checked if not possible
 
703
        if (ui.play_white_button->isChecked())
 
704
        {
 
705
                current_match_request->color_request = MatchRequest::WHITE;
 
706
                //FIXME maybe check here if we're the challenger??? 
 
707
                //current_match_request->challenger_is_black = 0;
 
708
        }
 
709
        else if(ui.play_black_button->isChecked())
 
710
        {
 
711
                current_match_request->color_request = MatchRequest::BLACK;
 
712
                //current_match_request->challenger_is_black = 1;
 
713
        }
 
714
        else if (ui.play_nigiri_button->isChecked() /*&& is_nmatch*/)   //what is this nmatch stuff ??? FIXME
 
715
        {
 
716
                current_match_request->color_request = MatchRequest::NIGIRI;
 
717
                //current_match_request->challenger_is_black = 0;
 
718
        }
 
719
        if(ui.ratedCB->isChecked())
 
720
                current_match_request->free_rated = RATED;
 
721
        else
 
722
                current_match_request->free_rated = FREE;
 
723
        current_match_request->board_size = ui.boardSizeSpin->value();
 
724
        qDebug("bs value: %d", current_match_request->board_size);
 
725
        current_match_request->handicap = ui.handicapSpin->cleanText().toInt();
 
726
        current_match_request->komi = (float)ui.komiSpin->value();
 
727
        if(current_match_request->komi > 0)
 
728
                current_match_request->komi += 0.5;
 
729
        else
 
730
                current_match_request->komi -= 0.5;
 
731
        /* According to ui form, there's only two time fields and according to existing code
 
732
         * and IGS parser code, there's only canadian time... so we'll go with that for now. 
 
733
         * I am now certain that "nmatch" means byoyomi according to IGS... so why
 
734
         * the comment below: "25 stones_periods hard coded: bad ??? FIXME */
 
735
        if(ui.timeTab->currentIndex() == 0)     //canadian or is it in IGS???
 
736
        {
 
737
                //FIXME, really its nmatch for IGS if we support nmatch and
 
738
                //opponent does as well
 
739
                //current_match_request->nmatch = false;
 
740
                current_match_request->nmatch = true;
 
741
                current_match_request->maintime = timeToSeconds(ui.timeSpin->time());
 
742
                current_match_request->periodtime = (ui.stonesTimeSpin->time().minute() * 60);
 
743
                current_match_request->periodtime += ui.stonesTimeSpin->time().second();
 
744
                current_match_request->stones_periods = ui.stonesSpin->value();
 
745
                current_match_request->timeSystem = canadian;
 
746
        }
 
747
        else if(ui.timeTab->currentIndex() == 1)        //byo yomi IGS nmatch
 
748
        {
 
749
                current_match_request->nmatch = true;
 
750
                current_match_request->maintime = timeToSeconds(ui.BYTimeSpin->time());
 
751
                if(!(flags & GDF_BY_CAN_MAIN_MIN))      //ugly FIXME
 
752
                        current_match_request->maintime += ui.BYTimeSpin->time().second();
 
753
                current_match_request->periodtime = (ui.BYPeriodTimeSpin->time().minute() * 60);
 
754
                current_match_request->periodtime += ui.BYPeriodTimeSpin->time().second();
 
755
                current_match_request->stones_periods = ui.BYPeriodsSpin->value();
 
756
                current_match_request->timeSystem = byoyomi;
 
757
        }
 
758
        else if(ui.timeTab->currentIndex() == 2)        //tv asia, ORO
 
759
        {
 
760
                current_match_request->maintime = timeToSeconds(ui.ASIATimeSpin->time());
 
761
                /* We can have more than 60 seconds... like 300 FIXME */
 
762
                //current_match_request->maintime = (ui.ASIATimeSpin->time().minute() * 60);
 
763
                //current_match_request->maintime += ui.ASIATimeSpin->time().second();
 
764
                current_match_request->periodtime = (ui.ASIAPeriodTimeSpin->time().minute() * 60);
 
765
                current_match_request->periodtime += ui.ASIAPeriodTimeSpin->time().second();
 
766
                current_match_request->stones_periods = ui.ASIAPeriodsSpin->value();
 
767
                current_match_request->timeSystem = tvasia;
 
768
        }
 
769
                
 
770
        qDebug("Match request changed %d\n", dialog_changed);
 
771
        connection->sendMatchRequest(current_match_request);
 
772
        /* FIXME
 
773
         * I'm pretty sure that we want to SetPalette on all the mutable ui
 
774
         * elements to the app default when we hit offer. But we should
 
775
         * double check this behavior, see if it makes sense.*/
 
776
        ui.boardSizeSpin->setPalette(QApplication::palette());
 
777
        ui.komiSpin->setPalette(QApplication::palette());
 
778
        ui.handicapSpin->setPalette(QApplication::palette());
 
779
        ui.timeSpin->setPalette(QApplication::palette());
 
780
        ui.stonesTimeSpin->setPalette(QApplication::palette());
 
781
        ui.stonesSpin->setPalette(QApplication::palette());
 
782
        ui.BYTimeSpin->setPalette(QApplication::palette());
 
783
        ui.BYPeriodTimeSpin->setPalette(QApplication::palette());
 
784
        ui.BYPeriodsSpin->setPalette(QApplication::palette());
 
785
        ui.ASIATimeSpin->setPalette(QApplication::palette());
 
786
        ui.ASIAPeriodTimeSpin->setPalette(QApplication::palette());
 
787
        ui.ASIAPeriodsSpin->setPalette(QApplication::palette());
 
788
}
 
789
 
 
790
void GameDialog::slot_decline()
 
791
{
 
792
        qDebug("#### GameDialog::slot_decline()");
 
793
        
 
794
        //QString opponent = ui.playerOpponentEdit->text();//(playerWhiteEdit->isReadOnly() ? playerBlackEdit->text():playerWhiteEdit->text());
 
795
        
 
796
#ifdef FIXME
 
797
        if (ui.buttonOffer->isDown())
 
798
        {
 
799
                // match has been offered
 
800
                // !! there seem to be not "setOn" in the code (apart init, but this should not reach this code)
 
801
                qDebug("GameDialog::slot_decline sends withdraw  (not IGS)");
 
802
                emit signal_sendCommand("withdraw", false);
 
803
                //ui.buttonOffer->setDown(false);
 
804
                ui.buttonOffer->setChecked(false);
 
805
                ui.buttonOffer->setText(tr("Offer"));
 
806
        }
 
807
#endif //FIXME
 
808
        /* FIXME this is also sending a lot of unnecessary declines in IGS.
 
809
         * like maybe we only need to send an IGS decline if there's been an offer
 
810
         * and a counter offer.  But what if you offer a game and then cancel
 
811
         * the offer?  Maybe you can't...  we could check for the decline text
 
812
         * on the button as well, but then what exactly is the flag for...
 
813
         * confusing...*/
 
814
        if(offered_and_unrefused)       //FIXME decline button shouldn't be possible otherwise
 
815
                connection->declineMatchOffer(opponent);
 
816
        
 
817
        close();
 
818
}
 
819
 
 
820
void GameDialog::slot_cancel()
 
821
{
 
822
        if(offered_and_unrefused && ui.buttonDecline->isEnabled())
 
823
                connection->declineMatchOffer(opponent);
 
824
        else if(ui.buttonOffer->isEnabled() && ui.buttonOffer->text() == tr("Offer"))
 
825
                connection->cancelMatchOffer(opponent);
 
826
        close();
 
827
}
 
828
 
 
829
//TODO : not used now
 
830
void GameDialog::slot_changed()
 
831
{
 
832
        qDebug("#### GameDialog::slot_changed()");
 
833
        if (ui.playerOpponentEdit->text() == myName)// playerBlackEdit->text())
 
834
        {
 
835
                ui.buttonOffer->setText(tr("Teaching"));
 
836
//              ComboBox_free->setEnabled(false);
 
837
 
 
838
                ui.stonesTimeSpin->setEnabled(false);
 
839
                ui.timeSpin->setEnabled(false);
 
840
        }
 
841
        else
 
842
        {
 
843
                //ui.buttonOffer->setText(tr("Offer"));
 
844
//              ComboBox_free->setEnabled(true);
 
845
 
 
846
                ui.stonesTimeSpin->setEnabled(true);
 
847
                ui.timeSpin->setEnabled(true);
 
848
        }
 
849
 
 
850
        // check for free game
 
851
        if (ui.playerOpponentRkEdit->text() == "NR" || myRk == "NR" || ui.playerOpponentRkEdit->text() == myRk)
 
852
        {
 
853
//              ComboBox_free->setCurrentItem(1);
 
854
        }
 
855
        else
 
856
        {
 
857
//              ComboBox_free->setEnabled(true);
 
858
        }
 
859
        // FIXME
 
860
        //ui.buttonOffer->setDown(false);
 
861
        ui.buttonOffer->setChecked(false);
 
862
        ui.buttonOffer->setText(tr("Offer"));   //counter?
 
863
}
 
864
 
 
865
void GameDialog::recvRefuseMatch(int motive)
 
866
{
 
867
        if (motive == GD_REFUSE_NOTOPEN)
 
868
                ui.refusedLabel->setText(tr("%1 not open for matches").arg(opponent.name));
 
869
        else if (motive == GD_REFUSE_DECLINE) 
 
870
                ui.refusedLabel->setText(tr("%1 declined the match request").arg(opponent.name));
 
871
        else if (motive == GD_REFUSE_CANCEL) 
 
872
                ui.refusedLabel->setText(tr("%1 canceled the match request").arg(opponent.name));
 
873
        else if (motive == GD_REFUSE_INGAME) 
 
874
                ui.refusedLabel->setText(tr("%1 already playing a game").arg(opponent.name));           
 
875
        else if(motive == GD_REFUSE_NODIRECT)
 
876
                ui.refusedLabel->setText(tr("%1 does not accept direct matches").arg(opponent.name));
 
877
        else if(motive == GD_OPP_NO_NMATCH)
 
878
                ui.refusedLabel->setText(tr("%1's client does not support nmatch").arg(opponent.name));
 
879
        else if(motive == GD_INVALID_PARAMETERS)
 
880
        {
 
881
                ui.refusedLabel->setText(tr("Invalid Parameters!"));
 
882
                ui.buttonOffer->setText(tr("Offer"));
 
883
                ui.buttonOffer->setChecked(false);
 
884
                ui.buttonDecline->setDisabled(true);
 
885
                return;
 
886
        }
 
887
        else if(motive == GD_RESET)
 
888
        {
 
889
                ui.buttonOffer->setText(tr("Offer"));
 
890
                ui.buttonOffer->setChecked(false);
 
891
                return;
 
892
        }
 
893
        qDebug("#### GameDialog::slot_notopen()");
 
894
        if (opponent.name.isEmpty())    //FIXME
 
895
        {
 
896
                // IGS: no player named -> check if offering && focus set
 
897
                if (ui.buttonOffer->isChecked())// && QWidget::hasFocus())
 
898
                {
 
899
                        
 
900
//                      ui.buttonOffer->setDown(false);
 
901
//                      ui.buttonOffer->setText(tr("Offer"));
 
902
                        ui.buttonOffer->setDisabled(true);
 
903
                        ui.buttonDecline->setDisabled(true);
 
904
                        ui.buttonCancel->setEnabled(true);
 
905
                }
 
906
        }
 
907
        else if (ui.playerOpponentEdit->text() == opponent.name)//(playerWhiteEdit->isReadOnly() && playerBlackEdit->text() == opponent ||               playerBlackEdit->isReadOnly() && playerWhiteEdit->text() == opponent)
 
908
        {
 
909
 
 
910
//              ui.buttonOffer->setDown(false);
 
911
//              ui.buttonOffer->setText(tr("Offer"));
 
912
                ui.buttonOffer->setDisabled(true);
 
913
                ui.buttonDecline->setDisabled(true);
 
914
                ui.buttonCancel->setEnabled(true);
 
915
        }
 
916
        offered_and_unrefused = false;
 
917
}
 
918
 
 
919
// if opponent has requestet for handicap, komi and/or free game
 
920
void GameDialog::slot_komiRequest(const QString &opponent, int h, int k, bool /*free*/)
 
921
{
 
922
        qDebug("#### GameDialog::slot_komirequest()");
 
923
        if (ui.playerOpponentEdit->text() == opponent)
 
924
        {
 
925
 
 
926
                ui.handicapSpin->setValue(h);
 
927
 
 
928
                komi_request = true; //the komi checkbox has been replaced by
 
929
                ui.komiSpin->setValue(k);
 
930
 
 
931
//              if (free)
 
932
//                      ComboBox_free->setCurrentItem(1);
 
933
//              else
 
934
//                      ComboBox_free->setCurrentItem(0);
 
935
 
 
936
//              ui.buttonOffer->setText(tr("Accept"));
 
937
                ui.buttonOffer->setDown(false);
 
938
                ui.buttonOffer->setChecked(false);
 
939
                ui.buttonCancel->setDisabled(true);
 
940
        }
 
941
        else
 
942
                ui.buttonCancel->setEnabled(true);
 
943
}
 
944
 
 
945
/* If there's an existing match request, we need to highlight the changes */
 
946
void GameDialog::recvRequest(MatchRequest * mr, unsigned long _flags)
 
947
{
 
948
        bool destroy_other_timetabs = false;
 
949
        bool this_is_offer = false;
 
950
        /* A little iffy here.  We might want to get the flags
 
951
         * every request, but it also might be that we don't
 
952
         * want to have them handy, so we just want to set them
 
953
         * once the first time */
 
954
        if(_flags)
 
955
        {
 
956
                flags = _flags;
 
957
                if(!(flags & GDF_CANADIAN))
 
958
                        ui.timeTab->setTabEnabled(0, false);
 
959
                if(!(flags & GDF_BYOYOMI))
 
960
                        ui.timeTab->setTabEnabled(1, false);
 
961
                /* We remove ASIA because its the last tab.
 
962
                 * this is rather unfortunately, we need names
 
963
                 * for the tabs, FIXME, otherwise it screws
 
964
                 * the indexes up to delete the tabs */
 
965
                if(!(flags & GDF_TVASIA))
 
966
                        ui.timeTab->removeTab(2);
 
967
                
 
968
                if(!(flags & GDF_FREE_RATED_CHOICE))
 
969
                        ui.ratedCB->setEnabled(false);
 
970
                if((flags & GDF_RATED_NO_HANDICAP) && (!mr || mr->free_rated == RATED))
 
971
                {
 
972
                        PlayerListing us = connection->getOurListing();
 
973
                        float k;
 
974
                        unsigned int h;
 
975
                        getProperKomiHandicap(us.rank, opponent.rank, &k, &h);
 
976
                        if(h > 1)
 
977
                        {
 
978
                                //mr->free_rated = FREE;        //necessary?? FIXME
 
979
                                ui.ratedCB->setChecked(false);
 
980
                                ui.ratedCB->setEnabled(false);
 
981
                        }
 
982
                }
 
983
                if((flags & GDF_STONES25_FIXED) && !mr)
 
984
                {
 
985
                        ui.stonesSpin->setValue(25);
 
986
                        ui.stonesSpin->setEnabled(false);
 
987
                }
 
988
                
 
989
                /* We can actually ignore this with ORO, change
 
990
                 * and send whatever we want, but I feel like its
 
991
                 * cheap to the opponent who doesn't even see
 
992
                 * the changes */
 
993
                if((flags & GDF_ONLY_DISPUTE_TIME) && mr)
 
994
                {
 
995
                        /* I don't like the color of this gray
 
996
                         * FIXME.  It looks more like an option
 
997
                         * that's removed rather than something
 
998
                         * that you're not allowed to change */
 
999
                        ui.handicapSpin->setEnabled(false);
 
1000
                        ui.boardSizeSpin->setEnabled(false);
 
1001
                        ui.komiSpin->setEnabled(false);
 
1002
                        ui.play_black_button->setEnabled(false);
 
1003
                        ui.play_white_button->setEnabled(false);
 
1004
                        ui.play_nigiri_button->setEnabled(false);
 
1005
                        ui.ratedCB->setEnabled(false);
 
1006
                        
 
1007
                        destroy_other_timetabs = true;
 
1008
                }
 
1009
                /* As far as I know, no protocols allow time systems
 
1010
                * with main time in seconds except TVASIA and there's
 
1011
                * also ranges on these things.  We need flags for that
 
1012
                * as well FIXME */
 
1013
                /* Note that we still FIXME need a flag for things like
 
1014
                 * 10 second increments and the like.
 
1015
                 * Also, it doesn't like more than two mm, or two ss
 
1016
                 * which means we need hours I guess and I wonder if
 
1017
                 * that's clear and then maybe we need a "seconds"
 
1018
                 * on the label. FIXME.*/
 
1019
                if(flags & GDF_BY_CAN_MAIN_MIN)
 
1020
                {
 
1021
                        //ui.timeSpin->setDisplayFormat("mmm");
 
1022
                        //ui.BYTimeSpin->setDisplayFormat("mmm");
 
1023
                }
 
1024
                //ui.ASIATimeSpin->setDisplayFormat("sss");
 
1025
                if((flags & GDF_KOMI_FIXED6) && !mr)
 
1026
                {
 
1027
                        if(ui.handicapSpin->value() == 0)
 
1028
                                ui.komiSpin->setValue(6);
 
1029
                        else
 
1030
                                ui.komiSpin->setValue(0);
 
1031
                        ui.komiSpin->setEnabled(false);
 
1032
                }
 
1033
                if(mr)
 
1034
                {
 
1035
#ifdef FIXME
 
1036
                        if(mr->timeSystem == canadian)
 
1037
                        {
 
1038
                                //is min 0 or is it the current ? FIXME
 
1039
                                if(mr->nmatch_timeMax)
 
1040
                                        ui.timeSpin->setTimeRange(qtimeFromSeconds(0), qtimeFromSeconds(mr->nmatch_timeMax));
 
1041
                                        //ui.timeSpin->setTimeRange(qtimeFromSeconds(mr->maintime), qtimeFromSeconds(mr->nmatch_timeMax));
 
1042
                                if(mr->nmatch_BYMax)
 
1043
                                        ui.stonesTimeSpin->setTimeRange(qtimeFromSeconds(0), qtimeFromSeconds(mr->nmatch_BYMax));
 
1044
                                        //ui.stonesTimeSpin->setTimeRange(qtimeFromSeconds(mr->periodtime), qtimeFromSeconds(mr->nmatch_BYMax));
 
1045
                        }
 
1046
                        else if(mr->timeSystem == byoyomi)
 
1047
                        {
 
1048
                                if(mr->nmatch_timeMax)
 
1049
                                        ui.BYTimeSpin->setTimeRange(QTime(0, mr->maintime/60, 0), QTime(0, mr->nmatch_timeMax/60, 0));
 
1050
                                if(mr->nmatch_BYMax)
 
1051
                                        ui.BYPeriodTimeSpin->setTimeRange(QTime(0, mr->periodtime/60, 0), QTime(0, mr->nmatch_BYMax/60, 0));
 
1052
                        }
 
1053
                        if(mr->nmatch_handicapMax)
 
1054
                                ui.handicapSpin->setRange(mr->handicap, mr->nmatch_handicapMax);        
 
1055
#endif //FIXME
 
1056
                        //not necessarily: !!! FIXME
 
1057
                        //we_are_challenger = true;
 
1058
                        //this_is_offer = true;
 
1059
                }
 
1060
        }
 
1061
        if(!mr)
 
1062
        {
 
1063
                /* FIXME FIXME FIXME
 
1064
                 * if this is the open of the dialog,
 
1065
                 * we need to fill out the current_match_request,
 
1066
                 * otherwise it gets sent as uninitialized garbage!!
 
1067
                 * at least sometimes */
 
1068
                //load defaults
 
1069
                //mr->time = preferences.default_maintime;
 
1070
                //mr->board_size = preferences.default_boardsize;
 
1071
                //etc...
 
1072
                // FIXME
 
1073
                mr = new MatchRequest();
 
1074
                PlayerListing us = connection->getOurListing();
 
1075
                mr->opponent = opponent.name;
 
1076
                mr->opponent_id = opponent.id;
 
1077
                mr->their_rank = opponent.rank;
 
1078
                mr->our_name = us.name;
 
1079
                mr->our_rank = us.rank; //us.rank sounds like bad grammar
 
1080
                mr->timeSystem = canadian;
 
1081
                mr->maintime = 600;
 
1082
                mr->periodtime = 600;
 
1083
                mr->stones_periods = 25;
 
1084
                if(getProperKomiHandicap(us.rank, opponent.rank, &(mr->komi), &(mr->handicap)))
 
1085
                {
 
1086
                        //challenger is black is a mystery byte
 
1087
                        //I'm thinking it might be whether the request is
 
1088
                        // modifiable, or if our only answer is to accept
 
1089
                        // or decline, okay, nevermind, its not modification...
 
1090
                        // FIXME
 
1091
                        mr->challenger_is_black = 1;
 
1092
                        mr->color_request = MatchRequest::BLACK;
 
1093
                }
 
1094
                else
 
1095
                {
 
1096
                        mr->challenger_is_black = 1;
 
1097
                        mr->color_request = MatchRequest::WHITE;
 
1098
                }
 
1099
                if(mr->handicap == 1 && !(flags & GDF_HANDICAP1))
 
1100
                        mr->handicap = 0; 
 
1101
                we_are_challenger = true;
 
1102
                this_is_offer = true;
 
1103
                /* FIXME, a lot of stuff to fill in here, defaults and the
 
1104
                 * like to make it kosher across the board */
 
1105
                mr->flags = 0xf0;       //FIXME for now
 
1106
                mr->number = connection->getRoomNumber();
 
1107
                mr->opponent_is_challenger = false;
 
1108
                mr->first_offer = true;
 
1109
                //mr->free_rated = FREE;
 
1110
                mr->free_rated = RATED;         /* its more typically rated by default, but we should get this from somewhere FIXME */
 
1111
                mr->nmatch = true;      //igs
 
1112
                current_match_request->nmatch = mr->nmatch;     //awkward, but not set anywhere else
 
1113
                dialog_changed = 10000; //so it can't be anything but "Offer"
 
1114
        }
 
1115
        else
 
1116
        {
 
1117
                if(mr->first_offer)
 
1118
                {
 
1119
                        this_is_offer = true;
 
1120
                        dialog_changed = 10000; //so it can't be anything but "Offer"
 
1121
                        //FIXME should be in one place, also, this FORCES us
 
1122
                        //to call recvRequest after getGameDialog
 
1123
                        //the whole thing is awkward and now that we have most
 
1124
                        //of the protocols figured out it should be cleaned up
 
1125
                        //also, this may not be necessary, it didn't fix the problem
 
1126
                        //FIXME
 
1127
                }
 
1128
                else
 
1129
                        offered_and_unrefused = true;
 
1130
        }
 
1131
        /* I think above is right... so if its a default that we haven't offered yet,
 
1132
         * then offered_and_unrefused is left off, but if its from them, then we
 
1133
         * can send decline.  We also send a decline after we offer which is
 
1134
         * a little weird... I mean either they accept it and there's a game, or
 
1135
         * they change it and then we'd alter offered_and_unrefused here.
 
1136
         * probably FIXME, I just wonder why its like that in the first place */
 
1137
        
 
1138
        QPalette p(QApplication::palette());
 
1139
        p.setColor(  QPalette::Base , QColor("cyan"));
 
1140
        
 
1141
        qDebug("GameDialog::recvRequest");
 
1142
        /* If there's no existing request, then nothing should have changed
 
1143
         * opponent can't change, so that's the check. */
 
1144
        if(current_match_request->opponent != mr->opponent)
 
1145
                *current_match_request = *mr;
 
1146
        
 
1147
        
 
1148
        set_oppRk(mr->their_rank);
 
1149
                
 
1150
        set_myRk(mr->our_rank);
 
1151
 
 
1152
        ui.playerOpponentEdit->setText(mr->opponent);           
 
1153
        ui.playerOpponentEdit->setReadOnly(true);               
 
1154
        ui.playerOpponentRkEdit->setText(mr->their_rank);
 
1155
        set_myName(mr->our_name);
 
1156
 
 
1157
        if(mr->free_rated != current_match_request->free_rated)
 
1158
                ui.ratedCB->setPalette(p);
 
1159
        if(mr->free_rated == RATED)
 
1160
                ui.ratedCB->setChecked(true);
 
1161
        else
 
1162
                ui.ratedCB->setChecked(false);
 
1163
        ratedCB_changed((mr->free_rated == RATED));
 
1164
        
 
1165
        /* These may have rated fixed issues as well */
 
1166
        switch(mr->color_request)
 
1167
        {
 
1168
                case MatchRequest::BLACK:
 
1169
                        ui.play_black_button->setChecked(true);
 
1170
                        if(mr->color_request != current_match_request->color_request)
 
1171
                                ui.play_black_button->setPalette(p);
 
1172
                        slot_play_black_button();
 
1173
                        break;
 
1174
                case MatchRequest::WHITE:
 
1175
                        ui.play_white_button->setChecked(true); 
 
1176
                        if(mr->color_request != current_match_request->color_request)
 
1177
                                ui.play_white_button->setPalette(p);
 
1178
                        slot_play_white_button();
 
1179
                        break;
 
1180
                case MatchRequest::NIGIRI:
 
1181
                        ui.play_nigiri_button->setChecked(true);
 
1182
                        if(mr->color_request != current_match_request->color_request)
 
1183
                                ui.play_nigiri_button->setPalette(p);
 
1184
                        slot_play_nigiri_button();
 
1185
                        break;
 
1186
        }
 
1187
        
 
1188
        if(mr->komi != current_match_request->komi)
 
1189
                        ui.komiSpin->setPalette(p);
 
1190
        ui.komiSpin->setValue((int)mr->komi);
 
1191
        
 
1192
        
 
1193
        if(mr->board_size != current_match_request->board_size)
 
1194
                ui.boardSizeSpin->setPalette(p);
 
1195
        ui.boardSizeSpin->setValue(mr->board_size);
 
1196
        
 
1197
        if(mr->handicap != current_match_request->handicap)
 
1198
                ui.handicapSpin->setPalette(p);
 
1199
        ui.handicapSpin->setValue(mr->handicap);
 
1200
        
 
1201
        if (/*mr->nmatch || */mr->timeSystem == byoyomi)
 
1202
        {
 
1203
                qDebug("nmatch");
 
1204
                qDebug("%d %d %d", mr->maintime, mr->periodtime, mr->stones_periods);
 
1205
                //specific behavior here : IGS nmatch not totally supported
 
1206
                // disputes are hardly supported
 
1207
                set_is_nmatch(true);    //FIXME, change to is BY setting
 
1208
                //mr->nmatch = true;
 
1209
                if(mr->maintime != current_match_request->maintime)
 
1210
                        ui.BYTimeSpin->setPalette(p);
 
1211
                ui.BYTimeSpin->setTime(QTime(mr->maintime/3600, (mr->maintime % 3600)/60, mr->maintime%60));
 
1212
                
 
1213
                if(mr->periodtime != current_match_request->periodtime)
 
1214
                        ui.BYPeriodTimeSpin->setPalette(p);
 
1215
                ui.BYPeriodTimeSpin->setTime(QTime(0, mr->periodtime/60, mr->periodtime%60));
 
1216
                
 
1217
                ui.BYPeriodsSpin->setRange(0,99);
 
1218
                if(mr->stones_periods != current_match_request->stones_periods)
 
1219
                        ui.BYPeriodsSpin->setPalette(p);
 
1220
                ui.BYPeriodsSpin->setValue(mr->stones_periods);
 
1221
                
 
1222
                //ui.BY_label->setText(tr(" Byo Time : (") + mr->stones_periods+ tr(" stones_periods)"));
 
1223
                // necessary?  these enables/disables?
 
1224
                //ui.handicapSpin->setEnabled(true);
 
1225
                //ui.play_nigiri_button->setEnabled(true);
 
1226
                ui.timeTab->setCurrentIndex(1);
 
1227
                if(current_match_request->timeSystem != byoyomi)
 
1228
                        ui.timeTab->setPalette(p);
 
1229
                if(destroy_other_timetabs && ui.timeTab->count() > 1)
 
1230
                {
 
1231
                        ui.timeTab->setTabEnabled(0, false);
 
1232
                        ui.timeTab->setTabEnabled(2, false);    
 
1233
                }
 
1234
        }
 
1235
        else if (mr->timeSystem == tvasia)
 
1236
        {
 
1237
                /* As I understand it, tv asia time is just
 
1238
                 * byo yomi with a maintime in seconds... if I'm wrong, if its
 
1239
                 * something else... and I really need to check this in an
 
1240
                 * actual ORO on ORO game... */
 
1241
                if(mr->maintime != current_match_request->maintime)
 
1242
                        ui.ASIATimeSpin->setPalette(p);
 
1243
                
 
1244
                ui.ASIATimeSpin->setTime(QTime(0, mr->maintime/60, mr->maintime%60));
 
1245
                
 
1246
                if(mr->periodtime != current_match_request->periodtime)
 
1247
                        ui.ASIAPeriodTimeSpin->setPalette(p);
 
1248
                ui.ASIAPeriodTimeSpin->setTime(QTime(0, mr->periodtime/60, mr->periodtime%60));
 
1249
                
 
1250
                ui.ASIAPeriodsSpin->setRange(0,99);
 
1251
                if(mr->stones_periods != current_match_request->stones_periods)
 
1252
                        ui.ASIAPeriodsSpin->setPalette(p);
 
1253
                ui.ASIAPeriodsSpin->setValue(mr->stones_periods);
 
1254
                
 
1255
                ui.timeTab->setCurrentIndex(2);
 
1256
                if(current_match_request->timeSystem != tvasia)
 
1257
                        ui.timeTab->setPalette(p);
 
1258
                if(destroy_other_timetabs && ui.timeTab->count() > 1)
 
1259
                {
 
1260
                        ui.timeTab->setTabEnabled(0, false);
 
1261
                        ui.timeTab->setTabEnabled(1, false);
 
1262
                }
 
1263
        }
 
1264
        else if(/* !mr->nmatch || */mr->timeSystem == canadian)
 
1265
        {
 
1266
                qDebug("no nmatch");
 
1267
                set_is_nmatch(false);
 
1268
                
 
1269
                ui.timeSpin->setTime(qtimeFromSeconds(mr->maintime));
 
1270
                if(mr->maintime != current_match_request->maintime)
 
1271
                        ui.timeSpin->setPalette(p);
 
1272
                
 
1273
                ui.stonesTimeSpin->setTime(qtimeFromSeconds(mr->periodtime));
 
1274
                if(mr->periodtime != current_match_request->periodtime)
 
1275
                        ui.stonesTimeSpin->setPalette(p);
 
1276
                
 
1277
                ui.stonesSpin->setValue(mr->stones_periods);
 
1278
                if(mr->stones_periods != current_match_request->stones_periods)
 
1279
                        ui.stonesSpin->setPalette(p);
 
1280
                
 
1281
                // necessary?  these enables/disables?
 
1282
                //ui.handicapSpin->setEnabled(false);
 
1283
                //ui.play_nigiri_button->setEnabled(false);
 
1284
                
 
1285
                if(mr->board_size != current_match_request->board_size)
 
1286
                        ui.boardSizeSpin->setPalette(p);
 
1287
                ui.boardSizeSpin->setValue(mr->board_size);
 
1288
 
 
1289
                ui.timeTab->setCurrentIndex(0);
 
1290
                if(current_match_request->timeSystem != canadian)
 
1291
                        ui.timeTab->setPalette(p);
 
1292
                if(destroy_other_timetabs && ui.timeTab->count() > 1)
 
1293
                {
 
1294
                        ui.timeTab->setTabEnabled(1, false);
 
1295
                        ui.timeTab->setTabEnabled(2, false);
 
1296
                }
 
1297
        }
 
1298
        
 
1299
        
 
1300
        qDebug("set-up accept");
 
1301
        if(this_is_offer)
 
1302
        {
 
1303
                ui.buttonDecline->setEnabled(false);
 
1304
                ui.buttonOffer->setChecked(false);
 
1305
                ui.buttonOffer->setText(tr("Offer"));
 
1306
                ui.buttonCancel->setEnabled(true);
 
1307
        }
 
1308
        else
 
1309
        {
 
1310
                ui.buttonDecline->setEnabled(true);
 
1311
                ui.buttonOffer->setChecked(false);
 
1312
                ui.buttonOffer->setText(tr("Accept"));
 
1313
                ui.buttonCancel->setDisabled(true);
 
1314
        }
 
1315
        
 
1316
        show();
 
1317
//      dlg->setWindowState(Qt::WindowActive);
 
1318
        raise();
 
1319
 
 
1320
        if(!this_is_offer)
 
1321
                gameSound->play();
 
1322
        // store this as the new offer
 
1323
        *current_match_request = *mr;
 
1324
        clearChangedFlags();
 
1325
}
 
1326
 
 
1327
void GameDialog::save_to_preferences(void)
 
1328
{
 
1329
        preferences.default_size = ui.boardSizeSpin->value();
 
1330
        //preferences.default_komi = ui.komiSpin->value();
 
1331
        
 
1332
        preferences.default_stonesmaintime = timeToSeconds(ui.timeSpin->time());
 
1333
        preferences.default_stonestime = (ui.stonesTimeSpin->time().minute() * 60) + ui.stonesTimeSpin->time().second();
 
1334
        preferences.default_stones = ui.stonesSpin->value();
 
1335
        preferences.default_byomaintime = (ui.BYTimeSpin->time().minute() * 60) + ui.BYTimeSpin->time().second();
 
1336
        preferences.default_byoperiodtime = (ui.BYPeriodTimeSpin->time().minute() * 60) + ui.BYPeriodTimeSpin->time().second();
 
1337
        preferences.default_byoperiods = ui.BYPeriodsSpin->value();
 
1338
        preferences.default_asiamaintime = (ui.ASIATimeSpin->time().minute() * 60) + ui.ASIATimeSpin->time().second();
 
1339
        preferences.default_asiaperiodtime = (ui.ASIAPeriodTimeSpin->time().minute() * 60) + ui.ASIAPeriodTimeSpin->time().second();
 
1340
        preferences.default_asiaperiods = ui.ASIAPeriodsSpin->value();
 
1341
}
 
1342
 
 
1343
 
 
1344
MatchRequest * GameDialog::getMatchRequest(void)
 
1345
{
 
1346
        return current_match_request;
 
1347
}
 
1348
 
 
1349
QTime GameDialog::qtimeFromSeconds(int seconds)
 
1350
{
 
1351
        if(seconds == 0)
 
1352
                return QTime(0, 0, 0);
 
1353
        int minutes = seconds / 60;
 
1354
        int hours;
 
1355
        seconds %= 60;
 
1356
        if(minutes == 0)
 
1357
                hours = 0;
 
1358
        else
 
1359
        {
 
1360
                hours = minutes / 60;
 
1361
                minutes %= 60;
 
1362
        }
 
1363
        return QTime(hours, minutes, seconds);  
 
1364
}
 
1365
 
 
1366
unsigned int GameDialog::timeToSeconds(QString time)
 
1367
{
 
1368
        QRegExp re = QRegExp("([0-9]{1,3}):([0-9]{1,2})");
 
1369
        int min, sec;
 
1370
        
 
1371
        if(re.indexIn(time) >= 0)
 
1372
        {
 
1373
                min = re.cap(1).toInt();
 
1374
                sec = re.cap(2).toInt();        
 
1375
        }
 
1376
        else
 
1377
        {
 
1378
                qDebug("Bad time string");
 
1379
                return 0xffff;
 
1380
        }
 
1381
        
 
1382
        return (60 * min) + sec;
 
1383
}
 
1384
 
 
1385
unsigned int GameDialog::timeToSeconds(const QTime & t)
 
1386
{
 
1387
        return ((t.hour() * 3600) + (t.minute() * 60) + t.second());    
 
1388
}
 
1389
 
 
1390
//we just assume that white has the higher rank
 
1391
/* We're having this return 1 handicap if there's a one stone
 
1392
 * difference, but this only works because this is only called
 
1393
 * from the one place... then we'll use the GDF_HANDICAP1 flag
 
1394
 * to determine if that's set */
 
1395
bool GameDialog::getProperKomiHandicap(QString rankA, QString rankB, float * komi, unsigned int * handicap)
 
1396
{
 
1397
        /* Check for k, d, or p (as d), calc difference, */
 
1398
        QString buffer = rankA;
 
1399
        buffer.replace(QRegExp("[pdk+?]"), "");
 
1400
        int ordinalA = buffer.toInt();
 
1401
        buffer = rankB;
 
1402
        buffer.replace(QRegExp("[pdk+?]"), "");
 
1403
        int ordinalB = buffer.toInt();
 
1404
        int difference;
 
1405
        bool A_lowerthan_B = false;
 
1406
        
 
1407
        if((rankA.contains("k") && (rankB.contains("d") || rankB.contains("p")))
 
1408
        || (rankB.contains("k") && (rankA.contains("d") || rankA.contains("p"))))
 
1409
        {
 
1410
                difference = ordinalB + ordinalA - 1;
 
1411
                *komi = 0.0;
 
1412
                if(difference == 1)
 
1413
                        *handicap = 1;  
 
1414
                else if(difference > 9)
 
1415
                        *handicap = 9;
 
1416
                else
 
1417
                        *handicap = difference;
 
1418
                if(rankA.contains("k"))
 
1419
                        A_lowerthan_B = true;
 
1420
                else
 
1421
                        A_lowerthan_B = false;
 
1422
                
 
1423
        }
 
1424
        else
 
1425
        {
 
1426
                if(ordinalA == ordinalB)
 
1427
                {
 
1428
                        *komi = preferences.default_komi;
 
1429
                        *handicap = 0;
 
1430
                }
 
1431
                else
 
1432
                {
 
1433
                        difference = abs(ordinalA - ordinalB);
 
1434
                        *komi = 0.0;
 
1435
                        if(difference == 1)
 
1436
                                *handicap = 1;  
 
1437
                        else if(difference > 9)
 
1438
                                *handicap = 9;
 
1439
                        else
 
1440
                                *handicap = difference;
 
1441
                        if(ordinalA > ordinalB && rankA.contains("k"))
 
1442
                                A_lowerthan_B = true;
 
1443
                        else if(ordinalA < ordinalB && rankA.contains("k"))
 
1444
                                A_lowerthan_B = false;
 
1445
                        else if(ordinalA > ordinalB)
 
1446
                                A_lowerthan_B = false;
 
1447
                        else if(ordinalA < ordinalB)
 
1448
                                A_lowerthan_B = true;
 
1449
                }       
 
1450
        }
 
1451
        return A_lowerthan_B;
 
1452
}