1 /*
2     This file is part of the Okteta Kasten module, made within the KDE community.
3 
4     SPDX-FileCopyrightText: 2009 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 // QCA
10 // need to have this first, as QCA needs QT_NO_CAST_FROM_ASCII disabled when included
11 #include <config-qca2.hpp> // krazy:excludeall=includes
12 #ifdef HAVE_QCA2
13 // disable QT_NO_CAST_FROM_ASCII
14 #ifdef QT_NO_CAST_FROM_ASCII
15 #undef QT_NO_CAST_FROM_ASCII
16 #endif
17 #include <QtCrypto>
18 #endif
19 
20 #include "checksumtool.hpp"
21 
22 // lib
23 #include "checksumcalculatejob.hpp"
24 #include "checksumlogging.hpp"
25 //
26 #include <bytearraychecksumalgorithmfactory.hpp>
27 #include <abstractbytearraychecksumalgorithm.hpp>
28 // Okteta Kasten gui
29 #include <Kasten/Okteta/ByteArrayView>
30 // Okteta Kasten core
31 #include <Kasten/Okteta/ByteArrayDocument>
32 // Okteta core
33 #include <Okteta/AbstractByteArrayModel>
34 #include <Okteta/ArrayChangeMetricsList>
35 // KF
36 #include <KLocalizedString>
37 // Qt
38 #include <QApplication>
39 
40 namespace Kasten {
41 
ChecksumTool()42 ChecksumTool::ChecksumTool()
43     : mChecksumUptodate(false)
44     , mSourceByteArrayModelUptodate(false)
45 {
46     setObjectName(QStringLiteral("Checksum"));
47 
48 // TODO: find a better place to do and store the initialization
49 #ifdef HAVE_QCA2
50     mQcaInitializer = new QCA::Initializer(QCA::Practical, 64);
51     qCDebug(LOG_OKTETA_KASTEN_CONTROLLER_CHECKSUM) << QCA::supportedFeatures();// Hash::supportedTypes();
52 #endif
53 
54     mAlgorithmList = ByteArrayChecksumAlgorithmFactory::createAlgorithms();
55 }
56 
~ChecksumTool()57 ChecksumTool::~ChecksumTool()
58 {
59     qDeleteAll(mAlgorithmList);
60 #ifdef HAVE_QCA2
61     delete mQcaInitializer;
62 #endif
63 }
64 
algorithmList() const65 QVector<AbstractByteArrayChecksumAlgorithm*> ChecksumTool::algorithmList() const { return mAlgorithmList; }
66 
isApplyable() const67 bool ChecksumTool::isApplyable() const
68 {
69     return (mByteArrayModel && mByteArrayView && mByteArrayView->hasSelectedData());
70 }
71 
title() const72 QString ChecksumTool::title() const { return i18nc("@title:window of the tool to calculate checksums", "Checksum"); }
73 
parameterSet()74 AbstractByteArrayChecksumParameterSet* ChecksumTool::parameterSet()
75 {
76     AbstractByteArrayChecksumAlgorithm* algorithm = mAlgorithmList.at(mAlgorithmId);
77 
78     return algorithm ? algorithm->parameterSet() : nullptr;
79 }
80 
setTargetModel(AbstractModel * model)81 void ChecksumTool::setTargetModel(AbstractModel* model)
82 {
83     if (mByteArrayView) {
84         mByteArrayView->disconnect(this);
85     }
86 
87     mByteArrayView = model ? model->findBaseModel<ByteArrayView*>() : nullptr;
88 
89     ByteArrayDocument* document =
90         mByteArrayView ? qobject_cast<ByteArrayDocument*>(mByteArrayView->baseModel()) : nullptr;
91     mByteArrayModel = document ? document->content() : nullptr;
92 
93     if (mByteArrayView && mByteArrayModel) {
94         connect(mByteArrayView,  &ByteArrayView::selectedDataChanged,
95                 this, &ChecksumTool::onSelectionChanged);
96     }
97 
98     // TODO: if there is no view, there is nothing calculate a checksum from
99     // or this could be the view where we did the checksum from and it did not change
100     checkUptoDate();
101     emit uptodateChanged(mChecksumUptodate);
102     emit isApplyableChanged(isApplyable());
103 }
104 
checkUptoDate()105 void ChecksumTool::checkUptoDate()
106 {
107     mChecksumUptodate =
108         (mSourceByteArrayModel == mByteArrayModel
109          && mByteArrayView && mSourceSelection == mByteArrayView->selection()
110          && mSourceAlgorithmId == mAlgorithmId
111          && mSourceByteArrayModelUptodate);
112 }
113 
calculateChecksum()114 void ChecksumTool::calculateChecksum()
115 {
116     AbstractByteArrayChecksumAlgorithm* algorithm = mAlgorithmList.at(mAlgorithmId);
117 
118     if (algorithm) {
119         // forget old string source
120         if (mSourceByteArrayModel) {
121             mSourceByteArrayModel->disconnect(this);
122         }
123 
124         QApplication::setOverrideCursor(Qt::WaitCursor);
125 
126         ChecksumCalculateJob* checksumCalculateJob =
127             new ChecksumCalculateJob(&mCheckSum, algorithm, mByteArrayModel, mByteArrayView->selection());
128         checksumCalculateJob->exec();
129 
130         QApplication::restoreOverrideCursor();
131 
132         // remember checksum source
133         mSourceAlgorithmId = mAlgorithmId;
134         mSourceByteArrayModel = mByteArrayModel;
135         mSourceSelection = mByteArrayView->selection();
136         connect(mSourceByteArrayModel,  &Okteta::AbstractByteArrayModel::contentsChanged,
137                 this, &ChecksumTool::onSourceChanged);
138         connect(mSourceByteArrayModel,  &Okteta::AbstractByteArrayModel::destroyed,
139                 this, &ChecksumTool::onSourceDestroyed);
140 
141         mChecksumUptodate = true;
142         mSourceByteArrayModelUptodate = true;
143         emit checksumChanged(mCheckSum);
144         emit uptodateChanged(true);
145     }
146 }
147 
setAlgorithm(int algorithmId)148 void ChecksumTool::setAlgorithm(int algorithmId)
149 {
150     mAlgorithmId = algorithmId;
151     checkUptoDate();
152     emit uptodateChanged(mChecksumUptodate);
153     emit isApplyableChanged(isApplyable());
154 }
155 
156 // TODO: hack!
157 // better would be to store the parameter set used for the source and compare if equal
158 // this hack does the same, except for that the source will never be uptodate
resetSourceTool()159 void ChecksumTool::resetSourceTool()
160 {
161     mSourceAlgorithmId = -1;
162 
163     checkUptoDate();
164     emit uptodateChanged(mChecksumUptodate);
165     emit isApplyableChanged(isApplyable());
166 }
167 
onSelectionChanged()168 void ChecksumTool::onSelectionChanged()
169 {
170 // TODO: could be quicker using the selection data
171     checkUptoDate();
172     emit uptodateChanged(mChecksumUptodate);
173     emit isApplyableChanged(isApplyable());
174 }
175 
onSourceChanged()176 void ChecksumTool::onSourceChanged()
177 {
178     mChecksumUptodate = false;
179     mSourceByteArrayModelUptodate = false;
180     emit uptodateChanged(false);
181 }
182 
onSourceDestroyed()183 void ChecksumTool::onSourceDestroyed()
184 {
185     mSourceByteArrayModel = nullptr;
186     onSourceChanged();
187 }
188 
189 }
190