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"