File indexing completed on 2025-01-05 05:23:37
0001 /* 0002 This file is part of the Okteta Kasten module, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2009, 2023 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 "replacetool.hpp" 0010 0011 // controller 0012 #include "replacejob.hpp" 0013 // libconfigentries 0014 #include <casesensitivityconfigentry.hpp> 0015 // libbytearraysearch 0016 #include <bytearraysearchutils.hpp> 0017 // Okteta Kasten gui 0018 #include <Kasten/Okteta/ByteArrayView> 0019 // Okteta Kasten core 0020 #include <Kasten/Okteta/ByteArrayDocument> 0021 // Okteta core 0022 #include <Okteta/AbstractByteArrayModel> 0023 // KF 0024 #include <KConfigGroup> 0025 #include <KSharedConfig> 0026 #include <KLocalizedString> 0027 0028 0029 namespace Kasten { 0030 0031 ReplaceTool::ReplaceTool() 0032 { 0033 setObjectName(QStringLiteral("Replace")); 0034 0035 const KConfigGroup configGroup(KSharedConfig::openConfig(), ConfigGroupId); 0036 mCaseSensitivity = configGroup.readEntry(CaseSensitivityConfigKey, DefaultCaseSensitivity); 0037 mDoPrompt = configGroup.readEntry(PromptConfigKey, DefaultDoPrompt); 0038 } 0039 0040 ReplaceTool::~ReplaceTool() = default; 0041 0042 bool ReplaceTool::isApplyable() const 0043 { 0044 return (mByteArrayView && mByteArrayModel && !mByteArrayView->isReadOnly()) && !mReplaceJob; 0045 // const int newPosition = finalTargetOffset(); 0046 0047 // return ( mByteArrayView && mByteArrayModel 0048 // && (0 <= newPosition) && (newPosition <= mByteArrayModel->size()) ); 0049 } 0050 0051 QString ReplaceTool::title() const { return i18nc("@title", "Replace"); } 0052 0053 bool ReplaceTool::hasSelectedData() const { return mByteArrayView->hasSelectedData(); } 0054 QString ReplaceTool::charCodingName() const { return mByteArrayView->charCodingName(); } 0055 0056 void ReplaceTool::setTargetModel(AbstractModel* model) 0057 { 0058 const bool oldIsApplyable = isApplyable(); 0059 0060 if (mByteArrayView) { 0061 mByteArrayView->disconnect(this); 0062 } 0063 if (mByteArrayModel) { 0064 mByteArrayModel->disconnect(this); 0065 } 0066 0067 mByteArrayView = model ? model->findBaseModel<ByteArrayView*>() : nullptr; 0068 0069 ByteArrayDocument* document = 0070 mByteArrayView ? qobject_cast<ByteArrayDocument*>(mByteArrayView->baseModel()) : nullptr; 0071 mByteArrayModel = document ? document->content() : nullptr; 0072 0073 if (mByteArrayView && mByteArrayModel) { 0074 connect(mByteArrayView, &ByteArrayView::readOnlyChanged, this, &ReplaceTool::onReadOnlyChanged); 0075 // TODO: update isApplyable on cursor movement and size changes 0076 } 0077 0078 const bool newIsApplyable = isApplyable(); 0079 if (oldIsApplyable != newIsApplyable) { 0080 Q_EMIT isApplyableChanged(newIsApplyable); 0081 } 0082 } 0083 0084 void ReplaceTool::setUserQueryAgent(QObject* userQueryAgent) 0085 { 0086 mUserQueryAgent = userQueryAgent; 0087 } 0088 0089 void ReplaceTool::setSearchData(const QByteArray& searchData) 0090 { 0091 // const bool oldIsApplyable = isApplyable(); 0092 0093 mSearchData = searchData; 0094 0095 // const bool newIsApplyable = isApplyable(); 0096 // if( oldIsApplyable != newIsApplyable ) 0097 // Q_EMIT isApplyableChanged( newIsApplyable ); 0098 } 0099 0100 void ReplaceTool::setReplaceData(const QByteArray& replaceData) 0101 { 0102 // const bool oldIsApplyable = isApplyable(); 0103 0104 mReplaceData = replaceData; 0105 0106 // const bool newIsApplyable = isApplyable(); 0107 // if( oldIsApplyable != newIsApplyable ) 0108 // Q_EMIT isApplyableChanged( newIsApplyable ); 0109 } 0110 0111 void ReplaceTool::setCaseSensitivity(Qt::CaseSensitivity caseSensitivity) 0112 { 0113 if (mCaseSensitivity == caseSensitivity) { 0114 return; 0115 } 0116 0117 // const bool oldIsApplyable = isApplyable(); 0118 0119 mCaseSensitivity = caseSensitivity; 0120 0121 KConfigGroup configGroup(KSharedConfig::openConfig(), ConfigGroupId); 0122 configGroup.writeEntry(CaseSensitivityConfigKey, mCaseSensitivity); 0123 0124 // const bool newIsApplyable = isApplyable(); 0125 // if( oldIsApplyable != newIsApplyable ) 0126 // Q_EMIT isApplyableChanged( newIsApplyable ); 0127 } 0128 0129 void ReplaceTool::setDoPrompt(bool doPrompt) 0130 { 0131 if (mDoPrompt == doPrompt) { 0132 return; 0133 } 0134 0135 mDoPrompt = doPrompt; 0136 0137 KConfigGroup configGroup(KSharedConfig::openConfig(), ConfigGroupId); 0138 configGroup.writeEntry(PromptConfigKey, mDoPrompt); 0139 } 0140 0141 void ReplaceTool::replace(FindDirection direction, bool fromCursor, bool inSelection) 0142 { 0143 Okteta::Address replaceRangeStartIndex; 0144 Okteta::Address replaceRangeEndIndex; 0145 0146 if (!ByteArraySearchUtils::getSearchIndexes(&replaceRangeStartIndex, &replaceRangeEndIndex, 0147 mByteArrayModel, 0148 mByteArrayView->selection(), 0149 mByteArrayView->cursorPosition(), 0150 mSearchData, 0151 direction, 0152 fromCursor, inSelection)) { 0153 // no search doable, so skip any search and finish now 0154 mReplaceJob = nullptr; 0155 Q_EMIT finished(false, 0); 0156 return; 0157 } 0158 0159 mReplaceJob = new ReplaceJob(mByteArrayView, mByteArrayModel, mUserQueryAgent, this); 0160 mReplaceJob->setSearchData(mSearchData); 0161 mReplaceJob->setReplaceData(mReplaceData); 0162 mReplaceJob->setCaseSensitivity(mCaseSensitivity); 0163 mReplaceJob->setDoPrompt(mDoPrompt); 0164 mReplaceJob->setRange(replaceRangeStartIndex, replaceRangeEndIndex, direction); 0165 connect(mReplaceJob, &ReplaceJob::finished, this, &ReplaceTool::onJobFinished); 0166 0167 Q_EMIT isApplyableChanged(isApplyable()); 0168 0169 mReplaceJob->start(); 0170 } 0171 0172 void ReplaceTool::onReadOnlyChanged(bool isReadOnly) 0173 { 0174 Q_UNUSED(isReadOnly) 0175 0176 // TODO: find out if isApplyable really changed, perhaps by caching the readonly state? 0177 Q_EMIT isApplyableChanged(isApplyable()); 0178 } 0179 0180 void ReplaceTool::onJobFinished(bool previousFound, int noOfReplacements) 0181 { 0182 delete mReplaceJob; 0183 mReplaceJob = nullptr; 0184 0185 Q_EMIT finished(previousFound, noOfReplacements); 0186 Q_EMIT isApplyableChanged(isApplyable()); 0187 } 0188 0189 } 0190 0191 #include "moc_replacetool.cpp"