File indexing completed on 2024-04-14 03:49:11

0001 /*
0002     SPDX-FileCopyrightText: 2009 Daniel Laidig <d.laidig@gmx.de>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "practicemainwindow.h"
0007 
0008 #include <QHBoxLayout>
0009 #include <QPropertyAnimation>
0010 #include <QToolButton>
0011 
0012 #include <KActionCollection>
0013 #include <KConfig>
0014 #include <KConfigGroup>
0015 #include <KLocalizedString>
0016 #include <KToggleFullScreenAction>
0017 #include <KToolBar>
0018 #include <QAction>
0019 #include <QMenuBar>
0020 
0021 #include "guifrontend.h"
0022 #include "parleymainwindow.h"
0023 #include "practicestatemachine.h"
0024 #include <languagesettings.h>
0025 
0026 using namespace Practice;
0027 
0028 PracticeMainWindow::PracticeMainWindow(SessionManagerBase *sessionManager, ParleyMainWindow *mainWindow)
0029     : KXmlGuiWindow(mainWindow)
0030     , m_mainWindow(mainWindow)
0031 {
0032     // KXmlGui
0033     setXMLFile(QStringLiteral("practiceui.rc"));
0034     setObjectName(QStringLiteral("Practice"));
0035 
0036     m_guiFrontend = new GuiFrontend(this);
0037     setCentralWidget(m_guiFrontend->widget());
0038 
0039     m_stateMachine = new PracticeStateMachine(m_guiFrontend, mainWindow->parleyDocument(), sessionManager, this);
0040 
0041     // setModified - otherwise we may not ask to save progress
0042     ///@todo trust the dirty bit
0043     mainWindow->parleyDocument()->document()->setModified(true);
0044 
0045     initActions();
0046 
0047     connect(this, &PracticeMainWindow::enterPressed, m_guiFrontend, &GuiFrontend::continueAction);
0048     connect(m_stateMachine, &PracticeStateMachine::practiceFinished, this, &PracticeMainWindow::practiceFinished);
0049 
0050     KConfigGroup cfg(KSharedConfig::openConfig(QStringLiteral("parleyrc")), objectName());
0051     applyMainWindowSettings(cfg);
0052 }
0053 
0054 PracticeMainWindow::~PracticeMainWindow()
0055 {
0056     // m_floatingToolBar is a child of m_mainWindow will be deleted with its children
0057     // before or after this.  So don't access it in toggleFullScreenMode.
0058     m_floatingToolBar = nullptr;
0059     toggleFullScreenMode(false);
0060 
0061     KConfigGroup cfg(KSharedConfig::openConfig(QStringLiteral("parleyrc")), objectName());
0062     saveMainWindowSettings(cfg);
0063 }
0064 
0065 void PracticeMainWindow::initActions()
0066 {
0067     QAction *stopPracticeAction = new QAction(this);
0068     stopPracticeAction->setText(i18n("Stop Practice"));
0069     stopPracticeAction->setIcon(QIcon::fromTheme(QStringLiteral("practice-stop")));
0070     stopPracticeAction->setToolTip(i18n("Stop practicing"));
0071     actionCollection()->addAction(QStringLiteral("practice_stop"), stopPracticeAction);
0072     connect(stopPracticeAction, &QAction::triggered, m_stateMachine, &PracticeStateMachine::slotPracticeFinished);
0073 
0074     m_fullScreenAction = KStandardAction::fullScreen(this, SLOT(toggleFullScreenMode(bool)), m_mainWindow, actionCollection());
0075 
0076     QAction *toggleAnswerState = new QAction(this);
0077     toggleAnswerState->setText(i18n("Change answer to right/wrong"));
0078     toggleAnswerState->setToolTip(
0079         i18n("When you answered, Parley will display that the answer was right or wrong.\nThis shortcut changes how the answer is counted."));
0080     actionCollection()->addAction(QStringLiteral("toggle_answer_state"), toggleAnswerState);
0081     toggleAnswerState->setShortcut(Qt::CTRL | Qt::Key_Space);
0082     connect(toggleAnswerState, &QAction::triggered, m_guiFrontend, &GuiFrontend::toggleResultState);
0083 
0084     // m_floatingToolBar now a child of m_mainWindow and will be deleted with its parent
0085     m_floatingToolBar = new QWidget(m_mainWindow);
0086     QHBoxLayout *layout = new QHBoxLayout();
0087     m_floatingToolBar->setLayout(layout);
0088     m_floatingToolBar->setAutoFillBackground(true);
0089     QToolButton *fullScreenButton = new QToolButton(m_floatingToolBar);
0090     fullScreenButton->setDefaultAction(m_fullScreenAction);
0091     fullScreenButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
0092     fullScreenButton->setIconSize(QSize(22, 22));
0093     fullScreenButton->setAutoRaise(true);
0094     QToolButton *stopPracticeButton = new QToolButton(m_floatingToolBar);
0095     stopPracticeButton->setDefaultAction(stopPracticeAction);
0096     stopPracticeButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
0097     stopPracticeButton->setIconSize(QSize(22, 22));
0098     stopPracticeButton->setAutoRaise(true);
0099     layout->addWidget(fullScreenButton);
0100     layout->addWidget(stopPracticeButton);
0101     layout->addStretch();
0102     m_animation = new QPropertyAnimation(m_floatingToolBar, "geometry", this);
0103     m_animation->setDuration(150);
0104 }
0105 
0106 void PracticeMainWindow::resizeEvent(QResizeEvent *)
0107 {
0108     m_floatingToolBar->resize(m_mainWindow->width(), m_floatingToolBar->sizeHint().height());
0109     m_animation->setStartValue(QRect(QPoint(0, -m_floatingToolBar->height()), m_floatingToolBar->size()));
0110     m_animation->setEndValue(QRect(QPoint(0, 0), m_floatingToolBar->size()));
0111     m_animation->setDirection(QAbstractAnimation::Backward);
0112     m_animation->stop();
0113     m_floatingToolBar->setGeometry(m_animation->startValue().toRect());
0114 }
0115 
0116 bool PracticeMainWindow::event(QEvent *event)
0117 {
0118     if (event->type() == QEvent::HoverMove && m_fullScreenAction->isChecked()) {
0119         QPoint pos = static_cast<QHoverEvent *>(event)->pos();
0120         if (m_animation->direction() == QAbstractAnimation::Backward && pos.y() <= m_floatingToolBar->height()) {
0121             m_animation->setDirection(QAbstractAnimation::Forward);
0122             m_animation->start();
0123         }
0124         if (m_animation->direction() == QAbstractAnimation::Forward && pos.y() > (m_floatingToolBar->height() + 20)) {
0125             m_animation->setDirection(QAbstractAnimation::Backward);
0126             m_animation->start();
0127         }
0128     }
0129     return KXmlGuiWindow::event(event);
0130 }
0131 
0132 void PracticeMainWindow::toggleFullScreenMode(bool fullScreen)
0133 {
0134     KToggleFullScreenAction::setFullScreen(m_mainWindow, fullScreen);
0135     m_mainWindow->toolBar(QStringLiteral("practiceToolBar"))->setVisible(!fullScreen);
0136     m_mainWindow->menuBar()->setVisible(!fullScreen);
0137     if (m_floatingToolBar != nullptr) {
0138         m_floatingToolBar->setVisible(fullScreen);
0139     }
0140     m_mainWindow->setSettingsDirty();
0141 }
0142 
0143 void PracticeMainWindow::startPractice()
0144 {
0145     // Set the fonts for the known language and learning language.
0146     // These are used in the practice state machine to set the
0147     // questionfont and answerfont in the mode widget.
0148     QString knownLangLocale = m_mainWindow->parleyDocument()->document()->identifier(Prefs::knownLanguage()).locale();
0149     LanguageSettings knownLangSettings(knownLangLocale);
0150     knownLangSettings.load();
0151     QFont knownLangFont = knownLangSettings.practiceFont();
0152     m_guiFrontend->setKnownLangFont(knownLangFont);
0153 
0154     QString learningLangLocale = m_mainWindow->parleyDocument()->document()->identifier(Prefs::learningLanguage()).locale();
0155     LanguageSettings learningLangSettings(learningLangLocale);
0156     learningLangSettings.load();
0157     QFont learningLangFont = learningLangSettings.practiceFont();
0158     m_guiFrontend->setLearningLangFont(learningLangFont);
0159 
0160     m_stateMachine->start();
0161 }
0162 
0163 void PracticeMainWindow::practiceFinished()
0164 {
0165     delete m_stateMachine;
0166     Q_EMIT stopPractice();
0167 }
0168 
0169 #include "moc_practicemainwindow.cpp"