1 /*
2     This file is part of the Okteta Kasten module, made within the KDE community.
3 
4     SPDX-FileCopyrightText: 2008 Friedrich W. H. Kossebau <kossebau@kde.org>
5 
6     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
7 */
8 
9 #include "filtertool.hpp"
10 
11 // tool
12 #include "filterjob.hpp"
13 // filter
14 #include <bytearrayfilterfactory.hpp>
15 #include <abstractbytearrayfilter.hpp>
16 // Okteta Kasten gui
17 #include <Kasten/Okteta/ByteArrayView>
18 // Okteta Kasten core
19 #include <Kasten/Okteta/ByteArrayDocument>
20 // Okteta core
21 #include <Okteta/AbstractByteArrayModel>
22 #include <Okteta/ChangesDescribable>
23 // KF
24 #include <KLocalizedString>
25 // Qt
26 #include <QApplication>
27 #include <QByteArray>
28 
29 namespace Kasten {
30 
FilterTool()31 FilterTool::FilterTool()
32 {
33     setObjectName(QStringLiteral("BinaryFilter"));
34 
35     mFilterList = ByteArrayFilterFactory::createFilters();
36 }
37 
~FilterTool()38 FilterTool::~FilterTool()
39 {
40     qDeleteAll(mFilterList);
41 }
42 
title() const43 QString FilterTool::title() const { return i18nc("@title:window", "Binary Filter"); }
filterList() const44 QVector<AbstractByteArrayFilter*> FilterTool::filterList() const { return mFilterList; }
charCodecName() const45 QString FilterTool::charCodecName() const
46 {
47     return mByteArrayView ? mByteArrayView->charCodingName() : QString();
48 }
49 
hasWriteable() const50 bool FilterTool::hasWriteable() const { return mHasWritable; }
51 
parameterSet(int filterId)52 AbstractByteArrayFilterParameterSet* FilterTool::parameterSet(int filterId)
53 {
54     AbstractByteArrayFilter* byteArrayFilter = mFilterList.at(filterId);
55 
56     return byteArrayFilter ? byteArrayFilter->parameterSet() : nullptr;
57 }
58 
setTargetModel(AbstractModel * model)59 void FilterTool::setTargetModel(AbstractModel* model)
60 {
61     if (mByteArrayView) {
62         mByteArrayView->disconnect(this);
63     }
64 
65     mByteArrayView = model ? model->findBaseModel<ByteArrayView*>() : nullptr;
66 
67     ByteArrayDocument* document =
68         mByteArrayView ? qobject_cast<ByteArrayDocument*>(mByteArrayView->baseModel()) : nullptr;
69     mByteArrayModel = document ? document->content() : nullptr;
70 
71     const bool hasByteArray = (mByteArrayModel && mByteArrayView);
72     QString newCharCodecName;
73     if (hasByteArray) {
74         newCharCodecName = mByteArrayView->charCodingName();
75         connect(mByteArrayView, &ByteArrayView::hasSelectedDataChanged, this, &FilterTool::onApplyableChanged);
76         connect(mByteArrayView, &ByteArrayView::readOnlyChanged,        this, &FilterTool::onApplyableChanged);
77         connect(mByteArrayView, &ByteArrayView::charCodecChanged,
78                 this, &FilterTool::charCodecChanged);
79     }
80 
81     onApplyableChanged();
82     emit charCodecChanged(newCharCodecName);
83 }
84 
filter(int filterId) const85 void FilterTool::filter(int filterId) const
86 {
87     AbstractByteArrayFilter* byteArrayFilter = mFilterList.at(filterId);
88 
89     if (byteArrayFilter) {
90         const Okteta::AddressRange filteredSection = mByteArrayView->selection();
91 
92         QByteArray filterResult;
93         filterResult.resize(filteredSection.width());
94 
95         QApplication::setOverrideCursor(Qt::WaitCursor);
96 
97         auto* filterJob = new FilterJob(byteArrayFilter, reinterpret_cast<Okteta::Byte*>(filterResult.data()), mByteArrayModel, filteredSection);
98         const bool success = filterJob->exec();
99 
100         QApplication::restoreOverrideCursor();
101 
102         if (success) {
103             Okteta::ChangesDescribable* changesDescribable =
104                 qobject_cast<Okteta::ChangesDescribable*>(mByteArrayModel);
105 
106             if (changesDescribable) {
107                 changesDescribable->openGroupedChange(byteArrayFilter->name());
108             }
109             mByteArrayModel->replace(filteredSection, filterResult);
110             if (changesDescribable) {
111                 changesDescribable->closeGroupedChange();
112             }
113         }
114     }
115 
116     mByteArrayView->setFocus();
117 }
118 
onApplyableChanged()119 void FilterTool::onApplyableChanged()
120 {
121     const bool newHasWriteable = (mByteArrayModel && mByteArrayView
122                                   && !mByteArrayView->isReadOnly() && mByteArrayView->hasSelectedData());
123     if (newHasWriteable != mHasWritable) {
124         mHasWritable = newHasWriteable;
125         emit hasWriteableChanged(newHasWriteable);
126     }
127 }
128 
129 }
130