File indexing completed on 2024-05-26 05:56:27

0001 /*
0002     This file is part of the Okteta Kasten module, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2009, 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 "checksumtool.hpp"
0010 
0011 // lib
0012 #include "checksumcalculatejob.hpp"
0013 #include "checksumlogging.hpp"
0014 //
0015 #include <bytearraychecksumalgorithmfactory.hpp>
0016 #include <abstractbytearraychecksumalgorithm.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 #include <Okteta/ArrayChangeMetricsList>
0024 // KF
0025 #include <KConfigGroup>
0026 #include <KSharedConfig>
0027 #include <KLocalizedString>
0028 // Qt
0029 #include <QApplication>
0030 
0031 
0032 namespace Kasten {
0033 
0034 ChecksumTool::ChecksumTool()
0035     : mChecksumUptodate(false)
0036     , mSourceByteArrayModelUptodate(false)
0037 {
0038     setObjectName(QStringLiteral("Checksum"));
0039 
0040     mAlgorithmList = ByteArrayChecksumAlgorithmFactory::createAlgorithms();
0041 
0042     const KConfigGroup configGroup(KSharedConfig::openConfig(), ConfigGroupId);
0043     for (auto *algorithm : std::as_const(mAlgorithmList)) {
0044         algorithm->loadConfig(configGroup);
0045     }
0046 
0047     mAlgorithmId = 0;
0048     const QString algorithmId = configGroup.readEntry(AlgorithmConfigKey);
0049     if (!algorithmId.isEmpty()) {
0050         for (int i = 0; i < mAlgorithmList.size(); ++i) {
0051             if (mAlgorithmList[i]->id() == algorithmId) {
0052                 mAlgorithmId = i;
0053                 break;
0054             }
0055         }
0056     }
0057 }
0058 
0059 ChecksumTool::~ChecksumTool()
0060 {
0061     qDeleteAll(mAlgorithmList);
0062 }
0063 
0064 QVector<AbstractByteArrayChecksumAlgorithm*> ChecksumTool::algorithmList() const { return mAlgorithmList; }
0065 
0066 bool ChecksumTool::isApplyable() const
0067 {
0068     return (mByteArrayModel && mByteArrayView && mByteArrayView->hasSelectedData());
0069 }
0070 
0071 QString ChecksumTool::title() const { return i18nc("@title:window of the tool to calculate checksums", "Checksum"); }
0072 
0073 AbstractByteArrayChecksumParameterSet* ChecksumTool::parameterSet()
0074 {
0075     AbstractByteArrayChecksumAlgorithm* algorithm = mAlgorithmList.at(mAlgorithmId);
0076 
0077     return algorithm ? algorithm->parameterSet() : nullptr;
0078 }
0079 
0080 void ChecksumTool::setTargetModel(AbstractModel* model)
0081 {
0082     if (mByteArrayView) {
0083         mByteArrayView->disconnect(this);
0084     }
0085 
0086     mByteArrayView = model ? model->findBaseModel<ByteArrayView*>() : nullptr;
0087 
0088     ByteArrayDocument* document =
0089         mByteArrayView ? qobject_cast<ByteArrayDocument*>(mByteArrayView->baseModel()) : nullptr;
0090     mByteArrayModel = document ? document->content() : nullptr;
0091 
0092     if (mByteArrayView && mByteArrayModel) {
0093         connect(mByteArrayView,  &ByteArrayView::selectedDataChanged,
0094                 this, &ChecksumTool::onSelectionChanged);
0095     }
0096 
0097     // TODO: if there is no view, there is nothing calculate a checksum from
0098     // or this could be the view where we did the checksum from and it did not change
0099     checkUptoDate();
0100     Q_EMIT uptodateChanged(mChecksumUptodate);
0101     Q_EMIT isApplyableChanged(isApplyable());
0102 }
0103 
0104 void ChecksumTool::checkUptoDate()
0105 {
0106     mChecksumUptodate =
0107         (mSourceByteArrayModel == mByteArrayModel
0108          && mByteArrayView && mSourceSelection == mByteArrayView->selection()
0109          && mSourceAlgorithmId == mAlgorithmId
0110          && mSourceByteArrayModelUptodate);
0111 }
0112 
0113 void ChecksumTool::calculateChecksum()
0114 {
0115     AbstractByteArrayChecksumAlgorithm* algorithm = mAlgorithmList.at(mAlgorithmId);
0116 
0117     if (algorithm) {
0118         // forget old string source
0119         if (mSourceByteArrayModel) {
0120             mSourceByteArrayModel->disconnect(this);
0121         }
0122 
0123         QApplication::setOverrideCursor(Qt::WaitCursor);
0124 
0125         auto* checksumCalculateJob =
0126             new ChecksumCalculateJob(&mCheckSum, algorithm, mByteArrayModel, mByteArrayView->selection());
0127         checksumCalculateJob->exec();
0128 
0129         QApplication::restoreOverrideCursor();
0130 
0131         // remember checksum source
0132         mSourceAlgorithmId = mAlgorithmId;
0133         mSourceByteArrayModel = mByteArrayModel;
0134         mSourceSelection = mByteArrayView->selection();
0135         connect(mSourceByteArrayModel,  &Okteta::AbstractByteArrayModel::contentsChanged,
0136                 this, &ChecksumTool::onSourceChanged);
0137         connect(mSourceByteArrayModel,  &Okteta::AbstractByteArrayModel::destroyed,
0138                 this, &ChecksumTool::onSourceDestroyed);
0139 
0140         mChecksumUptodate = true;
0141         mSourceByteArrayModelUptodate = true;
0142         Q_EMIT checksumChanged(mCheckSum);
0143         Q_EMIT uptodateChanged(true);
0144     }
0145 }
0146 
0147 void ChecksumTool::setAlgorithm(int algorithmId)
0148 {
0149     if (mAlgorithmId == algorithmId) {
0150         return;
0151     }
0152 
0153     mAlgorithmId = algorithmId;
0154     checkUptoDate();
0155 
0156     AbstractByteArrayChecksumAlgorithm* algorithm = mAlgorithmList.at(mAlgorithmId);
0157     if (algorithm) {
0158         KConfigGroup configGroup(KSharedConfig::openConfig(), ConfigGroupId);
0159         configGroup.writeEntry(AlgorithmConfigKey, algorithm->id());
0160     }
0161 
0162     Q_EMIT algorithmChanged(mAlgorithmId);
0163     Q_EMIT uptodateChanged(mChecksumUptodate);
0164     Q_EMIT isApplyableChanged(isApplyable());
0165 }
0166 
0167 // TODO: hack!
0168 // better would be to store the parameter set used for the source and compare if equal
0169 // this hack does the same, except for that the source will never be uptodate
0170 void ChecksumTool::resetSourceTool()
0171 {
0172     mSourceAlgorithmId = -1;
0173 
0174     AbstractByteArrayChecksumAlgorithm* algorithm = mAlgorithmList.at(mAlgorithmId);
0175     if (algorithm) {
0176         KConfigGroup configGroup(KSharedConfig::openConfig(), ConfigGroupId);
0177         algorithm->saveConfig(configGroup);
0178     }
0179 
0180     checkUptoDate();
0181     Q_EMIT uptodateChanged(mChecksumUptodate);
0182     Q_EMIT isApplyableChanged(isApplyable());
0183 }
0184 
0185 void ChecksumTool::onSelectionChanged()
0186 {
0187 // TODO: could be quicker using the selection data
0188     checkUptoDate();
0189     Q_EMIT uptodateChanged(mChecksumUptodate);
0190     Q_EMIT isApplyableChanged(isApplyable());
0191 }
0192 
0193 void ChecksumTool::onSourceChanged()
0194 {
0195     mChecksumUptodate = false;
0196     mSourceByteArrayModelUptodate = false;
0197     Q_EMIT uptodateChanged(false);
0198 }
0199 
0200 void ChecksumTool::onSourceDestroyed()
0201 {
0202     mSourceByteArrayModel = nullptr;
0203     onSourceChanged();
0204 }
0205 
0206 }
0207 
0208 #include "moc_checksumtool.cpp"