File indexing completed on 2024-05-05 05:50:40
0001 /* 0002 SPDX-FileCopyrightText: 2016 Ragnar Thomsen <rthomsen6@gmail.com> 0003 0004 SPDX-License-Identifier: BSD-2-Clause 0005 */ 0006 0007 #include "compressionoptionswidget.h" 0008 #include "ark_debug.h" 0009 #include "pluginmanager.h" 0010 #include "settings.h" 0011 0012 #include <KColorScheme> 0013 #include <KPluginMetaData> 0014 0015 #include <QMimeDatabase> 0016 0017 namespace Kerfuffle 0018 { 0019 CompressionOptionsWidget::CompressionOptionsWidget(QWidget *parent, const CompressionOptions &opts) 0020 : QWidget(parent) 0021 , m_opts(opts) 0022 { 0023 setupUi(this); 0024 0025 KColorScheme colorScheme(QPalette::Active, KColorScheme::View); 0026 pwdWidget->setBackgroundWarningColor(colorScheme.background(KColorScheme::NegativeBackground).color()); 0027 pwdWidget->setPasswordStrengthMeterVisible(false); 0028 0029 connect(multiVolumeCheckbox, &QCheckBox::stateChanged, this, &CompressionOptionsWidget::slotMultiVolumeChecked); 0030 connect(compMethodComboBox, &QComboBox::currentTextChanged, this, &CompressionOptionsWidget::slotCompMethodChanged); 0031 connect(encMethodComboBox, &QComboBox::currentTextChanged, this, &CompressionOptionsWidget::slotEncryptionMethodChanged); 0032 0033 if (m_opts.isVolumeSizeSet()) { 0034 multiVolumeCheckbox->setChecked(true); 0035 // Convert from kilobytes. 0036 volumeSizeSpinbox->setValue(static_cast<double>(m_opts.volumeSize()) / 1024); 0037 } 0038 0039 warningMsgWidget->setWordWrap(true); 0040 } 0041 0042 CompressionOptions CompressionOptionsWidget::commpressionOptions() const 0043 { 0044 CompressionOptions opts; 0045 opts.setCompressionLevel(compLevelSlider->value()); 0046 if (multiVolumeCheckbox->isChecked()) { 0047 opts.setVolumeSize(volumeSize()); 0048 } 0049 if (!compMethodComboBox->currentText().isEmpty()) { 0050 opts.setCompressionMethod(compMethodComboBox->currentText()); 0051 } 0052 0053 return opts; 0054 } 0055 0056 int CompressionOptionsWidget::compressionLevel() const 0057 { 0058 if (compLevelSlider->isEnabled()) { 0059 return compLevelSlider->value(); 0060 } else { 0061 return -1; 0062 } 0063 } 0064 0065 QString CompressionOptionsWidget::compressionMethod() const 0066 { 0067 return compMethodComboBox->currentText(); 0068 } 0069 0070 ulong CompressionOptionsWidget::volumeSize() const 0071 { 0072 if (collapsibleMultiVolume->isEnabled() && multiVolumeCheckbox->isChecked()) { 0073 // Convert to kilobytes. 0074 return static_cast<ulong>(volumeSizeSpinbox->value() * 1024); 0075 } else { 0076 return 0; 0077 } 0078 } 0079 0080 void CompressionOptionsWidget::setEncryptionVisible(bool visible) 0081 { 0082 collapsibleEncryption->setVisible(visible); 0083 } 0084 0085 QString CompressionOptionsWidget::password() const 0086 { 0087 return pwdWidget->password(); 0088 } 0089 0090 ArchiveFormat CompressionOptionsWidget::archiveFormat() const 0091 { 0092 const KPluginMetaData metadata = PluginManager().preferredPluginFor(m_mimetype)->metaData(); 0093 return ArchiveFormat::fromMetadata(m_mimetype, metadata); 0094 } 0095 0096 void CompressionOptionsWidget::updateWidgets() 0097 { 0098 const ArchiveFormat archiveFormat = this->archiveFormat(); 0099 Q_ASSERT(archiveFormat.isValid()); 0100 0101 if (archiveFormat.encryptionType() != Archive::Unencrypted) { 0102 collapsibleEncryption->setEnabled(true); 0103 collapsibleEncryption->setToolTip(QString()); 0104 0105 encMethodComboBox->clear(); 0106 encMethodComboBox->insertItems(0, archiveFormat.encryptionMethods()); 0107 0108 if (!m_opts.encryptionMethod().isEmpty() && encMethodComboBox->findText(m_opts.encryptionMethod()) > -1) { 0109 encMethodComboBox->setCurrentText(m_opts.encryptionMethod()); 0110 } else { 0111 encMethodComboBox->setCurrentText(archiveFormat.defaultEncryptionMethod()); 0112 } 0113 0114 if (!archiveFormat.encryptionMethods().isEmpty()) { 0115 lblEncMethod->setEnabled(true); 0116 encMethodComboBox->setEnabled(true); 0117 } 0118 0119 pwdWidget->setEnabled(true); 0120 0121 if (archiveFormat.encryptionType() == Archive::HeaderEncrypted) { 0122 encryptHeaderCheckBox->setEnabled(true); 0123 encryptHeaderCheckBox->setToolTip(QString()); 0124 } else { 0125 encryptHeaderCheckBox->setEnabled(false); 0126 // Show the tooltip only if the encryption is still enabled. 0127 // This is needed because if the new filter is e.g. tar, the whole encryption group gets disabled. 0128 if (collapsibleEncryption->isEnabled() && collapsibleEncryption->isExpanded()) { 0129 encryptHeaderCheckBox->setToolTip(i18n("Protection of the list of files is not possible with the %1 format.", m_mimetype.comment())); 0130 } else { 0131 encryptHeaderCheckBox->setToolTip(QString()); 0132 } 0133 } 0134 0135 } else { 0136 collapsibleEncryption->setEnabled(false); 0137 collapsibleEncryption->setToolTip(i18n("Protection of the archive with password is not possible with the %1 format.", m_mimetype.comment())); 0138 lblEncMethod->setEnabled(false); 0139 encMethodComboBox->setEnabled(false); 0140 encMethodComboBox->clear(); 0141 pwdWidget->setEnabled(false); 0142 encryptHeaderCheckBox->setToolTip(QString()); 0143 } 0144 0145 collapsibleCompression->setEnabled(true); 0146 if (archiveFormat.maxCompressionLevel() == 0) { 0147 compLevelSlider->setEnabled(false); 0148 lblCompLevel1->setEnabled(false); 0149 lblCompLevel2->setEnabled(false); 0150 lblCompLevel3->setEnabled(false); 0151 compLevelSlider->setToolTip(i18n("It is not possible to set compression level for the %1 format.", m_mimetype.comment())); 0152 } else { 0153 compLevelSlider->setEnabled(true); 0154 lblCompLevel1->setEnabled(true); 0155 lblCompLevel2->setEnabled(true); 0156 lblCompLevel3->setEnabled(true); 0157 compLevelSlider->setToolTip(QString()); 0158 compLevelSlider->setMinimum(archiveFormat.minCompressionLevel()); 0159 compLevelSlider->setMaximum(archiveFormat.maxCompressionLevel()); 0160 if (m_opts.isCompressionLevelSet()) { 0161 compLevelSlider->setValue(m_opts.compressionLevel()); 0162 } else { 0163 compLevelSlider->setValue(archiveFormat.defaultCompressionLevel()); 0164 } 0165 } 0166 0167 if (archiveFormat.compressionMethods().isEmpty()) { 0168 lblCompMethod->setEnabled(false); 0169 compMethodComboBox->setEnabled(false); 0170 compMethodComboBox->setToolTip(i18n("It is not possible to set compression method for the %1 format.", m_mimetype.comment())); 0171 compMethodComboBox->clear(); 0172 } else { 0173 lblCompMethod->setEnabled(true); 0174 compMethodComboBox->setEnabled(true); 0175 compMethodComboBox->setToolTip(QString()); 0176 compMethodComboBox->clear(); 0177 compMethodComboBox->insertItems(0, archiveFormat.compressionMethods().keys()); 0178 if (!m_opts.compressionMethod().isEmpty() && compMethodComboBox->findText(m_opts.compressionMethod()) > -1) { 0179 compMethodComboBox->setCurrentText(m_opts.compressionMethod()); 0180 } else { 0181 compMethodComboBox->setCurrentText(archiveFormat.defaultCompressionMethod()); 0182 } 0183 } 0184 collapsibleCompression->setEnabled(compLevelSlider->isEnabled() || compMethodComboBox->isEnabled()); 0185 0186 if (archiveFormat.supportsMultiVolume()) { 0187 collapsibleMultiVolume->setEnabled(true); 0188 collapsibleMultiVolume->setToolTip(QString()); 0189 } else { 0190 collapsibleMultiVolume->setEnabled(false); 0191 collapsibleMultiVolume->setToolTip(i18n("The %1 format does not support multi-volume archives.", m_mimetype.comment())); 0192 } 0193 } 0194 0195 void CompressionOptionsWidget::setMimeType(const QMimeType &mimeType) 0196 { 0197 m_mimetype = mimeType; 0198 updateWidgets(); 0199 } 0200 0201 bool CompressionOptionsWidget::isEncryptionAvailable() const 0202 { 0203 return collapsibleEncryption->isEnabled(); 0204 } 0205 0206 bool CompressionOptionsWidget::isEncryptionEnabled() const 0207 { 0208 return isEncryptionAvailable() && collapsibleEncryption->isExpanded(); 0209 } 0210 0211 bool CompressionOptionsWidget::isHeaderEncryptionAvailable() const 0212 { 0213 return isEncryptionEnabled() && encryptHeaderCheckBox->isEnabled(); 0214 } 0215 0216 bool CompressionOptionsWidget::isHeaderEncryptionEnabled() const 0217 { 0218 return isHeaderEncryptionAvailable() && encryptHeaderCheckBox->isChecked(); 0219 } 0220 0221 KNewPasswordWidget::PasswordStatus CompressionOptionsWidget::passwordStatus() const 0222 { 0223 return pwdWidget->passwordStatus(); 0224 } 0225 0226 QString CompressionOptionsWidget::encryptionMethod() const 0227 { 0228 if (encMethodComboBox->isEnabled() && encMethodComboBox->count() > 1 && !password().isEmpty()) { 0229 return encMethodComboBox->currentText(); 0230 } 0231 return QString(); 0232 } 0233 0234 void CompressionOptionsWidget::slotMultiVolumeChecked(int state) 0235 { 0236 if (state == Qt::Checked) { 0237 lblVolumeSize->setEnabled(true); 0238 volumeSizeSpinbox->setEnabled(true); 0239 } else { 0240 lblVolumeSize->setEnabled(false); 0241 volumeSizeSpinbox->setEnabled(false); 0242 } 0243 } 0244 0245 void CompressionOptionsWidget::slotCompMethodChanged(const QString &value) 0246 { 0247 // This hack is needed for the RAR format because the available encryption 0248 // method is dependent on the selected compression method. Rar uses AES128 0249 // for RAR4 format and AES256 for RAR5 format. 0250 0251 if (m_mimetype == QMimeDatabase().mimeTypeForName(QStringLiteral("application/vnd.rar")) 0252 || m_mimetype == QMimeDatabase().mimeTypeForName(QStringLiteral("application/x-rar"))) { 0253 encMethodComboBox->clear(); 0254 if (value == QLatin1String("RAR4")) { 0255 encMethodComboBox->insertItem(0, QStringLiteral("AES128")); 0256 } else { 0257 encMethodComboBox->insertItem(0, QStringLiteral("AES256")); 0258 } 0259 } 0260 0261 const ArchiveFormat archiveFormat = this->archiveFormat(); 0262 Q_ASSERT(archiveFormat.isValid()); 0263 0264 if (m_mimetype == QMimeDatabase().mimeTypeForName(QStringLiteral("application/zip"))) { 0265 if (value == QLatin1String("Zstd")) { 0266 compLevelSlider->setMaximum(22); 0267 } else { 0268 compLevelSlider->setMaximum(archiveFormat.maxCompressionLevel()); 0269 } 0270 } 0271 } 0272 0273 void CompressionOptionsWidget::slotEncryptionMethodChanged(const QString &value) 0274 { 0275 if (value.isEmpty() || m_mimetype != QMimeDatabase().mimeTypeForName(QStringLiteral("application/zip"))) { 0276 warningMsgWidget->hide(); 0277 return; 0278 } 0279 0280 // AES encryption is not supported by unzip, warn the users if they are creating a zip. 0281 warningMsgWidget->setVisible(value != QLatin1String("ZipCrypto") && ArkSettings::showEncryptionWarning()); 0282 } 0283 0284 } 0285 0286 #include "moc_compressionoptionswidget.cpp"