File indexing completed on 2024-06-09 04:53:00

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 "errorfinder.h"
0009 
0010 #include "appglobal.h"
0011 #include "application.h"
0012 #include "core/subtitleiterator.h"
0013 #include "errors/finderrorsdialog.h"
0014 #include "gui/treeview/lineswidget.h"
0015 
0016 #include <QCheckBox>
0017 #include <QGroupBox>
0018 #include <QGridLayout>
0019 #include <QPushButton>
0020 
0021 #include <QDebug>
0022 
0023 #include <KMessageBox>
0024 
0025 using namespace SubtitleComposer;
0026 
0027 
0028 ErrorFinder::ErrorFinder(QWidget *parent)
0029     : QObject(parent),
0030       m_subtitle(nullptr),
0031       m_dialog(new FindErrorsDialog(parent)),
0032       m_translationMode(false),
0033       m_iterator(nullptr)
0034 {
0035 }
0036 
0037 ErrorFinder::~ErrorFinder()
0038 {
0039     delete m_dialog;
0040     invalidate();
0041 }
0042 
0043 void
0044 ErrorFinder::invalidate()
0045 {
0046     delete m_iterator;
0047     m_iterator = nullptr;
0048 }
0049 
0050 QWidget *
0051 ErrorFinder::parentWidget()
0052 {
0053     return static_cast<QWidget *>(parent());
0054 }
0055 
0056 void
0057 ErrorFinder::setSubtitle(Subtitle *subtitle)
0058 {
0059     m_subtitle = subtitle;
0060     invalidate();
0061 }
0062 
0063 void
0064 ErrorFinder::setTranslationMode(bool enabled)
0065 {
0066     if(m_translationMode != enabled) {
0067         m_translationMode = enabled;
0068         invalidate();
0069     }
0070 }
0071 
0072 void
0073 ErrorFinder::find(int searchFromIndex, bool findBackwards)
0074 {
0075     if(!m_subtitle || m_subtitle->isEmpty())
0076         return;
0077 
0078     if(m_dialog->exec() != QDialog::Accepted)
0079         return;
0080 
0081     const RangeList targetRanges = app()->linesWidget()->targetRanges(m_dialog->selectedLinesTarget());
0082 
0083     {
0084         SubtitleCompositeActionExecutor executor(m_subtitle.constData(), i18n("Check Lines Errors"));
0085 
0086         if(m_dialog->clearOtherErrors())
0087             m_subtitle->clearErrors(targetRanges, SubtitleLine::AllErrors & ~SubtitleLine::UserMark);
0088 
0089         if(m_dialog->clearMarks())
0090             m_subtitle->setMarked(targetRanges, false);
0091 
0092         m_subtitle->checkErrors(targetRanges, m_dialog->selectedErrorFlags());
0093     }
0094 
0095 
0096     invalidate();
0097 
0098     m_findBackwards = findBackwards;
0099     m_targetErrorFlags = m_dialog->selectedErrorFlags() | SubtitleLine::UserMark;
0100 
0101     m_iterator = new SubtitleIterator(*m_subtitle, targetRanges);
0102     if(m_iterator->index() == SubtitleIterator::Invalid) {
0103         invalidate();
0104         return;
0105     }
0106     m_iterator->toIndex(searchFromIndex < 0 ? 0 : searchFromIndex);
0107 
0108     advance(false);
0109 }
0110 
0111 bool
0112 ErrorFinder::findNext(int fromIndex)
0113 {
0114     if(!m_iterator)
0115         return false;
0116 
0117     m_findBackwards = false;
0118     if(fromIndex != -1)
0119         m_iterator->toIndex(fromIndex);
0120 
0121     advance(true);
0122     return true;
0123 }
0124 
0125 bool
0126 ErrorFinder::findPrevious(int fromIndex)
0127 {
0128     if(!m_iterator)
0129         return false;
0130 
0131     m_findBackwards = true;
0132     if(fromIndex != -1)
0133         m_iterator->toIndex(fromIndex);
0134 
0135     advance(true);
0136     return true;
0137 }
0138 
0139 void
0140 ErrorFinder::advance(bool advanceIteratorOnFirstStep)
0141 {
0142     const int startIndex = m_iterator->index();
0143     bool searched = false;
0144 
0145     for(;;) {
0146         if(advanceIteratorOnFirstStep) {
0147             if(m_findBackwards)
0148                 --(*m_iterator);
0149             else
0150                 ++(*m_iterator);
0151 
0152             if(m_iterator->index() < 0) {
0153                 if(m_findBackwards)
0154                     m_iterator->toLast();
0155                 else
0156                     m_iterator->toFirst();
0157 
0158 //              const QString text = m_findBackwards
0159 //                      ? (m_selection ? i18n("Beginning of selection reached.\nContinue from the end?") : i18n("Beginning of subtitle reached.\nContinue from the end?"))
0160 //                      : (m_selection ? i18n("End of selection reached.\nContinue from the beginning?") : i18n("End of subtitle reached.\nContinue from the beginning?"));
0161 //              if(KMessageBox::warningContinueCancel(parentWidget(), text, i18n("Find Error")) != KMessageBox::Continue)
0162 //                  break;
0163             }
0164         } else {
0165             advanceIteratorOnFirstStep = true;
0166         }
0167 
0168         if(m_iterator->current()->errorFlags() & m_targetErrorFlags) {
0169             emit found(m_iterator->current());
0170             break;
0171         } else if(searched && startIndex == m_iterator->index()) {
0172             // searched through all lines and found no errors
0173             KMessageBox::information(parentWidget(), i18n("No errors matching given criteria were found!"), i18n("Find Error"));
0174             invalidate();
0175             return;
0176         }
0177 
0178         searched = true;
0179     }
0180 }