File indexing completed on 2024-05-12 16:40:15

0001 /* This file is part of the KDE project
0002    Copyright (C) 2004-2009 Adam Pigg <adam@piggz.co.uk>
0003    Copyright (C) 2004-2016 Jarosław Staniek <staniek@kde.org>
0004    Copyright (C) 2005 Martin Ellis <martin.ellis@kdemail.net>
0005 
0006    This library is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU Library General Public
0008    License as published by the Free Software Foundation; either
0009    version 2 of the License, or (at your option) any later version.
0010 
0011    This library is distributed in the hope that it will be useful,
0012    but WITHOUT ANY WARRANTY; without even the implied warranty of
0013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014    Library General Public License for more details.
0015 
0016    You should have received a copy of the GNU Library General Public License
0017    along with this library; see the file COPYING.LIB.  If not, write to
0018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019  * Boston, MA 02110-1301, USA.
0020 */
0021 
0022 #include "importwizard.h"
0023 #include "keximigrate.h"
0024 #include "importoptionsdlg.h"
0025 #include <core/KexiMainWindowIface.h>
0026 #include <core/kexidbconnectionset.h>
0027 #include <core/kexi.h>
0028 #include <kexiutils/utils.h>
0029 #include <kexidbdrivercombobox.h>
0030 #include <kexitextmsghandler.h>
0031 #include <widget/kexicharencodingcombobox.h>
0032 #include <widget/kexiprjtypeselector.h>
0033 #include <widget/KexiConnectionSelectorWidget.h>
0034 #include <widget/KexiProjectSelectorWidget.h>
0035 #include <widget/KexiDBCaptionPage.h>
0036 #include <widget/KexiDBPasswordDialog.h>
0037 #include <widget/KexiStartupFileHandler.h>
0038 #include <KexiIcon.h>
0039 
0040 #include <KDbDriverManager>
0041 #include <KDbDriver>
0042 #include <KDbConnectionData>
0043 #include <KDbUtils>
0044 #include <KDb>
0045 #include <KDbIdentifierValidator>
0046 
0047 #include <KMessageBox>
0048 
0049 #include <QGroupBox>
0050 #include <QLabel>
0051 #include <QLayout>
0052 #include <QRadioButton>
0053 #include <QCheckBox>
0054 #include <QVBoxLayout>
0055 #include <QHBoxLayout>
0056 #include <QDir>
0057 #include <QApplication>
0058 #include <QLineEdit>
0059 #include <QMimeDatabase>
0060 #include <QMimeType>
0061 #include <QPushButton>
0062 #include <QDebug>
0063 #include <QProgressBar>
0064 
0065 using namespace KexiMigration;
0066 
0067 class Q_DECL_HIDDEN ImportWizard::Private
0068 {
0069 public:
0070 
0071     Private(QMap<QString, QString>* args_)
0072       : srcProjectSelector(0)
0073       , fileBasedDstWasPresented(false)
0074       , setupFileBasedSrcNeeded(true)
0075       , importExecuted(false)
0076       , prjSet(0)
0077       , args(args_)
0078     {
0079     }
0080 
0081     ~Private()
0082     {
0083         delete prjSet;
0084     }
0085 
0086     QWidget *introPageWidget, *srcConnPageWidget, *srcDBPageWidget,
0087       *dstTypePageWidget, *dstPageWidget, *importTypePageWidget,
0088       *importingPageWidget, *finishPageWidget;
0089 
0090     KPageWidgetItem *introPageItem, *srcConnPageItem, *srcDBPageItem,
0091       *dstTypePageItem, *dstPageItem, *importTypePageItem,
0092       *importingPageItem, *finishPageItem;
0093 
0094 
0095     QGroupBox *importTypeGroupBox;
0096     QRadioButton *importTypeStructureAndDataCheckBox;
0097     QRadioButton *importTypeStructureOnlyCheckBox;
0098     KexiDBCaptionPage* dstCaptionPageWidget;
0099     KPageWidgetItem *dstCaptionPageItem;
0100 
0101     KexiPrjTypeSelector *dstPrjTypeSelector;
0102 
0103     KexiConnectionSelectorWidget *srcConn, *dstConn;
0104     QString driverIdForSelectedSource;
0105 
0106     QLineEdit *dstNewDBCaptionLineEdit;
0107     QLabel *dstNewDBNameLabel;
0108     QLineEdit *dstNewDBNameLineEdit;
0109 
0110     QLabel *dstNewDBNameUrlLabel;
0111     KUrlRequester *dstNewDBNameUrl;
0112     KexiStartupFileHandler *dstNewDBFileHandler;
0113     KexiProjectSelectorWidget *srcProjectSelector;
0114 
0115     QLabel *lblImportingTxt, *lblImportingErrTxt, *finishLbl;
0116     QCheckBox *openImportedProjectCheckBox;
0117     bool fileBasedDstWasPresented;
0118     bool setupFileBasedSrcNeeded;
0119     bool importExecuted; //!< used in import()
0120     KexiProjectSet* prjSet;
0121     QProgressBar *progressBar;
0122     QPushButton* importOptionsButton;
0123     QMap<QString, QString> *args;
0124     QString predefinedDatabaseName, predefinedMimeType;
0125     KDbConnectionData *predefinedConnectionData;
0126     MigrateManager migrateManager; //!< object lives here, so status messages can be globally preserved
0127 
0128     //! Encoding for source db. Currently only used for MDB driver.
0129 //! @todo Hardcoded. Move to KexiMigrate driver's impl.
0130     QString sourceDBEncoding;
0131 
0132 };
0133 
0134 //===========================================================
0135 //
0136 ImportWizard::ImportWizard(QWidget *parent, QMap<QString, QString>* args)
0137         : KAssistantDialog(parent)
0138         , d(new Private(args))
0139 {
0140     setModal(true);
0141     setWindowTitle(xi18nc("@title:window", "Import Database"));
0142     setWindowIcon(KexiIcon("database-import"));
0143 
0144     KexiMainWindowIface::global()->setReasonableDialogSize(this);
0145 
0146     parseArguments();
0147 
0148     setupIntro();
0149     setupSrcConn();
0150     setupSrcDB();
0151     setupDstType();
0152     setupDstCaption();
0153     setupDst();
0154     setupImportType();
0155     setupImporting();
0156     setupFinish();
0157 
0158     connect(this, SIGNAL(currentPageChanged(KPageWidgetItem*,KPageWidgetItem*)), this, SLOT(slot_currentPageChanged(KPageWidgetItem*,KPageWidgetItem*)));
0159     connect(button(QDialogButtonBox::Help), &QPushButton::clicked, this, &ImportWizard::helpClicked);
0160 
0161     if (d->predefinedConnectionData) {
0162         // setup wizard for predefined server source
0163         d->srcConn->showAdvancedConnection();
0164         setAppropriate(d->srcConnPageItem, false);
0165         setAppropriate(d->srcDBPageItem, false);
0166     } else if (!d->predefinedDatabaseName.isEmpty()) {
0167         // setup wizard for predefined source
0168         // (used when external project type was opened in Kexi, e.g. mdb file)
0169         setAppropriate(d->srcConnPageItem, false);
0170         setAppropriate(d->srcDBPageItem, false);
0171         d->srcConn->showSimpleConnection();
0172         d->srcConn->setSelectedFile(d->predefinedDatabaseName);
0173 
0174         #if 0
0175         //disable all prev pages except "welcome" page
0176         for (int i = 0; i < indexOf(d->dstTypePage); i++) {
0177             if (page(i) != d->introPage)
0178                 setAppropriate(page(i), false);
0179         }
0180         #endif
0181     }
0182 
0183     d->sourceDBEncoding = QString::fromLatin1(KexiUtils::encoding()); //default
0184 }
0185 
0186 //===========================================================
0187 //
0188 ImportWizard::~ImportWizard()
0189 {
0190     delete d;
0191 }
0192 
0193 //===========================================================
0194 //
0195 void ImportWizard::parseArguments()
0196 {
0197     d->predefinedConnectionData = 0;
0198     if (!d->args)
0199         return;
0200     if (!(*d->args)["databaseName"].isEmpty() && !(*d->args)["mimeType"].isEmpty()) {
0201         d->predefinedDatabaseName = (*d->args)["databaseName"];
0202         d->predefinedMimeType = (*d->args)["mimeType"];
0203         if (d->args->contains("connectionData")) {
0204             bool ok;
0205             d->predefinedConnectionData = new KDbConnectionData(
0206                 KDbUtils::deserializeMap((*d->args)["connectionData"]), &ok);
0207             if (!ok) {
0208                 delete d->predefinedConnectionData;
0209                 d->predefinedConnectionData = 0;
0210             }
0211         }
0212     }
0213     d->args->clear();
0214 }
0215 
0216 QString ImportWizard::selectedSourceFileName() const
0217 {
0218     if (d->predefinedDatabaseName.isEmpty())
0219         return d->srcConn->selectedFile();
0220 
0221     return d->predefinedDatabaseName;
0222 }
0223 
0224 //===========================================================
0225 //
0226 void ImportWizard::setupIntro()
0227 {
0228     d->introPageWidget = new QWidget(this);
0229     QVBoxLayout *vbox = new QVBoxLayout();
0230 
0231     d->introPageWidget->setLayout(vbox);
0232 
0233     KexiUtils::setStandardMarginsAndSpacing(vbox);
0234 
0235     QLabel *lblIntro = new QLabel(d->introPageWidget);
0236     lblIntro->setAlignment(Qt::AlignTop | Qt::AlignLeft);
0237     lblIntro->setWordWrap(true);
0238     lblIntro->setTextFormat(Qt::RichText);
0239     KLocalizedString msg;
0240     if (d->predefinedConnectionData) { // predefined import: server source
0241         msg = kxi18nc("@info",
0242                       "Database Importing Assistant is about to import <resource>%1</resource> "
0243                       "database "
0244                       "(connection <resource>%2</resource>) into a KEXI project.")
0245                   .subs(d->predefinedDatabaseName)
0246                   .subs(d->predefinedConnectionData->toUserVisibleString());
0247     } else if (!d->predefinedDatabaseName.isEmpty()) { // predefined import: file source
0248         //! @todo this message is currently ok for files only
0249         QMimeDatabase db;
0250         QMimeType mime = db.mimeTypeForName(d->predefinedMimeType);
0251         if (!mime.isValid()) {
0252             qWarning() << QString("'%1' mimetype not installed!").arg(d->predefinedMimeType);
0253         }
0254         d->driverIdForSelectedSource = driverIdForMimeType(mime);
0255         msg = kxi18nc(
0256                   "@info",
0257                   "Database Importing Assistant is about to import <filename>%1</filename> file "
0258                   "of type <resource>%2</resource> into a KEXI project.")
0259                   .subs(QDir::toNativeSeparators(d->predefinedDatabaseName))
0260                   .subs(mime.isValid() ? mime.comment() : "???");
0261     } else {
0262         msg = kxi18nc("@info",
0263                       "Database Importing Assistant allows you to import an existing database "
0264                       "into a KEXI project.");
0265     }
0266     const QString finalMessage = KexiUtils::localizedSentencesToHtml(
0267         msg,
0268         kxi18nc("@info",
0269                 "<para>Click <interface>Next</interface> button to continue or "
0270                 "<interface>Cancel</interface> button to exit this assistant.</para>"));
0271     lblIntro->setText(finalMessage);
0272     vbox->addWidget(lblIntro);
0273 
0274     d->introPageItem = new KPageWidgetItem(d->introPageWidget,
0275                                            xi18n("Welcome to the Database Importing Assistant"));
0276     addPage(d->introPageItem);
0277 }
0278 
0279 //===========================================================
0280 //
0281 void ImportWizard::setupSrcConn()
0282 {
0283     d->srcConnPageWidget = new QWidget(this);
0284     QVBoxLayout *vbox = new QVBoxLayout(d->srcConnPageWidget);
0285     KexiUtils::setStandardMarginsAndSpacing(vbox);
0286 
0287     d->srcConn = new KexiConnectionSelectorWidget(&Kexi::connset(),
0288                          QUrl("kfiledialog:///ProjectMigrationSourceDir"),
0289                          KexiConnectionSelectorWidget::Opening, d->srcConnPageWidget);
0290 
0291     d->srcConn->hideConnectonIcon();
0292     d->srcConn->showSimpleConnection();
0293     connect(d->srcConn, &KexiConnectionSelectorWidget::connectionSelected,
0294             this, &ImportWizard::sourceConnectionSelected);
0295 
0296     const QStringList excludedMimeTypes({
0297 //! @todo remove when support for kexi files as source prj is added in migration
0298         KDb::defaultFileBasedDriverMimeType(),
0299         "application/x-kexiproject-shortcut",
0300         "application/x-kexi-connectiondata"});
0301     d->srcConn->setExcludedMimeTypes(excludedMimeTypes);
0302     vbox->addWidget(d->srcConn);
0303 
0304     d->srcConnPageItem = new KPageWidgetItem(d->srcConnPageWidget, xi18n("Select Location for Source Database"));
0305     addPage(d->srcConnPageItem);
0306 }
0307 
0308 //===========================================================
0309 //
0310 void ImportWizard::setupSrcDB()
0311 {
0312 // arrivesrcdbPage creates widgets on that page
0313     d->srcDBPageWidget = new QWidget(this);
0314 
0315     d->srcDBPageItem = new KPageWidgetItem(d->srcDBPageWidget, xi18n("Select Source Database"));
0316     addPage(d->srcDBPageItem);
0317 }
0318 
0319 //===========================================================
0320 //
0321 void ImportWizard::setupDstType()
0322 {
0323     d->dstTypePageWidget = new QWidget(this);
0324     QVBoxLayout *vbox = new QVBoxLayout(d->dstTypePageWidget);
0325     KexiUtils::setStandardMarginsAndSpacing(vbox);
0326 
0327     QHBoxLayout *hbox = new QHBoxLayout;
0328     vbox->addLayout(hbox);
0329     KexiUtils::setStandardMarginsAndSpacing(hbox);
0330     QLabel *lbl = new QLabel(xi18n("Destination database type:") /*+ ' '*/, d->dstTypePageWidget);
0331     lbl->setAlignment(Qt::AlignLeft | Qt::AlignTop);
0332     lbl->setTextFormat(Qt::RichText);
0333     hbox->addWidget(lbl);
0334 
0335     d->dstPrjTypeSelector = new KexiPrjTypeSelector(d->dstTypePageWidget);
0336     hbox->addWidget(d->dstPrjTypeSelector);
0337     d->dstPrjTypeSelector->option_file->setText(xi18n("Database project stored in a file"));
0338     d->dstPrjTypeSelector->option_server->setText(xi18n("Database project stored on a server"));
0339     hbox->addStretch(1);
0340     vbox->addStretch(1);
0341 
0342     d->dstTypePageItem = new KPageWidgetItem(d->dstTypePageWidget, xi18n("Select Destination Database Type"));
0343     addPage(d->dstTypePageItem);
0344 }
0345 
0346 //===========================================================
0347 //
0348 void ImportWizard::setupDstCaption()
0349 {
0350     d->dstCaptionPageWidget = new KexiDBCaptionPage(xi18n("Destination project's caption:"), this);
0351     d->dstCaptionPageWidget->layout()->setMargin(KexiUtils::marginHint());
0352     d->dstCaptionPageWidget->updateGeometry();
0353     d->dstNewDBCaptionLineEdit = d->dstCaptionPageWidget->le_caption;
0354     connect(d->dstNewDBCaptionLineEdit, &QLineEdit::textChanged, this,
0355             &ImportWizard::destinationCaptionTextChanged);
0356     d->dstNewDBNameUrlLabel = d->dstCaptionPageWidget->label_requester;
0357     d->dstNewDBNameUrl = d->dstCaptionPageWidget->file_requester;
0358     d->dstNewDBFileHandler = new KexiStartupFileHandler(
0359         QUrl("kfiledialog:///ProjectMigrationDestinationDir"),
0360         KexiFileFilters::SavingFileBasedDB,
0361         d->dstCaptionPageWidget->file_requester);
0362     d->dstNewDBNameLabel = new QLabel(xi18n("Destination project's name:"), d->dstCaptionPageWidget);
0363     d->dstCaptionPageWidget->formLayout->setWidget(2, QFormLayout::LabelRole, d->dstNewDBNameLabel);
0364     d->dstNewDBNameLineEdit = new QLineEdit(d->dstCaptionPageWidget);
0365     d->dstNewDBNameLineEdit->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
0366     KDbIdentifierValidator *idValidator = new KDbIdentifierValidator(this);
0367     idValidator->setLowerCaseForced(true);
0368     d->dstNewDBNameLineEdit->setValidator(idValidator);
0369     d->dstCaptionPageWidget->formLayout->setWidget(2, QFormLayout::FieldRole, d->dstNewDBNameLineEdit);
0370 
0371     d->dstCaptionPageItem = new KPageWidgetItem(d->dstCaptionPageWidget, xi18n("Enter Destination Database Project's Caption"));
0372     addPage(d->dstCaptionPageItem);
0373 }
0374 
0375 void ImportWizard::destinationCaptionTextChanged(const QString &text)
0376 {
0377     Q_UNUSED(text);
0378     updateDestinationDBFileName();
0379 }
0380 
0381 void ImportWizard::updateDestinationDBFileName()
0382 {
0383     d->dstNewDBFileHandler->updateUrl(d->dstNewDBCaptionLineEdit->text());
0384     d->dstNewDBNameLineEdit->setText(d->dstNewDBCaptionLineEdit->text());
0385 }
0386 
0387 //===========================================================
0388 //
0389 void ImportWizard::setupDst()
0390 {
0391     d->dstPageWidget = new QWidget(this);
0392     QVBoxLayout *vbox = new QVBoxLayout(d->dstPageWidget);
0393     KexiUtils::setStandardMarginsAndSpacing(vbox);
0394 
0395     d->dstConn = new KexiConnectionSelectorWidget(&Kexi::connset(),
0396                          QUrl("kfiledialog:///ProjectMigrationDestinationDir"),
0397                          KexiConnectionSelectorWidget::Saving, d->dstPageWidget);
0398     d->dstConn->hideHelpers();
0399 
0400     vbox->addWidget(d->dstConn);
0401     connect(d->dstConn, SIGNAL(connectionItemExecuted(ConnectionDataLVItem*)),
0402             this, SLOT(next()));
0403 
0404     d->dstConn->showSimpleConnection();
0405     //anyway, db files will be _saved_
0406     d->dstConn->setFileMode(KexiFileFilters::SavingFileBasedDB);
0407     d->dstPageItem = new KPageWidgetItem(d->dstPageWidget, xi18n("Select Location for Destination Database Project"));
0408     addPage(d->dstPageItem);
0409 }
0410 
0411 //===========================================================
0412 //
0413 void ImportWizard::setupImportType()
0414 {
0415     d->importTypePageWidget = new QWidget(this);
0416     QVBoxLayout *vbox = new QVBoxLayout(d->importTypePageWidget);
0417     KexiUtils::setStandardMarginsAndSpacing(vbox);
0418     d->importTypeGroupBox = new QGroupBox(d->importTypePageWidget);
0419 
0420     vbox->addWidget(d->importTypeGroupBox);
0421     QVBoxLayout *importTypeGroupBoxLyr = new QVBoxLayout;
0422 
0423     importTypeGroupBoxLyr->addWidget(
0424         d->importTypeStructureAndDataCheckBox = new QRadioButton(
0425             xi18nc("Scope of import", "Structure and data"), d->importTypeGroupBox));
0426     d->importTypeStructureAndDataCheckBox->setChecked(true);
0427 
0428     importTypeGroupBoxLyr->addWidget(
0429         d->importTypeStructureOnlyCheckBox = new QRadioButton(
0430             xi18nc("Scope of import", "Structure only"), d->importTypeGroupBox));
0431 
0432     importTypeGroupBoxLyr->addStretch(1);
0433     d->importTypeGroupBox->setLayout(importTypeGroupBoxLyr);
0434 
0435     d->importTypePageItem = new KPageWidgetItem(d->importTypePageWidget,
0436                                                 xi18n("Select Scope of Import"));
0437     addPage(d->importTypePageItem);
0438 }
0439 
0440 //===========================================================
0441 //
0442 void ImportWizard::setupImporting()
0443 {
0444     d->importingPageWidget = new QWidget(this);
0445     d->importingPageWidget->hide();
0446     QVBoxLayout *vbox = new QVBoxLayout(d->importingPageWidget);
0447     KexiUtils::setStandardMarginsAndSpacing(vbox);
0448     d->lblImportingTxt = new QLabel(d->importingPageWidget);
0449     d->lblImportingTxt->setAlignment(Qt::AlignTop | Qt::AlignLeft);
0450     d->lblImportingTxt->setWordWrap(true);
0451     d->lblImportingTxt->setTextFormat(Qt::RichText);
0452 
0453     d->lblImportingErrTxt = new QLabel(d->importingPageWidget);
0454     d->lblImportingErrTxt->setAlignment(Qt::AlignTop | Qt::AlignLeft);
0455     d->lblImportingErrTxt->setWordWrap(true);
0456     d->lblImportingErrTxt->setTextFormat(Qt::RichText);
0457 
0458     d->progressBar = new QProgressBar(d->importingPageWidget);
0459     d->progressBar->setRange(0, 100);
0460     d->progressBar->hide();
0461 
0462     vbox->addWidget(d->lblImportingTxt);
0463     vbox->addWidget(d->lblImportingErrTxt);
0464     vbox->addStretch(1);
0465 
0466     QWidget *options_widget = new QWidget(d->importingPageWidget);
0467     vbox->addWidget(options_widget);
0468     QVBoxLayout *options_vbox = new QVBoxLayout(options_widget);
0469     options_vbox->setSpacing(KexiUtils::spacingHint());
0470     QHBoxLayout *importOptionsButtonLyr = new QHBoxLayout;
0471     options_vbox->addLayout(importOptionsButtonLyr);
0472     d->importOptionsButton = new QPushButton(koIcon("configure"),
0473                                              xi18n("Advanced Options"), options_widget);
0474     connect(d->importOptionsButton, SIGNAL(clicked()),
0475             this, SLOT(slotOptionsButtonClicked()));
0476     importOptionsButtonLyr->addStretch(1);
0477     importOptionsButtonLyr->addWidget(d->importOptionsButton);
0478     importOptionsButtonLyr->addStretch(1);
0479     options_vbox->addStretch(1);
0480 
0481     vbox->addWidget(d->progressBar);
0482     vbox->addStretch(2);
0483     d->importingPageWidget->show();
0484 
0485     d->importingPageItem = new KPageWidgetItem(d->importingPageWidget, xi18n("Importing"));
0486     addPage(d->importingPageItem);
0487 }
0488 
0489 //===========================================================
0490 //
0491 void ImportWizard::setupFinish()
0492 {
0493     d->finishPageWidget = new QWidget(this);
0494     d->finishPageWidget->hide();
0495     QVBoxLayout *vbox = new QVBoxLayout(d->finishPageWidget);
0496     KexiUtils::setStandardMarginsAndSpacing(vbox);
0497     d->finishLbl = new QLabel(d->finishPageWidget);
0498     d->finishLbl->setAlignment(Qt::AlignTop | Qt::AlignLeft);
0499     d->finishLbl->setWordWrap(true);
0500     d->finishLbl->setTextFormat(Qt::RichText);
0501 
0502     vbox->addWidget(d->finishLbl);
0503     d->openImportedProjectCheckBox = new QCheckBox(xi18n("Open imported project"),
0504             d->finishPageWidget);
0505     d->openImportedProjectCheckBox->setChecked(true);
0506     vbox->addSpacing(KexiUtils::spacingHint());
0507     vbox->addWidget(d->openImportedProjectCheckBox);
0508     vbox->addStretch(1);
0509 
0510     d->finishPageItem = new KPageWidgetItem(d->finishPageWidget, xi18n("Success"));
0511     addPage(d->finishPageItem);
0512 }
0513 
0514 //===========================================================
0515 //
0516 bool ImportWizard::checkUserInput()
0517 {
0518     KLocalizedString issues;
0519 
0520     if (d->dstNewDBCaptionLineEdit->text().isEmpty()) {
0521         issues = kxi18nc("@info", "<para>No new database name was entered.</para>");
0522     }
0523 
0524     Kexi::ObjectStatus result;
0525     KexiMigrate* sourceDriver = prepareImport(result);
0526     if (sourceDriver && sourceDriver->isSourceAndDestinationDataSourceTheSame()) {
0527         KLocalizedString sameDbIssue = kxi18nc("@info", "%1<para>Source database is the same as destination.</para>");
0528         issues = issues.isEmpty() ? sameDbIssue.subs("") : sameDbIssue.subs(issues);
0529     }
0530 
0531     if (!issues.isEmpty()) {
0532         d->lblImportingErrTxt->setText(
0533             xi18nc("@info", "<para>Following issues were found with the data you entered:</para>"
0534                    "%1"
0535                    "<para>Please click <interface>Back</interface> button and correct these issues.</para>",
0536                    issues));
0537         return false;
0538     }
0539     return true;
0540 }
0541 
0542 void ImportWizard::arriveSrcConnPage()
0543 {
0544     d->srcConnPageWidget->hide();
0545 
0546     /*! @todo KexiFileWidget needs "open file" and "open server" modes
0547     in addition to just "open" */
0548     if (d->setupFileBasedSrcNeeded) {
0549         d->setupFileBasedSrcNeeded = false;
0550         d->srcConn->setFileMode(KexiFileFilters::Opening);
0551         d->srcConn->setAdditionalMimeTypes(QStringList());
0552     }
0553 
0554     /*! @todo Support different file extensions based on MigrationDriver */
0555     d->srcConnPageWidget->show();
0556 }
0557 
0558 void ImportWizard::arriveSrcDBPage()
0559 {
0560     if (fileBasedSrcSelected()) {
0561         //! @todo Back button doesn't work after selecting a file to import
0562     }
0563     else {
0564         if (!d->srcProjectSelector) {
0565             QVBoxLayout *vbox = new QVBoxLayout(d->srcDBPageWidget);
0566             d->srcProjectSelector = new KexiProjectSelectorWidget(d->srcDBPageWidget);
0567             vbox->addWidget(d->srcProjectSelector);
0568             KexiUtils::setStandardMarginsAndSpacing(vbox);
0569             d->srcProjectSelector->label()->setText(xi18n("Select source database you wish to import:"));
0570         }
0571         d->srcDBPageWidget->hide();
0572         KDbConnectionData* condata = d->srcConn->selectedConnectionData();
0573         Q_ASSERT(condata);
0574         Q_ASSERT(d->prjSet);
0575         d->srcProjectSelector->setProjectSet(d->prjSet);
0576         d->srcDBPageWidget->show();
0577     }
0578 }
0579 
0580 void ImportWizard::arriveDstCaptionPage()
0581 {
0582     d->dstNewDBNameUrlLabel->setVisible(fileBasedDstSelected());
0583     d->dstNewDBNameUrl->setVisible(fileBasedDstSelected());
0584     d->dstNewDBNameLabel->setVisible(!fileBasedDstSelected());
0585     d->dstNewDBNameLineEdit->setVisible(!fileBasedDstSelected());
0586     if (fileBasedSrcSelected()) {
0587         const QString fname(selectedSourceFileName());
0588         QString suggestedDBName(QFileInfo(fname).fileName());
0589         const QFileInfo fi(suggestedDBName);
0590         suggestedDBName = suggestedDBName.left(suggestedDBName.length()
0591                                                - (fi.completeSuffix().isEmpty() ? 0 : (fi.completeSuffix().length() + 1)));
0592         d->dstNewDBCaptionLineEdit->setText(suggestedDBName);
0593     }
0594     else {
0595         if (d->predefinedConnectionData) {
0596             // server source db is predefined
0597             d->dstNewDBCaptionLineEdit->setText(d->predefinedDatabaseName);
0598         } else {
0599             if (!d->srcProjectSelector || !d->srcProjectSelector->selectedProjectData()) {
0600                 back(); //!< @todo
0601                 return;
0602             }
0603             d->dstNewDBCaptionLineEdit->setText(d->srcProjectSelector->selectedProjectData()->databaseName());
0604         }
0605     }
0606     d->dstNewDBCaptionLineEdit->selectAll();
0607     d->dstNewDBCaptionLineEdit->setFocus();
0608     updateDestinationDBFileName();
0609 }
0610 
0611 void ImportWizard::arriveDstPage()
0612 {
0613     if (fileBasedDstSelected()) {
0614         d->dstPageWidget->hide();
0615         KAssistantDialog::next();
0616         return;
0617     }
0618     else {
0619         d->dstConn->showAdvancedConnection();
0620     }
0621     d->dstPageWidget->show();
0622 }
0623 
0624 void ImportWizard::arriveImportingPage()
0625 {
0626     d->importingPageWidget->hide();
0627     nextButton()->setEnabled(checkUserInput());
0628     d->lblImportingTxt->setText(xi18nc("@info",
0629                                    "<para>All required information has now "
0630                                    "been gathered. Click <interface>Next</interface> button to start importing.</para>"
0631                                    "<para><note>Depending on size of the database this may take some time.</note></para>"
0632                                    /*"Note: You may be asked for extra "
0633                                    "information such as field types if "
0634                                    "the wizard could not automatically "
0635                                    "determine this for you."*/));
0636 
0637     //temp. hack for MS Access driver only
0638 //! @todo for other databases we will need KexiMigration::Connection
0639 //!       and KexiMigration::Driver classes
0640     bool showOptions = false;
0641     if (fileBasedSrcSelected()) {
0642         Kexi::ObjectStatus result;
0643         KexiMigrate* sourceDriver = prepareImport(result);
0644         if (sourceDriver) {
0645             showOptions = !result.error()
0646                           && sourceDriver->propertyValue("source_database_has_nonunicode_encoding").toBool();
0647             sourceDriver->setData(nullptr);
0648         }
0649     }
0650     if (showOptions)
0651         d->importOptionsButton->show();
0652     else
0653         d->importOptionsButton->hide();
0654 
0655     d->importingPageWidget->show();
0656 }
0657 
0658 void ImportWizard::arriveFinishPage()
0659 {
0660 }
0661 
0662 bool ImportWizard::fileBasedSrcSelected() const
0663 {
0664     if (d->predefinedConnectionData)
0665         return false;
0666 
0667 // qDebug() << (d->srcConn->selectedConnectionType()==KexiConnectionSelectorWidget::FileBased);
0668     return d->srcConn->selectedConnectionType() == KexiConnectionSelectorWidget::FileBased;
0669 }
0670 
0671 bool ImportWizard::fileBasedDstSelected() const
0672 {
0673     return d->dstPrjTypeSelector->option_file->isChecked();
0674 }
0675 
0676 void ImportWizard::progressUpdated(int percent)
0677 {
0678     d->progressBar->setValue(percent);
0679     qApp->processEvents();
0680 }
0681 
0682 QString ImportWizard::driverIdForMimeType(const QMimeType &mime) const
0683 {
0684     if (!mime.isValid()) {
0685         return QString();
0686     }
0687     const QStringList ids(d->migrateManager.driverIdsForMimeType(mime.name()));
0688     //! @todo do we want to return first migrate driver for the mime type or allow to select it?
0689     return ids.isEmpty() ? QString() : ids.first();
0690 }
0691 
0692 QString ImportWizard::findDriverIdForSelectedSource()
0693 {
0694     if (fileBasedSrcSelected()) {
0695         QMimeDatabase db;
0696         QMimeType mime = db.mimeTypeForFile(selectedSourceFileName());
0697         if (!mime.isValid()
0698                 || mime.name() == "application/octet-stream"
0699                 || mime.name() == "text/plain"
0700                 || mime.name() == "application/zip")
0701         {
0702             //try by URL:
0703             mime = db.mimeTypeForFile(selectedSourceFileName());
0704         }
0705         return driverIdForMimeType(mime);
0706     }
0707 
0708     //server-based
0709     QString sourceDriverId;
0710     if (d->predefinedConnectionData) {
0711         sourceDriverId = d->predefinedConnectionData->driverId();
0712     } else if (d->srcConn->selectedConnectionData()) {
0713         sourceDriverId = d->srcConn->selectedConnectionData()->driverId();
0714     }
0715     const QStringList migrationDriverIds(d->migrateManager.driverIdsForSourceDriver(sourceDriverId));
0716 
0717     //! @todo First found driver ID is picked. It's OK as long as there is one migration
0718     //! driver per source database type. How about allowing users to pick migration driver?
0719     return migrationDriverIds.isEmpty() ? QString() : migrationDriverIds.first();
0720 }
0721 
0722 //===========================================================
0723 //
0724 void ImportWizard::accept()
0725 {
0726     if (d->args) {
0727         if ((!fileBasedDstSelected() && !d->args->contains("destinationConnectionShortcut"))
0728                 || !d->openImportedProjectCheckBox->isChecked()) {
0729             //do not open dest db if used didn't want it
0730             //for server connections, destinationConnectionShortcut must be defined
0731             d->args->remove("destinationDatabaseName");
0732         }
0733     }
0734     KAssistantDialog::accept();
0735 }
0736 
0737 KexiMigrate* ImportWizard::prepareImport(Kexi::ObjectStatus& result)
0738 {
0739     KexiUtils::WaitCursor wait;
0740 
0741     // Start with a driver manager
0742     KDbDriverManager manager;
0743 
0744     //qDebug() << "Creating destination driver...";
0745 
0746     // Get a driver to the destination database
0747     KDbDriver *destDriver = manager.driver(
0748                         d->dstConn->selectedConnectionData()
0749                         ? d->dstConn->selectedConnectionData()->driverId()
0750                         : KDb::defaultFileBasedDriverId());
0751     if (!destDriver || manager.result().isError()) {
0752         result.setStatus(manager.resultable());
0753         qWarning() << "Manager error:" << manager.result();
0754     }
0755 
0756     // Set up destination connection data
0757     KDbConnectionData *cdata = 0;
0758     QScopedPointer<KDbConnectionData> cdataDeleter;
0759     QString dbname;
0760     if (!result.error()) {
0761         if (d->dstConn->selectedConnectionData()) {
0762             //server-based project
0763             qDebug() << "Server destination...";
0764             cdata = d->dstConn->selectedConnectionData();
0765             dbname = d->dstNewDBNameLineEdit->text();
0766         }
0767         else {
0768             //file-based project
0769             qDebug() << "File Destination...";
0770             cdata = new KDbConnectionData();
0771             cdataDeleter.reset(cdata); // ownership won't be transferred
0772             cdata->setCaption(d->dstNewDBCaptionLineEdit->text());
0773             cdata->setDriverId(KDb::defaultFileBasedDriverId());
0774             dbname = d->dstCaptionPageWidget->file_requester->url().toLocalFile();
0775             cdata->setDatabaseName(dbname);
0776             qDebug() << "Current file name:" << dbname;
0777         }
0778     }
0779 
0780     // Find a source (migration) driver name
0781     if (!result.error()) {
0782         if (d->driverIdForSelectedSource.isEmpty())
0783             result.setStatus(xi18n("No appropriate migration driver found."),
0784                              d->migrateManager.possibleProblemsMessage());
0785     }
0786 
0787     // Get a source (migration) driver
0788     KexiMigrate* sourceDriver = 0;
0789     if (!result.error()) {
0790         sourceDriver = d->migrateManager.driver(d->driverIdForSelectedSource);
0791         if (!sourceDriver || d->migrateManager.result().isError()) {
0792             qDebug() << "Import migrate driver error...";
0793             result.setStatus(d->migrateManager.resultable());
0794         }
0795     }
0796 
0797     KexiUtils::removeWaitCursor();
0798 
0799     // Set up source (migration) data required for connection
0800     if (sourceDriver && !result.error() && cdata) {
0801         // Setup progress feedback for the GUI
0802         if (sourceDriver->progressSupported()) {
0803             d->progressBar->updateGeometry();
0804             disconnect(sourceDriver, SIGNAL(progressPercent(int)),
0805                        this, SLOT(progressUpdated(int)));
0806             connect(sourceDriver, SIGNAL(progressPercent(int)),
0807                     this, SLOT(progressUpdated(int)));
0808             progressUpdated(0);
0809         }
0810 
0811         bool keepData;
0812         if (d->importTypeStructureAndDataCheckBox->isChecked()) {
0813             qDebug() << "Structure and data selected";
0814             keepData = true;
0815         } else if (d->importTypeStructureOnlyCheckBox->isChecked()) {
0816             qDebug() << "structure only selected";
0817             keepData = false;
0818         } else {
0819             qDebug() << "Neither radio button is selected (not possible?) presume keep data";
0820             keepData = true;
0821         }
0822 
0823         KexiMigration::Data* md = new KexiMigration::Data();
0824         md->setDestinationProjectData(new KexiProjectData(*cdata, dbname));
0825         if (fileBasedSrcSelected()) {
0826             KDbConnectionData* conn_data = new KDbConnectionData();
0827             conn_data->setDatabaseName(selectedSourceFileName());
0828             md->source = conn_data;
0829             md->sourceName.clear();
0830         } else {
0831             if (d->predefinedConnectionData)
0832                 md->source = d->predefinedConnectionData;
0833             else
0834                 md->source = d->srcConn->selectedConnectionData();
0835 
0836             if (!d->predefinedDatabaseName.isEmpty())
0837                 md->sourceName = d->predefinedDatabaseName;
0838             else
0839                 md->sourceName = d->srcProjectSelector->selectedProjectData()->databaseName();
0840             //! @todo Aah, this is so C-like. Move to performImport().
0841         }
0842         md->setShouldCopyData(keepData);
0843         sourceDriver->setData(md);
0844         return sourceDriver;
0845     }
0846     return 0;
0847 }
0848 
0849 tristate ImportWizard::import()
0850 {
0851     d->importExecuted = true;
0852     Kexi::ObjectStatus result;
0853     KexiMigrate* sourceDriver = prepareImport(result);
0854     bool acceptingNeeded = false;
0855 
0856     // Perform import
0857     if (sourceDriver && !result.error()) {
0858         if (!d->sourceDBEncoding.isEmpty()) {
0859             sourceDriver->setPropertyValue("source_database_nonunicode_encoding",
0860                                            QVariant(d->sourceDBEncoding.toUpper().remove(' ')) // "CP1250", not "cp 1250"
0861                                           );
0862         }
0863         if (!sourceDriver->checkIfDestinationDatabaseOverwritingNeedsAccepting(&result, &acceptingNeeded)) {
0864             qDebug() << "Abort import cause checkIfDestinationDatabaseOverwritingNeedsAccepting "
0865             "returned false.";
0866             return false;
0867         }
0868 
0869         qDebug() << sourceDriver->data()->destinationProjectData()->databaseName();
0870         qDebug() << "Performing import...";
0871     }
0872 
0873     if (sourceDriver && !result.error() && acceptingNeeded) {
0874         // ok, the destination-db already exists...
0875         if (KMessageBox::Yes != KMessageBox::warningYesNo(this,
0876                         xi18nc("@info (don't add tags around %1, it's done already)",
0877                                "<para>Database %1 already exists.</para>"
0878                                "<para>Do you want to replace it with a new one?</para>",
0879                                KexiUtils::localizedStringToHtmlSubstring(
0880                                    sourceDriver->data()->destinationProjectData()->infoString())),
0881                 0, KGuiItem(xi18nc("@action:button Replace Database", "&Replace")), KStandardGuiItem::no()))
0882         {
0883             return cancelled;
0884         }
0885     }
0886 
0887     if (sourceDriver && !result.error() && sourceDriver->progressSupported()) {
0888         d->progressBar->show();
0889     }
0890 
0891     if (sourceDriver && !result.error() && sourceDriver->performImport(&result)) {
0892         if (d->args) {
0893             d->args->insert("destinationDatabaseName",
0894                             fileBasedDstSelected()
0895                             ? sourceDriver->data()->destinationProjectData()->connectionData()->databaseName()
0896                             : sourceDriver->data()->destinationProjectData()->databaseName());
0897             QString destinationConnectionShortcut;
0898             if (d->dstConn->selectedConnectionData()) {
0899                 destinationConnectionShortcut
0900                     = Kexi::connset().fileNameForConnectionData(*d->dstConn->selectedConnectionData());
0901             }
0902             if (!destinationConnectionShortcut.isEmpty()) {
0903                 d->args->insert("destinationConnectionShortcut", destinationConnectionShortcut);
0904             }
0905         }
0906         d->finishPageItem->setHeader(xi18n("Success"));
0907         return true;
0908     }
0909 
0910     if (!sourceDriver || result.error()) {
0911         d->progressBar->setValue(0);
0912         d->progressBar->hide();
0913 
0914         QString msg, details;
0915         KexiTextMessageHandler handler(&msg, &details);
0916         handler.showErrorMessage(&result);
0917 
0918         qDebug() << msg << "\n" << details;
0919 
0920         d->finishPageItem->setHeader(xi18n("Failure"));
0921         // note: we're using QString.arg() here because the msg and details
0922         // arguments are already in rich-text format, but leaving out the
0923         // arguments from xi18nc writes (I18N_ARGUMENT_MISSING). Thus, first
0924         // replace %n with themselves to avoid ki18n warning and then call
0925         // QString.arg() to replace them with HTML text.
0926         d->finishLbl->setText(
0927             xi18nc("@info",
0928                    "<para>Import failed.</para>"
0929                    "<para>%1</para>"
0930                    "<para>%2</para>"
0931                    "<para>You can click <interface>Back</interface> button and try again.</para>",
0932                     "%1", "%2").arg(msg).arg(details));
0933         return false;
0934     }
0935     return true;
0936 }
0937 
0938 void ImportWizard::reject()
0939 {
0940     KAssistantDialog::reject();
0941 }
0942 
0943 //===========================================================
0944 //
0945 void ImportWizard::next()
0946 {
0947     if (currentPage() == d->srcConnPageItem) {
0948         if (fileBasedSrcSelected()
0949                 && /*! @todo use QUrl? */!QFileInfo(selectedSourceFileName()).isFile()) {
0950 
0951             KMessageBox::sorry(this, xi18n("Select source database filename."));
0952             return;
0953         }
0954 
0955         KDbConnectionData* conndata = d->srcConn->selectedConnectionData();
0956         if (!fileBasedSrcSelected() && !conndata) {
0957             KMessageBox::sorry(this, xi18n("Select source database."));
0958             return;
0959         }
0960 
0961         d->driverIdForSelectedSource = findDriverIdForSelectedSource(); // cache
0962         KexiMigrate* import = d->migrateManager.driver(d->driverIdForSelectedSource);
0963         if (!import || d->migrateManager.result().isError()) {
0964             QString dbname;
0965             if (fileBasedSrcSelected())
0966                 dbname = QDir::toNativeSeparators(selectedSourceFileName());
0967             else
0968                 dbname = conndata ? conndata->toUserVisibleString() : QString();
0969             KMessageBox::error(this,
0970                                dbname.isEmpty() ?
0971                                xi18n("Could not import database. This type is not supported.")
0972                                : xi18nc("@info",
0973                                         "Could not import database <resource>%1</resource>. "
0974                                         "This type is not supported.", dbname));
0975             return;
0976         }
0977 
0978         if (!fileBasedSrcSelected()) {
0979             // make sure we have password if needed
0980             tristate passwordNeeded = false;
0981             if (conndata->password().isEmpty()) {
0982                 passwordNeeded = KexiDBPasswordDialog::getPasswordIfNeeded(conndata, this);
0983             }
0984             bool ok = passwordNeeded != cancelled;
0985             if (ok) {
0986                 KexiGUIMessageHandler handler;
0987                 d->prjSet = new KexiProjectSet(&handler);
0988                 if (!d->prjSet->setConnectionData(conndata)) {
0989                     handler.showErrorMessage(d->prjSet->result());
0990                     ok = false;
0991                 }
0992             }
0993             if (!ok) {
0994                 if (passwordNeeded == true) {
0995                     conndata->setPassword(QString()); // not clear(), we have to remove password
0996                 }
0997                 delete d->prjSet;
0998                 d->prjSet = 0;
0999                 return;
1000             }
1001         }
1002     } else if (currentPage() == d->dstCaptionPageItem) {
1003         if (fileBasedDstSelected()) {
1004             if (QFileInfo::exists(d->dstNewDBNameUrl->url().toLocalFile())) {
1005                 if (!KexiUtils::askForFileOverwriting(d->dstNewDBNameUrl->url().toLocalFile(), this)) {
1006                     return;
1007                 }
1008             }
1009         }
1010     } else if (currentPage() == d->importTypePageItem) {
1011         if (!fileBasedDstSelected()) {
1012             // make sure we have password if needed
1013             tristate passwordNeeded = false;
1014             KDbConnectionData* condata = d->dstConn->selectedConnectionData();
1015             if (condata->password().isEmpty()) {
1016                 passwordNeeded = KexiDBPasswordDialog::getPasswordIfNeeded(condata, this);
1017             }
1018             bool ok = passwordNeeded != cancelled;
1019             if (!ok) {
1020                 if (passwordNeeded == true) {
1021                     condata->setPassword(QString()); // not clear(), we have to remove password
1022                 }
1023                 return;
1024             }
1025         }
1026     } else if (currentPage() == d->importingPageItem) {
1027         if (!d->importExecuted) {
1028             d->importOptionsButton->hide();
1029             backButton()->setEnabled(false);
1030             nextButton()->setEnabled(false);
1031             finishButton()->setEnabled(false);
1032             d->lblImportingTxt->setText(xi18n("Importing in progress..."));
1033             tristate res = import();
1034             if (true == res) {
1035                 d->finishLbl->setText(
1036                     xi18nc("@info",
1037                            "Database has been imported into Kexi project <resource>%1</resource>.",
1038                            d->dstNewDBNameLineEdit->text()));
1039                 button(QDialogButtonBox::Cancel)->setEnabled(false);
1040                 backButton()->setEnabled(false);
1041                 nextButton()->setEnabled(true);
1042                 finishButton()->setEnabled(false);
1043                 d->openImportedProjectCheckBox->show();
1044                 next();
1045                 return;
1046             }
1047 
1048             d->progressBar->hide();
1049 
1050             button(QDialogButtonBox::Cancel)->setEnabled(true);
1051             backButton()->setEnabled(true);
1052             nextButton()->setEnabled(false);
1053             finishButton()->setEnabled(false);
1054 
1055             d->openImportedProjectCheckBox->hide();
1056             if (!res)
1057                 next();
1058             else if (~res) {
1059                 arriveImportingPage();
1060             }
1061             d->importExecuted = false;
1062             return;
1063         }
1064     }
1065 
1066     setAppropriate(d->srcDBPageItem, !fileBasedSrcSelected() && !d->predefinedConnectionData);
1067     setAppropriate(d->dstPageItem, !fileBasedDstSelected());
1068     KAssistantDialog::next();
1069 }
1070 
1071 void ImportWizard::back()
1072 {
1073     setAppropriate(d->srcDBPageItem, !fileBasedSrcSelected() && !d->predefinedConnectionData);
1074     KAssistantDialog::back();
1075 }
1076 
1077 void ImportWizard::slot_currentPageChanged(KPageWidgetItem* curPage,KPageWidgetItem* prevPage)
1078 {
1079     Q_UNUSED(prevPage);
1080     if (curPage == d->introPageItem) {
1081     }
1082     else if (curPage == d->srcConnPageItem) {
1083         arriveSrcConnPage();
1084     } else if (curPage == d->srcDBPageItem) {
1085         arriveSrcDBPage();
1086     } else if (curPage == d->dstTypePageItem) {
1087     } else if (curPage == d->dstCaptionPageItem) {
1088         arriveDstCaptionPage();
1089     } else if (curPage == d->dstPageItem) {
1090         if (fileBasedDstSelected()) {
1091             if (prevPage == d->importTypePageItem) {
1092                 KAssistantDialog::back();
1093             }
1094             else {
1095                 KAssistantDialog::next();
1096             }
1097         }
1098         else {
1099             arriveDstPage();
1100         }
1101     } else if (curPage == d->importingPageItem) {
1102         arriveImportingPage();
1103     } else if (curPage == d->finishPageItem) {
1104         arriveFinishPage();
1105     }
1106 }
1107 
1108 void ImportWizard::helpClicked()
1109 {
1110     if (currentPage() == d->introPageItem) {
1111         KMessageBox::information(this, xi18n("No help is available for this page."), xi18n("Help"));
1112     }
1113     else if (currentPage() == d->srcConnPageItem) {
1114         KMessageBox::information(this, xi18n("Here you can choose the location to import data from."), xi18n("Help"));
1115     } else if (currentPage() == d->srcDBPageItem) {
1116         KMessageBox::information(this, xi18n("Here you can choose the actual database to import data from."), xi18n("Help"));
1117     } else if (currentPage() == d->dstTypePageItem) {
1118         KMessageBox::information(this, xi18n("Here you can choose the location to save the data."), xi18n("Help"));
1119     } else if (currentPage() == d->dstPageItem) {
1120         KMessageBox::information(this, xi18n("Here you can choose the location to save the data in and the new database name."), xi18n("Help"));
1121     } else if (currentPage() == d->finishPageItem || currentPage() == d->importingPageItem) {
1122         KMessageBox::information(this, xi18n("No help is available for this page."), xi18n("Help"));
1123     }
1124 }
1125 
1126 void ImportWizard::slotOptionsButtonClicked()
1127 {
1128     OptionsDialog dlg(selectedSourceFileName(), d->sourceDBEncoding, this);
1129     if (QDialog::Accepted == dlg.exec()) {
1130         d->sourceDBEncoding = dlg.encodingComboBox()->selectedEncoding();
1131     }
1132 }
1133 
1134 void ImportWizard::sourceConnectionSelected(bool selected)
1135 {
1136     if (selected) {
1137         next();
1138     }
1139 }