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 #include "checksumview.hpp"
10
11 // tool
12 #include "checksumtool.hpp"
13 // lib
14 #include <bytearraychecksumparameterseteditfactory.hpp>
15 #include <abstractbytearraychecksumparametersetedit.hpp>
16 #include <abstractbytearraychecksumparameterset.hpp>
17 #include <abstractbytearraychecksumalgorithm.hpp>
18 // KF
19 #include <KComboBox>
20 #include <KGuiItem>
21 #include <KLocalizedString>
22 // Qt
23 #include <QLabel>
24 #include <QGroupBox>
25 #include <QStackedWidget>
26 #include <QLineEdit>
27 #include <QPushButton>
28 #include <QLayout>
29 #include <QClipboard>
30 #include <QApplication>
31 #include <QAbstractItemView>
32
33 namespace Kasten {
34
ChecksumView(ChecksumTool * tool,QWidget * parent)35 ChecksumView::ChecksumView(ChecksumTool* tool, QWidget* parent)
36 : AbstractToolWidget(parent)
37 , mTool(tool)
38 {
39 auto* baseLayout = new QVBoxLayout(this);
40 baseLayout->setContentsMargins(0, 0, 0, 0);
41
42 // algorithm
43 auto* algorithmLayout = new QHBoxLayout();
44 QLabel* label = new QLabel(i18nc("@label:listbox algorithm to use for the checksum", "Algorithm:"), this);
45 mAlgorithmComboBox = new KComboBox(this);
46 connect(mAlgorithmComboBox, QOverload<int>::of(&KComboBox::activated),
47 this, &ChecksumView::onOperationChange);
48
49 label->setBuddy(mAlgorithmComboBox);
50 const QString algorithmWhatsThis =
51 i18nc("@info:whatsthis", "Select the algorithm to use for the checksum.");
52 label->setWhatsThis(algorithmWhatsThis);
53 mAlgorithmComboBox->setWhatsThis(algorithmWhatsThis);
54
55 algorithmLayout->addWidget(label);
56 algorithmLayout->addWidget(mAlgorithmComboBox, 10);
57 baseLayout->addLayout(algorithmLayout);
58
59 // parameter
60 QGroupBox* parameterSetBox = new QGroupBox(i18nc("@title:group", "Parameters"), this);
61 baseLayout->addWidget(parameterSetBox);
62
63 auto* parameterSetLayout = new QVBoxLayout(parameterSetBox);
64
65 mParameterSetEditStack = new QStackedWidget(parameterSetBox);
66 parameterSetLayout->addWidget(mParameterSetEditStack);
67
68 // calculate
69 auto* calculateLayout = new QHBoxLayout();
70
71 calculateLayout->addStretch();
72 const KGuiItem updateGuiItem =
73 KGuiItem(i18nc("@action:button calculate the checksum", "&Calculate"),
74 QStringLiteral("run-build"),
75 i18nc("@info:tooltip",
76 "Calculate the checksum for the bytes in the selected range."),
77 xi18nc("@info:whatsthis",
78 "If you press the <interface>Calculate</interface> button, the list will be updated "
79 "to all strings which are contained in the selected range and have the set minimum length."));
80 mCalculateButton = new QPushButton(this);
81 KGuiItem::assign(mCalculateButton, updateGuiItem);
82 mCalculateButton->setEnabled(mTool->isApplyable());
83 connect(mCalculateButton, &QPushButton::clicked, this, &ChecksumView::onCalculateClicked);
84 addButton(mCalculateButton, AbstractToolWidget::Default);
85 calculateLayout->addWidget(mCalculateButton);
86 baseLayout->addLayout(calculateLayout);
87
88 mChecksumLabel = new QLineEdit(this);
89 mChecksumLabel->setReadOnly(true);
90 mChecksumLabel->setText(mTool->checkSum());
91 connect(mTool, &ChecksumTool::checksumChanged, mChecksumLabel, &QLineEdit::setText);
92 baseLayout->addWidget(mChecksumLabel, 10);
93
94 baseLayout->addStretch(10);
95
96 connect(mTool, &ChecksumTool::uptodateChanged, this, &ChecksumView::onChecksumUptodateChanged);
97 connect(mTool, &ChecksumTool::isApplyableChanged, this, &ChecksumView::onApplyableChanged);
98
99 // automatically set focus to the parameters if a operation has been selected
100 QAbstractItemView* algorithmComboBoxListView = mAlgorithmComboBox->view();
101 QObject::connect(algorithmComboBoxListView, &QAbstractItemView::activated,
102 mParameterSetEditStack, QOverload<>::of(&QStackedWidget::setFocus));
103 // TODO: is a workaround for Qt 4.5.1 which doesn't emit activated() for mouse clicks
104 QObject::connect(algorithmComboBoxListView, &QAbstractItemView::pressed,
105 mParameterSetEditStack, QOverload<>::of(&QStackedWidget::setFocus));
106 // TODO: goto filter button if there are no parameters
107
108 addAlgorithms();
109 }
110
111 ChecksumView::~ChecksumView() = default;
112
addAlgorithms()113 void ChecksumView::addAlgorithms()
114 {
115 //
116 const QVector<AbstractByteArrayChecksumAlgorithm*> algorithmList = mTool->algorithmList();
117 for (AbstractByteArrayChecksumAlgorithm* algorithm : algorithmList) {
118 mAlgorithmComboBox->addItem(algorithm->name());
119
120 const char* const parameterSetId = algorithm->parameterSet()->id();
121 AbstractByteArrayChecksumParameterSetEdit* parameterEdit =
122 ByteArrayChecksumParameterSetEditFactory::createEdit(parameterSetId);
123
124 mParameterSetEditStack->addWidget(parameterEdit);
125 }
126
127 onOperationChange(mTool->algorithmId());
128 }
129
getParameterSet(AbstractByteArrayChecksumParameterSet * parameterSet) const130 void ChecksumView::getParameterSet(AbstractByteArrayChecksumParameterSet* parameterSet) const
131 {
132 auto* parametersetEdit =
133 qobject_cast<AbstractByteArrayChecksumParameterSetEdit*>(mParameterSetEditStack->currentWidget());
134 if (parametersetEdit) {
135 parametersetEdit->getParameterSet(parameterSet);
136 }
137 }
138
onCalculateClicked()139 void ChecksumView::onCalculateClicked()
140 {
141 AbstractByteArrayChecksumParameterSet* parameterSet = mTool->parameterSet();
142 if (parameterSet) {
143 getParameterSet(parameterSet);
144 }
145
146 mTool->calculateChecksum();
147 }
148
onOperationChange(int index)149 void ChecksumView::onOperationChange(int index)
150 {
151 QWidget* oldWidget = mParameterSetEditStack->currentWidget();
152 if (oldWidget) {
153 oldWidget->disconnect(this);
154 oldWidget->disconnect(mTool);
155 }
156
157 mTool->setAlgorithm(index);
158 mParameterSetEditStack->setCurrentIndex(index);
159
160 auto* parametersetEdit =
161 qobject_cast<AbstractByteArrayChecksumParameterSetEdit*>(mParameterSetEditStack->currentWidget());
162 if (parametersetEdit) {
163 connect(parametersetEdit, &AbstractByteArrayChecksumParameterSetEdit::validityChanged,
164 this, &ChecksumView::onValidityChanged);
165 // TODO: hack, see checksum source
166 connect(parametersetEdit, &AbstractByteArrayChecksumParameterSetEdit::valuesChanged,
167 mTool, &ChecksumTool::resetSourceTool);
168 onValidityChanged(parametersetEdit->isValid());
169 }
170 }
171
onChecksumUptodateChanged(bool checksumUptodate)172 void ChecksumView::onChecksumUptodateChanged(bool checksumUptodate)
173 {
174 const bool isApplyable = mTool->isApplyable();
175 mCalculateButton->setEnabled(!checksumUptodate && isApplyable);
176 }
177
onApplyableChanged(bool isApplyable)178 void ChecksumView::onApplyableChanged(bool isApplyable)
179 {
180 mCalculateButton->setEnabled(!mTool->isUptodate() && isApplyable);
181 }
182
onValidityChanged(bool isValid)183 void ChecksumView::onValidityChanged(bool isValid)
184 {
185 mCalculateButton->setEnabled(mTool->isApplyable() && isValid);
186 }
187
188 }
189