File indexing completed on 2024-06-23 05:48:55

0001 /*
0002     This file is part of the Okteta Kasten module, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2007-2009, 2012, 2022 Friedrich W. H. Kossebau <kossebau@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007 */
0008 
0009 #include "stringsextracttool.hpp"
0010 
0011 // lib
0012 #include "extractstringsjob.hpp"
0013 // Okteta Kasten gui
0014 #include <Kasten/Okteta/ByteArrayView>
0015 // Okteta Kasten core
0016 #include <Kasten/Okteta/ByteArrayDocument>
0017 // Okteta core
0018 #include <Okteta/CharCodec>
0019 #include <Okteta/AbstractByteArrayModel>
0020 #include <Okteta/ArrayChangeMetricsList>
0021 // KF
0022 #include <KConfigGroup>
0023 #include <KSharedConfig>
0024 #include <KLocalizedString>
0025 // Qt
0026 #include <QApplication>
0027 
0028 namespace Kasten {
0029 
0030 StringsExtractTool::StringsExtractTool()
0031     : mExtractedStringsUptodate(false)
0032     , mSourceByteArrayModelUptodate(false)
0033 {
0034     setObjectName(QStringLiteral("Strings"));
0035 
0036     const KConfigGroup configGroup(KSharedConfig::openConfig(), ConfigGroupId);
0037 
0038     mMinLength = configGroup.readEntry(MinimumLengthConfigKey, DefaultMinLength);
0039 }
0040 
0041 StringsExtractTool::~StringsExtractTool() = default;
0042 
0043 bool StringsExtractTool::isApplyable() const
0044 {
0045     return (mByteArrayModel && mByteArrayView && mByteArrayView->hasSelectedData() && mMinLength > 0);
0046 }
0047 
0048 bool StringsExtractTool::canHighlightString() const
0049 {
0050     return (mSourceByteArrayModel == mByteArrayModel
0051             && mByteArrayView && mSourceByteArrayModelUptodate);
0052 }
0053 
0054 QString StringsExtractTool::title() const { return i18nc("@title:window of the tool to extract strings", "Strings"); }
0055 
0056 // TODO: add model with offset and string
0057 // doubleclick moves cursor to offset
0058 // filter für Suche, inkl. Regulärausdrücke
0059 // groß/kleinschreibung
0060 // voll strings, auch mit Leerzeichen
0061 void StringsExtractTool::setTargetModel(AbstractModel* model)
0062 {
0063     if (mByteArrayView) {
0064         // disconnect explicitly from all connects but QObject::detroyed,
0065         // for the case mSourceByteArrayView is mByteArrayView
0066         disconnect(mByteArrayView,  &ByteArrayView::selectedDataChanged,
0067                    this, &StringsExtractTool::onSelectionChanged);
0068         disconnect(mByteArrayView, &ByteArrayView::offsetCodingChanged,
0069                    this, &StringsExtractTool::offsetCodingChanged);
0070     }
0071 
0072     mByteArrayView = model ? model->findBaseModel<ByteArrayView*>() : nullptr;
0073 
0074     ByteArrayDocument* document =
0075         mByteArrayView ? qobject_cast<ByteArrayDocument*>(mByteArrayView->baseModel()) : nullptr;
0076     mByteArrayModel = document ? document->content() : nullptr;
0077 
0078     if (mByteArrayView && mByteArrayModel) {
0079         connect(mByteArrayView,  &ByteArrayView::selectedDataChanged,
0080                 this, &StringsExtractTool::onSelectionChanged);
0081 
0082         // if strings are from same model, adapt offsetcoding
0083         if (mSourceByteArrayModel == mByteArrayModel) {
0084             connect(mByteArrayView, &ByteArrayView::offsetCodingChanged,
0085                     this, &StringsExtractTool::offsetCodingChanged);
0086         }
0087     }
0088 
0089     // TODO: if there is no view, there is nothing to extract.
0090     // or this could be the view where we got the strings from and it did not change
0091     checkUptoDate();
0092     Q_EMIT uptodateChanged(mExtractedStringsUptodate);
0093     Q_EMIT isApplyableChanged(isApplyable());
0094     Q_EMIT canHighlightStringChanged(canHighlightString());
0095     if (mSourceByteArrayModel == mByteArrayModel && mByteArrayView) {
0096         Q_EMIT offsetCodingChanged(mByteArrayView->offsetCoding());
0097     }
0098 }
0099 
0100 int StringsExtractTool::offsetCoding() const { return (mByteArrayView ? mByteArrayView->offsetCoding() : 0); }
0101 
0102 void StringsExtractTool::setMinLength(int minLength)
0103 {
0104     if (mMinLength == minLength) {
0105         return;
0106     }
0107 
0108     mMinLength = minLength;
0109 
0110     KConfigGroup configGroup(KSharedConfig::openConfig(), ConfigGroupId);
0111     configGroup.writeEntry(MinimumLengthConfigKey, mMinLength);
0112 
0113     checkUptoDate();
0114     Q_EMIT uptodateChanged(mExtractedStringsUptodate);
0115 }
0116 
0117 void StringsExtractTool::checkUptoDate()
0118 {
0119     mExtractedStringsUptodate =
0120         (mSourceByteArrayModel == mByteArrayModel
0121          && mByteArrayView && mSourceSelection == mByteArrayView->selection()
0122          && mSourceMinLength == mMinLength
0123          && mSourceByteArrayModelUptodate);
0124 }
0125 
0126 void StringsExtractTool::markString(int stringId)
0127 {
0128     if (mSourceByteArrayView != mByteArrayView) {
0129         if (mSourceByteArrayView) {
0130             mSourceByteArrayView->disconnect(this);
0131         }
0132         mSourceByteArrayView = mByteArrayView;
0133         connect(mSourceByteArrayView,  &ByteArrayView::destroyed,
0134                 this, &StringsExtractTool::onSourceViewDestroyed);
0135     }
0136     const ContainedString& containedString = mContainedStringList.at(stringId);
0137     const Okteta::Address offset = containedString.offset();
0138     const int length = containedString.string().length();
0139     const Okteta::AddressRange markingRange = Okteta::AddressRange::fromWidth(offset, length);
0140     mSourceByteArrayView->setMarking(markingRange, true);
0141 }
0142 
0143 void StringsExtractTool::unmarkString()
0144 {
0145 // TODO: marked region is property of document, not view?
0146     if (mSourceByteArrayView) {
0147         mSourceByteArrayView->setMarking(Okteta::AddressRange());
0148     }
0149 }
0150 
0151 void StringsExtractTool::onSelectionChanged()
0152 {
0153 // TODO: could be quicker using the selection data
0154     checkUptoDate();
0155     Q_EMIT uptodateChanged(mExtractedStringsUptodate);
0156     Q_EMIT isApplyableChanged(isApplyable());
0157 }
0158 
0159 void StringsExtractTool::onSourceChanged()
0160 {
0161     mExtractedStringsUptodate = false;
0162     mSourceByteArrayModelUptodate = false;
0163     Q_EMIT uptodateChanged(false);
0164     Q_EMIT canHighlightStringChanged(false);
0165 }
0166 
0167 void StringsExtractTool::onSourceDestroyed()
0168 {
0169     mSourceByteArrayModel = nullptr;
0170     onSourceChanged();
0171 }
0172 
0173 void StringsExtractTool::onSourceViewDestroyed()
0174 {
0175     mSourceByteArrayView = nullptr;
0176 }
0177 
0178 // TODO: use TextByteArrayAnalyzer
0179 void StringsExtractTool::extractStrings()
0180 {
0181     // forget old string source
0182     if (mSourceByteArrayModel) {
0183         mSourceByteArrayModel->disconnect(this);
0184     }
0185 
0186     QApplication::setOverrideCursor(Qt::WaitCursor);
0187 
0188     Okteta::CharCodec* charCodec = Okteta::CharCodec::createCodec(mByteArrayView->charCodingName());
0189     auto* extractStringsJob =
0190         new ExtractStringsJob(mByteArrayModel, mByteArrayView->selection(), charCodec, mMinLength,
0191                               &mContainedStringList);
0192     extractStringsJob->exec();
0193     delete charCodec;
0194 
0195     QApplication::restoreOverrideCursor();
0196 
0197     // remember new string source
0198     mSourceByteArrayModel = mByteArrayModel;
0199     mSourceSelection = mByteArrayView->selection();
0200     mSourceMinLength = mMinLength;
0201     connect(mSourceByteArrayModel,  &Okteta::AbstractByteArrayModel::contentsChanged,
0202             this, &StringsExtractTool::onSourceChanged);
0203     connect(mSourceByteArrayModel,  &Okteta::AbstractByteArrayModel::destroyed,
0204             this, &StringsExtractTool::onSourceDestroyed);
0205     connect(mByteArrayView, &ByteArrayView::offsetCodingChanged,
0206             this, &StringsExtractTool::offsetCodingChanged);
0207 
0208     mExtractedStringsUptodate = true;
0209     mSourceByteArrayModelUptodate = true;
0210     Q_EMIT uptodateChanged(true);
0211     Q_EMIT canHighlightStringChanged(true);
0212     Q_EMIT offsetCodingChanged(mByteArrayView->offsetCoding());
0213 }
0214 
0215 }
0216 
0217 #include "moc_stringsextracttool.cpp"