File indexing completed on 2024-05-12 16:40:14
0001 /* This file is part of the KDE project 0002 Copyright (C) 2009 Adam Pigg <adam@piggz.co.uk> 0003 Copyright (C) 2014-2016 Jarosław Staniek <staniek@kde.org> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License version 2 as published by the Free Software Foundation. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "importtablewizard.h" 0021 #include "importoptionsdlg.h" 0022 #include "migratemanager.h" 0023 #include "keximigrate.h" 0024 #include "keximigratedata.h" 0025 #include "AlterSchemaWidget.h" 0026 #include <KexiIcon.h> 0027 #include <core/kexidbconnectionset.h> 0028 #include <core/kexi.h> 0029 #include <core/kexipartmanager.h> 0030 #include <kexiutils/utils.h> 0031 #include <kexidbdrivercombobox.h> 0032 #include <kexitextmsghandler.h> 0033 #include <kexipart.h> 0034 #include <KexiMainWindowIface.h> 0035 #include <kexiproject.h> 0036 #include <widget/kexicharencodingcombobox.h> 0037 #include <widget/kexiprjtypeselector.h> 0038 #include <widget/KexiConnectionSelectorWidget.h> 0039 #include <widget/KexiProjectSelectorWidget.h> 0040 #include <widget/KexiDBCaptionPage.h> 0041 #include <widget/KexiNameWidget.h> 0042 0043 #include <KDbConnectionData> 0044 #include <KDbDriver> 0045 #include <KDbDriverManager> 0046 #include <KDbSqlResult> 0047 #include <KDbTransactionGuard> 0048 #include <KDbUtils> 0049 0050 #include <KMessageBox> 0051 0052 #include <QSet> 0053 #include <QVBoxLayout> 0054 #include <QListWidget> 0055 #include <QStringList> 0056 #include <QProgressBar> 0057 #include <QCheckBox> 0058 #include <QMimeDatabase> 0059 #include <QMimeType> 0060 #include <QPushButton> 0061 #include <QDebug> 0062 0063 using namespace KexiMigration; 0064 0065 #define RECORDS_FOR_PREVIEW 3 0066 0067 ImportTableWizard::ImportTableWizard ( KDbConnection* curDB, QWidget* parent, QMap<QString, QString>* args, Qt::WindowFlags flags) 0068 : KAssistantDialog ( parent, flags ), 0069 m_args(args) 0070 { 0071 m_connection = curDB; 0072 m_migrateDriver = 0; 0073 m_prjSet = 0; 0074 m_importComplete = false; 0075 m_importWasCanceled = false; 0076 m_sourceDbEncoding = QString::fromLatin1(KexiUtils::encoding()); //default 0077 0078 KexiMainWindowIface::global()->setReasonableDialogSize(this); 0079 0080 setupIntroPage(); 0081 setupSrcConn(); 0082 setupSrcDB(); 0083 setupTableSelectPage(); 0084 setupAlterTablePage(); 0085 setupImportingPage(); 0086 setupProgressPage(); 0087 setupFinishPage(); 0088 0089 setValid(m_srcConnPageItem, false); 0090 0091 connect(this, SIGNAL(currentPageChanged(KPageWidgetItem*,KPageWidgetItem*)), this, SLOT(slot_currentPageChanged(KPageWidgetItem*,KPageWidgetItem*))); 0092 //! @todo Change this to message prompt when we move to non-dialog wizard. 0093 connect(m_srcConnSel, SIGNAL(connectionSelected(bool)), this, 0094 SLOT(slotConnPageItemSelected(bool))); 0095 connect(m_srcConnSel, &KexiConnectionSelectorWidget::connectionItemHighlighted, 0096 [this]() { setValid(m_srcConnPageItem, true); }); 0097 connect(m_srcConnSel, &KexiConnectionSelectorWidget::connectionItemExecuted, [this]() { 0098 setValid(m_srcConnPageItem, true); 0099 next(); 0100 }); 0101 } 0102 0103 0104 ImportTableWizard::~ImportTableWizard() 0105 { 0106 delete m_prjSet; 0107 delete m_srcConnSel; 0108 } 0109 0110 void ImportTableWizard::back() { 0111 KAssistantDialog::back(); 0112 } 0113 0114 void ImportTableWizard::next() { 0115 if (currentPage() == m_srcConnPageItem) { 0116 if (fileBasedSrcSelected()) { 0117 setAppropriate(m_srcDBPageItem, false); 0118 } else { 0119 setAppropriate(m_srcDBPageItem, true); 0120 } 0121 } else if (currentPage() == m_alterTablePageItem) { 0122 if (m_alterSchemaWidget->nameExists(m_alterSchemaWidget->nameWidget()->nameText())) { 0123 KMessageBox::information(this, 0124 xi18nc("@info", 0125 "<resource>%1</resource> name is already used by an existing table. " 0126 "Enter different table name to continue.", 0127 m_alterSchemaWidget->nameWidget()->nameText()), 0128 xi18n("Name Already Used")); 0129 return; 0130 } 0131 } 0132 0133 KAssistantDialog::next(); 0134 } 0135 0136 void ImportTableWizard::accept() { 0137 if (m_args) { 0138 if (m_finishCheckBox->isChecked()) { 0139 m_args->insert("destinationTableName",m_alterSchemaWidget->nameWidget()->nameText()); 0140 } else { 0141 m_args->remove("destinationTableName"); 0142 } 0143 } 0144 0145 QDialog::accept(); 0146 } 0147 0148 void ImportTableWizard::reject() { 0149 QDialog::reject(); 0150 } 0151 0152 //=========================================================== 0153 // 0154 void ImportTableWizard::setupIntroPage() 0155 { 0156 m_introPageWidget = new QWidget(this); 0157 QVBoxLayout *vbox = new QVBoxLayout(); 0158 0159 m_introPageWidget->setLayout(vbox); 0160 0161 KexiUtils::setStandardMarginsAndSpacing(vbox); 0162 0163 QLabel *lblIntro = new QLabel(m_introPageWidget); 0164 lblIntro->setAlignment(Qt::AlignTop | Qt::AlignLeft); 0165 lblIntro->setWordWrap(true); 0166 lblIntro->setText( 0167 xi18nc("@info", 0168 "<para>Table Importing Assistant allows you to import a table from an existing " 0169 "database into the current Kexi project.</para>" 0170 "<para>Click <interface>Next</interface> button to continue or " 0171 "<interface>Cancel</interface> button to exit this assistant.</para>")); 0172 vbox->addWidget(lblIntro); 0173 0174 m_introPageItem = new KPageWidgetItem(m_introPageWidget, 0175 xi18n("Welcome to the Table Importing Assistant")); 0176 addPage(m_introPageItem); 0177 } 0178 0179 void ImportTableWizard::setupSrcConn() 0180 { 0181 m_srcConnPageWidget = new QWidget(this); 0182 QVBoxLayout *vbox = new QVBoxLayout(m_srcConnPageWidget); 0183 0184 m_srcConnSel = new KexiConnectionSelectorWidget(&Kexi::connset(), 0185 QUrl("kfiledialog:///ProjectMigrationSourceDir"), 0186 KexiConnectionSelectorWidget::Opening, m_srcConnPageWidget); 0187 0188 m_srcConnSel->hideConnectonIcon(); 0189 m_srcConnSel->showSimpleConnection(); 0190 0191 //! @todo remove when support for kexi files as source prj is added in migration 0192 const QStringList excludedMimeTypes({ 0193 KDb::defaultFileBasedDriverMimeType(), 0194 "application/x-kexiproject-shortcut", 0195 "application/x-kexi-connectiondata"}); 0196 m_srcConnSel->setExcludedMimeTypes(excludedMimeTypes); 0197 0198 vbox->addWidget(m_srcConnSel); 0199 0200 m_srcConnPageItem = new KPageWidgetItem(m_srcConnPageWidget, xi18n("Select Location for Source Database")); 0201 addPage(m_srcConnPageItem); 0202 } 0203 0204 void ImportTableWizard::setupSrcDB() 0205 { 0206 // arrivesrcdbPage creates widgets on that page 0207 m_srcDBPageWidget = new QWidget(this); 0208 m_srcDBName = NULL; 0209 0210 m_srcDBPageItem = new KPageWidgetItem(m_srcDBPageWidget, xi18n("Select Source Database")); 0211 addPage(m_srcDBPageItem); 0212 } 0213 0214 0215 void ImportTableWizard::setupTableSelectPage() { 0216 m_tablesPageWidget = new QWidget(this); 0217 QVBoxLayout *vbox = new QVBoxLayout(m_tablesPageWidget); 0218 KexiUtils::setStandardMarginsAndSpacing(vbox); 0219 0220 m_tableListWidget = new QListWidget(this); 0221 m_tableListWidget->setSelectionMode(QAbstractItemView::SingleSelection); 0222 connect(m_tableListWidget, SIGNAL(itemSelectionChanged()), 0223 this, SLOT(slotTableListWidgetSelectionChanged())); 0224 0225 vbox->addWidget(m_tableListWidget); 0226 0227 m_tablesPageItem = new KPageWidgetItem(m_tablesPageWidget, xi18n("Select the Table to Import")); 0228 addPage(m_tablesPageItem); 0229 } 0230 0231 //=========================================================== 0232 // 0233 void ImportTableWizard::setupImportingPage() 0234 { 0235 m_importingPageWidget = new QWidget(this); 0236 m_importingPageWidget->hide(); 0237 QVBoxLayout *vbox = new QVBoxLayout(m_importingPageWidget); 0238 KexiUtils::setStandardMarginsAndSpacing(vbox); 0239 m_lblImportingTxt = new QLabel(m_importingPageWidget); 0240 m_lblImportingTxt->setAlignment(Qt::AlignTop | Qt::AlignLeft); 0241 m_lblImportingTxt->setWordWrap(true); 0242 0243 m_lblImportingErrTxt = new QLabel(m_importingPageWidget); 0244 m_lblImportingErrTxt->setAlignment(Qt::AlignTop | Qt::AlignLeft); 0245 m_lblImportingErrTxt->setWordWrap(true); 0246 0247 vbox->addWidget(m_lblImportingTxt); 0248 vbox->addWidget(m_lblImportingErrTxt); 0249 vbox->addStretch(1); 0250 0251 QWidget *options_widget = new QWidget(m_importingPageWidget); 0252 vbox->addWidget(options_widget); 0253 QVBoxLayout *options_vbox = new QVBoxLayout(options_widget); 0254 options_vbox->setSpacing(KexiUtils::spacingHint()); 0255 m_importOptionsButton = new QPushButton(koIcon("configure"), xi18n("Advanced Options"), options_widget); 0256 connect(m_importOptionsButton, SIGNAL(clicked()),this, SLOT(slotOptionsButtonClicked())); 0257 options_vbox->addWidget(m_importOptionsButton); 0258 options_vbox->addStretch(1); 0259 0260 m_importingPageWidget->show(); 0261 0262 m_importingPageItem = new KPageWidgetItem(m_importingPageWidget, xi18n("Importing")); 0263 addPage(m_importingPageItem); 0264 } 0265 0266 void ImportTableWizard::setupAlterTablePage() 0267 { 0268 m_alterTablePageWidget = new QWidget(this); 0269 m_alterTablePageWidget->hide(); 0270 0271 QVBoxLayout *vbox = new QVBoxLayout(m_alterTablePageWidget); 0272 KexiUtils::setStandardMarginsAndSpacing(vbox); 0273 0274 m_alterSchemaWidget = new KexiMigration::AlterSchemaWidget(this); 0275 vbox->addWidget(m_alterSchemaWidget); 0276 m_alterTablePageWidget->show(); 0277 0278 m_alterTablePageItem = new KPageWidgetItem(m_alterTablePageWidget, xi18n("Alter the Detected Table Design")); 0279 addPage(m_alterTablePageItem); 0280 } 0281 0282 void ImportTableWizard::setupProgressPage() 0283 { 0284 m_progressPageWidget = new QWidget(this); 0285 m_progressPageWidget->hide(); 0286 QVBoxLayout *vbox = new QVBoxLayout(m_progressPageWidget); 0287 KexiUtils::setStandardMarginsAndSpacing(vbox); 0288 m_progressPageWidget->setLayout(vbox); 0289 m_progressLbl = new QLabel(m_progressPageWidget); 0290 m_progressLbl->setAlignment(Qt::AlignTop | Qt::AlignLeft); 0291 m_progressLbl->setWordWrap(true); 0292 m_rowsImportedLbl = new QLabel(m_progressPageWidget); 0293 0294 m_importingProgressBar = new QProgressBar(m_progressPageWidget); 0295 m_importingProgressBar->setMinimum(0); 0296 m_importingProgressBar->setMaximum(0); 0297 m_importingProgressBar->setValue(0); 0298 0299 vbox->addWidget(m_progressLbl); 0300 vbox->addWidget(m_rowsImportedLbl); 0301 vbox->addWidget(m_importingProgressBar); 0302 vbox->addStretch(1); 0303 0304 m_progressPageItem = new KPageWidgetItem(m_progressPageWidget, xi18n("Processing Import")); 0305 addPage(m_progressPageItem); 0306 } 0307 0308 void ImportTableWizard::setupFinishPage() 0309 { 0310 m_finishPageWidget = new QWidget(this); 0311 m_finishPageWidget->hide(); 0312 QVBoxLayout *vbox = new QVBoxLayout(m_finishPageWidget); 0313 KexiUtils::setStandardMarginsAndSpacing(vbox); 0314 m_finishLbl = new QLabel(m_finishPageWidget); 0315 m_finishLbl->setAlignment(Qt::AlignTop | Qt::AlignLeft); 0316 m_finishLbl->setWordWrap(true); 0317 0318 vbox->addWidget(m_finishLbl); 0319 m_finishCheckBox = new QCheckBox(xi18n("Open imported table"), 0320 m_finishPageWidget); 0321 m_finishCheckBox->setChecked(true); 0322 vbox->addSpacing(KexiUtils::spacingHint()); 0323 vbox->addWidget(m_finishCheckBox); 0324 vbox->addStretch(1); 0325 0326 m_finishPageItem = new KPageWidgetItem(m_finishPageWidget, xi18n("Success")); 0327 addPage(m_finishPageItem); 0328 } 0329 0330 void ImportTableWizard::slot_currentPageChanged(KPageWidgetItem* curPage,KPageWidgetItem* prevPage) 0331 { 0332 Q_UNUSED(prevPage); 0333 if (curPage == m_introPageItem) { 0334 } 0335 else if (curPage == m_srcConnPageItem) { 0336 arriveSrcConnPage(); 0337 } else if (curPage == m_srcDBPageItem) { 0338 arriveSrcDBPage(); 0339 } else if (curPage == m_tablesPageItem) { 0340 arriveTableSelectPage(prevPage); 0341 } else if (curPage == m_alterTablePageItem) { 0342 if (prevPage == m_tablesPageItem) { 0343 arriveAlterTablePage(); 0344 } 0345 } else if (curPage == m_importingPageItem) { 0346 arriveImportingPage(); 0347 } else if (curPage == m_progressPageItem) { 0348 arriveProgressPage(); 0349 } else if (curPage == m_finishPageItem) { 0350 arriveFinishPage(); 0351 } 0352 } 0353 0354 void ImportTableWizard::arriveSrcConnPage() 0355 { 0356 } 0357 0358 void ImportTableWizard::arriveSrcDBPage() 0359 { 0360 if (fileBasedSrcSelected()) { 0361 //! @todo Back button doesn't work after selecting a file to import 0362 } else { 0363 delete m_prjSet; 0364 m_prjSet = 0; 0365 m_srcDBPageWidget->hide(); 0366 qDebug() << "Looks like we need a project selector widget!"; 0367 0368 KDbConnectionData* conndata = m_srcConnSel->selectedConnectionData(); 0369 if (conndata) { 0370 KexiGUIMessageHandler handler; 0371 m_prjSet = new KexiProjectSet(&handler); 0372 if (!m_prjSet->setConnectionData(conndata)) { 0373 handler.showErrorMessage(m_prjSet->result()); 0374 delete m_prjSet; 0375 m_prjSet = 0; 0376 return; 0377 } 0378 if (!m_srcDBName) { 0379 QVBoxLayout *vbox = new QVBoxLayout(m_srcDBPageWidget); 0380 KexiUtils::setStandardMarginsAndSpacing(vbox); 0381 m_srcDBName = new KexiProjectSelectorWidget(m_srcDBPageWidget); 0382 vbox->addWidget(m_srcDBName); 0383 m_srcDBName->label()->setText(xi18n("Select source database you wish to import:")); 0384 } 0385 m_srcDBName->setProjectSet(m_prjSet); 0386 } 0387 m_srcDBPageWidget->show(); 0388 } 0389 } 0390 0391 void ImportTableWizard::arriveTableSelectPage(KPageWidgetItem *prevPage) 0392 { 0393 if (prevPage == m_alterTablePageItem) { 0394 if (m_tableListWidget->count() == 1) { //we was skiping it before 0395 back(); 0396 } 0397 } else { 0398 Kexi::ObjectStatus result; 0399 KexiUtils::WaitCursor wait; 0400 m_tableListWidget->clear(); 0401 m_migrateDriver = prepareImport(&result); 0402 0403 bool ok = m_migrateDriver; 0404 if (ok) { 0405 if (!m_sourceDbEncoding.isEmpty()) { 0406 m_migrateDriver->setPropertyValue( 0407 "source_database_nonunicode_encoding", 0408 QVariant(m_sourceDbEncoding.toUpper().remove(' ')) // "CP1250", not "cp 1250" 0409 ); 0410 } 0411 ok = m_migrateDriver->connectSource(&result); 0412 } 0413 if (ok) { 0414 QStringList tableNames; 0415 if (m_migrateDriver->tableNames(&tableNames)) { 0416 m_tableListWidget->addItems(tableNames); 0417 } 0418 if (m_tableListWidget->item(0)) { 0419 m_tableListWidget->item(0)->setSelected(true); 0420 if (m_tableListWidget->count() == 1) { 0421 KexiUtils::removeWaitCursor(); 0422 next(); 0423 } 0424 } 0425 } 0426 KexiUtils::removeWaitCursor(); 0427 if (!ok) { 0428 QString errMessage =result.message.isEmpty() ? xi18n("Unknown error") : result.message; 0429 QString errDescription = result.description.isEmpty() ? errMessage : result.description; 0430 KMessageBox::error(this, errMessage, errDescription); 0431 setValid(m_tablesPageItem, false); 0432 } 0433 } 0434 } 0435 0436 void ImportTableWizard::arriveAlterTablePage() 0437 { 0438 //! @todo handle errors 0439 if (m_tableListWidget->selectedItems().isEmpty()) 0440 return; 0441 //! @todo (js) support multiple tables? 0442 #if 0 0443 foreach(QListWidgetItem *table, m_tableListWidget->selectedItems()) { 0444 m_importTableName = table->text(); 0445 } 0446 #else 0447 m_importTableName = m_tableListWidget->selectedItems().first()->text(); 0448 #endif 0449 0450 QScopedPointer<KDbTableSchema> ts(new KDbTableSchema); 0451 if (!m_migrateDriver->readTableSchema(m_importTableName, ts.data())) { 0452 return; 0453 } 0454 0455 setValid(m_alterTablePageItem, ts->fieldCount() > 0); 0456 if (isValid(m_alterTablePageItem)) { 0457 connect(m_alterSchemaWidget->nameWidget(), SIGNAL(textChanged()), this, SLOT(slotNameChanged()), Qt::UniqueConnection); 0458 } 0459 0460 m_alterSchemaWidget->setTableSchema(ts.take()); 0461 if (!readFromTable()) { 0462 m_alterSchemaWidget->setTableSchema(nullptr); 0463 back(); 0464 KMessageBox::information(this, 0465 xi18nc("@info", "Could not import table <resource>%1</resource>. " 0466 "Select different table or cancel importing.", m_importTableName)); 0467 } 0468 } 0469 0470 bool ImportTableWizard::readFromTable() 0471 { 0472 QSharedPointer<KDbSqlResult> tableResult = m_migrateDriver->readFromTable(m_importTableName); 0473 KDbTableSchema *newSchema = m_alterSchemaWidget->newSchema(); 0474 if (!tableResult || tableResult->lastResult().isError() 0475 || tableResult->fieldsCount() != newSchema->fieldCount()) 0476 { 0477 back(); 0478 KMessageBox::information(this, 0479 xi18nc("@info", "Could not import table <resource>%1</resource>. " 0480 "Select different table or cancel importing.", m_importTableName)); 0481 return false; 0482 } 0483 QScopedPointer<QList<KDbRecordData*>> data(new QList<KDbRecordData*>); 0484 for (int i = 0; i < RECORDS_FOR_PREVIEW; ++i) { 0485 QSharedPointer<KDbRecordData> record(tableResult->fetchRecordData()); 0486 if (!record) { 0487 if (tableResult->lastResult().isError()) { 0488 return false; 0489 } 0490 break; 0491 } 0492 data->append(record.data()); 0493 } 0494 if (data->isEmpty()) { 0495 back(); 0496 KMessageBox::information(this, 0497 xi18nc("@info", "No data has been found in table <resource>%1</resource>. " 0498 "Select different table or cancel importing.", m_importTableName)); 0499 return false; 0500 } 0501 m_alterSchemaWidget->model()->setRowCount(data->count()); 0502 m_alterSchemaWidget->setData(data.take()); 0503 return true; 0504 } 0505 0506 void ImportTableWizard::arriveImportingPage() 0507 { 0508 m_importingPageWidget->hide(); 0509 #if 0 0510 if (checkUserInput()) { 0511 //setNextEnabled(m_importingPageWidget, true); 0512 user2Button->setEnabled(true); 0513 } else { 0514 //setNextEnabled(m_importingPageWidget, false); 0515 user2Button->setEnabled(false); 0516 } 0517 #endif 0518 0519 QString txt; 0520 0521 txt = xi18nc("@info Table import wizard, final message", "<para>All required information has now been gathered. " 0522 "Click <interface>Next</interface> button to start importing table <resource>%1</resource>.</para>" 0523 "<para><note>Depending on size of the table this may take some time.</note></para>", 0524 m_alterSchemaWidget->nameWidget()->nameText()); 0525 0526 m_lblImportingTxt->setText(txt); 0527 0528 //temp. hack for MS Access driver only 0529 //! @todo for other databases we will need KexiMigration::Connection 0530 //! and KexiMigration::Driver classes 0531 bool showOptions = false; 0532 if (fileBasedSrcSelected()) { 0533 Kexi::ObjectStatus result; 0534 KexiMigrate* sourceDriver = prepareImport(&result); 0535 if (sourceDriver) { 0536 showOptions = !result.error() 0537 && sourceDriver->propertyValue("source_database_has_nonunicode_encoding").toBool(); 0538 sourceDriver->setData(nullptr); 0539 } 0540 } 0541 if (showOptions) 0542 m_importOptionsButton->show(); 0543 else 0544 m_importOptionsButton->hide(); 0545 0546 m_importingPageWidget->show(); 0547 setAppropriate(m_progressPageItem, true); 0548 } 0549 0550 void ImportTableWizard::arriveProgressPage() 0551 { 0552 m_progressLbl->setText(xi18nc("@info", "Please wait while the table is imported.")); 0553 0554 backButton()->setEnabled(false); 0555 nextButton()->setEnabled(false); 0556 0557 connect(button(QDialogButtonBox::Cancel), &QPushButton::clicked, 0558 this, &ImportTableWizard::slotCancelClicked); 0559 0560 QApplication::setOverrideCursor(Qt::BusyCursor); 0561 m_importComplete = doImport(); 0562 QApplication::restoreOverrideCursor(); 0563 0564 disconnect(button(QDialogButtonBox::Cancel), &QPushButton::clicked, 0565 this, &ImportTableWizard::slotCancelClicked); 0566 0567 next(); 0568 } 0569 0570 void ImportTableWizard::arriveFinishPage() 0571 { 0572 if (m_importComplete) { 0573 m_finishPageItem->setHeader(xi18n("Success")); 0574 m_finishLbl->setText(xi18nc("@info", 0575 "Table <resource>%1</resource> has been imported.", 0576 m_alterSchemaWidget->nameWidget()->nameText())); 0577 } else { 0578 m_finishPageItem->setHeader(xi18n("Failure")); 0579 m_finishLbl->setText(xi18n("An error occurred.")); 0580 } 0581 m_migrateDriver->disconnectSource(); 0582 button(QDialogButtonBox::Cancel)->setEnabled(!m_importComplete); 0583 m_finishCheckBox->setVisible(m_importComplete); 0584 finishButton()->setEnabled(m_importComplete); 0585 nextButton()->setEnabled(m_importComplete); 0586 setAppropriate(m_progressPageItem, false); 0587 } 0588 0589 bool ImportTableWizard::fileBasedSrcSelected() const 0590 { 0591 return m_srcConnSel->selectedConnectionType() == KexiConnectionSelectorWidget::FileBased; 0592 } 0593 0594 KexiMigrate* ImportTableWizard::prepareImport(Kexi::ObjectStatus *result) 0595 { 0596 Q_ASSERT(result); 0597 // Find a source (migration) driver name 0598 QString sourceDriverId = driverIdForSelectedSource(); 0599 if (sourceDriverId.isEmpty()) { 0600 result->setStatus(xi18n("No appropriate migration driver found."), 0601 m_migrateManager.possibleProblemsMessage()); 0602 } 0603 0604 // Get a source (migration) driver 0605 KexiMigrate* sourceDriver = 0; 0606 if (!result->error()) { 0607 sourceDriver = m_migrateManager.driver(sourceDriverId); 0608 if (!sourceDriver || m_migrateManager.result().isError()) { 0609 qDebug() << "Import migrate driver error..."; 0610 result->setStatus(m_migrateManager.resultable()); 0611 } 0612 } 0613 0614 // Set up source (migration) data required for connection 0615 if (sourceDriver && !result->error()) { 0616 #if 0 0617 // Setup progress feedback for the GUI 0618 if (sourceDriver->progressSupported()) { 0619 m_progressBar->updateGeometry(); 0620 disconnect(sourceDriver, SIGNAL(progressPercent(int)), 0621 this, SLOT(progressUpdated(int))); 0622 connect(sourceDriver, SIGNAL(progressPercent(int)), 0623 this, SLOT(progressUpdated(int))); 0624 progressUpdated(0); 0625 } 0626 #endif 0627 0628 bool keepData = true; 0629 0630 #if 0 0631 if (m_importTypeStructureAndDataCheckBox->isChecked()) { 0632 qDebug() << "Structure and data selected"; 0633 keepData = true; 0634 } else if (m_importTypeStructureOnlyCheckBox->isChecked()) { 0635 qDebug() << "structure only selected"; 0636 keepData = false; 0637 } else { 0638 qDebug() << "Neither radio button is selected (not possible?) presume keep data"; 0639 keepData = true; 0640 } 0641 #endif 0642 0643 KexiMigration::Data* md = new KexiMigration::Data(); 0644 0645 if (fileBasedSrcSelected()) { 0646 KDbConnectionData* conn_data = new KDbConnectionData(); 0647 conn_data->setDatabaseName(m_srcConnSel->selectedFile()); 0648 md->source = conn_data; 0649 md->sourceName.clear(); 0650 } else { 0651 md->source = m_srcConnSel->selectedConnectionData(); 0652 md->sourceName = m_srcDBName->selectedProjectData()->databaseName(); 0653 0654 } 0655 0656 md->setShouldCopyData(keepData); 0657 sourceDriver->setData(md); 0658 0659 return sourceDriver; 0660 } 0661 return 0; 0662 } 0663 0664 //=========================================================== 0665 // 0666 QString ImportTableWizard::driverIdForSelectedSource() 0667 { 0668 if (fileBasedSrcSelected()) { 0669 QMimeDatabase db; 0670 QMimeType mime = db.mimeTypeForFile(m_srcConnSel->selectedFile()); 0671 if (!mime.isValid() 0672 || mime.name() == "application/octet-stream" 0673 || mime.name() == "text/plain" 0674 || mime.name() == "application/zip") 0675 { 0676 //try by URL: 0677 mime = db.mimeTypeForFile(m_srcConnSel->selectedFile()); 0678 } 0679 if (!mime.isValid()) { 0680 return QString(); 0681 } 0682 const QStringList ids(m_migrateManager.driverIdsForMimeType(mime.name())); 0683 //! @todo do we want to return first migrate driver for the mime type or allow to select it? 0684 return ids.isEmpty() ? QString() : ids.first(); 0685 } 0686 return m_srcConnSel->selectedConnectionData() 0687 ? m_srcConnSel->selectedConnectionData()->databaseName() : QString(); 0688 } 0689 0690 bool ImportTableWizard::doImport() 0691 { 0692 KexiGUIMessageHandler msg; 0693 0694 KexiProject* project = KexiMainWindowIface::global()->project(); 0695 if (!project) { 0696 msg.showErrorMessage(KDbMessageHandler::Error, xi18n("No project available.")); 0697 return false; 0698 } 0699 0700 KexiPart::Part *part = Kexi::partManager().partForPluginId("org.kexi-project.table"); 0701 if (!part) { 0702 msg.showErrorMessage(Kexi::partManager().result()); 0703 return false; 0704 } 0705 0706 KDbTableSchema* newSchema = m_alterSchemaWidget->newSchema(); 0707 if (!newSchema) { 0708 msg.showErrorMessage(KDbMessageHandler::Error, xi18n("No table was selected to import.")); 0709 return false; 0710 } 0711 newSchema->setName(m_alterSchemaWidget->nameWidget()->nameText()); 0712 newSchema->setCaption(m_alterSchemaWidget->nameWidget()->captionText()); 0713 0714 KexiPart::Item* partItemForSavedTable = project->createPartItem(part->info(), newSchema->name()); 0715 if (!partItemForSavedTable) { 0716 msg.showErrorMessage(project->result()); 0717 return false; 0718 } 0719 0720 //Create the table 0721 if (!m_connection->createTable(newSchema, 0722 KDbConnection::CreateTableOption::Default | KDbConnection::CreateTableOption::DropDestination)) 0723 { 0724 msg.showErrorMessage(KDbMessageHandler::Error, 0725 xi18nc("@info", "Unable to create table <resource>%1</resource>.", 0726 newSchema->name())); 0727 return false; 0728 } 0729 m_alterSchemaWidget->takeTableSchema(); //m_connection takes ownership of the KDbTableSchema object 0730 0731 //Import the data 0732 QApplication::setOverrideCursor(Qt::BusyCursor); 0733 QList<QVariant> row; 0734 unsigned int fieldCount = newSchema->fieldCount(); 0735 m_migrateDriver->moveFirst(); 0736 KDbTransactionGuard tg(m_connection); 0737 if (m_connection->result().isError()) { 0738 QApplication::restoreOverrideCursor(); 0739 return false; 0740 } 0741 do { 0742 for (unsigned int i = 0; i < fieldCount; ++i) { 0743 if (m_importWasCanceled) { 0744 return false; 0745 } 0746 if (i % 100 == 0) { 0747 QApplication::processEvents(); 0748 } 0749 row.append(m_migrateDriver->value(i)); 0750 } 0751 m_connection->insertRecord(newSchema, row); 0752 row.clear(); 0753 } while (m_migrateDriver->moveNext()); 0754 if (!tg.commit()) { 0755 QApplication::restoreOverrideCursor(); 0756 return false; 0757 } 0758 QApplication::restoreOverrideCursor(); 0759 0760 //Done so save part and update gui 0761 partItemForSavedTable->setIdentifier(newSchema->id()); 0762 project->addStoredItem(part->info(), partItemForSavedTable); 0763 0764 return true; 0765 } 0766 0767 void ImportTableWizard::slotConnPageItemSelected(bool isSelected) 0768 { 0769 setValid(m_srcConnPageItem, isSelected); 0770 if (isSelected && fileBasedSrcSelected()) { 0771 next(); 0772 } 0773 } 0774 0775 void ImportTableWizard::slotTableListWidgetSelectionChanged() 0776 { 0777 setValid(m_tablesPageItem, !m_tableListWidget->selectedItems().isEmpty()); 0778 } 0779 0780 void ImportTableWizard::slotNameChanged() 0781 { 0782 setValid(m_alterTablePageItem, !m_alterSchemaWidget->nameWidget()->captionText().isEmpty()); 0783 } 0784 0785 void ImportTableWizard::slotCancelClicked() 0786 { 0787 m_importWasCanceled = true; 0788 } 0789 0790 void ImportTableWizard::slotOptionsButtonClicked() 0791 { 0792 OptionsDialog dlg(m_srcConnSel->selectedFile(), m_sourceDbEncoding, this); 0793 if (QDialog::Accepted == dlg.exec()) { 0794 m_sourceDbEncoding = dlg.encodingComboBox()->selectedEncoding(); 0795 } 0796 }