File indexing completed on 2024-06-09 04:53:12
0001 /* 0002 SPDX-FileCopyrightText: 2007-2009 Sergio Pistone <sergio_pistone@yahoo.com.ar> 0003 SPDX-FileCopyrightText: 2010-2022 Mladen Milinkovic <max@smoothware.net> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "speller.h" 0009 #include "application.h" 0010 #include "core/richtext/richdocument.h" 0011 #include "core/subtitleiterator.h" 0012 0013 #include <QDebug> 0014 0015 #include <KMessageBox> 0016 #include <KLocalizedString> 0017 0018 #include <sonnet_version.h> 0019 #include <sonnet/dialog.h> 0020 #include <sonnet/backgroundchecker.h> 0021 0022 using namespace SubtitleComposer; 0023 0024 Speller::Speller(QWidget *parent) : 0025 QObject(parent), 0026 m_subtitle(0), 0027 m_translationMode(false), 0028 m_useTranslation(false), 0029 m_sonnetDialog(0), 0030 m_iterator(0) 0031 { 0032 connect(SCConfig::self(), &KCoreConfigSkeleton::configChanged, this, &Speller::onConfigChanged); 0033 } 0034 0035 Speller::~Speller() 0036 { 0037 setSubtitle(0); 0038 } 0039 0040 void 0041 Speller::invalidate() 0042 { 0043 delete m_iterator; 0044 m_iterator = 0; 0045 } 0046 0047 QWidget * 0048 Speller::parentWidget() 0049 { 0050 return static_cast<QWidget *>(parent()); 0051 } 0052 0053 void 0054 Speller::setSubtitle(Subtitle *subtitle) 0055 { 0056 m_subtitle = subtitle; 0057 0058 invalidate(); 0059 } 0060 0061 void 0062 Speller::setTranslationMode(bool enabled) 0063 { 0064 m_translationMode = enabled; 0065 0066 if(!enabled) 0067 m_useTranslation = false; 0068 } 0069 0070 void 0071 Speller::setUseTranslation(bool useTranslation) 0072 { 0073 if(m_useTranslation != useTranslation) { 0074 m_useTranslation = useTranslation; 0075 updateBuffer(); 0076 } 0077 } 0078 0079 void 0080 Speller::updateBuffer() 0081 { 0082 if(m_iterator) 0083 m_sonnetDialog->setBuffer((m_useTranslation ? m_iterator->current()->secondaryDoc() : m_iterator->current()->primaryDoc())->toPlainText()); 0084 } 0085 0086 void 0087 Speller::spellCheck(int currentIndex) 0088 { 0089 invalidate(); 0090 0091 if(!m_subtitle || !m_subtitle->linesCount()) 0092 return; 0093 0094 m_iterator = new SubtitleIterator(*m_subtitle); 0095 m_iterator->toIndex(currentIndex < 0 ? 0 : currentIndex); 0096 m_firstIndex = m_iterator->index(); 0097 0098 if(!m_sonnetDialog) { 0099 m_sonnetDialog = new Sonnet::Dialog(new Sonnet::BackgroundChecker(this), parentWidget()); 0100 0101 #if SONNET_VERSION < QT_VERSION_CHECK(5, 65, 0) 0102 connect(m_sonnetDialog, QOverload<const QString &>::of(&Sonnet::Dialog::done), this, &Speller::onBufferDone); 0103 #else 0104 connect(m_sonnetDialog, &Sonnet::Dialog::spellCheckDone, this, &Speller::onBufferDone); 0105 #endif 0106 0107 connect(m_sonnetDialog, &Sonnet::Dialog::replace, this, &Speller::onCorrected); 0108 0109 connect(m_sonnetDialog, &Sonnet::Dialog::misspelling, this, &Speller::onMisspelling); 0110 } 0111 0112 updateBuffer(); 0113 m_sonnetDialog->show(); 0114 } 0115 0116 void 0117 Speller::onBufferDone() 0118 { 0119 // NOTE: not setting the buffer in this slots closes the dialog 0120 if(advance()) 0121 updateBuffer(); 0122 } 0123 0124 bool 0125 Speller::advance() 0126 { 0127 ++(*m_iterator); 0128 0129 if((m_firstIndex == m_iterator->index()) || (m_firstIndex == m_iterator->firstIndex() && m_iterator->index() == SubtitleIterator::AfterLast)) 0130 return false; 0131 0132 if(m_iterator->index() < 0) { 0133 m_iterator->toFirst(); 0134 0135 if(KMessageBox::Continue != KMessageBox::warningContinueCancel(parentWidget(), i18n("End of subtitle reached.\nContinue from the beginning?"), i18n("Spell Checking"))) 0136 return false; 0137 } 0138 0139 return true; 0140 } 0141 0142 void 0143 Speller::onMisspelling(const QString &before, int pos) 0144 { 0145 emit misspelled(m_iterator->current(), !m_useTranslation, pos, pos + before.length() - 1); 0146 } 0147 0148 void 0149 Speller::onCorrected(const QString &before, int pos, const QString &after) 0150 { 0151 if(before == after) 0152 return; 0153 0154 if(m_useTranslation) 0155 m_iterator->current()->secondaryDoc()->replace(pos, before.length(), after); 0156 else 0157 m_iterator->current()->primaryDoc()->replace(pos, before.length(), after); 0158 } 0159 0160 void 0161 Speller::onConfigChanged() 0162 { 0163 if(m_sonnetDialog) { 0164 invalidate(); 0165 0166 m_sonnetDialog->deleteLater(); 0167 m_sonnetDialog = nullptr; 0168 } 0169 } 0170 0171