File indexing completed on 2024-09-22 04:51:46
0001 /* 0002 SPDX-FileCopyrightText: 2013-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "selectiontypetreewidget.h" 0008 #include "core/utils.h" 0009 #include "core/xml/templateselection.h" 0010 0011 #include <PimCommon/PimUtil> 0012 0013 #include <QFileDialog> 0014 0015 #include <KLocalizedString> 0016 #include <QTemporaryFile> 0017 0018 #include <QHeaderView> 0019 #include <QPointer> 0020 #include <QTreeWidgetItem> 0021 0022 SelectionTypeTreeWidget::SelectionTypeTreeWidget(bool backupData, QWidget *parent) 0023 : QTreeWidget(parent) 0024 { 0025 initialize(backupData); 0026 expandAll(); 0027 header()->hide(); 0028 } 0029 0030 SelectionTypeTreeWidget::~SelectionTypeTreeWidget() = default; 0031 0032 void SelectionTypeTreeWidget::initialize(bool backupData) 0033 { 0034 mKmailItem = new QTreeWidgetItem(this); 0035 mKmailItem->setCheckState(0, Qt::Checked); 0036 mKmailItem->setText(0, Utils::appTypeToI18n(Utils::KMail)); 0037 createSubItem(mKmailItem, Utils::Identity); 0038 createSubItem(mKmailItem, Utils::Mails); 0039 createSubItem(mKmailItem, Utils::MailTransport); 0040 createSubItem(mKmailItem, Utils::Resources); 0041 createSubItem(mKmailItem, Utils::Config); 0042 0043 mKaddressbookItem = new QTreeWidgetItem(this); 0044 mKaddressbookItem->setText(0, Utils::appTypeToI18n(Utils::KAddressBook)); 0045 mKaddressbookItem->setCheckState(0, Qt::Checked); 0046 createSubItem(mKaddressbookItem, Utils::Resources); 0047 createSubItem(mKaddressbookItem, Utils::Config); 0048 0049 mKalarmItem = new QTreeWidgetItem(this); 0050 mKalarmItem->setText(0, Utils::appTypeToI18n(Utils::KAlarm)); 0051 mKalarmItem->setCheckState(0, Qt::Checked); 0052 createSubItem(mKalarmItem, Utils::Resources); 0053 createSubItem(mKalarmItem, Utils::Config); 0054 0055 mKorganizerItem = new QTreeWidgetItem(this); 0056 mKorganizerItem->setText(0, Utils::appTypeToI18n(Utils::KOrganizer)); 0057 mKorganizerItem->setCheckState(0, Qt::Checked); 0058 createSubItem(mKorganizerItem, Utils::Resources); 0059 createSubItem(mKorganizerItem, Utils::Config); 0060 0061 mKNotesItem = new QTreeWidgetItem(this); 0062 mKNotesItem->setText(0, Utils::appTypeToI18n(Utils::KNotes)); 0063 mKNotesItem->setCheckState(0, Qt::Checked); 0064 createSubItem(mKNotesItem, Utils::Resources); 0065 createSubItem(mKNotesItem, Utils::Config); 0066 if (!backupData) { 0067 createSubItem(mKNotesItem, Utils::Data); 0068 } 0069 0070 mAkregatorItem = new QTreeWidgetItem(this); 0071 mAkregatorItem->setText(0, Utils::appTypeToI18n(Utils::Akregator)); 0072 mAkregatorItem->setCheckState(0, Qt::Checked); 0073 createSubItem(mAkregatorItem, Utils::Config); 0074 createSubItem(mAkregatorItem, Utils::Data); 0075 0076 connect(this, &SelectionTypeTreeWidget::itemChanged, this, &SelectionTypeTreeWidget::slotItemChanged); 0077 } 0078 0079 void SelectionTypeTreeWidget::removeNotSelectedItems() 0080 { 0081 if (!removeNotSelectedItem(mKmailItem)) { 0082 delete mKmailItem; 0083 mKmailItem = nullptr; 0084 } 0085 if (!removeNotSelectedItem(mKalarmItem)) { 0086 delete mKalarmItem; 0087 mKalarmItem = nullptr; 0088 } 0089 if (!removeNotSelectedItem(mKaddressbookItem)) { 0090 delete mKaddressbookItem; 0091 mKaddressbookItem = nullptr; 0092 } 0093 if (!removeNotSelectedItem(mKorganizerItem)) { 0094 delete mKorganizerItem; 0095 mKorganizerItem = nullptr; 0096 } 0097 if (!removeNotSelectedItem(mKNotesItem)) { 0098 delete mKNotesItem; 0099 mKNotesItem = nullptr; 0100 } 0101 if (!removeNotSelectedItem(mAkregatorItem)) { 0102 delete mAkregatorItem; 0103 mAkregatorItem = nullptr; 0104 } 0105 } 0106 0107 bool SelectionTypeTreeWidget::removeNotSelectedItem(QTreeWidgetItem *parent) 0108 { 0109 for (int i = parent->childCount() - 1; i >= 0; --i) { 0110 QTreeWidgetItem *item = parent->child(i); 0111 if (item->checkState(0) == Qt::Unchecked) { 0112 delete item; 0113 } 0114 } 0115 bool hasChildren = (parent->childCount() != 0); 0116 if (hasChildren) { 0117 parent->setCheckState(0, Qt::Checked); 0118 } 0119 return hasChildren; 0120 } 0121 0122 QMap<Utils::AppsType, Utils::importExportParameters> SelectionTypeTreeWidget::storedType() const 0123 { 0124 QMap<Utils::AppsType, Utils::importExportParameters> stored; 0125 Utils::importExportParameters var = typeChecked(mKmailItem); 0126 if (!var.isEmpty()) { 0127 stored.insert(Utils::KMail, var); 0128 } 0129 var = typeChecked(mKalarmItem); 0130 if (!var.isEmpty()) { 0131 stored.insert(Utils::KAlarm, var); 0132 } 0133 var = typeChecked(mKaddressbookItem); 0134 if (!var.isEmpty()) { 0135 stored.insert(Utils::KAddressBook, var); 0136 } 0137 var = typeChecked(mKorganizerItem); 0138 if (!var.isEmpty()) { 0139 stored.insert(Utils::KOrganizer, var); 0140 } 0141 var = typeChecked(mKNotesItem); 0142 if (!var.isEmpty()) { 0143 stored.insert(Utils::KNotes, var); 0144 } 0145 var = typeChecked(mAkregatorItem); 0146 if (!var.isEmpty()) { 0147 stored.insert(Utils::Akregator, var); 0148 } 0149 return stored; 0150 } 0151 0152 Utils::importExportParameters SelectionTypeTreeWidget::typeChecked(QTreeWidgetItem *parent) const 0153 { 0154 Utils::importExportParameters parameters; 0155 if (parent) { 0156 int numberOfStep = 0; 0157 Utils::StoredTypes types = Utils::None; 0158 for (int i = 0; i < parent->childCount(); ++i) { 0159 QTreeWidgetItem *item = parent->child(i); 0160 if (item->checkState(0) == Qt::Checked) { 0161 types |= static_cast<Utils::StoredType>(item->data(0, action).toInt()); 0162 ++numberOfStep; 0163 } 0164 } 0165 parameters.types = types; 0166 parameters.numberSteps = numberOfStep; 0167 } 0168 return parameters; 0169 } 0170 0171 void SelectionTypeTreeWidget::createSubItem(QTreeWidgetItem *parent, Utils::StoredType type) 0172 { 0173 switch (type) { 0174 case Utils::None: 0175 break; 0176 case Utils::Identity: { 0177 auto item = new QTreeWidgetItem(parent); 0178 item->setText(0, Utils::storedTypeToI18n(Utils::Identity)); 0179 item->setCheckState(0, Qt::Checked); 0180 item->setData(0, action, type); 0181 break; 0182 } 0183 case Utils::Mails: { 0184 auto item = new QTreeWidgetItem(parent); 0185 item->setText(0, Utils::storedTypeToI18n(Utils::Mails)); 0186 item->setCheckState(0, Qt::Checked); 0187 item->setData(0, action, type); 0188 break; 0189 } 0190 case Utils::MailTransport: { 0191 auto item = new QTreeWidgetItem(parent); 0192 item->setText(0, Utils::storedTypeToI18n(Utils::MailTransport)); 0193 item->setCheckState(0, Qt::Checked); 0194 item->setData(0, action, type); 0195 break; 0196 } 0197 case Utils::Resources: { 0198 auto item = new QTreeWidgetItem(parent); 0199 item->setText(0, Utils::storedTypeToI18n(Utils::Resources)); 0200 item->setCheckState(0, Qt::Checked); 0201 item->setData(0, action, type); 0202 break; 0203 } 0204 case Utils::Config: { 0205 auto item = new QTreeWidgetItem(parent); 0206 item->setText(0, Utils::storedTypeToI18n(Utils::Config)); 0207 item->setCheckState(0, Qt::Checked); 0208 item->setData(0, action, type); 0209 break; 0210 } 0211 case Utils::Data: { 0212 auto item = new QTreeWidgetItem(parent); 0213 item->setText(0, Utils::storedTypeToI18n(Utils::Data)); 0214 item->setCheckState(0, Qt::Checked); 0215 item->setData(0, action, type); 0216 break; 0217 } 0218 } 0219 } 0220 0221 void SelectionTypeTreeWidget::selectAllItems() 0222 { 0223 setSelectItems(true); 0224 } 0225 0226 void SelectionTypeTreeWidget::unSelectAllItems() 0227 { 0228 setSelectItems(false); 0229 } 0230 0231 void SelectionTypeTreeWidget::setSelectItems(bool b) 0232 { 0233 changeState(mKmailItem, b); 0234 changeState(mKalarmItem, b); 0235 changeState(mKaddressbookItem, b); 0236 changeState(mKorganizerItem, b); 0237 changeState(mKNotesItem, b); 0238 changeState(mAkregatorItem, b); 0239 } 0240 0241 void SelectionTypeTreeWidget::changeState(QTreeWidgetItem *item, bool b) 0242 { 0243 if (item) { 0244 blockSignals(true); 0245 item->setCheckState(0, b ? Qt::Checked : Qt::Unchecked); 0246 for (int i = 0; i < item->childCount(); ++i) { 0247 item->child(i)->setCheckState(0, b ? Qt::Checked : Qt::Unchecked); 0248 } 0249 blockSignals(false); 0250 } 0251 } 0252 0253 void SelectionTypeTreeWidget::slotItemChanged(QTreeWidgetItem *item, int column) 0254 { 0255 if (column != 0) { 0256 return; 0257 } 0258 // Parent 0259 if (item->childCount() != 0) { 0260 changeState(item, item->checkState(0) == Qt::Checked); 0261 } else { // child 0262 blockSignals(true); 0263 QTreeWidgetItem *parent = item->parent(); 0264 Qt::CheckState state = Qt::PartiallyChecked; 0265 for (int i = 0; i < parent->childCount(); ++i) { 0266 if (i == 0) { 0267 state = parent->child(i)->checkState(0); 0268 } else { 0269 if (state != parent->child(i)->checkState(0)) { 0270 state = Qt::PartiallyChecked; 0271 break; 0272 } 0273 } 0274 } 0275 parent->setCheckState(0, state); 0276 blockSignals(false); 0277 } 0278 } 0279 0280 void SelectionTypeTreeWidget::loadFileName(const QString &fileName) 0281 { 0282 unSelectAllItems(); 0283 TemplateSelection templateSelection; 0284 const QMap<Utils::AppsType, Utils::importExportParameters> params = templateSelection.loadTemplate(fileName); 0285 setParameters(params); 0286 } 0287 0288 void SelectionTypeTreeWidget::loadDefaultTemplate() 0289 { 0290 // Keep old name for compatibility 0291 QString ret = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("/pimsettingexporter/defaulttemplate.xml")); 0292 if (ret.isEmpty()) { 0293 ret = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("/pimdataexporter/defaulttemplate.xml")); 0294 } 0295 if (!ret.isEmpty()) { 0296 loadFileName(ret); 0297 } 0298 } 0299 0300 void SelectionTypeTreeWidget::loadTemplate(const QString &fileName) 0301 { 0302 if (fileName.isEmpty()) { 0303 QPointer<QFileDialog> dlg = new QFileDialog(this, QString(), QString(), QStringLiteral("*.xml")); 0304 dlg->setFileMode(QFileDialog::ExistingFile); 0305 if (dlg->exec()) { 0306 const QStringList file = dlg->selectedFiles(); 0307 loadFileName(file.at(0)); 0308 } 0309 delete dlg; 0310 } else { 0311 loadFileName(fileName); 0312 } 0313 } 0314 0315 QString SelectionTypeTreeWidget::exportedFileInfo() 0316 { 0317 const QString templateStr = templateSelectionToString(); 0318 QTemporaryFile tmp; 0319 tmp.open(); 0320 if (!PimCommon::Util::saveToFile(tmp.fileName(), templateStr)) { 0321 return {}; 0322 } else { 0323 tmp.setAutoRemove(false); 0324 } 0325 return tmp.fileName(); 0326 } 0327 0328 QString SelectionTypeTreeWidget::templateSelectionToString() 0329 { 0330 TemplateSelection templateSelection; 0331 templateSelection.createTemplate(storedType()); 0332 const QString templateStr = templateSelection.saveTemplate(); 0333 return templateStr; 0334 } 0335 0336 void SelectionTypeTreeWidget::saveAsDefaultTemplate() 0337 { 0338 const QString templateStr = templateSelectionToString(); 0339 const QString ret = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/pimdataexporter/"); 0340 QDir().mkpath(ret); 0341 0342 if (!PimCommon::Util::saveToFile(ret + QStringLiteral("defaulttemplate.xml"), templateStr)) { 0343 qWarning() << "Impossible to save as defaulttemplate.xml"; 0344 } 0345 } 0346 0347 void SelectionTypeTreeWidget::saveAsTemplate() 0348 { 0349 const QString templateStr = templateSelectionToString(); 0350 const QString filter(i18n("Template Files (*.xml)")); 0351 PimCommon::Util::saveTextAs(templateStr, filter, this); 0352 } 0353 0354 void SelectionTypeTreeWidget::initializeSubItem(QTreeWidgetItem *item, Utils::StoredTypes types) 0355 { 0356 for (int i = 0; i < item->childCount(); ++i) { 0357 QTreeWidgetItem *child = item->child(i); 0358 if (types & static_cast<Utils::StoredType>(child->data(0, action).toInt())) { 0359 child->setCheckState(0, Qt::Checked); 0360 } else { 0361 child->setCheckState(0, Qt::Unchecked); 0362 } 0363 } 0364 } 0365 0366 void SelectionTypeTreeWidget::setParameters(const QMap<Utils::AppsType, Utils::importExportParameters> ¶ms) 0367 { 0368 QMap<Utils::AppsType, Utils::importExportParameters>::const_iterator i = params.constBegin(); 0369 while (i != params.constEnd()) { 0370 switch (i.key()) { 0371 case Utils::KMail: 0372 initializeSubItem(mKmailItem, i.value().types); 0373 break; 0374 case Utils::KAddressBook: 0375 initializeSubItem(mKaddressbookItem, i.value().types); 0376 break; 0377 case Utils::KAlarm: 0378 initializeSubItem(mKalarmItem, i.value().types); 0379 break; 0380 case Utils::KOrganizer: 0381 initializeSubItem(mKorganizerItem, i.value().types); 0382 break; 0383 case Utils::KNotes: 0384 initializeSubItem(mKNotesItem, i.value().types); 0385 break; 0386 case Utils::Akregator: 0387 initializeSubItem(mAkregatorItem, i.value().types); 0388 break; 0389 case Utils::Unknown: 0390 break; 0391 } 0392 ++i; 0393 } 0394 } 0395 0396 #include "moc_selectiontypetreewidget.cpp"