1 /***************************************************************************
2 File : board.cpp
3 Project : Knights
4 Description : Game board (scene)
5 --------------------------------------------------------------------
6 Copyright : (C) 2016 by Alexander Semke (alexander.semke@web.de)
7 Copyright : (C) 2009-2011 by Miha Čančula (miha@noughmad.eu)
8
9 ***************************************************************************/
10
11 /***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 * This program is distributed in the hope that it will be useful, *
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
21 * GNU General Public License for more details. *
22 * *
23 * You should have received a copy of the GNU General Public License *
24 * along with this program; if not, write to the Free Software *
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
26 * Boston, MA 02110-1301 USA *
27 * *
28 ***************************************************************************/
29
30 #include "board.h"
31 #include "gamemanager.h"
32 #include "settings.h"
33 #include "core/pos.h"
34 #include "core/move.h"
35 #include "core/item.h"
36 #include "rules/chessrules.h"
37 #include "ui_promotiondialog.h"
38
39 #include <KGameRenderer>
40
41 #include <QDialog>
42 #include <QDialogButtonBox>
43 #include <QDrag>
44 #include <QGraphicsSceneMouseEvent>
45 #include <QMimeData>
46 #include <QPushButton>
47 #include <QtMath>
48
49 using namespace Knights;
50
51 const qreal backgroundZValue = -3.0;
52 const qreal borderZValue = -2.0;
53 const qreal notationZValue = -1.0;
54 const qreal tileZValue = 0.0;
55 const qreal pieceZValue = 1.0;
56 const qreal legalMarkerZValue = 3.0;
57 const qreal dragZValue = 4.0;
58
59 const QString backgroundKey = QStringLiteral ( "Background" );
60 const QString whiteTileKey = QStringLiteral ( "WhiteTile" );
61 const QString blackTileKey = QStringLiteral ( "BlackTile" );
62 const QString legalMarkerKey = QStringLiteral ( "Marker" );
63 const QString motionMarkerKey = QStringLiteral ( "Motion" );
64 const QString dangerMarkerKey = QStringLiteral ( "Danger" );
65
66 const QString tbBorderKey = QStringLiteral ( "TopBottomBorder" );
67 const QString lrBorderKey = QStringLiteral ( "LeftRightBorder" );
68 const QString whiteLettersKey = QStringLiteral ( "WhiteLetters" );
69 const QString blackLettersKey = QStringLiteral ( "BlackLetters" );
70 const QString whiteNumbersKey = QStringLiteral ( "WhiteNumbers" );
71 const QString blackNumbersKey = QStringLiteral ( "BlackNumbers" );
72
Board(KgThemeProvider * provider,QObject * parent)73 Board::Board(KgThemeProvider* provider, QObject* parent) : QGraphicsScene(parent),
74 m_rules(nullptr),
75 m_background(nullptr),
76 m_displayBorders(true),
77 m_displayNotations(true),
78 renderer(nullptr),
79 m_themeProvider(provider),
80 m_dragActive(false),
81 draggedPiece(nullptr),
82 selectedPiece(nullptr),
83 m_paused(false),
84 m_animated(true),
85 m_currentPlayer(White),
86 m_displayedPlayer(NoColor),
87 m_drawFrame(true) {
88
89 renderer = new KGameRenderer(m_themeProvider);
90 if (!Manager::self()->rules())
91 Manager::self()->setRules(new ChessRules);
92 Manager::self()->rules()->setGrid(&m_grid);
93 updateTheme();
94
95 connect (provider, &KgThemeProvider::currentThemeChanged, this, &Board::updateTheme);
96 }
97
~Board()98 Board::~Board() {
99 qDeleteAll(m_grid);
100 qDeleteAll(m_tiles);
101 qDeleteAll(markers);
102 delete renderer;
103 //TODO: this crashes the application, s.a. BUG 405763
104 //delete Manager::self()->rules();
105 }
106
addPiece(PieceType type,Color color,const Pos & pos)107 void Board::addPiece(PieceType type, Color color, const Pos& pos) {
108 Piece* t_piece = new Piece ( renderer, type, color, this, pos );
109 if ( Settings::animationSpeed() != Settings::EnumAnimationSpeed::Instant )
110 t_piece->setPos ( mapToScene ( Pos ( ( pos.first > 4 ) ? 5 : 4, ( pos.second > 4 ) ? 5 : 4 ) ) );
111 t_piece->setZValue ( pieceZValue );
112 m_grid.insert ( pos, t_piece );
113 }
114
movePiece(const Move & move)115 void Board::movePiece(const Move& move) {
116 qCDebug(LOG_KNIGHTS) << move;
117 Move m = move;
118 if ( ( m.flag ( Move::Illegal ) && !m.flag ( Move::Forced ) ) || m.to() == m.from() || !m_grid.contains ( m.from() ) ) {
119 qCWarning(LOG_KNIGHTS) << "Invalid move:" << m;
120 return;
121 }
122 if ( !m.flag ( Move::Forced ) &&
123 ( m_grid[m.from()]->color() != m_currentPlayer || !Manager::self()->rules()->legalMoves(m.from()).contains(m) ) ) {
124 qCWarning(LOG_KNIGHTS) << "Move not allowed:" << m;
125 return;
126 }
127 qDeleteAll ( markers );
128 markers.clear();
129 if ( m.flag(Move::Promote) )
130 m_grid[m.from() ]->setPieceType ( m.promotedType() ? m.promotedType() : Queen );
131
132 PieceDataMap map = m.removedPieces();
133 PieceDataMap::const_iterator it = map.constBegin();
134 PieceDataMap::const_iterator end = map.constEnd();
135 for ( ; it != end; ++it ) {
136 delete m_grid.value ( it.key(), nullptr );
137 m_grid.remove ( it.key() );
138 }
139
140 centerOnPos ( m_grid.value ( m.from() ), m.to() );
141 m_grid.insert ( m.to(), m_grid.take ( m.from() ) );
142
143 map = m.addedPieces();
144 it = map.constBegin();
145 end = map.constEnd();
146 for ( ; it != end; ++it )
147 addPiece ( it.value().second, it.value().first, it.key() );
148
149 if ( m_playerColors & oppositeColor ( m_currentPlayer ) ) {
150 // We only display motion and danger markers if the next player is a human
151 if ( Settings::showMotion() ) {
152 addMarker ( m.from(), Motion );
153 addMarker ( m.to(), Motion );
154 }
155 if ( Settings::showDanger() ) {
156 bool check = false;
157 for ( Piece* piece : qAsConst(m_grid) ) {
158 if ( piece->color() == m_currentPlayer && Manager::self()->rules()->isAttacking ( piece->boardPos() ) ) {
159 check = true;
160 addMarker ( piece->boardPos(), Danger );
161 }
162 }
163 if ( check ) {
164 for ( Piece* piece : qAsConst(m_grid) ) {
165 if ( piece->color() != m_currentPlayer && piece->pieceType() == King )
166 addMarker ( piece->boardPos(), Danger );
167 }
168 }
169 }
170 }
171
172 for ( const Move& additionalMove : m.additionalMoves() )
173 movePiece ( additionalMove );
174
175 updateGraphics();
176 }
177
populate()178 void Board::populate() {
179 const PieceDataMap pieces = Manager::self()->rules()->startingPieces();
180 PieceDataMap::const_iterator it = pieces.constBegin();
181 PieceDataMap::const_iterator end = pieces.constEnd();
182 for ( ; it != end; ++it )
183 addPiece ( it.value().second, it.value().first, it.key() );
184 updateGraphics();
185 }
186
addTiles()187 void Board::addTiles() {
188 if ( !m_tiles.isEmpty() ) {
189 qCWarning(LOG_KNIGHTS) << "Tiles are already present, delete them first";
190 return;
191 }
192 for ( int i = 1; i < 9; ++i ) {
193 for ( int j = 1; j < 9; ++j ) {
194 QString key = ( ( i + j ) % 2 == 0 ) ? blackTileKey : whiteTileKey;
195 Item* tile = new Item ( renderer, key, this, Pos ( i, j ) );
196 tile->setZValue ( tileZValue );
197 m_tiles.insert ( Pos ( i, j ), tile );
198 }
199 }
200 }
201
mousePressEvent(QGraphicsSceneMouseEvent * e)202 void Board::mousePressEvent(QGraphicsSceneMouseEvent* e) {
203 if ( !Manager::self()->canLocalMove() ) {
204 // It is not the human player's turn
205 e->ignore();
206 return;
207 }
208
209 Piece* d_piece = pieceAt ( e->scenePos() );
210 if ( !d_piece || d_piece->color() != m_currentPlayer ) {
211 // The piece doesn't belong to the player whose turn it is, or there is no piece
212 if ( !selectedPiece ) {
213 e->ignore();
214 return;
215 }
216 Pos from = selectedPiece->boardPos();
217 Pos to = mapFromScene ( e->scenePos() );
218 if ( Manager::self()->rules()->legalMoves ( from ).contains ( Move ( from, to ) ) ) {
219 Move move ( from, to );
220 move.setFlag ( Move::Take, m_grid.contains ( to ) );
221
222 if ( m_grid[from]->pieceType() == Pawn && ( to.second == 1 || to.second == 8 ) ) {
223 move.setFlag ( Move::Promote, true );
224 move.setPromotedType ( getPromotedType() );
225 }
226 Q_EMIT pieceMoved(move);
227 selectedPiece = nullptr;
228 }
229 } else {
230 // The active player clicked on his/her own piece
231 if (d_piece != selectedPiece) {
232 qDeleteAll ( markers );
233 markers.clear();
234
235 selectedPiece = d_piece;
236
237 Pos t_pos = mapFromScene ( e->scenePos() );
238 QList<Move> t_legalMoves = Manager::self()->rules()->legalMoves ( t_pos );
239 if ( t_legalMoves.isEmpty() ) {
240 e->ignore();
241 return;
242 }
243 d_piece->setZValue ( dragZValue );
244 if ( Settings::showMarker() ) {
245 for ( const Move& t_move : qAsConst(t_legalMoves) )
246 addMarker ( t_move.to(), LegalMove );
247 }
248 draggedPiece = d_piece;
249 }
250 m_draggedPos = e->scenePos();
251 dragStartPoint = e->screenPos();
252 }
253 }
254
mouseReleaseEvent(QGraphicsSceneMouseEvent * e)255 void Board::mouseReleaseEvent(QGraphicsSceneMouseEvent* e) {
256 Q_UNUSED(e);
257 draggedPiece = nullptr;
258 }
259
mouseMoveEvent(QGraphicsSceneMouseEvent * e)260 void Board::mouseMoveEvent(QGraphicsSceneMouseEvent* e) {
261 if (!(e->buttons() & Qt::LeftButton) || m_dragActive)
262 return;
263 if (draggedPiece && ((e->screenPos() - dragStartPoint).manhattanLength() >= QApplication::startDragDistance()) ) {
264 //initiate a new drag event
265 drag = new QDrag ( e->widget() );
266 drag->setMimeData ( new QMimeData() );
267 m_dragActive = true;
268 selectedPiece = nullptr;
269 drag->exec();
270 }
271 }
272
dragLeaveEvent(QGraphicsSceneDragDropEvent * e)273 void Board::dragLeaveEvent(QGraphicsSceneDragDropEvent* e) {
274 Q_UNUSED(e);
275 if ( !m_dragActive )
276 return;
277
278 qDeleteAll(markers);
279 markers.clear();
280 centerOnPos(draggedPiece);
281 draggedPiece->setZValue(pieceZValue);
282 draggedPiece = nullptr;
283 m_dragActive = false;
284 }
285
dropEvent(QGraphicsSceneDragDropEvent * e)286 void Board::dropEvent(QGraphicsSceneDragDropEvent* e) {
287 qDeleteAll(markers);
288 markers.clear();
289
290 if (draggedPiece) {
291 m_dragActive = false;
292 Pos from = draggedPiece->boardPos();
293 Pos to = mapFromScene ( e->scenePos() );
294 Move move ( from, to );
295 if ( !Manager::self()->rules()->legalMoves ( from ).contains ( move ) )
296 centerOnPos ( draggedPiece );
297 else {
298 if ( m_grid[from]->pieceType() == Pawn && ( to.second == 1 || to.second == 8 ) ) {
299 move.setFlag ( Move::Promote, true );
300 move.setPromotedType ( getPromotedType() );
301 }
302 Q_EMIT pieceMoved(move);
303 }
304 draggedPiece->setZValue(pieceZValue);
305 draggedPiece = nullptr;
306 }
307 }
308
dragEnterEvent(QGraphicsSceneDragDropEvent * e)309 void Board::dragEnterEvent(QGraphicsSceneDragDropEvent* e) {
310 e->setAccepted(Manager::self()->canLocalMove());
311 }
312
dragMoveEvent(QGraphicsSceneDragDropEvent * e)313 void Board::dragMoveEvent(QGraphicsSceneDragDropEvent* e) {
314 if ( !draggedPiece ) {
315 e->ignore();
316 return;
317 }
318 e->accept();
319 qreal x = e->scenePos().x() - m_draggedPos.x();
320 qreal y = e->scenePos().y() - m_draggedPos.y();
321
322 draggedPiece->moveBy ( x, y );
323 m_draggedPos = e->scenePos();
324 }
325
pieceAt(const QPointF & point)326 Piece* Board::pieceAt(const QPointF& point) {
327 return m_grid.value(mapFromScene(point), nullptr);
328 }
329
mapFromScene(const QPointF & point)330 Pos Board::mapFromScene(const QPointF& point) {
331 Pos pos;
332 pos.first = ( point.x() - m_boardRect.left() ) / m_tileSize + 1;
333 pos.second = 1 - ( point.y() - m_boardRect.bottom() ) / m_tileSize;
334 if ( m_displayedPlayer != White )
335 pos = Pos ( 9, 9 ) - pos;
336 return pos;
337 }
338
mapToScene(Pos pos)339 QPointF Board::mapToScene(Pos pos) {
340 if ( m_displayedPlayer != White )
341 pos = Pos ( 9, 9 ) - pos;
342 QPointF point;
343 point.setX ( m_boardRect.left() + ( pos.first - 1 ) * m_tileSize );
344 point.setY ( m_boardRect.bottom() - pos.second * m_tileSize );
345 return point;
346 }
347
centerOnPos(Item * item,const Pos & pos,bool animated)348 void Board::centerOnPos(Item* item, const Pos& pos, bool animated) {
349 item->setBoardPos(pos);
350 centerOnPos(item, animated);
351 }
352
centerOnPos(Item * item,bool animated)353 void Board::centerOnPos(Item* item, bool animated) {
354 item->move(mapToScene(item->boardPos()), m_tileSize, animated);
355 }
356
centerAndResize(Item * item,QSize size,bool animated)357 void Board::centerAndResize(Item* item, QSize size, bool animated) {
358 item->moveAndResize(mapToScene ( item->boardPos() ), m_tileSize, size, animated);
359 }
360
isInBoard(const Pos & pos)361 bool Board::isInBoard(const Pos& pos) {
362 return pos.first > 0 && pos.first < 9 && pos.second > 0 && pos.second < 9;
363 }
364
setPlayerColors(Colors colors)365 void Board::setPlayerColors(Colors colors) {
366 m_playerColors = colors;
367 if ( m_playerColors & m_currentPlayer )
368 m_displayedPlayer = m_currentPlayer;
369 else {
370 if ( m_playerColors == Black )
371 m_displayedPlayer = Black;
372 else
373 m_displayedPlayer = White;
374 }
375 changeDisplayedPlayer();
376 populate();
377 }
378
setCurrentColor(Color color)379 void Board::setCurrentColor(Color color) {
380 m_currentPlayer = color;
381 Color nextPlayer = m_displayedPlayer;
382 if ( ( ( m_playerColors & (Black|White) ) == (Black|White) ) && !Settings::flipBoard() )
383 nextPlayer = White;
384 else if ( m_playerColors & color )
385 nextPlayer = color;
386 if ( m_displayedPlayer != nextPlayer ) {
387 m_displayedPlayer = nextPlayer;
388 changeDisplayedPlayer();
389 }
390 Q_EMIT activePlayerChanged ( m_currentPlayer );
391 }
392
393
addMarker(const Pos & pos,MarkerType type)394 void Board::addMarker(const Pos& pos, MarkerType type) {
395 QString key;
396 switch ( type ) {
397 case LegalMove:
398 key = legalMarkerKey;
399 break;
400 case Danger:
401 key = dangerMarkerKey;
402 break;
403 case Motion:
404 key = motionMarkerKey;
405 break;
406 }
407 addMarker ( pos, key );
408 }
409
addMarker(const Pos & pos,const QString & spriteKey)410 void Board::addMarker(const Pos& pos, const QString& spriteKey) {
411 if ( markers.contains ( pos ) ) {
412 // Prevent two markers (usually Motion and Danger) from being on the same square
413 delete markers[pos];
414 }
415 Item* marker = new Item ( renderer, spriteKey, this, pos );
416 centerOnPos ( marker, false );
417 marker->setRenderSize ( QSizeF ( m_tileSize, m_tileSize ).toSize() );
418 marker->setZValue ( legalMarkerZValue );
419 markers.insert ( pos, marker );
420 }
421
updateTheme()422 void Board::updateTheme() {
423 delete m_background;
424 qDebug()<<"background key " << backgroundKey;
425 if ( renderer->spriteExists ( backgroundKey ) ) {
426 m_background = new Item ( renderer, backgroundKey, this, Pos() );
427 m_background->setZValue ( backgroundZValue );
428 } else
429 m_background = nullptr;
430
431 qDeleteAll ( m_borders );
432 m_borders.clear();
433 qDeleteAll ( m_notations );
434 m_notations.clear();
435 m_displayBorders = Settings::borderDisplayType() != Settings::EnumBorderDisplayType::None
436 && renderer->spriteExists ( lrBorderKey )
437 && renderer->spriteExists ( tbBorderKey );
438 m_displayNotations = Settings::borderDisplayType() == Settings::EnumBorderDisplayType::Notation
439 && renderer->spriteExists ( whiteLettersKey )
440 && renderer->spriteExists ( blackLettersKey )
441 && renderer->spriteExists ( whiteNumbersKey )
442 && renderer->spriteExists ( blackNumbersKey );
443 if ( m_displayBorders ) {
444 m_borders << new Item ( renderer, tbBorderKey, this, Pos() );
445
446 Item *tItem = new Item ( renderer, lrBorderKey, this, Pos() );
447 tItem->setRotation ( 180 );
448 m_borders << tItem;
449
450 tItem = new Item ( renderer, tbBorderKey, this, Pos() );
451 tItem->setRotation ( 180 );
452 m_borders << tItem;
453
454 m_borders << new Item ( renderer, lrBorderKey, this, Pos() );
455 for ( Item* item : qAsConst(m_borders) )
456 item->setZValue ( borderZValue );
457 }
458 if ( m_displayNotations ) {
459 QString lettersKey;
460 QString numbersKey;
461 if ( m_displayedPlayer == White ) {
462 lettersKey = whiteLettersKey;
463 numbersKey = whiteNumbersKey;
464 } else {
465 lettersKey = blackLettersKey;
466 numbersKey = blackNumbersKey;
467 }
468 m_notations << new Item ( renderer, lettersKey, this, Pos() );
469 m_notations << new Item ( renderer, numbersKey, this, Pos() );
470 m_notations << new Item ( renderer, lettersKey, this, Pos() );
471 m_notations << new Item ( renderer, numbersKey, this, Pos() );
472 for ( Item* item : qAsConst(m_notations) )
473 item->setZValue ( notationZValue );
474 }
475 addTiles();
476 updateGraphics();
477 }
478
updateGraphics()479 void Board::updateGraphics() {
480 if ( m_background )
481 m_background->setRenderSize ( sceneRect().size().toSize() );
482 QSizeF tileSize = renderer->boundsOnSprite ( whiteTileKey ).size();
483 QSizeF boardSize = 8 * tileSize;
484 qreal sideMargin;
485 qreal topMargin;
486 if ( m_displayBorders ) {
487 sideMargin = renderer->boundsOnSprite ( lrBorderKey ).width();
488 topMargin = renderer->boundsOnSprite ( tbBorderKey ).height();
489 } else {
490 sideMargin = 0.0;
491 topMargin = 0.0;
492 }
493 boardSize = boardSize + 2 * QSize ( sideMargin, topMargin );
494 qreal ratio = qMin ( sceneRect().width() / boardSize.width(), sceneRect().height() / boardSize.height() );
495 sideMargin *= ratio;
496 topMargin *= ratio;
497
498 QSizeF tpSize = tileSize * ratio;
499 m_tileSize = qFloor ( qMin ( tpSize.width(), tpSize.height() ) );
500 /*
501 if ( m_displayBorders )
502 {
503 if ( m_tileSize % 2 )
504 {
505 m_tileSize -= 1;
506 }
507 sideMargin = m_tileSize / 2;
508 topMargin = m_tileSize / 2;
509 }
510 */
511
512 QSize hBorderSize = QSize ( 8 * m_tileSize + 2 * qRound ( sideMargin ), qRound ( topMargin ) );
513 QSize vBorderSize = QSize ( qRound ( sideMargin ), 8 * m_tileSize );
514 int hBorderMargin = qRound ( topMargin );
515 int vBorderMargin = qRound ( sideMargin );
516
517
518 sideMargin = qMax ( sideMargin, ( sceneRect().width() - 8 * m_tileSize ) / 2 );
519 topMargin = qMax ( topMargin, ( sceneRect().height() - 8 * m_tileSize ) / 2 );
520 m_boardRect = QRect( sceneRect().topLeft().toPoint() + QPoint( sideMargin, topMargin ),
521 QSize( m_tileSize, m_tileSize ) * 8);
522
523 QSize tSize = QSizeF ( m_tileSize, m_tileSize ).toSize();
524 /*
525 * For historical reasons, QRect's
526 */
527 QPointF topBorderPoint = m_boardRect.topRight() + QPoint ( vBorderMargin, 0 );
528 QPointF rightBorderPoint = m_boardRect.bottomRight() + QPoint ( vBorderMargin, 0 );
529 QPointF bottomBorderPoint = m_boardRect.bottomLeft() - QPoint ( vBorderMargin, 0 );
530 QPointF leftBorderPoint = m_boardRect.topLeft() - QPoint ( vBorderMargin, 0 );
531
532 for ( Piece* p : qAsConst(m_grid) )
533 centerAndResize ( p, tSize );
534 for ( Item* t : qAsConst(m_tiles) )
535 centerAndResize ( t, tSize, Settings::animateBoard() );
536 for ( Item* t : qAsConst(markers) )
537 centerAndResize ( t, tSize );
538 if ( m_displayBorders ) {
539 m_borders[0]->moveAndResize ( bottomBorderPoint, m_tileSize, hBorderSize, Settings::animateBoard() );
540 m_borders[1]->moveAndResize ( rightBorderPoint, m_tileSize, vBorderSize, Settings::animateBoard() );
541 m_borders[2]->moveAndResize ( topBorderPoint, m_tileSize, hBorderSize, Settings::animateBoard() );
542 m_borders[3]->moveAndResize ( leftBorderPoint, m_tileSize, vBorderSize, Settings::animateBoard() );
543 }
544 if ( m_displayNotations ) {
545 m_notations[0]->moveAndResize ( bottomBorderPoint, m_tileSize, hBorderSize, Settings::animateBoard() );
546 m_notations[1]->moveAndResize ( m_boardRect.topRight(), m_tileSize, vBorderSize, Settings::animateBoard() );
547 m_notations[2]->moveAndResize ( m_boardRect.topLeft() - QPointF ( vBorderMargin, hBorderMargin ), m_tileSize, hBorderSize, Settings::animateBoard() );
548 m_notations[3]->moveAndResize ( leftBorderPoint, m_tileSize, vBorderSize, Settings::animateBoard() );
549 }
550 }
551
changeDisplayedPlayer()552 void Board::changeDisplayedPlayer() {
553 for ( Piece* p : qAsConst(m_grid) )
554 centerOnPos ( p );
555 for ( Item* i : qAsConst(markers) )
556 centerOnPos ( i );
557 if ( Settings::animateBoard() ) {
558 for ( Item* i : qAsConst(m_tiles) )
559 centerOnPos ( i );
560 }
561 if ( m_displayNotations ) {
562 if ( m_displayedPlayer == White ) {
563 m_notations[0]->setSpriteKey ( whiteLettersKey );
564 m_notations[1]->setSpriteKey ( whiteNumbersKey );
565 m_notations[2]->setSpriteKey ( whiteLettersKey );
566 m_notations[3]->setSpriteKey ( whiteNumbersKey );
567 } else {
568 m_notations[0]->setSpriteKey ( blackLettersKey );
569 m_notations[1]->setSpriteKey ( blackNumbersKey );
570 m_notations[2]->setSpriteKey ( blackLettersKey );
571 m_notations[3]->setSpriteKey ( blackNumbersKey );
572 }
573 }
574 Q_EMIT displayedPlayerChanged(m_displayedPlayer);
575 }
576
getPromotedType()577 PieceType Board::getPromotedType() {
578 PieceType piece = Queen;
579 QPointer<QDialog> dialog = new QDialog();
580 dialog->setWindowTitle(i18nc("@title:window", "Promotion"));
581 QWidget *widget = new QWidget();
582 QVBoxLayout *layout = new QVBoxLayout();
583 QDialogButtonBox *bBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
584 bBox->button(QDialogButtonBox::Ok)->setText(i18n("Promote"));
585 bBox->button(QDialogButtonBox::Ok)->setDefault(true);
586
587 Ui::PromotionWidget ui;
588 ui.setupUi ( widget );
589
590 layout->addWidget ( widget );
591 layout->addWidget ( bBox );
592 dialog->setLayout ( layout );
593
594 connect (bBox, &QDialogButtonBox::accepted, dialog, &QDialog::accept);
595 connect (bBox, &QDialogButtonBox::rejected, dialog, &QDialog::reject);
596
597 if ( dialog->exec() == QDialog::Accepted ) {
598 if ( ui.radioButtonKnight->isChecked() )
599 piece = Knight;
600 else if ( ui.radioButtonBishop->isChecked() )
601 piece = Bishop;
602 else if ( ui.radioButtonRook->isChecked() )
603 piece = Rook;
604 }
605 delete dialog;
606 return piece;
607 }
608