1 /* This file is part of KsirK.
2 Copyright (C) 2008 Gael Clouet <pelouas@hotmail.fr>
3
4 KsirK is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public
6 License as published by the Free Software Foundation, either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA
18 */
19
20 /* begin : Thu JAN 22 2008 */
21
22 #include "krightdialog.h"
23 #include "Sprites/animsprite.h"
24 #include <qdrawutil.h>
25 #include <QColor>
26 #include <QBrush>
27 #include <QBitmap>
28 #include <QPixmap>
29 #include <QString>
30 #include <QScrollBar>
31 #include <QScrollArea>
32 #include <QPalette>
33 #include <QMovie>
34
35 namespace Ksirk
36 {
37 using namespace GameLogic;
38
KRightDialog(QDockWidget * parent,ONU * world,KGameWindow * m_game)39 KRightDialog::KRightDialog(QDockWidget * parent, ONU * world,KGameWindow* m_game)
40 : QWidget(parent),
41 mainLayout(new QGridLayout(this)),
42 m_parentWidget(parent),
43 world(world),
44 rightContents(),
45 flag1(0),
46 flag2(0),
47 milieu(0),
48 milieu2(0),
49 btRecycleWidget(0),
50 btValidWidget(0),
51 game(m_game),
52 buttonStopAttack(0),
53 buttonStopDefense(0)
54 {
55 setLayout(mainLayout);
56 // setBaseSize(220,360);
57
58 // load the armie image
59 KConfig config(world->getConfigFileName());
60 KConfigGroup onugroup = config.group("onu");
61 QString skin = onugroup.readEntry("skinpath");
62
63 InfantrySprite *sprite = new InfantrySprite(1.0, m_game->backGnd());
64 sprite-> setDestination(0); // Sprite immobile
65 soldat = sprite->image(0).scaled(24,24,Qt::KeepAspectRatioByExpanding);
66 delete sprite;
67
68 // load the stopAttackAuto image
69 QString imageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, skin + "/Images/stopAttackAuto.png");
70 stopAttackAuto.load(imageFileName);
71
72 // load the recycle image
73 imageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, skin + '/' +CM_RECYCLING);
74 recycleContinue.load(imageFileName);
75
76 // load the finish recycle image
77 imageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, skin + '/' + CM_RECYCLINGFINISHED);
78 recycleDone.load(imageFileName);
79
80 // load the next player image
81 imageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, skin + '/' + CM_NEXTPLAYER);
82 recycleNextPlayer.load(imageFileName);
83
84 show();
85 }
86
~KRightDialog()87 KRightDialog::~KRightDialog()
88 {
89 delete mainLayout;
90 }
91
displayCountryDetails(const QPointF & countryPoint)92 void KRightDialog::displayCountryDetails(const QPointF& countryPoint)
93 {
94 qCDebug(KSIRK_LOG);
95 Country* country = world->countryAt(countryPoint);
96 if (country == 0)
97 {
98 return;
99 }
100 clearLayout();
101 QHBoxLayout * unit = new QHBoxLayout();
102 QHBoxLayout * drap = new QHBoxLayout();
103 flag1 = new QLabel();
104 flag2 = new QLabel();
105 initListLabel(7);
106
107 QPixmap picture;
108
109 picture = country->owner()->getFlag()->image(0);
110
111 QString continent = i18n(country->continent()->name().toUtf8().data());
112 QString pays = i18n(country->name().toUtf8().data());
113 QString units = QString::number(country->nbArmies());
114 QString owner = country->owner()->name();
115
116 rightContents.at(0)->setText(i18n("<b>Nationality:</b>"));
117 rightContents.at(1)->setText(i18n("<b>Continent:</b> %1", continent));
118 rightContents.at(2)->setText(i18n("<b>Country:</b> %1", pays));
119
120 rightContents.at(3)->setPixmap(soldat);
121 rightContents.at(6)->setText(units);
122 rightContents.at(4)->setText(i18n("<b>Owner:</b> %1", owner));
123 rightContents.at(5)->setText(i18n("<b><u>Country details</u></b>"));
124
125 flag1->setPixmap(QPixmap());
126 flag2->setPixmap(QPixmap());
127 flag1->setPixmap(picture);
128
129 drap->addWidget(rightContents.at(0));
130 drap->addWidget(flag1);
131 mainLayout->addWidget(rightContents.at(5),0,0,Qt::AlignLeft);
132 mainLayout->addWidget(rightContents.at(1),2,0,Qt::AlignLeft);
133 mainLayout->addWidget(rightContents.at(2),3,0,Qt::AlignLeft);
134
135 mainLayout->addWidget(rightContents.at(4),5,0,Qt::AlignLeft);
136
137 unit->addWidget(rightContents.at(3));
138 unit->addWidget(rightContents.at(6));
139
140 mainLayout->addLayout(unit,4,0,Qt::AlignLeft);
141 mainLayout->addLayout(drap,1,0,Qt::AlignLeft);
142
143 m_parentWidget->show();
144 repaint();
145 }
146
displayFightDetails(Country * attaker,Country * defender,int nb_A,int nb_D)147 void KRightDialog::displayFightDetails(Country * attaker, Country * defender,int nb_A, int nb_D)
148 {
149 qCDebug(KSIRK_LOG);
150
151 clearLayout();
152 initListLabel(10);
153
154 haut = new QWidget();
155 bas = new QWidget();
156 QGridLayout * hautGrid = new QGridLayout(this);
157 QGridLayout * basGrid = new QGridLayout(this);
158
159 flag1 = new QLabel();
160 flag2 = new QLabel();
161
162 QHBoxLayout * box1 = new QHBoxLayout();
163 QHBoxLayout * box2 = new QHBoxLayout();
164 QHBoxLayout * box3 = new QHBoxLayout();
165 QHBoxLayout * box4 = new QHBoxLayout();
166
167 QGridLayout * tp = new QGridLayout();
168 infoProcess = new QLabel();
169 infoProcess->setWordWrap(true);
170 infoProcess->setText(i18n("<i>Fighting in progress...</i>"));
171 loadingLabel = new QLabel();
172 QLabel *l3 = new QLabel();
173 QLabel *l4 = new QLabel();
174
175 KConfig config(world->getConfigFileName());
176 KConfigGroup onugroup = config.group("onu");
177 QString skin = onugroup.readEntry("skinpath");
178 QString imageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, skin + "/Images/loader.gif");
179
180 QMovie * loading = new QMovie(imageFileName);
181 loadingLabel->setMovie(loading);
182 loading->start();
183
184 tp->addWidget(l3,0,0);
185 tp->addWidget(infoProcess,1,0,Qt::AlignCenter);
186 tp->addWidget(loadingLabel,2,0,Qt::AlignCenter);
187 tp->addWidget(l4,3,0);
188
189 milieu2 = new QWidget(this);
190 milieu2->setAutoFillBackground(true);
191 QPalette tempP(milieu2->palette());
192 tempP.setColor(QPalette::Window,QColor(190,190,190));
193 milieu2->setPalette(tempP);
194
195 milieu2->setLayout(tp);
196
197 haut->setLayout(hautGrid);
198 bas->setLayout(basGrid);
199
200 //ATTACKER
201 QString owner_A = attaker->owner()->name();
202 QString nb_units_A = QString::number(attaker->nbArmies());
203 QString pays_A = attaker->name();
204
205 QString owner_D = defender->owner()->name();
206 QString nb_units_D = QString::number(defender->nbArmies());
207 QString pays_D = defender->name();
208
209 QPixmap picture1;
210 QPixmap picture2;
211 picture1 = attaker->owner()->getFlag()->image(0);
212 picture2 = defender->owner()->getFlag()->image(0);
213
214 rightContents.at(0)->setText("<u><b>"+i18n(pays_A.toUtf8().data())+"</b></u>");
215 flag1->setPixmap(picture1);
216 rightContents.at(1)->setText("<i>("+owner_A+")</i> ");
217
218 if (!soldat.isNull())
219 rightContents.at(2)->setPixmap(soldat);
220 rightContents.at(3)->setText("<b>"+nb_units_A+"</b>");
221
222 rightContents.at(4)->setText(i18np("<font color=\"red\">Attack</font> with 1 army.<br>","<font color=\"red\">Attack</font> with %1 armies.<br>", nb_A));
223
224
225 rightContents.at(5)->setText("<u><b>"+i18n(pays_D.toUtf8().data())+"</b></u> ");
226 flag2->setPixmap(picture2);
227 rightContents.at(6)->setText("<i>("+owner_D+")</i> ");
228
229 if (!soldat.isNull())
230 rightContents.at(7)->setPixmap(soldat);
231 rightContents.at(8)->setText("<b>"+nb_units_D+"</b> ");
232
233 rightContents.at(9)->setText(i18np("<font color=\"blue\">Defend</font> with 1 army.<br>","<font color=\"blue\">Defend</font> with %1 armies.<br>", nb_D));
234
235 box1->addWidget(rightContents.at(0));
236 box1->addWidget(flag1);
237
238 box2->addWidget(rightContents.at(2));
239 box2->addWidget(rightContents.at(3));
240
241 box3->addWidget(rightContents.at(5));
242 box3->addWidget(flag2);
243
244 box4->addWidget(rightContents.at(7));
245 box4->addWidget(rightContents.at(8));
246
247 hautGrid->addLayout(box1,0,0,Qt::AlignCenter);
248 hautGrid->addWidget(rightContents.at(1),1,0,Qt::AlignCenter);
249 hautGrid->addLayout(box2,2,0,Qt::AlignLeft);
250 hautGrid->addWidget(rightContents.at(4),3,0,Qt::AlignLeft);
251
252 basGrid->addLayout(box3,0,0,Qt::AlignCenter);
253 basGrid->addWidget(rightContents.at(6),1,0,Qt::AlignCenter);
254 basGrid->addLayout(box4,2,0,Qt::AlignLeft);
255 basGrid->addWidget(rightContents.at(9),3,0,Qt::AlignLeft);
256
257 mainLayout->addWidget(haut,0,0);
258 mainLayout->addWidget(milieu2,1,0);
259 mainLayout->addWidget(bas,2,0);
260
261 if (game->automaton()->isAttackAuto()
262 && !game->automaton()->currentPlayer()->isAI()
263 && !game->automaton()->currentPlayer()->isVirtual())
264 {
265 buttonStopAttack = new QPushButton(stopAttackAuto,i18n("Stop Auto-Attack"));
266 mainLayout->addWidget(buttonStopAttack,3,0);
267 connect(buttonStopAttack, &QAbstractButton::clicked, this, &KRightDialog::slotStopAttackAuto);
268 }
269 if (game->automaton()->isDefenseAuto()
270 && !game->automaton()->currentPlayer()->isAI()
271 && !game->automaton()->currentPlayer()->isVirtual())
272 {
273 buttonStopDefense = new QPushButton(stopAttackAuto,i18n("Stop Auto-Defense"));
274 mainLayout->addWidget(buttonStopDefense,4,0);
275 connect(buttonStopDefense, &QAbstractButton::clicked, this, &KRightDialog::slotStopDefenseAuto);
276 }
277
278 mainLayout->update();
279 m_parentWidget->show();
280 repaint();
281 }
282
displayRecycleDetails(GameLogic::Player * player,int nbAvailArmies)283 void KRightDialog::displayRecycleDetails(GameLogic::Player * player, int nbAvailArmies)
284 {
285 qCDebug(KSIRK_LOG) << player->name() << nbAvailArmies;
286 this->show();
287
288 clearLayout();
289 initListLabel(4);
290
291 flag1 = new QLabel();
292 flag2 = new QLabel();
293
294 QGridLayout* recycleLayout = new QGridLayout();
295 QGridLayout* btRecycleLayout = new QGridLayout();
296 QGridLayout* btValidLayout = new QGridLayout();
297
298 QPushButton* buttonValid = new QPushButton(recycleNextPlayer, i18n("Valid"), this);
299 QPushButton* buttonRecycle = new QPushButton(recycleContinue, i18n("Recycle"), this);
300 QPushButton* buttonRecycleDone = new QPushButton(recycleDone, i18n("Done"), this);
301
302 connect(buttonValid, &QAbstractButton::clicked, game, &KGameWindow::slotNextPlayer);
303 connect(buttonRecycle, &QAbstractButton::clicked, game, &KGameWindow::slotRecycling);
304 connect(buttonRecycleDone, &QAbstractButton::clicked, game, &KGameWindow::slotRecyclingFinished);
305
306 QHBoxLayout* title = new QHBoxLayout();
307
308 haut = new QWidget();
309
310
311 // Widgets which contains buttons
312 btRecycleWidget = new QWidget();
313 btValidWidget = new QWidget();
314
315 btRecycleLayout->addWidget(buttonRecycle,0,0,Qt::AlignCenter);
316 btRecycleLayout->addWidget(buttonRecycleDone,0,1,Qt::AlignCenter);
317
318 btValidLayout->addWidget(buttonValid,0,0,Qt::AlignCenter);
319
320 btRecycleWidget->setLayout(btRecycleLayout);
321 btValidWidget->setLayout(btValidLayout);
322
323
324 rightContents.at(0)->setText("<u><b>"+player->name()+"</b></u> ");
325 flag1->setPixmap(player->getFlag()->image(0));
326
327 rightContents.at(1)->setText(i18np("%1 army to place", "%1 armies to place", nbAvailArmies));
328
329 title->addWidget(rightContents.at(0));
330 title->addWidget(flag1);
331
332 recycleLayout->addLayout(title,0,0,Qt::AlignCenter);
333 recycleLayout->addWidget(rightContents.at(1),1,0,Qt::AlignCenter);
334
335 recycleLayout->addWidget(rightContents.at(2),2,0,Qt::AlignCenter);
336 recycleLayout->addWidget(rightContents.at(3),3,0,Qt::AlignCenter);
337
338 recycleLayout->addWidget(btRecycleWidget,4,0,Qt::AlignCenter);
339 recycleLayout->addWidget(btValidWidget,5,0,Qt::AlignCenter);
340
341 haut->setLayout(recycleLayout);
342 mainLayout->addWidget(haut,0,0);
343
344 // hide buttons initialy
345 btRecycleWidget->hide();
346 if (nbAvailArmies > 0 || game->getState() == GameLogic::GameAutomaton::INTERLUDE || player->isVirtual() || player->isAI())
347 {
348 btValidWidget->hide();
349 }
350 else
351 {
352 btValidWidget->show();
353 }
354
355 mainLayout->update();
356 m_parentWidget->show();
357 repaint();
358 }
359
updateRecycleDetails(GameLogic::Country * country,bool recyclePhase,int nbAvailArmies)360 void KRightDialog::updateRecycleDetails(GameLogic::Country* country, bool recyclePhase, int nbAvailArmies)
361 {
362 qCDebug(KSIRK_LOG) << (void*)country << recyclePhase << nbAvailArmies;
363 this->show();
364 if (btValidWidget == 0)
365 {
366 if (country == 0)
367 {
368 return;
369 }
370 displayRecycleDetails(country->owner(),nbAvailArmies);
371 }
372
373 if (recyclePhase)
374 {
375 rightContents.at(0)->setText(i18n("<u><b>Change some<br>placements?</b></u> "));
376 flag1->hide();
377 rightContents.at(1)->setText(QString());
378 rightContents.at(2)->setText(QString());
379 rightContents.at(3)->setText(QString());
380
381 // show "redistribute" and "end redistribute" buttons
382 if (!game->automaton()->allLocalPlayersComputer())
383 {
384 btRecycleWidget->show();
385 }
386 btValidWidget->hide();
387 }
388 else
389 {
390 rightContents.at(1)->setText(i18np("1 army to place", "%1 armies to place", nbAvailArmies));
391 rightContents.at(2)->setText("<b>"+i18n(country->name().toUtf8().data())+"</b>");
392 rightContents.at(3)->setText(i18n("<b>Armies:</b> %1", country->nbArmies()));
393 if (nbAvailArmies > 0)
394 {
395 btValidWidget->hide();
396 }
397 else
398 {
399 if (!game->currentPlayer()->isVirtual() && !game->currentPlayer()->isAI())
400 {
401 btValidWidget->show();
402 }
403 }
404 }
405 qCDebug(KSIRK_LOG) << "before update and repaint";
406 mainLayout->update();
407 repaint();
408
409 }
410
displayFightResult(int A1=0,int A2=0,int A3=0,int D1=0,int D2=0,int nbA=0,int nbD=0,bool win=false)411 void KRightDialog::displayFightResult(int A1=0, int A2=0, int A3=0, int D1=0, int D2=0,int nbA=0,int nbD=0, bool win=false)
412 {
413 qCDebug(KSIRK_LOG);
414
415 // Bug 309863. Should not happen anymore because Country details and Fight results shouldn't be mixed.
416 // If, by any chance, occurs again, do not crash and log the incident. In that case label just won't be refreshed.
417 if (loadingLabel != 0)
418 {
419 QMovie* movie = loadingLabel->movie();
420 delete movie;
421 loadingLabel->clear();
422 }
423 else
424 qCDebug(KSIRK_LOG) << "Item (loadingLabel) has already been cleared!";
425
426 if (infoProcess != 0)
427 infoProcess->clear();
428 else
429 qCDebug(KSIRK_LOG) << "Item (infoProcess) has already been cleared!";
430
431 milieu = new QWidget(this);
432 milieu->setAutoFillBackground(true);
433 QPalette tempP(milieu->palette());
434 tempP.setColor(QPalette::Window,QColor(190,190,190));
435 milieu->setPalette(tempP);
436
437 QGridLayout * milieuGrid = new QGridLayout();
438 QHBoxLayout * deAtt = new QHBoxLayout();
439 QHBoxLayout * deDef = new QHBoxLayout();
440
441 if(A1!=0 && A1!=-1)
442 {
443 QLabel * de1 = new QLabel();
444 de1->setPixmap(game->getDice(KGameWindow::Red,A1));
445 rightContents.insert(0,de1);deAtt->addWidget(de1);
446 }
447 if(A2!=0 && A2!=-1)
448 {
449 QLabel * de2= new QLabel();
450 de2->setPixmap(game->getDice(KGameWindow::Red,A2));
451 rightContents.insert(0,de2);deAtt->addWidget(de2);
452 }
453 if(A3!=0 && A3!=-1)
454 {
455 QLabel * de3= new QLabel();
456 de3->setPixmap(game->getDice(KGameWindow::Red,A3));
457 rightContents.insert(0,de3);deAtt->addWidget(de3);
458 }
459 if(D1!=0 && D1!=-1)
460 {
461 QLabel * de4= new QLabel();
462 de4->setPixmap(game->getDice(KGameWindow::Blue,D1));
463 rightContents.insert(0,de4);deDef->addWidget(de4);
464 }
465 if(D2!=0 && D2!=-1)
466 {
467 QLabel * de5= new QLabel();
468 de5->setPixmap(game->getDice(KGameWindow::Blue,D2));
469 rightContents.insert(0,de5);deDef->addWidget(de5);
470 }
471 QLabel * rLabelR = new QLabel(i18n("<font color=\"red\">lost armies: %1</font>", nbA));
472 rLabelR->setWordWrap(true);
473
474 rightContents.insert(0,rLabelR);
475
476 QLabel * rLabelB = new QLabel(i18n("<font color=\"blue\">lost armies: %1</font>", nbD));
477 rLabelB->setWordWrap(true);
478
479 rightContents.insert(0,rLabelB);
480
481 milieuGrid->addWidget(rightContents.at(1),0,0,Qt::AlignCenter);
482 milieuGrid->addLayout(deAtt,1,0,Qt::AlignCenter);
483 milieuGrid->addLayout(deDef,2,0,Qt::AlignCenter);
484 milieuGrid->addWidget(rightContents.at(0),4,0,Qt::AlignCenter);
485
486 milieu->setLayout(milieuGrid);
487 mainLayout->addWidget(milieu,1,0);
488
489 if (buttonStopAttack != 0 && win)
490 {
491 buttonStopAttack->setEnabled(false);
492 }
493 repaint();
494 }
495
initListLabel(int nb)496 void KRightDialog::initListLabel(int nb)
497 {
498 qCDebug(KSIRK_LOG);
499
500 removeListLabel();
501 for (int i=0;i<nb;i++)
502 {
503 QLabel* label = new QLabel();
504 label->setWordWrap ( true );
505 rightContents.push_back(label);
506 }
507 clearLabel();
508 }
509
removeListLabel()510 void KRightDialog::removeListLabel()
511 {
512 qCDebug(KSIRK_LOG);
513 while (rightContents.size() > 0)
514 {
515 QLabel* label = rightContents.first();
516 rightContents.removeFirst();
517 delete label;
518 }
519 }
520
clearLabel()521 void KRightDialog::clearLabel()
522 {
523 qCDebug(KSIRK_LOG);
524 for (int i=0;i<rightContents.size();i++)
525 {
526 rightContents.at(i)->setText("");
527 rightContents.at(i)->setPixmap(QPixmap());
528 }
529 }
530
clearLayout()531 void KRightDialog::clearLayout()
532 {
533 qCDebug(KSIRK_LOG);
534 while (rightContents.size() > 0)
535 {
536 QLabel* obj = rightContents.first();
537 rightContents.removeFirst();
538 mainLayout->removeWidget(obj);
539 delete obj;
540 }
541 if (flag1 != 0)
542 {
543 mainLayout->removeWidget(flag1);
544 delete flag1;
545 flag1 = 0;
546 }
547 if (flag2 != 0)
548 {
549 mainLayout->removeWidget(flag2);
550 delete flag2;
551 flag2 = 0;
552 }
553 if (btRecycleWidget != 0)
554 {
555 delete btRecycleWidget;
556 btRecycleWidget = 0;
557 }
558 if (btValidWidget != 0)
559 {
560 delete btValidWidget;
561 btValidWidget = 0;
562 }
563 if (buttonStopAttack != 0)
564 {
565 mainLayout->removeWidget(buttonStopAttack);
566 delete buttonStopAttack;
567 buttonStopAttack = 0;
568 }
569 if (buttonStopDefense != 0)
570 {
571 mainLayout->removeWidget(buttonStopDefense);
572 delete buttonStopDefense;
573 buttonStopDefense = 0;
574 }
575 if(bas != 0 && mainLayout->indexOf(bas)!=-1)
576 {
577 mainLayout->removeWidget(bas);
578 delete bas;
579 }
580 if(milieu != 0)
581 {
582 mainLayout->removeWidget(milieu);
583 delete milieu;
584 milieu = 0;
585 }
586 if (milieu2 != 0)
587 {
588 mainLayout->removeWidget(milieu2);
589 QMovie* movie = loadingLabel->movie();
590 loadingLabel->clear();
591 delete movie;
592 delete loadingLabel;
593 loadingLabel = 0;
594 delete infoProcess;
595 infoProcess = 0;
596 delete milieu2;
597 milieu2 = 0;
598 }
599 if(mainLayout->indexOf(haut)!=-1)
600 {
601 mainLayout->removeWidget(haut);
602 delete haut;
603 }
604 }
605
slotStopAttackAuto()606 void KRightDialog::slotStopAttackAuto()
607 {
608 qCDebug(KSIRK_LOG);
609 this->game->automaton()->setAttackAuto(false);
610 this->buttonStopAttack->setEnabled(false);
611 }
612
slotStopDefenseAuto()613 void KRightDialog::slotStopDefenseAuto()
614 {
615 qCDebug(KSIRK_LOG);
616 this->game->automaton()->setDefenseAuto(false);
617 this->buttonStopDefense->setEnabled(false);
618 }
619
620 }
621
622
623