Add shortcut for Game - New game (Ctrl+N).
[sloppygui.git] / projects / gui / src / mainwindow.cpp
bloba322bb9b085d95b6b58d3e4c759a23c20dab335f
1 /*
2 This file is part of SloppyGUI.
4 SloppyGUI is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 SloppyGUI 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
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with SloppyGUI. If not, see <http://www.gnu.org/licenses/>.
18 #include <QtGui>
19 #include <QDebug>
20 #include <QApplication>
21 #include <QVBoxLayout>
22 #include <QHBoxLayout>
24 #include <chessgame.h>
25 #include <chessplayer.h>
26 #include <xboardengine.h>
27 #include <uciengine.h>
28 #include <timecontrol.h>
29 #include <engineconfiguration.h>
31 #include "mainwindow.h"
32 #include "graphicschessboarditem.h"
33 #include "chessboardview.h"
34 #include "newgamedlg.h"
35 #include "chessclock.h"
36 #include "engineconfigurationmodel.h"
37 #include "enginemanagementdlg.h"
39 MainWindow::MainWindow()
41 QHBoxLayout* clockLayout = new QHBoxLayout();
42 for (int i = 0; i < 2; i++)
44 m_chessClock[i] = new ChessClock();
45 clockLayout->addWidget(m_chessClock[i]);
48 m_chessboardView = new ChessboardView;
49 m_chessboardScene = new QGraphicsScene(m_chessboardView);
50 m_chessboardView->setScene(m_chessboardScene);
51 m_chessboardView->setMinimumSize(400, 400);
53 QVBoxLayout* mainLayout = new QVBoxLayout();
54 mainLayout->addLayout(clockLayout);
55 mainLayout->addWidget(m_chessboardView);
57 m_visualChessboard = new GraphicsChessboardItem();
58 m_chessboardScene->addItem(m_visualChessboard);
60 QWidget* mainWidget = new QWidget(this);
61 mainWidget->setLayout(mainLayout);
62 setCentralWidget(mainWidget);
64 setStatusBar(new QStatusBar());
66 m_engineConfigurations = new EngineConfigurationModel(this);
68 createActions();
69 createMenus();
70 createToolBars();
71 createDockWindows();
73 readSettings();
76 void MainWindow::closeEvent(QCloseEvent* event)
78 writeSettings();
79 event->accept();
82 void MainWindow::createActions()
84 m_newGameAct = new QAction(tr("&New game..."), this);
85 m_newGameAct->setShortcut(QKeySequence("Ctrl+N"));
87 m_printGameAct = new QAction(tr("&Print..."), this);
89 m_quitGameAct = new QAction(tr("&Quit"), this);
90 m_quitGameAct->setShortcut(QKeySequence(tr("Ctrl+Q")));
92 m_manageEnginesAct = new QAction(tr("Manage..."), this);
94 connect(m_newGameAct, SIGNAL(triggered(bool)), this, SLOT(newGame()));
95 connect(m_printGameAct, SIGNAL(triggered(bool)), this, SLOT(printGame()));
96 connect(m_quitGameAct, SIGNAL(triggered(bool)), this, SLOT(close()));
98 connect (m_manageEnginesAct, SIGNAL(triggered(bool)), this,
99 SLOT(manageEngines()));
102 void MainWindow::createMenus()
104 m_gameMenu = menuBar()->addMenu(tr("&Game"));
105 m_gameMenu->addAction(m_newGameAct);
106 m_gameMenu->addSeparator();
107 m_gameMenu->addAction(m_printGameAct);
108 m_gameMenu->addSeparator();
109 m_gameMenu->addAction(m_quitGameAct);
111 m_viewMenu = menuBar()->addMenu(tr("&View"));
113 m_enginesMenu = menuBar()->addMenu(tr("En&gines"));
114 m_enginesMenu->addAction(m_manageEnginesAct);
116 m_helpMenu = menuBar()->addMenu(tr("&Help"));
118 m_debugMenu = menuBar()->addMenu("&Debug");
121 void MainWindow::createToolBars()
123 // Create tool bars here, use actions from createActions()
124 // See: createActions(), QToolBar documentation
127 void MainWindow::createDockWindows()
129 // Log
130 QDockWidget* logDock = new QDockWidget(tr("Log"), this);
131 QTextEdit* logTextEdit = new QTextEdit(logDock);
132 logTextEdit->setReadOnly(true);
133 logDock->setWidget(logTextEdit);
135 addDockWidget(Qt::BottomDockWidgetArea, logDock);
137 // Engine debug
138 QDockWidget* engineDebugDock = new QDockWidget(tr("Engine Debug"), this);
139 m_engineDebugTextEdit = new QTextEdit(engineDebugDock);
140 m_engineDebugTextEdit->setReadOnly(true);
141 engineDebugDock->setWidget(m_engineDebugTextEdit);
143 addDockWidget(Qt::BottomDockWidgetArea, engineDebugDock);
146 void MainWindow::writeSettings()
148 QSettings settings(QSettings::IniFormat, QSettings::UserScope,
149 QCoreApplication::organizationName(),
150 QCoreApplication::applicationName());
152 const QList<EngineConfiguration> engines = m_engineConfigurations->configurations();
154 settings.beginWriteArray("engines");
155 for (int i = 0; i < engines.size(); i++)
157 settings.setArrayIndex(i);
158 settings.setValue("name", engines.at(i).name());
159 settings.setValue("command", engines.at(i).command());
160 settings.setValue("working_directory", engines.at(i).workingDirectory());
161 settings.setValue("protocol", engines.at(i).protocol());
163 settings.endArray();
166 void MainWindow::readSettings()
168 QSettings settings(QSettings::IniFormat, QSettings::UserScope,
169 QCoreApplication::organizationName(),
170 QCoreApplication::applicationName());
172 int size = settings.beginReadArray("engines");
173 for (int i = 0; i < size; i++)
175 settings.setArrayIndex(i);
176 EngineConfiguration config;
177 config.setName(settings.value("name").toString());
178 config.setCommand(settings.value("command").toString());
179 config.setWorkingDirectory(
180 settings.value("working_directory").toString());
181 config.setProtocol(EngineConfiguration::ChessEngineProtocol(
182 settings.value("protocol").toInt()));
184 m_engineConfigurations->addConfiguration(config);
186 settings.endArray();
189 void MainWindow::newGame()
191 NewGameDialog dlg(m_engineConfigurations, this);
192 if (dlg.exec() != QDialog::Accepted)
193 return;
195 if (dlg.whitePlayerType() == NewGameDialog::Human ||
196 dlg.blackPlayerType() == NewGameDialog::Human)
198 qDebug() << "Human players are not currently supported.";
199 return;
202 const EngineConfiguration engineConfig[2] =
204 m_engineConfigurations->configurations().at(dlg.selectedWhiteEngine()),
205 m_engineConfigurations->configurations().at(dlg.selectedBlackEngine())
208 QProcess* engineProcess[2] = { new QProcess(this), new QProcess(this) };
210 // Set up working directories for the engines:
211 // If user hasn't set any directory, use temp
212 for (int i = 0; i < 2; i++)
214 QProcess* engine = engineProcess[i];
215 const EngineConfiguration& config = engineConfig[i];
217 if (config.workingDirectory().isEmpty())
218 engine->setWorkingDirectory(QDir::tempPath());
219 else
220 engine->setWorkingDirectory(config.workingDirectory());
222 engine->start(config.command());
223 if (!engine->waitForStarted())
225 qDebug() << "Cannot start the engine process:" << config.command();
226 return;
230 ChessGame* chessgame = new ChessGame(this);
232 connect(chessgame, SIGNAL(moveHappened(const Chess::Move&)),
233 m_visualChessboard, SLOT(makeMove(const Chess::Move&)));
235 ChessPlayer* player[2] = { 0, 0 };
237 TimeControl tc;
238 tc.setTimePerTc(180000);
239 tc.setMovesPerTc(40);
241 for (int i = 0; i < 2; i++)
243 switch (engineConfig[i].protocol())
245 case EngineConfiguration::UCI:
246 player[i] = new UciEngine(engineProcess[i], chessgame->chessboard(), tc, this);
247 break;
248 default:
249 player[i] = new XboardEngine(engineProcess[i], chessgame->chessboard(), tc, this);
250 break;
253 connect(player[i], SIGNAL(startedThinking(int)),
254 m_chessClock[i], SLOT(start(int)));
256 connect(player[i], SIGNAL(moveMade(const Chess::Move&)),
257 m_chessClock[i], SLOT(stop()));
259 connect(player[i], SIGNAL(resign()),
260 m_chessClock[i], SLOT(stop()));
262 connect(player[i], SIGNAL(debugMessage(const QString&)),
263 m_engineDebugTextEdit, SLOT(append(const QString&)));
266 chessgame->newGame(player[0], player[1]);
269 void MainWindow::printGame()
271 QPrinter printer(QPrinter::HighResolution);
273 QPrintDialog* printDialog = new QPrintDialog(&printer, this);
274 printDialog->setWindowTitle(tr("Print game"));
276 if (printDialog->exec() != QDialog::Accepted)
277 return;
279 QPainter painter;
280 painter.begin(&printer);
282 m_chessboardView->render(&painter);
284 painter.end();
287 void MainWindow::manageEngines()
289 QList<EngineConfiguration> oldConfigurations =
290 m_engineConfigurations->configurations();
292 EngineManagementDialog dlg(m_engineConfigurations, this);
293 if (dlg.exec() != QDialog::Accepted)
295 // Release the engine configurations model and use
296 // the old configurations as base for the new model
297 delete m_engineConfigurations;
298 m_engineConfigurations = new EngineConfigurationModel(oldConfigurations);