File indexing completed on 2024-06-16 05:24:49

0001 /*
0002     This file is part of the Okteta Kasten module, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2008, 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 "filtertool.hpp"
0010 
0011 // tool
0012 #include "filterjob.hpp"
0013 // filter
0014 #include <bytearrayfilterfactory.hpp>
0015 #include <abstractbytearrayfilter.hpp>
0016 // Okteta Kasten gui
0017 #include <Kasten/Okteta/ByteArrayView>
0018 // Okteta Kasten core
0019 #include <Kasten/Okteta/ByteArrayDocument>
0020 // Okteta core
0021 #include <Okteta/AbstractByteArrayModel>
0022 #include <Okteta/ChangesDescribable>
0023 // KF
0024 #include <KConfigGroup>
0025 #include <KSharedConfig>
0026 #include <KLocalizedString>
0027 // Qt
0028 #include <QApplication>
0029 #include <QByteArray>
0030 
0031 
0032 namespace Kasten {
0033 
0034 FilterTool::FilterTool()
0035 {
0036     setObjectName(QStringLiteral("BinaryFilter"));
0037 
0038     mFilterList = ByteArrayFilterFactory::createFilters();
0039 
0040     const KConfigGroup configGroup(KSharedConfig::openConfig(), ConfigGroupId);
0041     for (auto* filter : std::as_const(mFilterList)) {
0042         filter->loadConfig(configGroup);
0043     }
0044 
0045     mFilterId = 0;
0046     const QString operationId = configGroup.readEntry(OperationConfigKey);
0047     if (!operationId.isEmpty()) {
0048         for (int i = 0; i < mFilterList.size(); ++i) {
0049             if (mFilterList[i]->id() == operationId) {
0050                 mFilterId = i;
0051                 break;
0052             }
0053         }
0054     }
0055 }
0056 
0057 FilterTool::~FilterTool()
0058 {
0059     qDeleteAll(mFilterList);
0060 }
0061 
0062 QString FilterTool::title() const { return i18nc("@title:window", "Binary Filter"); }
0063 QVector<AbstractByteArrayFilter*> FilterTool::filterList() const { return mFilterList; }
0064 QString FilterTool::charCodecName() const
0065 {
0066     return mByteArrayView ? mByteArrayView->charCodingName() : QString();
0067 }
0068 
0069 bool FilterTool::hasWriteable() const { return mHasWritable; }
0070 
0071 AbstractByteArrayFilterParameterSet* FilterTool::parameterSet(int filterId)
0072 {
0073     AbstractByteArrayFilter* byteArrayFilter = mFilterList.at(filterId);
0074 
0075     return byteArrayFilter ? byteArrayFilter->parameterSet() : nullptr;
0076 }
0077 
0078 void FilterTool::setTargetModel(AbstractModel* model)
0079 {
0080     if (mByteArrayView) {
0081         mByteArrayView->disconnect(this);
0082     }
0083 
0084     mByteArrayView = model ? model->findBaseModel<ByteArrayView*>() : nullptr;
0085 
0086     ByteArrayDocument* document =
0087         mByteArrayView ? qobject_cast<ByteArrayDocument*>(mByteArrayView->baseModel()) : nullptr;
0088     mByteArrayModel = document ? document->content() : nullptr;
0089 
0090     const bool hasByteArray = (mByteArrayModel && mByteArrayView);
0091     QString newCharCodecName;
0092     if (hasByteArray) {
0093         newCharCodecName = mByteArrayView->charCodingName();
0094         connect(mByteArrayView, &ByteArrayView::hasSelectedDataChanged, this, &FilterTool::onApplyableChanged);
0095         connect(mByteArrayView, &ByteArrayView::readOnlyChanged,        this, &FilterTool::onApplyableChanged);
0096         connect(mByteArrayView, &ByteArrayView::charCodecChanged,
0097                 this, &FilterTool::charCodecChanged);
0098     }
0099 
0100     onApplyableChanged();
0101     Q_EMIT charCodecChanged(newCharCodecName);
0102 }
0103 
0104 void FilterTool::saveParameterSet(int filterId)
0105 {
0106     AbstractByteArrayFilter* byteArrayFilter = mFilterList.at(filterId);
0107 
0108     if (!byteArrayFilter) {
0109         return;
0110     }
0111 
0112     KConfigGroup configGroup(KSharedConfig::openConfig(), ConfigGroupId);
0113     byteArrayFilter->saveConfig(configGroup);
0114 }
0115 
0116 void FilterTool::setFilter(int filterId)
0117 {
0118     if (mFilterId == filterId) {
0119         return;
0120     }
0121 
0122     mFilterId = filterId;
0123 
0124     AbstractByteArrayFilter* byteArrayFilter = mFilterList.at(mFilterId);
0125     if (byteArrayFilter) {
0126         KConfigGroup configGroup(KSharedConfig::openConfig(), ConfigGroupId);
0127         configGroup.writeEntry(OperationConfigKey, byteArrayFilter->id());
0128     }
0129 
0130     Q_EMIT filterChanged(mFilterId);
0131 }
0132 
0133 void FilterTool::filter() const
0134 {
0135     AbstractByteArrayFilter* byteArrayFilter = mFilterList.at(mFilterId);
0136 
0137     if (byteArrayFilter) {
0138         const Okteta::AddressRange filteredSection = mByteArrayView->selection();
0139 
0140         QByteArray filterResult;
0141         filterResult.resize(filteredSection.width());
0142 
0143         QApplication::setOverrideCursor(Qt::WaitCursor);
0144 
0145         auto* filterJob = new FilterJob(byteArrayFilter, reinterpret_cast<Okteta::Byte*>(filterResult.data()), mByteArrayModel, filteredSection);
0146         const bool success = filterJob->exec();
0147 
0148         QApplication::restoreOverrideCursor();
0149 
0150         if (success) {
0151             Okteta::ChangesDescribable* changesDescribable =
0152                 qobject_cast<Okteta::ChangesDescribable*>(mByteArrayModel);
0153 
0154             if (changesDescribable) {
0155                 changesDescribable->openGroupedChange(byteArrayFilter->name());
0156             }
0157             mByteArrayModel->replace(filteredSection, filterResult);
0158             if (changesDescribable) {
0159                 changesDescribable->closeGroupedChange();
0160             }
0161         }
0162     }
0163 
0164     mByteArrayView->setFocus();
0165 }
0166 
0167 void FilterTool::onApplyableChanged()
0168 {
0169     const bool newHasWriteable = (mByteArrayModel && mByteArrayView
0170                                   && !mByteArrayView->isReadOnly() && mByteArrayView->hasSelectedData());
0171     if (newHasWriteable != mHasWritable) {
0172         mHasWritable = newHasWriteable;
0173         Q_EMIT hasWriteableChanged(newHasWriteable);
0174     }
0175 }
0176 
0177 }
0178 
0179 #include "moc_filtertool.cpp"