File indexing completed on 2024-05-12 05:11:07

0001 /*
0002    SPDX-FileCopyrightText: 2012-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #include "importwizard.h"
0007 #include "autodetect/importaddressbookpage.h"
0008 #include "autodetect/importcalendarpage.h"
0009 #include "autodetect/importfilterpage.h"
0010 #include "autodetect/importfinishpage.h"
0011 #include "autodetect/importmailpage.h"
0012 #include "autodetect/importsettingpage.h"
0013 #include "autodetect/selectcomponentpage.h"
0014 #include "autodetect/selectprogrampage.h"
0015 #include "importmailpluginmanager.h"
0016 #include "importwizarddisplayinfo.h"
0017 #include "importwizardkernel.h"
0018 
0019 #include "manual/importwizardfilterinfogui.h"
0020 #include "manual/manualimportmailpage.h"
0021 #include "manual/manualselectfilterpage.h"
0022 
0023 #include <MailImporter/FilterInfo>
0024 #include <MailImporterAkonadi/FilterImporterAkonadi>
0025 
0026 #include <Akonadi/ControlGui>
0027 #include <KAboutData>
0028 #include <KConfigGroup>
0029 #include <KHelpMenu>
0030 #include <KLocalizedString>
0031 #include <KMessageBox>
0032 #include <MailCommon/MailKernel>
0033 #include <QAction>
0034 #include <QPushButton>
0035 
0036 ImportWizard::ImportWizard(WizardMode mode, QWidget *parent)
0037     : KAssistantDialog(parent)
0038     , mMode(mode)
0039 {
0040     setModal(true);
0041     setWindowTitle(i18nc("@title:window", "PIM Import Tool"));
0042     setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Help);
0043     mAbstractDisplayInfo = new ImportWizardDisplayInfo(this);
0044 
0045     auto kernel = new ImportWizardKernel(this);
0046     CommonKernel->registerKernelIf(kernel); // register KernelIf early, it is used by the Filter classes
0047     CommonKernel->registerSettingsIf(kernel); // SettingsIf is used in FolderTreeWidget
0048     createAutomaticModePage();
0049     createManualModePage();
0050     initializeImportModule();
0051 
0052     // Disable the 'next button to begin with.
0053     setValid(currentPage(), false);
0054 
0055     connect(mSelectProgramPage, &SelectProgramPage::programSelected, this, &ImportWizard::slotProgramSelected);
0056     connect(mSelectProgramPage, &SelectProgramPage::doubleClicked, this, &ImportWizard::slotProgramDoubleClicked);
0057     connect(mImportMailPage, &ImportMailPage::importMailsClicked, this, &ImportWizard::slotImportMailsClicked);
0058     connect(mImportFilterPage, &ImportFilterPage::importFiltersClicked, this, &ImportWizard::slotImportFiltersClicked);
0059     connect(mImportSettingPage, &ImportSettingPage::importSettingsClicked, this, &ImportWizard::slotImportSettingsClicked);
0060     connect(mImportAddressbookPage, &ImportAddressbookPage::importAddressbookClicked, this, &ImportWizard::slotImportAddressbookClicked);
0061     connect(mImportCalendarPage, &ImportCalendarPage::importCalendarClicked, this, &ImportWizard::slotImportCalendarClicked);
0062 
0063     connect(mSelectComponentPage, &SelectComponentPage::atLeastOneComponentSelected, this, &ImportWizard::slotAtLeastOneComponentSelected);
0064 
0065     resize(640, 480);
0066     Akonadi::ControlGui::widgetNeedsAkonadi(this);
0067 
0068     if (mode == WizardMode::AutoDetect) {
0069         checkModules();
0070         KMessageBox::information(this, i18n("Close KMail before importing data. Some plugins will modify KMail config file."));
0071     }
0072     auto helpMenu = new KHelpMenu(this, KAboutData::applicationData(), true);
0073     // Initialize menu
0074     QMenu *menu = helpMenu->menu();
0075     helpMenu->action(KHelpMenu::menuAboutApp)->setIcon(QIcon::fromTheme(QStringLiteral("kmail")));
0076     button(QDialogButtonBox::Help)->setMenu(menu);
0077     updatePagesFromMode();
0078     readConfig();
0079 }
0080 
0081 ImportWizard::~ImportWizard()
0082 {
0083     writeConfig();
0084 }
0085 
0086 void ImportWizard::readConfig()
0087 {
0088     KConfigGroup group(KSharedConfig::openConfig(), QStringLiteral("FolderSelectionDialog"));
0089     if (group.hasKey("LastSelectedFolder")) {
0090         mSelfilterpage->widget()->mCollectionRequestor->setCollection(CommonKernel->collectionFromId(group.readEntry("LastSelectedFolder", -1)));
0091     }
0092 }
0093 
0094 void ImportWizard::writeConfig()
0095 {
0096     KConfigGroup group(KSharedConfig::openConfig(), QStringLiteral("FolderSelectionDialog"));
0097     group.writeEntry("LastSelectedFolder", mSelfilterpage->widget()->mCollectionRequestor->collection().id());
0098     group.sync();
0099 }
0100 
0101 void ImportWizard::updatePagesFromMode()
0102 {
0103     const bool autodetectMode = (mMode == WizardMode::AutoDetect);
0104     setAppropriate(mSelectProgramPageItem, autodetectMode);
0105     setAppropriate(mSelectComponentPageItem, autodetectMode);
0106     setAppropriate(mImportMailPageItem, autodetectMode);
0107     setAppropriate(mImportFilterPageItem, autodetectMode);
0108     setAppropriate(mImportSettingPageItem, autodetectMode);
0109     setAppropriate(mImportAddressbookPageItem, autodetectMode);
0110     setAppropriate(mImportCalendarPageItem, autodetectMode);
0111     setAppropriate(mImportFinishPageItem, autodetectMode);
0112 
0113     setAppropriate(mSelfilterpageItem, !autodetectMode);
0114     setAppropriate(mImportpageItem, !autodetectMode);
0115     if (autodetectMode) {
0116         setCurrentPage(mSelectProgramPageItem);
0117     } else {
0118         setCurrentPage(mSelfilterpageItem);
0119     }
0120 }
0121 
0122 void ImportWizard::createManualModePage()
0123 {
0124     mSelfilterpage = new ManualSelectFilterPage(this);
0125     mSelfilterpageItem = new KPageWidgetItem(mSelfilterpage, i18n("Step 1: Select Filter"));
0126 
0127     addPage(mSelfilterpageItem);
0128 
0129     mImportpage = new ManualImportMailPage(this);
0130     mImportpageItem = new KPageWidgetItem(mImportpage, i18n("Step 2: Importing..."));
0131     addPage(mImportpageItem);
0132 
0133     // Disable the 'next button to begin with.
0134     setValid(mSelfilterpageItem, false);
0135 
0136     connect(mSelfilterpage->widget()->mCollectionRequestor, &MailCommon::FolderRequester::folderChanged, this, &ImportWizard::slotCollectionChanged);
0137 }
0138 
0139 void ImportWizard::slotCollectionChanged(const Akonadi::Collection &selectedCollection)
0140 {
0141     if (selectedCollection.isValid()) {
0142         setValid(mSelfilterpageItem, true);
0143     } else {
0144         setValid(mSelfilterpageItem, false);
0145     }
0146 }
0147 
0148 void ImportWizard::reject()
0149 {
0150     if (currentPage() == mImportpageItem) {
0151         MailImporter::FilterInfo::terminateASAP(); // ie. import in progress
0152     }
0153     KAssistantDialog::reject();
0154 }
0155 
0156 void ImportWizard::createAutomaticModePage()
0157 {
0158     mSelectProgramPage = new SelectProgramPage(this);
0159     mSelectProgramPageItem = new KPageWidgetItem(mSelectProgramPage, i18n("Detect program"));
0160     connect(mSelectProgramPage, &SelectProgramPage::selectManualSelectionChanged, this, &ImportWizard::slotSelectManualSelectionChanged);
0161     addPage(mSelectProgramPageItem);
0162 
0163     mSelectComponentPage = new SelectComponentPage(this);
0164     mSelectComponentPageItem = new KPageWidgetItem(mSelectComponentPage, i18n("Select material to import"));
0165     addPage(mSelectComponentPageItem);
0166 
0167     mImportMailPage = new ImportMailPage(this);
0168     mImportMailPageItem = new KPageWidgetItem(mImportMailPage, i18n("Import mail messages"));
0169     addPage(mImportMailPageItem);
0170 
0171     mImportFilterPage = new ImportFilterPage(this);
0172     mImportFilterPageItem = new KPageWidgetItem(mImportFilterPage, i18n("Import mail filters"));
0173     addPage(mImportFilterPageItem);
0174 
0175     mImportSettingPage = new ImportSettingPage(this);
0176     mImportSettingPageItem = new KPageWidgetItem(mImportSettingPage, i18n("Import settings"));
0177     addPage(mImportSettingPageItem);
0178 
0179     mImportAddressbookPage = new ImportAddressbookPage(this);
0180     mImportAddressbookPageItem = new KPageWidgetItem(mImportAddressbookPage, i18n("Import addressbooks"));
0181     addPage(mImportAddressbookPageItem);
0182 
0183     mImportCalendarPage = new ImportCalendarPage(this);
0184     mImportCalendarPageItem = new KPageWidgetItem(mImportCalendarPage, i18n("Import calendars"));
0185     addPage(mImportCalendarPageItem);
0186 
0187     mImportFinishPage = new ImportFinishPage(this);
0188     mImportFinishPageItem = new KPageWidgetItem(mImportFinishPage, i18n("Finish"));
0189     addPage(mImportFinishPageItem);
0190 }
0191 
0192 void ImportWizard::initializeImportModule()
0193 {
0194     const QList<LibImportWizard::AbstractImporter *> lstPlugins = ImportMailPluginManager::self()->pluginsList();
0195     for (LibImportWizard::AbstractImporter *abstractPlugin : lstPlugins) {
0196         if (abstractPlugin->foundMailer()) {
0197             abstractPlugin->setAbstractDisplayInfo(mAbstractDisplayInfo);
0198             mlistImport.insert(abstractPlugin->name(), abstractPlugin);
0199         }
0200     }
0201 }
0202 
0203 void ImportWizard::slotProgramDoubleClicked()
0204 {
0205     next();
0206 }
0207 
0208 void ImportWizard::slotImportAddressbookClicked()
0209 {
0210     addFinishInfo(i18n("Import addressbook from %1...", mSelectedPim->name()));
0211     mImportAddressbookPage->setImportButtonEnabled(false);
0212     const bool result = mSelectedPim->importAddressBook();
0213     addFinishInfo(i18n("Import addressbook from %1: Done", mSelectedPim->name()));
0214     setValid(mImportAddressbookPageItem, result);
0215 }
0216 
0217 void ImportWizard::slotImportFiltersClicked()
0218 {
0219     addFinishInfo(i18n("Import filters from %1...", mSelectedPim->name()));
0220     mImportFilterPage->setImportButtonEnabled(false);
0221     const bool result = mSelectedPim->importFilters();
0222     addFinishInfo(i18n("Import filters from %1: Done", mSelectedPim->name()));
0223     setValid(mImportFilterPageItem, result);
0224 }
0225 
0226 void ImportWizard::slotImportMailsClicked()
0227 {
0228     addFinishInfo(i18n("Import mails from %1...", mSelectedPim->name()));
0229     mImportMailPage->setImportButtonEnabled(false);
0230     const bool result = mSelectedPim->importMails();
0231     addFinishInfo(i18n("Import mails from %1: Done", mSelectedPim->name()));
0232     setValid(mImportMailPageItem, result);
0233 }
0234 
0235 void ImportWizard::slotImportSettingsClicked()
0236 {
0237     addFinishInfo(i18n("Import settings from %1...", mSelectedPim->name()));
0238     mImportSettingPage->setImportButtonEnabled(false);
0239     const bool result = mSelectedPim->importSettings();
0240     addFinishInfo(i18n("Import settings from %1: Done", mSelectedPim->name()));
0241     setValid(mImportSettingPageItem, result);
0242 }
0243 
0244 void ImportWizard::slotImportCalendarClicked()
0245 {
0246     addFinishInfo(i18n("Import calendar from %1...", mSelectedPim->name()));
0247     mImportCalendarPage->setImportButtonEnabled(false);
0248     const bool result = mSelectedPim->importCalendar();
0249     addFinishInfo(i18n("Import calendar from %1: Done", mSelectedPim->name()));
0250     setValid(mImportCalendarPageItem, result);
0251 }
0252 
0253 void ImportWizard::slotProgramSelected(const QString &program)
0254 {
0255     LibImportWizard::AbstractImporter *importer = mlistImport.value(program);
0256     if (importer) {
0257         mSelectedPim = importer;
0258         setValid(currentPage(), true);
0259     }
0260 }
0261 
0262 void ImportWizard::checkModules()
0263 {
0264     mSelectProgramPage->setFoundProgram(mlistImport.keys());
0265 }
0266 
0267 void ImportWizard::addImportModule(LibImportWizard::AbstractImporter *import)
0268 {
0269     if (import->foundMailer()) {
0270         mlistImport.insert(import->name(), import);
0271     } else {
0272         delete import;
0273     }
0274 }
0275 
0276 void ImportWizard::slotAtLeastOneComponentSelected(bool result)
0277 {
0278     setValid(mSelectComponentPageItem, result);
0279 }
0280 
0281 void ImportWizard::setAppropriatePage(LibImportWizard::AbstractImporter::TypeSupportedOptions options)
0282 {
0283     setAppropriate(mImportMailPageItem, (options & LibImportWizard::AbstractImporter::Mails));
0284     setAppropriate(mImportFilterPageItem, (options & LibImportWizard::AbstractImporter::Filters));
0285     setAppropriate(mImportSettingPageItem, (options & LibImportWizard::AbstractImporter::Settings));
0286     setAppropriate(mImportAddressbookPageItem, (options & LibImportWizard::AbstractImporter::AddressBooks));
0287     setAppropriate(mImportCalendarPageItem, (options & LibImportWizard::AbstractImporter::Calendars));
0288 }
0289 
0290 void ImportWizard::next()
0291 {
0292     if (currentPage() == mSelectProgramPageItem) {
0293         KAssistantDialog::next();
0294         mSelectProgramPage->disableSelectProgram();
0295         mSelectComponentPage->setEnabledComponent(mSelectedPim->supportedOption());
0296     } else if (currentPage() == mSelectComponentPageItem) {
0297         setAppropriatePage(mSelectComponentPage->selectedComponents());
0298         KAssistantDialog::next();
0299         setValid(mImportMailPageItem, false);
0300     } else if (currentPage() == mImportMailPageItem) {
0301         KAssistantDialog::next();
0302         setValid(mImportFilterPageItem, false);
0303     } else if (currentPage() == mImportFilterPageItem) {
0304         KAssistantDialog::next();
0305         setValid(mImportSettingPageItem, false);
0306     } else if (currentPage() == mImportSettingPageItem) {
0307         KAssistantDialog::next();
0308         setValid(mImportAddressbookPageItem, false);
0309     } else if (currentPage() == mImportAddressbookPageItem) {
0310         KAssistantDialog::next();
0311         setValid(mImportCalendarPageItem, false);
0312     } else if (currentPage() == mImportCalendarPageItem) {
0313         KAssistantDialog::next();
0314         setValid(mImportFinishPageItem, true);
0315     } else if (currentPage() == mSelfilterpageItem) {
0316         // Save selected filter
0317         MailImporter::Filter *selectedFilter = mSelfilterpage->getSelectedFilter();
0318         Akonadi::Collection selectedCollection = mSelfilterpage->widget()->mCollectionRequestor->collection();
0319         // without filter don't go next
0320         if (!selectedFilter) {
0321             return;
0322         }
0323         // Ensure we have a valid collection.
0324         if (!selectedCollection.isValid()) {
0325             return;
0326         }
0327         // Goto next page
0328         KAssistantDialog::next();
0329         // Disable back & finish
0330         setValid(currentPage(), false);
0331 
0332         finishButton()->setEnabled(false);
0333 
0334         auto info = new MailImporter::FilterInfo();
0335         auto filterImporter = new MailImporter::FilterImporterAkonadi(info);
0336         auto infoGui = new ImportWizardFilterInfoGui(mImportpage, this);
0337         info->setFilterInfoGui(infoGui);
0338         info->setStatusMessage(i18n("Import in progress"));
0339         info->setRemoveDupMessage(mSelfilterpage->removeDupMsg_checked());
0340         info->clear(); // Clear info from last time
0341         filterImporter->setRootCollection(selectedCollection);
0342         selectedFilter->setFilterImporter(filterImporter);
0343         selectedFilter->setFilterInfo(info);
0344         selectedFilter->import();
0345         info->setStatusMessage(i18n("Import finished"));
0346         // Cleanup
0347         delete filterImporter;
0348         delete info;
0349         // Enable finish & back buttons
0350         setValid(currentPage(), true);
0351         finishButton()->setEnabled(true);
0352     } else {
0353         KAssistantDialog::next();
0354     }
0355 }
0356 
0357 void ImportWizard::enableAllImportButton()
0358 {
0359     mImportMailPage->setImportButtonEnabled(true);
0360     mImportFilterPage->setImportButtonEnabled(true);
0361     mImportSettingPage->setImportButtonEnabled(true);
0362     mImportAddressbookPage->setImportButtonEnabled(true);
0363     mImportCalendarPage->setImportButtonEnabled(true);
0364 }
0365 
0366 void ImportWizard::back()
0367 {
0368     if (currentPage() == mSelectProgramPageItem) {
0369         return;
0370     } else if (currentPage() == mImportFilterPageItem || currentPage() == mImportSettingPageItem || currentPage() == mImportAddressbookPageItem
0371                || currentPage() == mImportCalendarPageItem || currentPage() == mImportFinishPageItem) {
0372         enableAllImportButton();
0373     }
0374     KAssistantDialog::back();
0375 }
0376 
0377 ImportMailPage *ImportWizard::importMailPage() const
0378 {
0379     return mImportMailPage;
0380 }
0381 
0382 ImportFilterPage *ImportWizard::importFilterPage() const
0383 {
0384     return mImportFilterPage;
0385 }
0386 
0387 ImportAddressbookPage *ImportWizard::importAddressBookPage() const
0388 {
0389     return mImportAddressbookPage;
0390 }
0391 
0392 ImportSettingPage *ImportWizard::importSettingPage() const
0393 {
0394     return mImportSettingPage;
0395 }
0396 
0397 ImportFinishPage *ImportWizard::importFinishPage() const
0398 {
0399     return mImportFinishPage;
0400 }
0401 
0402 ImportCalendarPage *ImportWizard::importCalendarPage() const
0403 {
0404     return mImportCalendarPage;
0405 }
0406 
0407 void ImportWizard::addFinishInfo(const QString &log)
0408 {
0409     mImportFinishPage->addImportInfo(log);
0410 }
0411 
0412 void ImportWizard::addFinishError(const QString &log)
0413 {
0414     mImportFinishPage->addImportError(log);
0415 }
0416 
0417 void ImportWizard::slotSelectManualSelectionChanged(bool b)
0418 {
0419     mMode = b ? WizardMode::Manual : WizardMode::AutoDetect;
0420     updatePagesFromMode();
0421 }
0422 
0423 #include "moc_importwizard.cpp"