Merge from master bf883501679502d078aa719efed53ca4b2d4328c.
[tagua/yd.git] / src / mainwindow.cpp
blobd35fb77fc01019f7964d3957cf934202e77906d0
1 /*
2 Copyright (c) 2006-2008 Paolo Capriotti <p.capriotti@gmail.com>
3 (c) 2006-2007 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 */
11 #include "mainwindow.h"
12 #include <boost/scoped_ptr.hpp>
14 #include <QKeySequence>
15 #include <QStackedWidget>
16 #include <QDockWidget>
17 #include <QCloseEvent>
18 #include <QTextStream>
19 #include <QTextCodec>
21 #include <KAction>
22 #include <KActionCollection>
23 #include <KDebug>
24 #include <KFileDialog>
25 #include <KIcon>
26 #include <KLocale>
27 #include <kio/netaccess.h>
28 #include <KMessageBox>
29 #include <KMenuBar>
30 #include <KStandardAction>
31 #include <KTemporaryFile>
33 #include <core/behaviour.h>
34 #include <core/color.h>
35 #include <core/state.h>
36 #include "variant.h"
38 #include "actioncollection.h"
39 #include "chesstable.h"
40 #include "console.h"
41 #include "clock.h"
42 #include "newgame.h"
43 #include "variants.h"
44 #include "gameinfo.h"
45 #include "controllers/editgame.h"
46 #include "controllers/editposition.h"
47 #include "engineinfo.h"
48 #include "movelist_table.h"
49 #include "icsconnection.h"
50 #include "qconnect.h"
51 #include "mastersettings.h"
52 #include "flash.h"
53 #include "foreach.h"
54 #include "pgnparser.h"
55 #include "pref_highlight.h"
56 #include "pref_preferences.h"
57 #include "tabwidget.h"
59 using namespace Qt;
60 using namespace boost;
62 MainWindow::~MainWindow() {
63 delete console;
64 qApp->quit();
67 MainWindow::MainWindow(const QString& variant)
68 : KXmlGuiWindow(0)
69 , m_ui(actionCollection()) {
70 setObjectName("tagua_main");
71 m_main = new TabWidget(this);
72 m_main->setTabBarHidden(true);
73 setCentralWidget(m_main);
75 m_movelist_stack = new QStackedWidget;
77 connect(m_main, SIGNAL(currentChanged(int)),
78 this, SLOT(changeTab(int)));
79 connect(m_main, SIGNAL(closeTab()),
80 this, SLOT(closeTab()));
82 movelist_dock = new QDockWidget(this);
83 movelist_dock->setWidget(m_movelist_stack);
84 movelist_dock->setWindowTitle(i18n("Move list"));
85 movelist_dock->setObjectName("move_list");
86 addDockWidget(Qt::LeftDockWidgetArea, movelist_dock, Qt::Vertical);
87 movelist_dock->show();
89 Variant* v = Variants::self().create(variant);
90 if (v == NULL)
91 kFatal() << "Cannot instantiate variant \"" << variant << "\", aborting";
93 ChessTable* board = new ChessTable(v);
95 board->setFocus();
97 console_dock = new QDockWidget(this);
98 console = new Console(0, i18n("FICS Connection"));
99 console_dock->setWidget(console);
100 console_dock->setFocusProxy(console);
101 console_dock->setWindowTitle(i18n("Console"));
102 console_dock->setObjectName("console");
103 addDockWidget(Qt::BottomDockWidgetArea, console_dock, Qt::Horizontal);
104 console_dock->setWindowFlags(console_dock->windowFlags() & ~Qt::WindowStaysOnTopHint);
105 console_dock->show();
107 settings().onChange(this, "settingsChanged");
109 connect(board, SIGNAL(error(ErrorCode)), this, SLOT(displayErrorMessage(ErrorCode)));
111 setupActions();
112 setupGUI();
113 setupEngineMenu();
115 // start in edit game mode
116 newGame(v->name(), StatePtr(), true);
117 updateVariantActions();
120 ChessTable* MainWindow::table() {
121 return qobject_cast<ChessTable*>(m_main->currentWidget());
124 KAction* MainWindow::installRegularAction(const QString& name, const KIcon& icon, const QString& text, QObject* obj, const char* slot) {
125 KAction* temp = new KAction(icon, text, this);
126 actionCollection()->addAction(name, temp);
127 connect(temp, SIGNAL(triggered(bool)), obj, slot);
128 return temp;
131 void MainWindow::setupEngineMenu() {
132 QMenu* engine_menu = 0;
133 SettingArray engine_settings = settings().group("engines").array("engine");
134 foreach (Settings s, engine_settings) {
135 if (!engine_menu) {
136 // this way the menu is created only if there is at least one engine
137 engine_menu = menuBar()->addMenu(i18n("E&ngines"));
140 QString name;
141 EngineDetails engine_details;
142 engine_details.load(s);
144 EngineInfo* engine = new EngineInfo(engine_details, ui());
146 m_engines.push_back(engine);
148 QMenu* menu = engine_menu->addMenu(engine_details.name);
151 KAction* play_white = new KAction(i18n("Play as &white"), this);
152 play_white->setCheckable(true);
153 connect(play_white, SIGNAL(triggered()), engine, SLOT(playAsWhite()));
154 menu->addAction(play_white);
157 KAction* play_black = new KAction(i18n("Play as &black"), this);
158 play_black->setCheckable(true);
159 connect(play_black, SIGNAL(triggered()), engine, SLOT(playAsBlack()));
160 menu->addAction(play_black);
162 #if 0 // disable analysis for the moment
164 KAction* analyze = new KAction(i18n("&Analyze"), this);
165 analyze->setCheckable(true);
166 connect(analyze, SIGNAL(triggered()), engine, SLOT(analyze()));
167 menu->addAction(analyze);
169 #endif
173 void MainWindow::setupActions() {
174 KAction* tmp;
176 KStandardAction::openNew(this, SLOT(newGame()), actionCollection());
177 KStandardAction::open(this, SLOT(loadGame()), actionCollection());
178 KStandardAction::save(this, SLOT(saveGame()), actionCollection());
179 KStandardAction::saveAs(this, SLOT(saveGameAs()), actionCollection());
180 KStandardAction::quit(this, SLOT(quit()), actionCollection());
181 KStandardAction::preferences(this, SLOT(preferences()), actionCollection());
183 installRegularAction("back", KIcon("go-previous"), i18n("&Back"), &ui(), SLOT(back()));
184 installRegularAction("forward", KIcon("go-next"), i18n("&Forward"), &ui(), SLOT(forward()));
185 installRegularAction("begin", KIcon("go-first"), i18n("Be&gin"), &ui(), SLOT(gotoFirst()));
186 installRegularAction("end", KIcon("go-last"), i18n("&End"), &ui(), SLOT(gotoLast()));
187 installRegularAction("connect", KIcon("network-connect"), i18n("&Connect"), this, SLOT(icsConnect()));
188 installRegularAction("disconnect", KIcon("network-disconnect"),
189 i18n("&Disconnect"), this, SLOT(icsDisconnect()));
191 KStandardAction::undo(&ui(), SLOT(undo()), actionCollection());
192 KStandardAction::redo(&ui(), SLOT(redo()), actionCollection());
194 // installRegularAction("pgnCopy", KIcon("edit-copy"), i18n("Copy PGN"), this, SLOT(pgnCopy()));
195 // installRegularAction("pgnPaste", KIcon("edit-paste"), i18n("Paste PGN"), this, SLOT(pgnPaste()));
196 installRegularAction("editPosition", KIcon("edit"), i18n("&Edit position"), this, SLOT(editPosition()));
197 installRegularAction("clearBoard", KIcon("edit-delete"), i18n("&Clear board"), &ui(), SLOT(clearBoard()));
198 installRegularAction("setStartingPosition", KIcon("contents"), i18n("&Set starting position"),
199 &ui(), SLOT(setStartingPosition()));
200 // installRegularAction("copyPosition", KIcon(), i18n("&Copy position"), &ui(), SLOT(copyPosition()));
201 // installRegularAction("pastePosition", KIcon(), i18n("&Paste position"), &ui(), SLOT(pastePosition()));
202 tmp = installRegularAction("flip", KIcon("object-rotate-left"), i18n("&Flip view"), this, SLOT(flipView()));
203 tmp->setShortcut(Qt::CTRL + Qt::Key_F);
204 installRegularAction("toggleConsole", KIcon("utilities-terminal"), i18n("Toggle &console"), this, SLOT(toggleConsole()));
205 installRegularAction("toggleMoveList", KIcon("view-list-tree"), i18n("Toggle &move list"), this, SLOT(toggleMoveList()));
208 void MainWindow::updateVariantActions(bool unplug) {
209 ActionCollection* variant_actions = m_ui.variantActions();
210 if (unplug)
211 unplugActionList("variantActions");
212 if (variant_actions) {
213 plugActionList("variantActions", variant_actions->actions());
215 else {
216 kWarning() << "No variant actions";
220 void MainWindow::readSettings() { }
221 void MainWindow::writeSettings() { }
223 void MainWindow::closeEvent(QCloseEvent* e) {
224 e->accept();
225 writeSettings();
226 delete this;
230 void MainWindow::keyPressEvent(QKeyEvent* event) {
231 if (event->key() == Qt::Key_F5) {
232 ui().createCtrlAction();
236 void MainWindow::keyReleaseEvent(QKeyEvent* event) {
237 if (event->key() == Qt::Key_F5) {
238 ui().destroyCtrlAction();
242 void MainWindow::changeTab(int index) {
243 m_ui.setCurrentTab(m_main->currentWidget());
244 m_movelist_stack->setCurrentIndex(index);
245 updateVariantActions();
248 void MainWindow::closeTab() {
249 if (m_main->count() > 1) {
250 int old_index = m_main->currentIndex();
251 ChessTable* old_board = table();
253 int new_index = old_index - 1;
254 if (new_index < 0)
255 new_index = old_index + 1;
256 m_main->setCurrentIndex(new_index);
258 m_main->removeTab(old_index);
259 m_movelist_stack->removeWidget(m_movelist_stack->widget(old_index));
260 m_ui.removeController(old_board);
262 if (m_main->count() <= 1) {
263 m_main->setTabBarHidden(true);
266 #if 0 // this doesn't work... why?
267 ChessTable* old_board = table();
268 m_ui.removeController(old_board);
269 m_movelist_stack->removeWidget(
270 m_movelist_stack->widget(m_main->currentIndex()));
271 m_main->removeTab(m_main->currentIndex());
273 delete old_board;
275 if (m_main->count() <= 1) {
276 m_main->hideTabBar();
279 // update ui controller (just in case...)
280 m_ui.setCurrentTab(m_main->currentWidget());
281 #endif
285 void MainWindow::createTab(ChessTable* board, const shared_ptr<Controller>& controller,
286 const QString& caption, int index) {
287 if (index == -1)
288 index = m_main->addTab(board, caption);
289 else
290 m_main->insertTab(index, board, caption);
292 m_ui.addController(board, controller);
293 // m_ui.setCurrentTab(board);
294 m_movelist_stack->addWidget(board->moveListTable());
296 m_main->setCurrentIndex(index);
297 m_movelist_stack->setCurrentIndex(index);
299 if (m_main->count() > 1) m_main->setTabBarHidden(false);
303 void MainWindow::cleanupGame(const QString& what, const QString& result) {
304 Q_UNUSED(what);
305 Q_UNUSED(result);
307 cleanupGame();
310 void MainWindow::cleanupGame() {
311 ui().detach();
312 ui().end();
315 bool MainWindow::newGame(const QString& variantName,
316 const StatePtr& startingPos,
317 bool newTab) {
318 Variant* variant = Variants::self().create(variantName);
319 if (!variant) {
320 kWarning() << "no variant" << variantName << "found";
321 variant = Variants::self().create("chess");
324 if (variant) {
325 ChessTable* board = newTab ? new ChessTable(variant) : table();
326 QString text = QString("Editing %1 game").arg(variant->name().toLower());
328 shared_ptr<Controller> controller(
329 new EditGameController(board, startingPos));
330 if (newTab) {
331 createTab(board, controller, text);
333 else {
334 unplugActionList("variantActions");
335 ui().setController(controller);
336 table()->setPlayers(Player(), Player());
337 m_main->setTabText(m_main->currentIndex(), text);
338 updateVariantActions(false);
340 return true;
342 else {
343 kError() << "Could not find the chess variant";
344 exit(1);
345 return false;
350 void MainWindow::editPosition() {
351 //BROKEN
352 #if 0
353 shared_ptr<Controller> controller(new EditPositionController(table(), ChessVariant::info()));
354 m_main->setTabText(m_main->currentIndex(), "Editing chess position");
355 ui().setController(controller);
356 #endif
359 void MainWindow::setupGame(const GameInfo* gameInfo, const PositionInfo& style12) {
360 QString variantCode = gameInfo->variant();
361 Variant* variant = Variants::self().create(variantCode);
362 shared_ptr<EditGameController> controller(
363 new EditGameController(table()));
364 Q_ASSERT(style12.relation == PositionInfo::NotMyMove ||
365 style12.relation == PositionInfo::MyMove);
367 // set opponent side
368 const IColor* turn = style12.position->turn();
369 const IBehaviour* behaviour = style12.position->behaviour();
370 if (!behaviour) return;
371 const IColor* side = style12.relation == PositionInfo::MyMove ?
372 behaviour->opponent(turn) : turn;
374 if (controller->addICSPlayer(side, style12.gameNumber, m_connection)) {
375 ui().setController(controller);
376 table()->setPlayers(gameInfo->white(), gameInfo->black());
377 m_main->setTabText(m_main->currentIndex(),
378 QString("FICS Game - %1 vs %2").arg(style12.whitePlayer)
379 .arg(style12.blackPlayer));
383 void MainWindow::setupExaminedGame(const GameInfo* gameInfo, const PositionInfo& style12) {
384 table()->setVariant(
385 Variants::self().create(gameInfo->variant()));
386 shared_ptr<EditGameController> controller(
387 new EditGameController(table()));
388 if (controller->setExaminationMode(style12.gameNumber, m_connection)) {
389 table()->setPlayers(Player(style12.whitePlayer, -1),
390 Player(style12.blackPlayer, -1));
391 ui().setController(controller);
392 m_main->setTabText(m_main->currentIndex(),
393 QString("Examining - %1 vs %2").arg(style12.whitePlayer)
394 .arg(style12.blackPlayer));
399 void MainWindow::setupObservedGame(const GameInfo* g, const PositionInfo& style12) {
400 Variant* variant = Variants::self().create(g->variant());
401 std::auto_ptr<ChessTable> board(new ChessTable(variant));
403 shared_ptr<EditGameController> controller(
404 new EditGameController(board.get()));
405 if (controller->setObserveMode(style12.gameNumber, m_connection)) {
406 board->setPlayers(Player(style12.whitePlayer, -1),
407 Player(style12.blackPlayer, -1));
408 // ui().setController(controller);
409 //kDebug() << "adding tab";
410 createTab(board.get(), controller,
411 QString("Observing - %1 vs %2").arg(style12.whitePlayer)
412 .arg(style12.blackPlayer));
413 board.release();
417 void MainWindow::setupPGN(const QString& s) {
418 PGN pgn(s);
420 std::map<QString, QString>::const_iterator var = pgn.m_tags.find("Variant");
421 Variant* variant;
423 if (var == pgn.m_tags.end()) {
424 variant = Variants::self().create("chess");
426 else if (!(variant = Variants::self().create(var->second))) {
427 kDebug() << " --> MainWindow::setupPGN: Error, no such variant " << var->second;
428 return;
431 shared_ptr<EditGameController> controller(
432 new EditGameController(table()));
433 ui().setController(controller);
434 controller->loadPGN(pgn);
436 // table()->setPlayers(gameInfo->white(), gameInfo->black());
437 // m_main->setTabText(m_main->currentIndex(),
438 // QString("FICS Game - %1 vs %2").arg(style12.whitePlayer)
439 // .arg(style12.blackPlayer));
442 bool MainWindow::openFile(const QString& filename) {
443 QFileInfo info(filename);
445 if(info.isDir()) {
446 KMessageBox::sorry(this, i18n("You have specified a folder"), i18n("Error"));
447 return false;
450 if(!info.exists() || !info.isFile()) {
451 KMessageBox::sorry(this, i18n("The specified file does not exist"), i18n("Error"));
452 return false;
455 QFile file(filename);
457 if(!file.open(QIODevice::ReadOnly)) {
458 KMessageBox::sorry(this, i18n("You do not have read permission to this file."), i18n("Error"));
459 return false;
462 QTextStream stream(&file);
463 QTextCodec *codec;
464 codec = QTextCodec::codecForLocale();
465 stream.setCodec(codec);
467 setupPGN(stream.readAll());
468 //ui().pgnPaste(stream.readAll());
469 return true;
472 void MainWindow::loadGame() {
473 KUrl url = KFileDialog::getOpenUrl(KUrl(), "*.pgn", this, i18n("Open PGN file"));
475 if(url.isEmpty())
476 return;
478 QString tmp_file;
479 if (KIO::NetAccess::download(url, tmp_file, this)) {
480 openFile(tmp_file);
481 KIO::NetAccess::removeTempFile(tmp_file);
483 else
484 KMessageBox::error(this, KIO::NetAccess::lastErrorString());
487 void MainWindow::saveGame() {
488 if (ui().url().isEmpty())
489 saveGameAs();
490 else
491 ui().setUrl(saveGame(ui().url()));
494 void MainWindow::saveGameAs() {
495 ui().setUrl(saveGame(KFileDialog::getSaveUrl(KUrl(), "*.pgn", this, i18n("Save PGN file"))));
498 bool MainWindow::checkOverwrite(const KUrl& url) {
499 if (!url.isLocalFile())
500 return true;
502 QFileInfo info(url.path());
503 if (!info.exists())
504 return true;
506 return KMessageBox::Cancel != KMessageBox::warningContinueCancel(this,
507 i18n("A file named \"%1\" already exists. "
508 "Are you sure you want to overwrite it?" , info.fileName()),
509 i18n("Overwrite File?"),
510 KGuiItem(i18n("&Overwrite")));
513 KUrl MainWindow::saveGame(const KUrl& url) {
514 if (!checkOverwrite(url))
515 return KUrl();
517 if (url.isEmpty())
518 return KUrl();
520 if (!url.isLocalFile()) {
521 // save in a temporary file
522 KTemporaryFile tmp_file;
523 tmp_file.open();
524 saveFile(tmp_file);
525 if (!KIO::NetAccess::upload(tmp_file.fileName(), url, this))
526 return KUrl();
528 else {
529 QFile file(url.path());
530 if (!file.open(QIODevice::WriteOnly))
531 return KUrl();
532 saveFile(file);
535 return url;
538 void MainWindow::saveFile(QFile& file) {
539 QTextStream stream(&file);
540 QTextCodec *codec;
541 codec = QTextCodec::codecForLocale();
542 stream.setCodec(codec);
543 stream << ui().currentPGN() << "\n";
546 void MainWindow::createConnection(const QString& username, const QString& password,
547 const QString& host, quint16 port,
548 const QString& timeseal, const QString& timeseal_cmd) {
549 m_connection = shared_ptr<ICSConnection>(new ICSConnection);
551 connect(m_connection.get(), SIGNAL(established()), this, SLOT(onEstablishConnection()));
552 connect(m_connection.get(), SIGNAL(hostLookup()), this, SLOT(onHostLookup()));
553 connect(m_connection.get(), SIGNAL(hostFound()), this, SLOT(onHostFound()));
555 connect(m_connection.get(), SIGNAL(receivedLine(QString, int)), console, SLOT(displayText(QString, int)));
556 connect(m_connection.get(), SIGNAL(receivedText(QString, int)), console, SLOT(displayText(QString, int)));
558 connect(console, SIGNAL(receivedInput(const QString&)), m_connection.get(), SLOT(sendText(const QString&)));
559 connect(console, SIGNAL(notify()), this, SLOT(flash()));
561 connect(m_connection.get(), SIGNAL(loginPrompt()), this, SLOT(sendLogin()));
562 connect(m_connection.get(), SIGNAL(registeredNickname()), this, SLOT(sendBlankPassword()));
563 connect(m_connection.get(), SIGNAL(prompt()), this, SLOT(prompt()));
566 connect(m_connection.get(), SIGNAL(creatingExaminedGame(const GameInfo*, const PositionInfo&)),
567 this, SLOT(setupExaminedGame(const GameInfo*, const PositionInfo&)));
568 connect(m_connection.get(), SIGNAL(endingExaminedGame(int)), this, SLOT(cleanupGame()));
570 connect(m_connection.get(), SIGNAL(creatingObservedGame(const GameInfo*, const PositionInfo&)),
571 this, SLOT(setupObservedGame(const GameInfo*, const PositionInfo&)));
572 connect(m_connection.get(), SIGNAL(endingObservedGame(int)), this, SLOT(cleanupGame()));
575 connect(m_connection.get(), SIGNAL(creatingGame(const GameInfo*, const PositionInfo&)),
576 this, SLOT(setupGame(const GameInfo*, const PositionInfo&)));
577 connect(m_connection.get(), SIGNAL(endingGame(const QString&, const QString&)),
578 this, SLOT(cleanupGame(const QString&, const QString&)));
579 connect(m_connection.get(), SIGNAL(notification()), this, SLOT(flash()));
581 m_connection->establish(host.toAscii().constData(), port, timeseal, timeseal_cmd);
582 console->show();
584 // send username / password combination
585 if (!username.isEmpty()) {
586 m_connection->sendText(username);
587 m_connection->sendText(password);
590 quickConnectDialog.reset();
593 void MainWindow::icsConnect() {
594 quickConnectDialog = shared_ptr<QConnect>(new QConnect(this));
595 connect(quickConnectDialog.get(),
596 SIGNAL(acceptConnection(const QString&,
597 const QString&,
598 const QString&,
599 quint16,
600 const QString&,
601 const QString&)),
602 this,
603 SLOT(createConnection(const QString&,
604 const QString&,
605 const QString&,
606 quint16,
607 const QString&,
608 const QString&)));
609 quickConnectDialog->show();
612 void MainWindow::destroyConnection() {
613 m_connection.reset();
616 void MainWindow::icsDisconnect() {
617 destroyConnection();
618 console->hide();
619 console->clear();
622 void MainWindow::testConnect() {
623 Settings s_ics = settings().group("ics");
624 if (s_ics["username"]) {
625 QString username = s_ics["username"].value<QString>();
626 QString password = (s_ics["password"] | "");
627 QString host = (s_ics["icsHost"] | "freechess.org");
628 quint16 port = (s_ics["icsPort"] | 5000);
629 createConnection(username, password, host, port, QString(), QString() );
631 else icsConnect();
635 void MainWindow::onEstablishConnection() {
636 // kDebug() << "connection established";
639 void MainWindow::onConnectionError(int ) {
640 // kDebug() << "connection error (" << code << ")";
643 void MainWindow::onHostLookup() {
644 // kDebug() << "hostLookup..." << std::flush;
647 void MainWindow::onHostFound() {
648 // kDebug() << "found";
652 void MainWindow::sendLogin() {
653 // kDebug() << "sending username";
654 // connection->sendText(connection->username());
657 void MainWindow::sendBlankPassword() {
658 m_connection->sendText("");
661 void MainWindow::prompt() {
662 if (!m_connection->initialized()) {
663 m_connection->startup();
664 m_connection->setInitialized();
668 void MainWindow::newGame() {
669 StatePtr pos = ui().position();
670 scoped_ptr<NewGame> dialog(new NewGame(this));
671 if (dialog->exec() == QDialog::Accepted) {
672 if (!newGame(dialog->variant(), StatePtr(), dialog->newTab()))
673 QMessageBox::information(this, i18n("Error"), i18n("Error creating game"));
677 void MainWindow::quit() {
678 delete this;
681 void MainWindow::flipView() {
682 table()->flip();
685 void MainWindow::toggleConsole() {
686 if (console_dock->isVisible())
687 console_dock->hide();
688 else {
689 console_dock->show();
690 console_dock->setFocus(Qt::MouseFocusReason
691 /*Qt::ActiveWindowFocusReason*/ /*Qt::OtherFocusReason*/);
695 void MainWindow::toggleMoveList() {
696 if (movelist_dock->isVisible())
697 movelist_dock->hide();
698 else {
699 movelist_dock->show();
700 movelist_dock->setFocus(Qt::OtherFocusReason);
705 void MainWindow::displayMessage(const QString& msg) {
706 Q_UNUSED(msg); // TODO
707 // statusBar()->message(msg, 2000);
710 void MainWindow::displayErrorMessage(ErrorCode code) {
711 switch(code) {
712 case InvalidMove:
713 displayMessage(i18n("Illegal move"));
714 break;
718 void MainWindow::flash() {
719 if( !isAncestorOf(QApplication::focusWidget()) )
720 Flash::flash(this);
723 #if 0
724 void MainWindow::prefHighlight() {
725 PrefHighlight dialog;
726 int result = dialog.exec();
727 if (result == QDialog::Accepted) {
728 dialog.apply();
731 #endif
733 void MainWindow::preferences() {
734 Preferences dialog(ui().currentVariant());
735 int result = dialog.exec();
736 if (result == QDialog::Accepted)
737 dialog.apply();
740 void MainWindow::settingsChanged() {
741 ui().reloadSettings();