00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kanagram.h"
00022
00023 #include <QMouseEvent>
00024 #include <QPainter>
00025 #include <QPaintEvent>
00026 #include <QPixmap>
00027 #include <QSvgRenderer>
00028 #include <QTimer>
00029
00030 #include <Phonon/MediaObject>
00031
00032 #include <KAction>
00033 #include <KActionCollection>
00034 #include <KApplication>
00035 #include <KComponentData>
00036 #include <KConfigDialog>
00037 #include <KConfigSkeleton>
00038 #include <KGlobalSettings>
00039 #include <KHelpMenu>
00040 #include <KLineEdit>
00041 #include <KMessageBox>
00042 #include <KShortcutsEditor>
00043 #include <KStandardAction>
00044 #include <KStandardDirs>
00045 #include <KStandardShortcut>
00046 #include <kdeversion.h>
00047
00048 #include <sharedkvtmlfiles.h>
00049
00050 #include "kanagramgame.h"
00051 #include "kanagramsettings.h"
00052 #include "mainsettings.h"
00053 #include "vocabsettings.h"
00054 #include "newstuff.h"
00055 #include "libkdeedu/kdeeduui/kedufontutils.h"
00056
00057 static const char* m_textRevealWord = I18N_NOOP("reveal word");
00058 static const char* m_textHint = I18N_NOOP("hint");
00059 static const char* m_nextText = I18N_NOOP("Next Anagram");
00060
00061 double kWindowWidth = 1000.0;
00062 double kWindowHeight = 725.0;
00063
00064 double xEyesScale = 270.437 / kWindowWidth;
00065 double yEyesScale = 195.176 / kWindowHeight;
00066
00067 double xScale57Buttons = 57.5 / kWindowWidth;
00068 double yScale57Buttons = 57.5 / kWindowHeight;
00069
00070 double xScale55Buttons = 55.0 / kWindowWidth;
00071 double yScale55Buttons = 55.0 / kWindowHeight;
00072
00073 double xTranslateButtons = 810.053 / kWindowWidth;
00074
00075 double yTranslateNextButton = 59.588 / kWindowHeight;
00076 double yTranslateConfigButton = 199.85 / kWindowHeight;
00077 double yTranslateHelpButton = 337.487 / kWindowHeight;
00078
00079 double xScaleQuitButton = 77.484 / kWindowWidth;
00080 double yScaleQuitButton = 77.5 / kWindowHeight;
00081
00082 Kanagram::Kanagram()
00083 : KMainWindow(), m_game(NULL), m_overNext(false), m_overConfig(false),
00084 m_overHelp(false), m_overQuit(false), m_overReveal(false), m_overHint(false),
00085 m_overUp(false), m_overAboutKDE(false), m_overAboutApp(false),
00086 m_overHandbook(false), m_overSwitcher(false), m_overLogo(false),
00087 m_overHintBox(false), m_showHint(false), m_player(NULL), m_actionCollection(NULL)
00088 {
00089 setAttribute(Qt::WA_StaticContents);
00090 m_renderer = new QSvgRenderer(KStandardDirs::locate("appdata", "images/kanagram.svg"));
00091
00092 m_helpMenu = new KHelpMenu(this, KGlobal::mainComponent().aboutData());
00093
00094 setupActions();
00095
00096 loadSettings();
00097
00098 m_game = new KanagramGame();
00099
00100 setMouseTracking(true);
00101 m_chalkColor = QColor(155, 155, 155);
00102 m_chalkHighlightColor = QColor(255, 255, 255);
00103 m_fillColor = QColor(45, 45, 45);
00104 m_fontColor = QColor(55, 55, 55);
00105 m_fontHighlightColor = QColor(99, 99, 99);
00106
00107 m_hintTimer = new QTimer(this);
00108 m_hintTimer->setSingleShot(true);
00109
00110 m_inputBox = new KLineEdit(this);
00111 m_inputBox->setFrame(false);
00112
00113 connect(m_inputBox, SIGNAL(returnPressed()), SLOT(checkWord()));
00114 connect(m_hintTimer, SIGNAL(timeout()), SLOT(hideHint()));
00115 connect(m_inputBox, SIGNAL(textChanged(const QString &)), SLOT(update()));
00116 connect(m_game, SIGNAL(fileError(const QString &)), SLOT(slotFileError(const QString &)));
00117
00118 QFont f = QFont();
00119 f.setPointSize(17);
00120 m_inputBox->setFont(f);
00121 m_inputBox->show();
00122
00123 show();
00124
00125 setAutoSaveSettings();
00126
00127 setMinimumSize(650, 471);
00128 }
00129
00130 Kanagram::~Kanagram()
00131 {
00132 if (m_player != NULL)
00133 {
00134 delete m_player;
00135 m_player = NULL;
00136 }
00137
00138 if (m_game != NULL)
00139 {
00140 delete m_game;
00141 m_game = NULL;
00142 }
00143
00144 if (m_renderer != NULL)
00145 {
00146 delete m_renderer;
00147 m_renderer = NULL;
00148 }
00149 }
00150
00151 QSize Kanagram::sizeHint() const
00152 {
00153 return QSize(650, 471);
00154 }
00155
00156 void Kanagram::loadSettings()
00157 {
00158 QString hideTime = KanagramSettings::hintHideTime();
00159 if (hideTime[0].isDigit())
00160 {
00161
00162 m_hintHideTime = (hideTime[0].digitValue() * 2) + 1;
00163
00164
00165 if (m_hintHideTime == 1)
00166 {
00167 m_hintHideTime = 0;
00168 }
00169 }
00170 else
00171 {
00172 m_hintHideTime = 0;
00173 }
00174
00175 if (KanagramSettings::dataLanguage().isEmpty())
00176 {
00177 QStringList userLanguagesCode = KGlobal::locale()->languageList();
00178
00179 int i = 0;
00180 bool foundLanguage = false;
00181 while (i < userLanguagesCode.size() && !foundLanguage)
00182 {
00183 if (SharedKvtmlFiles::languages().contains(userLanguagesCode[i]))
00184 {
00185 foundLanguage = true;
00186 }
00187 else
00188 {
00189 ++i;
00190 }
00191 }
00192
00193
00194 KanagramSettings::setDataLanguage(foundLanguage ? userLanguagesCode[i] : "en");
00195 }
00196
00197 m_useSounds = KanagramSettings::useSounds();
00198 m_arrowName = "basicarrow";
00199 }
00200
00201 void Kanagram::reloadSettings()
00202 {
00203 loadSettings();
00204 refreshVocabularies();
00205 }
00206
00207 void Kanagram::setupActions()
00208 {
00209 m_actionCollection = new KActionCollection(this);
00210
00211
00212 KAction *nextAnagramAction = new KAction(i18n(m_nextText), m_actionCollection);
00213 nextAnagramAction->setShortcut(Qt::CTRL+Qt::Key_N);
00214 connect(nextAnagramAction, SIGNAL(triggered(bool)), this, SLOT(slotNextAnagram()));
00215 m_actionCollection->addAction("nextanagram", nextAnagramAction);
00216
00217
00218 KAction *showHintAction = new KAction(i18n("Show Hint"), m_actionCollection);
00219 showHintAction->setShortcut(Qt::CTRL+Qt::Key_H);
00220 connect(showHintAction, SIGNAL(triggered(bool)), this, SLOT(slotToggleHint()));
00221 m_actionCollection->addAction("showhint", showHintAction);
00222
00223
00224 KAction *revealWordAction = new KAction(i18n("Reveal Anagram"), m_actionCollection);
00225 revealWordAction->setShortcut(Qt::CTRL+Qt::Key_R);
00226 connect(revealWordAction, SIGNAL(triggered(bool)), this, SLOT(slotRevealWord()));
00227 m_actionCollection->addAction("revealword", revealWordAction);
00228
00229
00230 KStandardAction::prior(this, SLOT(slotPrevVocabulary()), m_actionCollection);
00231 KStandardAction::next(this, SLOT(slotNextVocabulary()), m_actionCollection);
00232
00233
00234 KStandardAction::aboutApp(m_helpMenu, SLOT(aboutApplication()), m_actionCollection);
00235 KStandardAction::aboutKDE(m_helpMenu, SLOT(aboutKDE()), m_actionCollection);
00236 KStandardAction::helpContents(m_helpMenu, SLOT(appHelpActivated()), m_actionCollection);
00237
00238
00239 KStandardAction::preferences(this, SLOT(slotShowSettings()), m_actionCollection);
00240 KStandardAction::quit(this, SLOT(close()), m_actionCollection);
00241
00242
00243
00244 m_actionCollection->readSettings();
00245
00246 m_actionCollection->addAssociatedWidget(this);
00247 foreach (QAction* action, m_actionCollection->actions())
00248 #if QT_VERSION < KDE_MAKE_VERSION(4,4,0)
00249 action->setShortcutContext(Qt::WidgetShortcut);
00250 #else
00251 action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
00252 #endif
00253 }
00254
00255 void Kanagram::paintEvent(QPaintEvent *)
00256 {
00257 QPixmap buf(width(), height());
00258 QPainter p(&buf);
00259 p.setRenderHint(QPainter::Antialiasing);
00260
00261 m_renderer->render(&p, "background");
00262
00263 m_xRatio = width() / kWindowWidth;
00264 m_yRatio = height() / kWindowHeight;
00265
00266 if (m_overLogo)
00267 {
00268 p.translate(int(112.188 * m_xRatio), int(32.375 * m_yRatio));
00269 p.scale(466.981 / kWindowWidth, 91.407 / kWindowHeight);
00270 m_renderer->render(&p, "logo_hover");
00271 p.resetMatrix();
00272 }
00273 else
00274 {
00275 p.translate(int(112.188 * m_xRatio), int(32.375 * m_yRatio));
00276 p.scale(466.981 / kWindowWidth, 91.407 / kWindowHeight);
00277 m_renderer->render(&p, "logo");
00278 p.resetMatrix();
00279 }
00280
00281 if (m_overNext)
00282 {
00283 p.translate(xTranslateButtons * width(), yTranslateNextButton * height());
00284 p.scale(xScale55Buttons, yScale55Buttons);
00285 m_renderer->render(&p, "next_hover");
00286 p.resetMatrix();
00287 }
00288
00289 if (m_overConfig)
00290 {
00291 p.translate(xTranslateButtons * width(), yTranslateConfigButton * height());
00292 p.scale(xScale55Buttons, yScale55Buttons);
00293 m_renderer->render(&p, "config_hover");
00294 p.resetMatrix();
00295 }
00296
00297 if (m_overHelp)
00298 {
00299 p.translate(xTranslateButtons * width(), yTranslateHelpButton * height());
00300 p.scale(xScale55Buttons, yScale55Buttons);
00301 m_renderer->render(&p, "help_hover");
00302 p.resetMatrix();
00303 }
00304
00305 if (m_overQuit)
00306 {
00307 p.translate(798.811 * m_xRatio, 556.803 * m_yRatio);
00308 p.scale(xScaleQuitButton, yScaleQuitButton);
00309 m_renderer->render(&p, "quit_hover");
00310 p.resetMatrix();
00311 }
00312
00313 QString anagram = m_game->getAnagram();
00314 int afontSize = fontUtils::fontSize(p, anagram, m_blackboardRect.width(), m_blackboardRect.height() / 5);
00315 FixFontSize(afontSize);
00316 drawTextNew(p, anagram, Qt::AlignCenter, 10, 10, m_blackboardRect, true, afontSize);
00317
00318 QString reveal = i18n(m_textRevealWord);
00319 m_cornerFontSize = fontUtils::fontSize(p, reveal, m_blackboardRect.width() / 3, m_blackboardRect.height() / 5);
00320 FixFontSize(m_cornerFontSize);
00321
00322 drawTextNew(p, reveal, Qt::AlignBottom | Qt::AlignRight, 6, 0, m_blackboardRect, m_overReveal, m_cornerFontSize);
00323 drawTextNew(p, i18n(m_textHint), Qt::AlignBottom | Qt::AlignLeft, 6, 0, m_blackboardRect, m_overHint, m_cornerFontSize);
00324
00325
00326 QFont font = KGlobalSettings::generalFont();
00327 font.setPointSize(m_cornerFontSize);
00328 font.setBold(true);
00329 QFontMetrics fm(font);
00330 QRect r = innerRect(m_blackboardRect, 6, 0);
00331 m_hintRect = fm.boundingRect(r, Qt::AlignBottom|Qt::AlignLeft, i18n(m_textHint));
00332 m_hintBoxRect = QRect(int(684.813 * m_xRatio), int(319.896 * m_yRatio), int(xEyesScale * width()), int(yEyesScale * height()));
00333 r = innerRect(m_blackboardRect, 6, 0);
00334 m_revealRect = fm.boundingRect(r, Qt::AlignBottom|Qt::AlignRight, reveal);
00335
00336 drawSwitcher(p, 9, 8);
00337
00338 p.setPen(QPen(Qt::black, 3));
00339
00340
00341 QRect borderRect = m_inputBox->geometry();
00342 p.drawRoundRect(borderRect, 10, 5);
00343 int inputBoxFontSize = fontUtils::fontSize(p, "A", borderRect.width(), borderRect.height()) - 1;
00344 FixFontSize(inputBoxFontSize);
00345 QFont f = QFont();
00346 f.setPointSize(inputBoxFontSize);
00347 m_inputBox->setFont(f);
00348
00349
00350 borderRect = m_upRect;
00351 p.fillRect(borderRect, m_fillColor);
00352 p.drawRoundRect(borderRect, 10, 5);
00353
00354 QString upArrow = "up";
00355 if (m_overUp && !m_inputBox->text().isEmpty())
00356 {
00357 upArrow = "up_hover";
00358 }
00359 else if (m_inputBox->text().isEmpty())
00360 {
00361 upArrow = "up_disabled";
00362 }
00363
00364 p.translate(m_inputBox->x() + m_inputBox->width() + 26 * m_xRatio, m_inputBox->y() + 12 * m_yRatio);
00365 p.scale(38 / kWindowWidth, 20 / kWindowHeight);
00366 m_renderer->render(&p, upArrow);
00367 p.resetMatrix();
00368
00369 if (m_showHint)
00370 {
00371 p.translate(684.813 * m_xRatio, 319.896 * m_yRatio);
00372 p.scale(xEyesScale, yEyesScale);
00373 m_renderer->render(&p, m_hintOverlayName);
00374 p.resetMatrix();
00375
00376
00377 QFont f = KGlobalSettings::generalFont();
00378 f.setWeight(QFont::Bold);
00379 QString hint = m_game->getHint();
00380 int fontSize = fontUtils::fontSize(p, hint, int(250 * m_xRatio), int(100 * m_yRatio));
00381 FixFontSize(fontSize);
00382 f.setPointSize(fontSize);
00383 p.setFont(f);
00384 p.drawText(int(694 * m_xRatio), int(330 * m_yRatio), int(250 * m_xRatio), int(100 * m_yRatio),
00385 Qt::TextWordWrap | Qt::AlignCenter, hint);
00386 }
00387
00388 if (m_overHelp && !m_showHint)
00389 {
00390 if (m_overAboutApp)
00391 {
00392 p.translate(808.377 * m_xRatio, 335.352 * m_yRatio);
00393 p.scale(xScale57Buttons, yScale57Buttons);
00394 m_renderer->render(&p, "appicon_hover");
00395 p.resetMatrix();
00396 drawHelpText(p, i18n("About Kanagram"));
00397 }
00398 else
00399 {
00400 p.translate(808.377 * m_xRatio, 335.352 * m_yRatio);
00401 p.scale(xScale57Buttons, yScale57Buttons);
00402 m_renderer->render(&p, "appicon");
00403 p.resetMatrix();
00404 }
00405 if (m_overAboutKDE)
00406 {
00407 p.translate(865.877 * m_xRatio, 335.352 * m_yRatio);
00408 p.scale(xScale57Buttons, yScale57Buttons);
00409 m_renderer->render(&p, "kicon_hover");
00410 p.resetMatrix();
00411 drawHelpText(p, i18n("About KDE"));
00412 }
00413 else
00414 {
00415 p.translate(865.877 * m_xRatio, 335.352 * m_yRatio);
00416 p.scale(xScale57Buttons, yScale57Buttons);
00417 m_renderer->render(&p, "kicon");
00418 p.resetMatrix();
00419 }
00420 if (m_overHandbook)
00421 {
00422 p.translate(750.877 * m_xRatio, 335.352 * m_yRatio);
00423 p.scale(xScale57Buttons, yScale57Buttons);
00424 m_renderer->render(&p, "handbook_hover");
00425 p.resetMatrix();
00426 drawHelpText(p, i18n("Kanagram Handbook"));
00427 }
00428 else
00429 {
00430 p.translate(750.877 * m_xRatio, 335.352 * m_yRatio);
00431 p.scale(xScale57Buttons, yScale57Buttons);
00432 m_renderer->render(&p, "handbook");
00433 p.resetMatrix();
00434 }
00435 }
00436 else if (m_overNext)
00437 {
00438 drawHelpText(p, i18n(m_nextText));
00439 }
00440 else if (m_overConfig)
00441 {
00442 drawHelpText(p, i18n("Configure Kanagram"));
00443 }
00444 else if (m_overQuit)
00445 {
00446 drawHelpText(p, i18n("Quit Kanagram"));
00447 }
00448
00449 QPainter p2(this);
00450 p2.drawPixmap(0, 0, buf);
00451 }
00452
00454 void Kanagram::FixFontSize(int &fontSize)
00455 {
00456 if (fontSize <= 0)
00457 {
00458 fontSize = 8;
00459 }
00460 }
00461
00462 void Kanagram::resizeEvent(QResizeEvent *)
00463 {
00464 m_xRatio = width() / kWindowWidth;
00465 m_yRatio = height() / kWindowHeight;
00466
00467 m_blackboardRect = QRect(int(63.657 * m_xRatio), int(182.397 * m_yRatio), int(563.273 * m_xRatio), int(380.735 * m_yRatio));
00468 m_inputBox->setGeometry(QRect(int(80 * m_xRatio), int(657.272 * m_yRatio), int(420 * m_xRatio), int(44.639 * m_yRatio)));
00469
00470 m_upRect = QRect(int(m_inputBox->x() + m_inputBox->width() + 20 * m_xRatio), m_inputBox->y(), int(50 * m_xRatio), m_inputBox->height());
00471 m_arrowRect = QRect(m_switcherRect.right() + 5, m_switcherRect.top(), int(16.250 * m_xRatio), int(25.0 * m_yRatio));
00472 m_logoRect = QRect(int(112.188 * m_xRatio), int(32.375 * m_yRatio), int(466.981 * m_xRatio), int(91.407 * m_yRatio));
00473
00474 m_aboutAppRect = QRect(int(xTranslateButtons * width()), int(yTranslateHelpButton * height()),
00475 int(xScale57Buttons * width()), int(yScale57Buttons * height()));
00476 m_aboutKDERect = QRect(int(867 * m_xRatio), int(335.352 * m_yRatio),
00477 int(xScale57Buttons * width()), int(yScale57Buttons * height()));
00478 m_handbookRect = QRect(int(753 * m_xRatio), int(335.352 * m_yRatio),
00479 int(xScale57Buttons * width()), int(yScale57Buttons * height()));
00480
00481 m_nextRect = QRect(int(735.448 * m_xRatio), int(49.028 * m_yRatio), int(206.142 * m_xRatio), int(117.537 * m_yRatio));
00482 m_configRect = QRect(int(735.448 * m_xRatio), int(188.264 * m_yRatio), int(206.142 * m_xRatio), int(117.537 * m_yRatio));
00483 m_helpRect = QRect(int(735.448 * m_xRatio), int(327.5 * m_yRatio), int(206.142 * m_xRatio), int(117.537 * m_yRatio));
00484 m_quitRect = QRect(int(697.549 * m_xRatio), int(542.337 * m_yRatio), int(279.935 * m_xRatio), int(160.68 * m_yRatio));
00485
00486 update();
00487 }
00488
00489 void Kanagram::drawHelpText(QPainter &p, const QString &text)
00490 {
00491 p.translate(700.582 * m_xRatio, 424.176 * m_yRatio);
00492 p.scale(256.582 / kWindowWidth, 101.150 / kWindowHeight);
00493 m_renderer->render(&p, "card");
00494 p.resetMatrix();
00495
00496 p.save();
00497 QFont font = KGlobalSettings::generalFont();
00498 font.setPointSize(m_cornerFontSize);
00499 p.setFont(font);
00500
00501 p.translate(720.582 * m_xRatio, 480 * m_yRatio);
00502 p.rotate(-3.29);
00503 p.setPen(Qt::black);
00504
00505
00506 p.drawText(0, 0, text.section(' ', 0, 0));
00507
00508 p.drawText(0, int(30 * m_yRatio), text.section(' ', 1));
00509 p.restore();
00510 }
00511
00512 void Kanagram::drawSwitcher(QPainter &p, const int xMargin, const int yMargin)
00513 {
00514 const int padding = 5;
00515 QString text = m_game->getDocTitle();
00516 QFont font = KGlobalSettings::generalFont();
00517 font.setPointSize(m_cornerFontSize);
00518 QFontMetrics fm(font);
00519 QRect r = innerRect(m_blackboardRect, xMargin, yMargin);
00520 r = r.normalized();
00521 r.translate(- padding - int(16.250 * m_xRatio), yMargin);
00522 r.setHeight(int(25.0 * m_yRatio));
00523 m_switcherRect = p.boundingRect(r, Qt::AlignVCenter|Qt::AlignRight, text);
00524 p.setFont(font);
00525 QString arrow = m_arrowName;
00526 if (m_overSwitcher)
00527 {
00528 p.setPen(m_chalkHighlightColor);
00529 arrow = m_arrowName + "_hover";
00530 }
00531 else
00532 {
00533 p.setPen(m_chalkColor);
00534 }
00535 p.translate(m_switcherRect.right() + padding, m_switcherRect.top());
00536 p.scale(16.250 / kWindowWidth, 25.0 / kWindowHeight);
00537 m_renderer->render(&p, arrow);
00538 p.resetMatrix();
00539
00540 m_switcherRect.translate(0, -2);
00541 p.drawText(m_switcherRect, Qt::AlignVCenter|Qt::AlignRight, text);
00542 }
00543
00544 QRect Kanagram::innerRect(const QRect &rect, const int xMargin, const int yMargin)
00545 {
00546 QRect r = rect;
00547
00548 if (xMargin>0)
00549 {
00550 r.setWidth(r.width() - 2 * xMargin);
00551 r.translate(xMargin, 0);
00552 }
00553 if (yMargin>0)
00554 {
00555 r.setHeight(r.height() - 2 * yMargin);
00556 r.translate(0, yMargin);
00557 }
00558
00559 return r;
00560 }
00561
00563 void Kanagram::slotNextAnagram()
00564 {
00565 hideHint();
00566 m_game->nextAnagram();
00567 if (m_useSounds)
00568 {
00569 play("chalk.ogg");
00570 }
00571 m_inputBox->setPalette(QPalette());
00572 update();
00573 }
00574
00575 void Kanagram::slotRevealWord()
00576 {
00577 m_game->restoreWord();
00578 update();
00579 }
00580
00582 void Kanagram::slotNextVocabulary()
00583 {
00584 m_game->nextVocab();
00585 hideHint();
00586 m_game->nextAnagram();
00587
00588 if (m_useSounds)
00589 {
00590 play("chalk.ogg");
00591 }
00592
00593 KanagramSettings::setDefaultVocab(m_game->getFilename());
00594 KanagramSettings::self()->writeConfig();
00595 update();
00596 }
00597
00599 void Kanagram::slotPrevVocabulary()
00600 {
00601 m_game->previousVocab();
00602 hideHint();
00603 m_game->nextAnagram();
00604
00605 if (m_useSounds)
00606 {
00607 play("chalk.ogg");
00608 }
00609
00610 KanagramSettings::setDefaultVocab(m_game->getFilename());
00611 KanagramSettings::self()->writeConfig();
00612 update();
00613 }
00614
00615 void Kanagram::slotToggleHint()
00616 {
00617 if (m_showHint)
00618 {
00619 m_showHint = false;
00620 }
00621 else
00622 {
00623 if (m_hintHideTime)
00624 {
00625 m_hintTimer->start(m_hintHideTime * 1000);
00626 }
00627 m_showHint = true;
00628 randomHintImage();
00629 }
00630 update();
00631 }
00632
00633 void Kanagram::mousePressEvent(QMouseEvent *e)
00634 {
00635 if (m_nextRect.contains(e->pos()))
00636 {
00637 slotNextAnagram();
00638 }
00639
00640 if (m_configRect.contains(e->pos()))
00641 {
00642 slotShowSettings();
00643 }
00644
00645 if (m_quitRect.contains(e->pos()))
00646 {
00647 close();
00648 }
00649
00650 if (m_revealRect.contains(e->pos()))
00651 {
00652 slotRevealWord();
00653 }
00654
00655 if (m_logoRect.contains(e->pos()))
00656 {
00657 m_helpMenu->aboutApplication();
00658 }
00659
00660 if (!m_showHint && m_overHelp)
00661 {
00662 if (m_handbookRect.contains(e->pos()))
00663 {
00664 m_helpMenu->appHelpActivated();
00665 }
00666
00667 if (m_aboutKDERect.contains(e->pos()))
00668 {
00669 m_helpMenu->aboutKDE();
00670 }
00671
00672 if (m_aboutAppRect.contains(e->pos()))
00673 {
00674 m_helpMenu->aboutApplication();
00675 }
00676 }
00677
00678 if (m_hintBoxRect.contains(e->pos()))
00679 {
00680 hideHint();
00681 }
00682
00683 if (m_switcherRect.contains(e->pos()) || m_arrowRect.contains(e->pos()))
00684 {
00685 if (!(e->button() == Qt::RightButton))
00686 {
00687 slotNextVocabulary();
00688 }
00689 else
00690 {
00691 slotPrevVocabulary();
00692 }
00693 }
00694
00695 if (m_hintRect.contains(e->pos()))
00696 {
00697 slotToggleHint();
00698 }
00699
00700 if (m_upRect.contains(e->pos()) && !m_inputBox->text().isEmpty())
00701 {
00702 checkWord();
00703 }
00704 }
00705
00707 void Kanagram::CheckRect(const QRect &rect, const QPoint &p, bool &flag, bool &changed)
00708 {
00709 if (rect.contains(p))
00710 {
00711 changed = !flag;
00712 flag = true;
00713 }
00714 else if (flag)
00715 {
00716 flag = false;
00717 changed = true;
00718 }
00719 }
00720
00721 void Kanagram::mouseMoveEvent(QMouseEvent *e)
00722 {
00723 QPoint p = e->pos();
00724 bool haveToUpdate = false;
00725
00726 CheckRect(m_nextRect, p, m_overNext, haveToUpdate);
00727 CheckRect(m_configRect, p, m_overConfig, haveToUpdate);
00728 CheckRect(m_logoRect, p, m_overLogo, haveToUpdate);
00729 CheckRect(m_helpRect, p, m_overHelp, haveToUpdate);
00730 CheckRect(m_quitRect, p, m_overQuit, haveToUpdate);
00731 CheckRect(m_hintRect, p, m_overHint, haveToUpdate);
00732 CheckRect(m_hintBoxRect, p, m_overHintBox, haveToUpdate);
00733 CheckRect(m_revealRect, p, m_overReveal, haveToUpdate);
00734 CheckRect(m_upRect, p, m_overUp, haveToUpdate);
00735 CheckRect(m_aboutAppRect, p, m_overAboutApp, haveToUpdate);
00736
00737 if (m_switcherRect.contains(p) || m_arrowRect.contains(p))
00738 {
00739 haveToUpdate = !m_overSwitcher;
00740 m_overSwitcher = true;
00741 }
00742 else if (m_overSwitcher)
00743 {
00744 m_overSwitcher = false;
00745 haveToUpdate = true;
00746 }
00747
00748 if (!m_showHint)
00749 {
00750 CheckRect(m_handbookRect, p, m_overHandbook, haveToUpdate);
00751 CheckRect(m_aboutKDERect, p, m_overAboutKDE, haveToUpdate);
00752 }
00753
00754 if (m_overAboutKDE || m_overHandbook || m_overSwitcher || m_overNext || m_overQuit
00755 || m_overConfig || m_overReveal || m_overHint || (m_overUp && !m_inputBox->text().isEmpty())
00756 || m_overAboutApp || m_overHintBox || m_overLogo)
00757 {
00758 this->setCursor(Qt::PointingHandCursor);
00759 }
00760 else
00761 {
00762 this->unsetCursor();
00763 }
00764
00765 if (haveToUpdate)
00766 {
00767 update();
00768 }
00769 }
00770
00771 void Kanagram::drawTextNew(QPainter &p, const QString &text, int textAlign, int xMargin, int yMargin, const QRect &rect, bool highlight, int fontSize)
00772 {
00773 QRect r = innerRect(rect, xMargin, yMargin);
00774 QFont font = KGlobalSettings::generalFont();
00775 font.setPointSize(fontSize);
00776 font.setBold(true);
00777 p.setFont(font);
00778
00779 const bool withMargin = false;
00780 if (withMargin)
00781 {
00782 p.fillRect(r, m_fillColor);
00783 p.setPen(QPen(Qt::black, 3));
00784 p.drawRoundRect(r.left(), r.top(), r.width(), r.height(), 15, 15);
00785 }
00786
00787 if (highlight)
00788 p.setPen(m_chalkHighlightColor);
00789 else
00790 p.setPen(m_chalkColor);
00791 p.drawText(r, textAlign, text);
00792 }
00793
00794 void Kanagram::checkWord()
00795 {
00796 QPalette palette;
00797 QString enteredWord = m_inputBox->text().toLower().trimmed();
00798 QString word = m_game->getWord().toLower().trimmed();
00799 if (!enteredWord.isEmpty())
00800 {
00801 if (enteredWord == word || stripAccents(enteredWord) == stripAccents(word))
00802 {
00803 if (m_useSounds) play("right.ogg");
00804 palette.setColor(m_inputBox->backgroundRole(), QColor(0, 255, 0));
00805 QTimer::singleShot(1000, this, SLOT(resetInputBox()));
00806 m_inputBox->clear();
00807 hideHint();
00808 m_game->nextAnagram();
00809 }
00810 else
00811 {
00812 if (m_useSounds) play("wrong.ogg");
00813 palette.setColor(m_inputBox->backgroundRole(), QColor(255, 0, 0));
00814 QTimer::singleShot(1000, this, SLOT(resetInputBox()));
00815 m_inputBox->clear();
00816 }
00817 m_inputBox->setPalette(palette);
00818 update();
00819 }
00820 }
00821
00822 QString Kanagram::stripAccents(const QString & original)
00823 {
00824 QString noAccents;
00825 QString decomposed = original.normalized(QString::NormalizationForm_D);
00826 for (int i = 0; i < decomposed.length(); ++i) {
00827 if ( decomposed[i].category() != QChar::Mark_NonSpacing ) {
00828 noAccents.append(decomposed[i]);
00829 }
00830 }
00831 return noAccents;
00832 }
00833
00834 void Kanagram::randomHintImage()
00835 {
00836 unsigned long imageNum = m_randomImage.getLong(8);
00837 m_hintOverlayName = "eyes" + QString::number(imageNum + 1);
00838 }
00839
00840 void Kanagram::slotShowSettings()
00841 {
00842 if (!KConfigDialog::showDialog("settings"))
00843 {
00844 m_configDialog = new KConfigDialog( this, "settings", KanagramSettings::self() );
00845 m_configDialog->setAttribute(Qt::WA_DeleteOnClose);
00846 connect(m_configDialog, SIGNAL(finished()), this, SLOT(reloadSettings()));
00847
00848
00849 MainSettings * mainSettingsPage = new MainSettings( m_configDialog );
00850 connect (mainSettingsPage, SIGNAL(settingsChanged()), this, SLOT(reloadSettings()));
00851 m_configDialog->addPage(mainSettingsPage , i18nc("@title:group main settings page name", "General" ), "preferences-other" );
00852
00853
00854 m_vocabSettings = new VocabSettings( m_configDialog );
00855 m_configDialog->addPage(m_vocabSettings, i18n("Vocabularies"), "document-properties" );
00856
00857
00858 m_shortcutsEditor = new KShortcutsEditor(m_actionCollection, m_configDialog);
00859 m_configDialog->addPage(m_shortcutsEditor, i18n("Shortcuts"), "preferences-desktop-keyboard");
00860 connect(m_configDialog, SIGNAL(accepted()), this, SLOT(slotSaveSettings()));
00861 connect(m_configDialog, SIGNAL(rejected()), this, SLOT(slotSettingsCancelled()));
00862 connect(m_shortcutsEditor, SIGNAL(keyChange()), this, SLOT(slotEnableApplyButton()));
00863
00864
00865 m_configDialog->addPage( new NewStuff( m_configDialog ), i18n("New Stuff"), "get-hot-new-stuff" );
00866
00867 m_configDialog->setHelp("kanagram/index.html");
00868 m_configDialog->show();
00869 }
00870 }
00871
00872 void Kanagram::slotSaveSettings()
00873 {
00874 m_shortcutsEditor->save();
00875 }
00876
00877 void Kanagram::slotSettingsCancelled()
00878 {
00879 m_shortcutsEditor->undoChanges();
00880 }
00881
00882 void Kanagram::slotEnableApplyButton()
00883 {
00884 m_configDialog->enableButtonApply(true);
00885 }
00886
00887 void Kanagram::hideHint()
00888 {
00889 if (m_showHint == true)
00890 {
00891 m_showHint = false;
00892 }
00893 update();
00894 }
00895
00896 void Kanagram::resetInputBox()
00897 {
00898 m_inputBox->setPalette(QPalette());
00899 }
00900
00901 void Kanagram::refreshVocabularies()
00902 {
00903 if (m_game->refreshVocabList())
00904 {
00905
00906 m_game->nextVocab();
00907 m_game->nextAnagram();
00908 hideHint();
00909
00910 if (m_useSounds)
00911 {
00912 play("chalk.ogg");
00913 }
00914
00915
00916 KanagramSettings::setDefaultVocab(m_game->getFilename());
00917 KanagramSettings::self()->writeConfig();
00918 m_vocabSettings->refreshView();
00919 }
00920 }
00921
00922 void Kanagram::play(const QString &filename)
00923 {
00924 if (!filename.isEmpty())
00925 {
00926 QString soundFile = KStandardDirs::locate("appdata", "sounds/" + filename);
00927 if (!soundFile.isEmpty())
00928 {
00929 if (!m_player)
00930 {
00931 m_player = Phonon::createPlayer(Phonon::GameCategory, soundFile);
00932 }
00933 else
00934 {
00935 m_player->setCurrentSource(soundFile);
00936 }
00937 m_player->play();
00938 }
00939 }
00940 }
00941
00942 void Kanagram::slotFileError(const QString &filename)
00943 {
00944 QString msg = i18n("File %1 cannot be found.\n Please ensure that Kanagram is properly installed.", filename);
00945 KMessageBox::sorry(this, msg, i18n("Error"));
00946 exit(0);
00947 }
00948
00950 void Kanagram::slotChooseVocabulary()
00951 {
00952 }
00953
00954
00955 #include "kanagram.moc"