Replaced all std::cout with kDebug.
[tagua/yd.git] / src / mainwindow.cpp
blob12fa3adad9ebdf65dfc27e0a3835914bb9502e9f
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 "actioncollection.h"
34 #include "chesstable.h"
35 #include "console.h"
36 #include "clock.h"
37 #include "newgame.h"
38 #include "variants.h"
39 #include "gameinfo.h"
40 #include "controllers/editgame.h"
41 #include "controllers/editposition.h"
42 #include "engineinfo.h"
43 #include "movelist_table.h"
44 #include "icsconnection.h"
45 #include "qconnect.h"
46 #include "mastersettings.h"
47 #include "flash.h"
48 #include "foreach.h"
49 #include "pgnparser.h"
50 #include "pref_highlight.h"
51 #include "pref_preferences.h"
52 #include "tabwidget.h"
54 using namespace Qt;
55 using namespace boost;
57 MainWindow::~MainWindow() {
58 delete console;
59 qApp->quit();
62 MainWindow::MainWindow(const QString& variant)
63 : KXmlGuiWindow(0)
64 , m_ui(actionCollection()) {
65 setObjectName("tagua_main");
66 m_main = new TabWidget(this);
67 m_main->setTabBarHidden(true);
68 setCentralWidget(m_main);
70 m_movelist_stack = new QStackedWidget;
72 connect(m_main, SIGNAL(currentChanged(int)),
73 this, SLOT(changeTab(int)));
74 connect(m_main, SIGNAL(closeTab()),
75 this, SLOT(closeTab()));
77 movelist_dock = new QDockWidget(this);
78 movelist_dock->setWidget(m_movelist_stack);
79 movelist_dock->setWindowTitle(i18n("Move list"));
80 movelist_dock->setObjectName("move_list");
81 addDockWidget(Qt::LeftDockWidgetArea, movelist_dock, Qt::Vertical);
82 movelist_dock->show();
84 ChessTable* board = new ChessTable;
86 board->setFocus();
88 console_dock = new QDockWidget(this);
89 console = new Console(0, i18n("FICS Connection"));
90 console_dock->setWidget(console);
91 console_dock->setFocusProxy(console);
92 console_dock->setWindowTitle(i18n("Console"));
93 console_dock->setObjectName("console");
94 addDockWidget(Qt::BottomDockWidgetArea, console_dock, Qt::Horizontal);
95 console_dock->setWindowFlags(console_dock->windowFlags() & ~Qt::WindowStaysOnTopHint);
96 console_dock->show();
98 settings().onChange(this, "settingsChanged");
100 connect(board, SIGNAL(error(ErrorCode)), this, SLOT(displayErrorMessage(ErrorCode)));
101 //BROKEN connect(board->clock(), SIGNAL(labelClicked(int)), &ui(), SLOT(setTurn(int)));
103 setupActions();
104 setupGUI();
105 setupEngineMenu();
107 // start in edit game mode
108 newGame(variant, AbstractPosition::Ptr(), true);
109 updateVariantActions();
112 ChessTable* MainWindow::table() {
113 return qobject_cast<ChessTable*>(m_main->currentWidget());
116 KAction* MainWindow::installRegularAction(const QString& name, const KIcon& icon, const QString& text, QObject* obj, const char* slot) {
117 KAction* temp = new KAction(icon, text, this);
118 actionCollection()->addAction(name, temp);
119 connect(temp, SIGNAL(triggered(bool)), obj, slot);
120 return temp;
123 void MainWindow::setupEngineMenu() {
124 QMenu* engine_menu = 0;
125 SettingArray engine_settings = settings().group("engines").array("engine");
126 foreach (Settings s, engine_settings) {
127 if (!engine_menu) {
128 // this way the menu is created only if there is at least one engine
129 engine_menu = menuBar()->addMenu(i18n("E&ngines"));
132 QString name;
133 EngineDetails engine_details;
134 engine_details.load(s);
136 EngineInfo* engine = new EngineInfo(engine_details, ui());
138 m_engines.push_back(engine);
140 QMenu* menu = engine_menu->addMenu(engine_details.name);
143 KAction* play_white = new KAction(i18n("Play as &white"), this);
144 play_white->setCheckable(true);
145 connect(play_white, SIGNAL(triggered()), engine, SLOT(playAsWhite()));
146 menu->addAction(play_white);
149 KAction* play_black = new KAction(i18n("Play as &black"), this);
150 play_black->setCheckable(true);
151 connect(play_black, SIGNAL(triggered()), engine, SLOT(playAsBlack()));
152 menu->addAction(play_black);
154 #if 0 // disable analysis for the moment
156 KAction* analyze = new KAction(i18n("&Analyze"), this);
157 analyze->setCheckable(true);
158 connect(analyze, SIGNAL(triggered()), engine, SLOT(analyze()));
159 menu->addAction(analyze);
161 #endif
165 void MainWindow::setupActions() {
166 KAction* tmp;
168 KStandardAction::openNew(this, SLOT(newGame()), actionCollection());
169 KStandardAction::open(this, SLOT(loadGame()), actionCollection());
170 KStandardAction::save(this, SLOT(saveGame()), actionCollection());
171 KStandardAction::saveAs(this, SLOT(saveGameAs()), actionCollection());
172 KStandardAction::quit(this, SLOT(quit()), actionCollection());
173 KStandardAction::preferences(this, SLOT(preferences()), actionCollection());
175 installRegularAction("back", KIcon("go-previous"), i18n("&Back"), &ui(), SLOT(back()));
176 installRegularAction("forward", KIcon("go-next"), i18n("&Forward"), &ui(), SLOT(forward()));
177 installRegularAction("begin", KIcon("go-first"), i18n("Be&gin"), &ui(), SLOT(gotoFirst()));
178 installRegularAction("end", KIcon("go-last"), i18n("&End"), &ui(), SLOT(gotoLast()));
179 installRegularAction("connect", KIcon("network-connect"), i18n("&Connect"), this, SLOT(icsConnect()));
180 installRegularAction("disconnect", KIcon("network-disconnect"),
181 i18n("&Disconnect"), this, SLOT(icsDisconnect()));
183 KStandardAction::undo(&ui(), SLOT(undo()), actionCollection());
184 KStandardAction::redo(&ui(), SLOT(redo()), actionCollection());
186 // installRegularAction("pgnCopy", KIcon("edit-copy"), i18n("Copy PGN"), this, SLOT(pgnCopy()));
187 // installRegularAction("pgnPaste", KIcon("edit-paste"), i18n("Paste PGN"), this, SLOT(pgnPaste()));
188 installRegularAction("editPosition", KIcon("edit"), i18n("&Edit position"), this, SLOT(editPosition()));
189 installRegularAction("clearBoard", KIcon("edit-delete"), i18n("&Clear board"), &ui(), SLOT(clearBoard()));
190 installRegularAction("setStartingPosition", KIcon("contents"), i18n("&Set starting position"),
191 &ui(), SLOT(setStartingPosition()));
192 // installRegularAction("copyPosition", KIcon(), i18n("&Copy position"), &ui(), SLOT(copyPosition()));
193 // installRegularAction("pastePosition", KIcon(), i18n("&Paste position"), &ui(), SLOT(pastePosition()));
194 tmp = installRegularAction("flip", KIcon("object-rotate-left"), i18n("&Flip view"), this, SLOT(flipView()));
195 tmp->setShortcut(Qt::CTRL + Qt::Key_F);
196 installRegularAction("toggleConsole", KIcon("utilities-terminal"), i18n("Toggle &console"), this, SLOT(toggleConsole()));
197 installRegularAction("toggleMoveList", KIcon("view-list-tree"), i18n("Toggle &move list"), this, SLOT(toggleMoveList()));
200 void MainWindow::updateVariantActions(bool unplug) {
201 ActionCollection* variant_actions = m_ui.variantActions();
202 if (unplug)
203 unplugActionList("variantActions");
204 if (variant_actions) {
205 plugActionList("variantActions", variant_actions->actions());
207 else {
208 kWarning() << "No variant actions";
212 void MainWindow::readSettings() { }
213 void MainWindow::writeSettings() { }
215 void MainWindow::closeEvent(QCloseEvent* e) {
216 e->accept();
217 writeSettings();
218 delete this;
222 void MainWindow::keyPressEvent(QKeyEvent* event) {
223 if (event->key() == Qt::Key_F5) {
224 ui().createCtrlAction();
228 void MainWindow::keyReleaseEvent(QKeyEvent* event) {
229 if (event->key() == Qt::Key_F5) {
230 ui().destroyCtrlAction();
234 void MainWindow::changeTab(int index) {
235 m_ui.setCurrentTab(m_main->currentWidget());
236 m_movelist_stack->setCurrentIndex(index);
237 updateVariantActions();
240 void MainWindow::closeTab() {
241 if (m_main->count() > 1) {
242 int old_index = m_main->currentIndex();
243 ChessTable* old_board = table();
245 int new_index = old_index - 1;
246 if (new_index < 0)
247 new_index = old_index + 1;
248 m_main->setCurrentIndex(new_index);
250 m_main->removeTab(old_index);
251 m_movelist_stack->removeWidget(m_movelist_stack->widget(old_index));
252 m_ui.removeController(old_board);
254 if (m_main->count() <= 1) {
255 m_main->setTabBarHidden(true);
258 #if 0 // this doesn't work... why?
259 ChessTable* old_board = table();
260 m_ui.removeController(old_board);
261 m_movelist_stack->removeWidget(
262 m_movelist_stack->widget(m_main->currentIndex()));
263 m_main->removeTab(m_main->currentIndex());
265 delete old_board;
267 if (m_main->count() <= 1) {
268 m_main->hideTabBar();
271 // update ui controller (just in case...)
272 m_ui.setCurrentTab(m_main->currentWidget());
273 #endif
277 void MainWindow::createTab(ChessTable* board, const shared_ptr<Controller>& controller,
278 const QString& caption, int index) {
279 if (index == -1)
280 index = m_main->addTab(board, caption);
281 else
282 m_main->insertTab(index, board, caption);
284 m_ui.addController(board, controller);
285 // m_ui.setCurrentTab(board);
286 m_movelist_stack->addWidget(board->moveListTable());
288 m_main->setCurrentIndex(index);
289 m_movelist_stack->setCurrentIndex(index);
291 if (m_main->count() > 1) m_main->setTabBarHidden(false);
295 void MainWindow::cleanupGame(const QString& what, const QString& result) {
296 Q_UNUSED(what);
297 Q_UNUSED(result);
299 cleanupGame();
302 void MainWindow::cleanupGame() {
303 ui().detach();
304 ui().end();
307 bool MainWindow::newGame(const QString& variantName, AbstractPosition::Ptr startingPos,
308 bool newTab) {
309 VariantPtr variant = Variants::instance().get(variantName);
310 if (!variant) {
311 kWarning() << "no variant" << variantName << "found";
312 variant = Variants::instance().get("chess");
315 if (variant) {
316 ChessTable* board = newTab ? new ChessTable : table();
317 QString text = QString("Editing %1 game").arg(variant->name().toLower());
319 shared_ptr<Controller> controller(new EditGameController(
320 board, variant, startingPos));
321 if (newTab) {
322 createTab(board, controller, text);
324 else {
325 unplugActionList("variantActions");
326 ui().setController(controller);
327 table()->setPlayers(Player(), Player());
328 m_main->setTabText(m_main->currentIndex(), text);
329 updateVariantActions(false);
331 return true;
333 else {
334 kError() << "Could not find the chess variant";
335 exit(1);
336 return false;
341 void MainWindow::editPosition() {
342 //BROKEN
343 #if 0
344 shared_ptr<Controller> controller(new EditPositionController(table(), ChessVariant::info()));
345 m_main->setTabText(m_main->currentIndex(), "Editing chess position");
346 ui().setController(controller);
347 #endif
350 void MainWindow::setupGame(const GameInfo* gameInfo, const PositionInfo& style12) {
351 QString variantCode = gameInfo->variant();
352 VariantPtr variant = Variants::instance().get(variantCode);
353 shared_ptr<EditGameController> controller(new EditGameController(
354 table(), variant));
355 Q_ASSERT(style12.relation == PositionInfo::NotMyMove ||
356 style12.relation == PositionInfo::MyMove);
358 // set opponent side
359 int side = (style12.relation == PositionInfo::MyMove ^ style12.turn == 0) ? 0 : 1;
361 if (controller->addICSPlayer(side, style12.gameNumber, m_connection)) {
362 ui().setController(controller);
363 table()->setPlayers(gameInfo->white(), gameInfo->black());
364 m_main->setTabText(m_main->currentIndex(),
365 QString("FICS Game - %1 vs %2").arg(style12.whitePlayer)
366 .arg(style12.blackPlayer));
370 void MainWindow::setupExaminedGame(const GameInfo* gameInfo, const PositionInfo& style12) {
371 shared_ptr<EditGameController> controller(
372 new EditGameController(table(), Variants::instance().get(gameInfo->variant())));
373 if (controller->setExaminationMode(style12.gameNumber, m_connection)) {
374 table()->setPlayers(Player(style12.whitePlayer, -1),
375 Player(style12.blackPlayer, -1));
376 ui().setController(controller);
377 m_main->setTabText(m_main->currentIndex(),
378 QString("Examining - %1 vs %2").arg(style12.whitePlayer)
379 .arg(style12.blackPlayer));
384 void MainWindow::setupObservedGame(const GameInfo* g, const PositionInfo& style12) {
385 std::auto_ptr<ChessTable> board(new ChessTable);
387 shared_ptr<EditGameController> controller(new EditGameController(
388 board.get(), Variants::instance().get(g->variant())));
389 if (controller->setObserveMode(style12.gameNumber, m_connection)) {
390 board->setPlayers(Player(style12.whitePlayer, -1),
391 Player(style12.blackPlayer, -1));
392 // ui().setController(controller);
393 //kDebug() << "adding tab";
394 createTab(board.get(), controller,
395 QString("Observing - %1 vs %2").arg(style12.whitePlayer)
396 .arg(style12.blackPlayer));
397 board.release();
401 void MainWindow::setupPGN(const QString& s) {
402 PGN pgn(s);
404 std::map<QString, QString>::const_iterator var = pgn.m_tags.find("Variant");
405 VariantPtr variant;
407 if (var == pgn.m_tags.end()) {
408 variant = Variants::instance().get("chess");
410 else if (!(variant = Variants::instance().get(var->second))) {
411 kDebug() << " --> MainWindow::setupPGN: Error, no such variant " << var->second;
412 return;
415 shared_ptr<EditGameController> controller(new EditGameController(
416 table(), variant));
417 ui().setController(controller);
418 controller->loadPGN(pgn);
420 // table()->setPlayers(gameInfo->white(), gameInfo->black());
421 // m_main->setTabText(m_main->currentIndex(),
422 // QString("FICS Game - %1 vs %2").arg(style12.whitePlayer)
423 // .arg(style12.blackPlayer));
426 bool MainWindow::openFile(const QString& filename) {
427 QFileInfo info(filename);
429 if(info.isDir()) {
430 KMessageBox::sorry(this, i18n("You have specified a folder"), i18n("Error"));
431 return false;
434 if(!info.exists() || !info.isFile()) {
435 KMessageBox::sorry(this, i18n("The specified file does not exist"), i18n("Error"));
436 return false;
439 QFile file(filename);
441 if(!file.open(QIODevice::ReadOnly)) {
442 KMessageBox::sorry(this, i18n("You do not have read permission to this file."), i18n("Error"));
443 return false;
446 QTextStream stream(&file);
447 QTextCodec *codec;
448 codec = QTextCodec::codecForLocale();
449 stream.setCodec(codec);
451 setupPGN(stream.readAll());
452 //ui().pgnPaste(stream.readAll());
453 return true;
456 void MainWindow::loadGame() {
457 KUrl url = KFileDialog::getOpenUrl(KUrl(), "*.pgn", this, i18n("Open PGN file"));
459 if(url.isEmpty())
460 return;
462 QString tmp_file;
463 if (KIO::NetAccess::download(url, tmp_file, this)) {
464 openFile(tmp_file);
465 KIO::NetAccess::removeTempFile(tmp_file);
467 else
468 KMessageBox::error(this, KIO::NetAccess::lastErrorString());
471 void MainWindow::saveGame() {
472 if (ui().url().isEmpty())
473 saveGameAs();
474 else
475 ui().setUrl(saveGame(ui().url()));
478 void MainWindow::saveGameAs() {
479 ui().setUrl(saveGame(KFileDialog::getSaveUrl(KUrl(), "*.pgn", this, i18n("Save PGN file"))));
482 bool MainWindow::checkOverwrite(const KUrl& url) {
483 if (!url.isLocalFile())
484 return true;
486 QFileInfo info(url.path());
487 if (!info.exists())
488 return true;
490 return KMessageBox::Cancel != KMessageBox::warningContinueCancel(this,
491 i18n("A file named \"%1\" already exists. "
492 "Are you sure you want to overwrite it?" , info.fileName()),
493 i18n("Overwrite File?"),
494 KGuiItem(i18n("&Overwrite")));
497 KUrl MainWindow::saveGame(const KUrl& url) {
498 if (!checkOverwrite(url))
499 return KUrl();
501 if (url.isEmpty())
502 return KUrl();
504 if (!url.isLocalFile()) {
505 // save in a temporary file
506 KTemporaryFile tmp_file;
507 tmp_file.open();
508 saveFile(tmp_file);
509 if (!KIO::NetAccess::upload(tmp_file.fileName(), url, this))
510 return KUrl();
512 else {
513 QFile file(url.path());
514 if (!file.open(QIODevice::WriteOnly))
515 return KUrl();
516 saveFile(file);
519 return url;
522 void MainWindow::saveFile(QFile& file) {
523 QTextStream stream(&file);
524 QTextCodec *codec;
525 codec = QTextCodec::codecForLocale();
526 stream.setCodec(codec);
527 stream << ui().currentPGN() << "\n";
530 void MainWindow::createConnection(const QString& username, const QString& password,
531 const QString& host, quint16 port,
532 const QString& timeseal, const QString& timeseal_cmd) {
533 m_connection = shared_ptr<ICSConnection>(new ICSConnection);
535 connect(m_connection.get(), SIGNAL(established()), this, SLOT(onEstablishConnection()));
536 connect(m_connection.get(), SIGNAL(hostLookup()), this, SLOT(onHostLookup()));
537 connect(m_connection.get(), SIGNAL(hostFound()), this, SLOT(onHostFound()));
539 connect(m_connection.get(), SIGNAL(receivedLine(QString, int)), console, SLOT(displayText(QString, int)));
540 connect(m_connection.get(), SIGNAL(receivedText(QString, int)), console, SLOT(displayText(QString, int)));
542 connect(console, SIGNAL(receivedInput(const QString&)), m_connection.get(), SLOT(sendText(const QString&)));
543 connect(console, SIGNAL(notify()), this, SLOT(flash()));
545 connect(m_connection.get(), SIGNAL(loginPrompt()), this, SLOT(sendLogin()));
546 connect(m_connection.get(), SIGNAL(registeredNickname()), this, SLOT(sendBlankPassword()));
547 connect(m_connection.get(), SIGNAL(prompt()), this, SLOT(prompt()));
550 connect(m_connection.get(), SIGNAL(creatingExaminedGame(const GameInfo*, const PositionInfo&)),
551 this, SLOT(setupExaminedGame(const GameInfo*, const PositionInfo&)));
552 connect(m_connection.get(), SIGNAL(endingExaminedGame(int)), this, SLOT(cleanupGame()));
554 connect(m_connection.get(), SIGNAL(creatingObservedGame(const GameInfo*, const PositionInfo&)),
555 this, SLOT(setupObservedGame(const GameInfo*, const PositionInfo&)));
556 connect(m_connection.get(), SIGNAL(endingObservedGame(int)), this, SLOT(cleanupGame()));
559 connect(m_connection.get(), SIGNAL(creatingGame(const GameInfo*, const PositionInfo&)),
560 this, SLOT(setupGame(const GameInfo*, const PositionInfo&)));
561 connect(m_connection.get(), SIGNAL(endingGame(const QString&, const QString&)),
562 this, SLOT(cleanupGame(const QString&, const QString&)));
563 connect(m_connection.get(), SIGNAL(notification()), this, SLOT(flash()));
565 m_connection->establish(host.toAscii().constData(), port, timeseal, timeseal_cmd);
566 console->show();
568 // send username / password combination
569 if (!username.isEmpty()) {
570 m_connection->sendText(username);
571 m_connection->sendText(password);
574 quickConnectDialog.reset();
577 void MainWindow::icsConnect() {
578 quickConnectDialog = shared_ptr<QConnect>(new QConnect(this));
579 connect(quickConnectDialog.get(),
580 SIGNAL(acceptConnection(const QString&,
581 const QString&,
582 const QString&,
583 quint16,
584 const QString&,
585 const QString&)),
586 this,
587 SLOT(createConnection(const QString&,
588 const QString&,
589 const QString&,
590 quint16,
591 const QString&,
592 const QString&)));
593 quickConnectDialog->show();
596 void MainWindow::destroyConnection() {
597 m_connection.reset();
600 void MainWindow::icsDisconnect() {
601 destroyConnection();
602 console->hide();
603 console->clear();
606 void MainWindow::testConnect() {
607 Settings s_ics = settings().group("ics");
608 if (s_ics["username"]) {
609 QString username = s_ics["username"].value<QString>();
610 QString password = (s_ics["password"] | "");
611 QString host = (s_ics["icsHost"] | "freechess.org");
612 quint16 port = (s_ics["icsPort"] | 5000);
613 createConnection(username, password, host, port, QString(), QString() );
615 else icsConnect();
619 void MainWindow::onEstablishConnection() {
620 // kDebug() << "connection established";
623 void MainWindow::onConnectionError(int ) {
624 // kDebug() << "connection error (" << code << ")";
627 void MainWindow::onHostLookup() {
628 // kDebug() << "hostLookup..." << std::flush;
631 void MainWindow::onHostFound() {
632 // kDebug() << "found";
636 void MainWindow::sendLogin() {
637 // kDebug() << "sending username";
638 // connection->sendText(connection->username());
641 void MainWindow::sendBlankPassword() {
642 m_connection->sendText("");
645 void MainWindow::prompt() {
646 if (!m_connection->initialized()) {
647 m_connection->startup();
648 m_connection->setInitialized();
652 void MainWindow::newGame() {
653 AbstractPosition::Ptr pos = ui().position();
654 scoped_ptr<NewGame> dialog(new NewGame(this));
655 if (dialog->exec() == QDialog::Accepted) {
656 if (!newGame(dialog->variant(), PositionPtr(), dialog->newTab()))
657 QMessageBox::information(this, i18n("Error"), i18n("Error creating game"));
661 void MainWindow::quit() {
662 delete this;
665 void MainWindow::flipView() {
666 table()->flip();
669 void MainWindow::toggleConsole() {
670 if (console_dock->isVisible())
671 console_dock->hide();
672 else {
673 console_dock->show();
674 console_dock->setFocus(Qt::MouseFocusReason
675 /*Qt::ActiveWindowFocusReason*/ /*Qt::OtherFocusReason*/);
679 void MainWindow::toggleMoveList() {
680 if (movelist_dock->isVisible())
681 movelist_dock->hide();
682 else {
683 movelist_dock->show();
684 movelist_dock->setFocus(Qt::OtherFocusReason);
689 void MainWindow::displayMessage(const QString& msg) {
690 Q_UNUSED(msg); // TODO
691 // statusBar()->message(msg, 2000);
694 void MainWindow::displayErrorMessage(ErrorCode code) {
695 switch(code) {
696 case InvalidMove:
697 displayMessage(i18n("Illegal move"));
698 break;
702 void MainWindow::flash() {
703 if( !isAncestorOf(QApplication::focusWidget()) )
704 Flash::flash(this);
707 #if 0
708 void MainWindow::prefHighlight() {
709 PrefHighlight dialog;
710 int result = dialog.exec();
711 if (result == QDialog::Accepted) {
712 dialog.apply();
715 #endif
717 void MainWindow::preferences() {
718 Preferences dialog(ui().currentVariant());
719 int result = dialog.exec();
720 if (result == QDialog::Accepted)
721 dialog.apply();
724 void MainWindow::settingsChanged() {
725 ui().reloadSettings();