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