diff --git a/src/core/kexiactionproxy.h b/src/core/kexiactionproxy.h index 2736029cb..88223479b 100644 --- a/src/core/kexiactionproxy.h +++ b/src/core/kexiactionproxy.h @@ -1,171 +1,171 @@ /* This file is part of the KDE project Copyright (C) 2003-2004 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIACTIONPROXY_H #define KEXIACTIONPROXY_H #include "kexiproject.h" #include "kexisharedactionhost.h" class QAction; class KexiActionProxy; //! Abstract helper class used to connect shared actions from outside of shared-action-aware object. /*! Methods like KexiActionProxy::plugSharedAction() are not public, but sometimes there's need for plugging an object that implements KexiActionProxy interface from outside. Reimplement KexiSharedActionConnector: do all needed connections in the constructor. For example, with KexiQueryDesignerSqlEditor class we're using KTextEdit - (or KTextEditor::View) that's not shared-action-aware. So it's needed to conenct + (or KTextEditor::View) that's not shared-action-aware. So it's needed to connect e.g. "edit_undo" shared action to undo() slot, and so on. It is impelmented in more generic way by implementing KTextEdit_SharedActionConnector class, - so the conenction can be reused many times by just allocating KTextEdit_SharedActionConnector + so the connection can be reused many times by just allocating KTextEdit_SharedActionConnector object for any KTextEditor when required (not only within KexiQueryDesignerSqlEditor). */ //! @todo add method for setAvailable() class KEXICORE_EXPORT KexiSharedActionConnector { public: /* Connects shared actions offered by \a proxy to \a obj. */ KexiSharedActionConnector(KexiActionProxy* proxy, QObject *obj); ~KexiSharedActionConnector(); protected: void plugSharedAction(const QString& action_name, const char *slot); KexiActionProxy* m_proxy; QObject *m_object; }; //! An interface that acts as proxy for shared actions within the application. /*! For example, edit->copy action can be reused to copy different types of items. Availability and meaning of given action depends on the context, while the context changes e.g. when another window is activated. This class is mostly used by subclassing in KexiWindow or KexiDockBase - you can subclass in a similar way. */ class KEXICORE_EXPORT KexiActionProxy { public: /*! Constructs action proxy for object \a receiver, using \a host. If \a host is NULL, KexiSharedActionHost::defaultHost() is used. (you must be sure that it's true) -- it is casted to QObject and assigned as the receiver.*/ explicit KexiActionProxy(QObject *receiver , KexiSharedActionHost *host = 0); virtual ~KexiActionProxy(); /*! Activates action named \a action_name for this proxy. If the action is executed (accepted), true is returned. */ bool activateSharedAction(const QString& action_name, bool alsoCheckInChildren = true); /*! Sets host to \a host; rerely used. */ void setSharedActionHost(KexiSharedActionHost& host) { m_host = &host; } /*! \return true, if action named \a action_name is enabled within the proxy. False is returned either if the action is not available or is not supported. \ sa isSupported() */ bool isAvailable(const QString& action_name, bool alsoCheckInChildren = true) const; /*! \return true, if action named \a action_name is supported by the proxy. */ bool isSupported(const QString& action_name) const; protected: /*! Plugs shared action named \a action_name to slot \a slot in \a receiver. \a Receiver is usually a child of _this_ widget. */ void plugSharedAction(const QString& action_name, QObject* receiver, const char *slot); void unplugSharedAction(const QString& action_name); /*! Typical version of plugAction() method -- plugs action named \a action_name to slot \a slot in _this_ widget. */ inline void plugSharedAction(const QString& action_name, const char *slot) { plugSharedAction(action_name, m_receiver, slot); } /*! Plugs action named \a action_name to a widget \a w, so the action is visible on this widget as an item. \a w will typically be a menu, popup menu or a toolbar. Does nothing if no action found, so generally this is safer than just caling e.g. action("myaction")->plug(myPopup); \sa action(), QWidget::addAction(QAction*) */ void plugSharedAction(const QString& action_name, QWidget* w); /*! Unplugs action named \a action_name from a widget \a w. \sa plugSharedAction(const char *action_name, QWidget* w) */ void unplugSharedAction(const QString& action_name, QWidget* w); /*! Like above, but creates alternative action as a copy of \a action_name, with \a alternativeText set. When this action is activated, just original action specified by \a action_name is activated. The aternative action has autmatically set name as: action_name + "_alt". The new action's owner is \a w. You can delete this action without informing action proxy about this. \return newly created action or 0 if \a action_name not found. */ QAction * plugSharedAction(const QString& action_name, const QString& alternativeText, QWidget* w); /*! \return action named with \a name or NULL if there is no such action. */ virtual QAction* sharedAction(const QString& action_name); inline QObject *receiver() const { return m_receiver; } virtual void setAvailable(const QString& action_name, bool set); /*! Adds \a child of this proxy. Children will receive activateSharedAction() event, If activateSharedAction() "event" is not consumed by the main proxy, we start to iterate over proxy children (in unspecified order) to and call activateSharedAction() on every child until one of them accept the "event". If proxy child is destroyed, it is automatically detached from its parent proxy. Parent proxy is 0 by default. This pointer is properly cleared when parent proxy is destroyed. */ void addActionProxyChild(KexiActionProxy* child); void takeActionProxyChild(KexiActionProxy* child); KexiSharedActionHost *m_host; QPointer m_receiver; QList m_sharedActionChildren; QList m_alternativeActions; KexiActionProxy* m_actionProxyParent; QObject m_signal_parent; //!< it's just to have common parent for owned signals public: //! For internal use by addActionProxyChild(). \a parent can be 0. void setActionProxyParent_internal(KexiActionProxy* parent); //! @internal KexiActionProxy *m_focusedChild; friend class KexiSharedActionHost; friend class KexiSharedActionConnector; private: class Private; Private * const d; }; #endif diff --git a/src/main/startup/KexiStartupDialog.h b/src/main/startup/KexiStartupDialog.h index 4dc179d35..be2c7d5ec 100644 --- a/src/main/startup/KexiStartupDialog.h +++ b/src/main/startup/KexiStartupDialog.h @@ -1,155 +1,155 @@ /* This file is part of the KDE project Copyright (C) 2003-2007 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KexiStartupDialog_h #define KexiStartupDialog_h #include "keximain_export.h" #include #include #include #include class KexiProjectData; class KexiDBConnectionSet; class ConnectionDataLVItem; class QEvent; //! @short Kexi startup dialog /*! This class is used to show the template/open-existing tabbed dialog on Kexi startup. If only one page is shown, tab is not displayed, so the dialog becomes a normal "plain" type dialog. */ class KEXIMAIN_EXPORT KexiStartupDialog : public KPageDialog { Q_OBJECT public: //! Result of the user's input. enum Result { CancelResult, //!< The user has pressed 'Cancel' CreateBlankResult, //!< The user has selected a template CreateFromTemplateResult, //!< The user has selected a template to be used for creating a new db ImportResult, //!< The user has chosen to import db OpenExistingResult //!< The user has chosen an existing connection or db file }; /*! To configure the dialog you have to use this enum (any !=0 or'ed value is ok) - Templates Show "Templates" tab - OpenExisting Show "Open existing" tab - Everything Show everything above */ enum DialogType { Templates = 1, OpenExisting = 2, Everything = (1 + 2 + 4) }; /*! Options for a dialog (any or'ed value or 0 is ok) - CheckBoxDoNotShowAgain Adds "do not show this window" checkbox at the bottom */ enum DialogOptions { CheckBoxDoNotShowAgain = 1 }; /*! Creates a dialog. @param dialogType see DialogType description @param dialogOptions see dialogOptions description - @param connSet conenction set used to present available conenctions + @param connSet connection set used to present available connections in "Open Existing" tab. Pass an empty object is this tab is not used. @param parent parent widget, if any. @param name name of this object. */ KexiStartupDialog( int dialogType, int dialogOptions, KexiDBConnectionSet& connSet, QWidget *parent = 0); ~KexiStartupDialog(); /*! Executes dialog. \return one of Result values. Use this after dialog is closed. */ int result() const; /*! \return data of selected Kexi project. Returns NULL if no selection has been made or other tab was selected. */ KexiProjectData* selectedProjectData() const; /*! \return name of selected Kexi project file (if result() == OpenExistingResult) or name of template file to be used for creating a new database. (if result() == CreateFromTemplateResult). Returns empty string if no such selection has been made or other tab was selected. */ QString selectedFileName() const; #ifdef KEXI_PROJECT_TEMPLATES /*! \return "autoopen" objects defined for selected template. Only makes sense if template was used. */ KexiProjectData::AutoOpenObjects autoopenObjects() const; #endif /*! \return a pointer to selected Kexi connection data. (if "Open Existing" tab was selected and this connection data was clicked). Returns NULL if no such selection has been made or other tab was selected. */ KDbConnectionData* selectedExistingConnection() const; public Q_SLOTS: virtual void done(int r); virtual void reject(); protected Q_SLOTS: virtual void slotOk(); //! slot activated when one of the top-level tabs is shown void slotCurrentPageChanged(KPageWidgetItem* current, KPageWidgetItem* before); //! slot activated when one of the subpages within templates tab is shown void slotCurrentTemplatesubpageChanged(KPageWidgetItem* current, KPageWidgetItem* before); void templateSelected(const QString& fileName); //! helper void existingFileSelected(); void showSimpleConnForOpenExisting(); void showAdvancedConnForOpenExisting(); void connectionItemForOpenExistingExecuted(ConnectionDataLVItem *item); void connectionItemForOpenExistingHighlighted(ConnectionDataLVItem *item); protected: virtual bool eventFilter(QObject *o, QEvent *e); virtual void showEvent(QShowEvent *e); //! helper: updates a state of dialog's OK button void updateDialogOKButton(KPageWidgetItem *pageWidgetItem); private: void setupPageTemplates(); void setupPageOpenExisting(); class Private; Private * const d; }; #endif diff --git a/src/migration/importtablewizard.cpp b/src/migration/importtablewizard.cpp index 9d4737ae4..0a0574a75 100644 --- a/src/migration/importtablewizard.cpp +++ b/src/migration/importtablewizard.cpp @@ -1,768 +1,768 @@ /* This file is part of the KDE project Copyright (C) 2009 Adam Pigg Copyright (C) 2014-2016 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "importtablewizard.h" #include "migratemanager.h" #include "keximigrate.h" #include "keximigratedata.h" #include "AlterSchemaWidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace KexiMigration; #define RECORDS_FOR_PREVIEW 3 ImportTableWizard::ImportTableWizard ( KDbConnection* curDB, QWidget* parent, QMap* args, Qt::WindowFlags flags) : KAssistantDialog ( parent, flags ), m_args(args) { m_connection = curDB; m_migrateDriver = 0; m_prjSet = 0; m_importComplete = false; m_importWasCanceled = false; KexiMainWindowIface::global()->setReasonableDialogSize(this); setupIntroPage(); setupSrcConn(); setupSrcDB(); setupTableSelectPage(); setupAlterTablePage(); setupImportingPage(); setupProgressPage(); setupFinishPage(); setValid(m_srcConnPageItem, false); connect(this, SIGNAL(currentPageChanged(KPageWidgetItem*,KPageWidgetItem*)), this, SLOT(slot_currentPageChanged(KPageWidgetItem*,KPageWidgetItem*))); //! @todo Change this to message prompt when we move to non-dialog wizard. connect(m_srcConnSel, SIGNAL(connectionSelected(bool)), this, SLOT(slotConnPageItemSelected(bool))); } ImportTableWizard::~ImportTableWizard() { delete m_prjSet; delete m_srcConnSel; } void ImportTableWizard::back() { KAssistantDialog::back(); } void ImportTableWizard::next() { if (currentPage() == m_srcConnPageItem) { if (fileBasedSrcSelected()) { setAppropriate(m_srcDBPageItem, false); } else { setAppropriate(m_srcDBPageItem, true); } } else if (currentPage() == m_alterTablePageItem) { if (m_alterSchemaWidget->nameExists(m_alterSchemaWidget->nameWidget()->nameText())) { KMessageBox::information(this, xi18nc("@info", "%1 name is already used by an existing table. " "Enter different table name to continue.", m_alterSchemaWidget->nameWidget()->nameText()), xi18n("Name Already Used")); return; } } KAssistantDialog::next(); } void ImportTableWizard::accept() { if (m_args) { if (m_finishCheckBox->isChecked()) { m_args->insert("destinationTableName",m_alterSchemaWidget->nameWidget()->nameText()); } else { m_args->remove("destinationTableName"); } } QDialog::accept(); } void ImportTableWizard::reject() { QDialog::reject(); } //=========================================================== // void ImportTableWizard::setupIntroPage() { m_introPageWidget = new QWidget(this); QVBoxLayout *vbox = new QVBoxLayout(); m_introPageWidget->setLayout(vbox); KexiUtils::setStandardMarginsAndSpacing(vbox); QLabel *lblIntro = new QLabel(m_introPageWidget); lblIntro->setAlignment(Qt::AlignTop | Qt::AlignLeft); lblIntro->setWordWrap(true); lblIntro->setText( xi18nc("@info", "Table Importing Assistant allows you to import a table from an existing " "database into the current Kexi project." "Click Next button to continue or " "Cancel button to exit this assistant.")); vbox->addWidget(lblIntro); m_introPageItem = new KPageWidgetItem(m_introPageWidget, xi18n("Welcome to the Table Importing Assistant")); addPage(m_introPageItem); } void ImportTableWizard::setupSrcConn() { m_srcConnPageWidget = new QWidget(this); QVBoxLayout *vbox = new QVBoxLayout(m_srcConnPageWidget); KexiUtils::setStandardMarginsAndSpacing(vbox); m_srcConnSel = new KexiConnectionSelectorWidget(&Kexi::connset(), "kfiledialog:///ProjectMigrationSourceDir", KFileWidget::Opening, m_srcConnPageWidget); m_srcConnSel->hideConnectonIcon(); m_srcConnSel->showSimpleConnection(); QSet excludedFilters; //! @todo remove when support for kexi files as source prj is added in migration excludedFilters << KDb::defaultFileBasedDriverMimeType() << "application/x-kexiproject-shortcut" << "application/x-kexi-connectiondata"; m_srcConnSel->fileWidget->setExcludedFilters(excludedFilters); vbox->addWidget(m_srcConnSel); m_srcConnPageItem = new KPageWidgetItem(m_srcConnPageWidget, xi18n("Select Location for Source Database")); addPage(m_srcConnPageItem); } void ImportTableWizard::setupSrcDB() { // arrivesrcdbPage creates widgets on that page m_srcDBPageWidget = new QWidget(this); m_srcDBName = NULL; m_srcDBPageItem = new KPageWidgetItem(m_srcDBPageWidget, xi18n("Select Source Database")); addPage(m_srcDBPageItem); } void ImportTableWizard::setupTableSelectPage() { m_tablesPageWidget = new QWidget(this); QVBoxLayout *vbox = new QVBoxLayout(m_tablesPageWidget); KexiUtils::setStandardMarginsAndSpacing(vbox); m_tableListWidget = new QListWidget(this); m_tableListWidget->setSelectionMode(QAbstractItemView::SingleSelection); connect(m_tableListWidget, SIGNAL(itemSelectionChanged()), this, SLOT(slotTableListWidgetSelectionChanged())); vbox->addWidget(m_tableListWidget); m_tablesPageItem = new KPageWidgetItem(m_tablesPageWidget, xi18n("Select the Table to Import")); addPage(m_tablesPageItem); } //=========================================================== // void ImportTableWizard::setupImportingPage() { m_importingPageWidget = new QWidget(this); m_importingPageWidget->hide(); QVBoxLayout *vbox = new QVBoxLayout(m_importingPageWidget); KexiUtils::setStandardMarginsAndSpacing(vbox); m_lblImportingTxt = new QLabel(m_importingPageWidget); m_lblImportingTxt->setAlignment(Qt::AlignTop | Qt::AlignLeft); m_lblImportingTxt->setWordWrap(true); m_lblImportingErrTxt = new QLabel(m_importingPageWidget); m_lblImportingErrTxt->setAlignment(Qt::AlignTop | Qt::AlignLeft); m_lblImportingErrTxt->setWordWrap(true); vbox->addWidget(m_lblImportingTxt); vbox->addWidget(m_lblImportingErrTxt); vbox->addStretch(1); QWidget *options_widget = new QWidget(m_importingPageWidget); vbox->addWidget(options_widget); QVBoxLayout *options_vbox = new QVBoxLayout(options_widget); options_vbox->setSpacing(KexiUtils::spacingHint()); m_importOptionsButton = new QPushButton(koIcon("configure"), xi18n("Advanced Options"), options_widget); connect(m_importOptionsButton, SIGNAL(clicked()),this, SLOT(slotOptionsButtonClicked())); options_vbox->addWidget(m_importOptionsButton); options_vbox->addStretch(1); m_importingPageWidget->show(); m_importingPageItem = new KPageWidgetItem(m_importingPageWidget, xi18n("Importing")); addPage(m_importingPageItem); } void ImportTableWizard::setupAlterTablePage() { m_alterTablePageWidget = new QWidget(this); m_alterTablePageWidget->hide(); QVBoxLayout *vbox = new QVBoxLayout(m_alterTablePageWidget); KexiUtils::setStandardMarginsAndSpacing(vbox); m_alterSchemaWidget = new KexiMigration::AlterSchemaWidget(this); vbox->addWidget(m_alterSchemaWidget); m_alterTablePageWidget->show(); m_alterTablePageItem = new KPageWidgetItem(m_alterTablePageWidget, xi18n("Alter the Detected Table Design")); addPage(m_alterTablePageItem); } void ImportTableWizard::setupProgressPage() { m_progressPageWidget = new QWidget(this); m_progressPageWidget->hide(); QVBoxLayout *vbox = new QVBoxLayout(m_progressPageWidget); KexiUtils::setStandardMarginsAndSpacing(vbox); m_progressPageWidget->setLayout(vbox); m_progressLbl = new QLabel(m_progressPageWidget); m_progressLbl->setAlignment(Qt::AlignTop | Qt::AlignLeft); m_progressLbl->setWordWrap(true); m_rowsImportedLbl = new QLabel(m_progressPageWidget); m_importingProgressBar = new QProgressBar(m_progressPageWidget); m_importingProgressBar->setMinimum(0); m_importingProgressBar->setMaximum(0); m_importingProgressBar->setValue(0); vbox->addWidget(m_progressLbl); vbox->addWidget(m_rowsImportedLbl); vbox->addWidget(m_importingProgressBar); vbox->addStretch(1); m_progressPageItem = new KPageWidgetItem(m_progressPageWidget, xi18n("Processing Import")); addPage(m_progressPageItem); } void ImportTableWizard::setupFinishPage() { m_finishPageWidget = new QWidget(this); m_finishPageWidget->hide(); QVBoxLayout *vbox = new QVBoxLayout(m_finishPageWidget); KexiUtils::setStandardMarginsAndSpacing(vbox); m_finishLbl = new QLabel(m_finishPageWidget); m_finishLbl->setAlignment(Qt::AlignTop | Qt::AlignLeft); m_finishLbl->setWordWrap(true); vbox->addWidget(m_finishLbl); m_finishCheckBox = new QCheckBox(xi18n("Open imported table"), m_finishPageWidget); m_finishCheckBox->setChecked(true); vbox->addSpacing(KexiUtils::spacingHint()); vbox->addWidget(m_finishCheckBox); vbox->addStretch(1); m_finishPageItem = new KPageWidgetItem(m_finishPageWidget, xi18n("Success")); addPage(m_finishPageItem); } void ImportTableWizard::slot_currentPageChanged(KPageWidgetItem* curPage,KPageWidgetItem* prevPage) { Q_UNUSED(prevPage); if (curPage == m_introPageItem) { } else if (curPage == m_srcConnPageItem) { arriveSrcConnPage(); } else if (curPage == m_srcDBPageItem) { arriveSrcDBPage(); } else if (curPage == m_tablesPageItem) { arriveTableSelectPage(prevPage); } else if (curPage == m_alterTablePageItem) { if (prevPage == m_tablesPageItem) { arriveAlterTablePage(); } } else if (curPage == m_importingPageItem) { arriveImportingPage(); } else if (curPage == m_progressPageItem) { arriveProgressPage(); } else if (curPage == m_finishPageItem) { arriveFinishPage(); } } void ImportTableWizard::arriveSrcConnPage() { } void ImportTableWizard::arriveSrcDBPage() { if (fileBasedSrcSelected()) { //! @todo Back button doesn't work after selecting a file to import } else if (!m_srcDBName) { m_srcDBPageWidget->hide(); qDebug() << "Looks like we need a project selector widget!"; KDbConnectionData* conndata = m_srcConnSel->selectedConnectionData(); if (conndata) { KexiGUIMessageHandler handler; m_prjSet = new KexiProjectSet(&handler); if (!m_prjSet->setConnectionData(conndata)) { handler.showErrorMessage(m_prjSet->result()); delete m_prjSet; m_prjSet = 0; return; } QVBoxLayout *vbox = new QVBoxLayout(m_srcDBPageWidget); KexiUtils::setStandardMarginsAndSpacing(vbox); m_srcDBName = new KexiProjectSelectorWidget(m_srcDBPageWidget, m_prjSet); vbox->addWidget(m_srcDBName); m_srcDBName->label()->setText(xi18n("Select source database you wish to import:")); } m_srcDBPageWidget->show(); } } void ImportTableWizard::arriveTableSelectPage(KPageWidgetItem *prevPage) { if (prevPage == m_alterTablePageItem) { if (m_tableListWidget->count() == 1) { //we was skiping it before back(); } } else { Kexi::ObjectStatus result; KexiUtils::WaitCursor wait; m_tableListWidget->clear(); m_migrateDriver = prepareImport(&result); bool ok = m_migrateDriver; if (ok) { ok = m_migrateDriver->connectSource(&result); } if (ok) { QStringList tableNames; if (m_migrateDriver->tableNames(&tableNames)) { m_tableListWidget->addItems(tableNames); } if (m_tableListWidget->item(0)) { m_tableListWidget->item(0)->setSelected(true); if (m_tableListWidget->count() == 1) { KexiUtils::removeWaitCursor(); next(); } } } KexiUtils::removeWaitCursor(); if (!ok) { QString errMessage =result.message.isEmpty() ? xi18n("Unknown error") : result.message; QString errDescription = result.description.isEmpty() ? errMessage : result.description; KMessageBox::error(this, errMessage, errDescription); setValid(m_tablesPageItem, false); } } } void ImportTableWizard::arriveAlterTablePage() { //! @todo handle errors if (m_tableListWidget->selectedItems().isEmpty()) return; //! @todo (js) support multiple tables? #if 0 foreach(QListWidgetItem *table, m_tableListWidget->selectedItems()) { m_importTableName = table->text(); } #else m_importTableName = m_tableListWidget->selectedItems().first()->text(); #endif QScopedPointer ts(new KDbTableSchema); if (!m_migrateDriver->readTableSchema(m_importTableName, ts.data())) { return; } setValid(m_alterTablePageItem, ts->fieldCount() > 0); if (isValid(m_alterTablePageItem)) { connect(m_alterSchemaWidget->nameWidget(), SIGNAL(textChanged()), this, SLOT(slotNameChanged()), Qt::UniqueConnection); } m_alterSchemaWidget->setTableSchema(ts.take()); if (!readFromTable()) { m_alterSchemaWidget->setTableSchema(nullptr); back(); KMessageBox::information(this, xi18nc("@info", "Could not import table %1. " "Select different table or cancel importing.", m_importTableName)); } } bool ImportTableWizard::readFromTable() { QSharedPointer tableResult = m_migrateDriver->readFromTable(m_importTableName); KDbTableSchema *newSchema = m_alterSchemaWidget->newSchema(); if (!tableResult || tableResult->lastResult().isError() || tableResult->fieldsCount() != newSchema->fieldCount()) { back(); KMessageBox::information(this, xi18nc("@info", "Could not import table %1. " "Select different table or cancel importing.", m_importTableName)); return false; } QScopedPointer> data(new QList); for (int i = 0; i < RECORDS_FOR_PREVIEW; ++i) { QSharedPointer record(tableResult->fetchRecordData()); if (!record) { if (tableResult->lastResult().isError()) { return false; } break; } data->append(record.data()); } if (data->isEmpty()) { back(); KMessageBox::information(this, xi18nc("@info", "No data has been found in table %1. " "Select different table or cancel importing.", m_importTableName)); return false; } m_alterSchemaWidget->model()->setRowCount(data->count()); m_alterSchemaWidget->setData(data.take()); return true; } void ImportTableWizard::arriveImportingPage() { m_importingPageWidget->hide(); #if 0 if (checkUserInput()) { //setNextEnabled(m_importingPageWidget, true); user2Button->setEnabled(true); } else { //setNextEnabled(m_importingPageWidget, false); user2Button->setEnabled(false); } #endif QString txt; txt = xi18nc("@info Table import wizard, final message", "All required information has now been gathered. " "Click Next button to start importing table %1." "Depending on size of the table this may take some time.", m_alterSchemaWidget->nameWidget()->nameText()); m_lblImportingTxt->setText(txt); //temp. hack for MS Access driver only - //! @todo for other databases we will need KexiMigration::Conenction + //! @todo for other databases we will need KexiMigration::Connection //! and KexiMigration::Driver classes bool showOptions = false; if (fileBasedSrcSelected()) { Kexi::ObjectStatus result; KexiMigrate* sourceDriver = prepareImport(&result); if (sourceDriver) { showOptions = !result.error() && sourceDriver->propertyValue("source_database_has_nonunicode_encoding").toBool(); sourceDriver->setData(nullptr); } } if (showOptions) m_importOptionsButton->show(); else m_importOptionsButton->hide(); m_importingPageWidget->show(); setAppropriate(m_progressPageItem, true); } void ImportTableWizard::arriveProgressPage() { m_progressLbl->setText(xi18nc("@info", "Please wait while the table is imported.")); backButton()->setEnabled(false); nextButton()->setEnabled(false); connect(button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &ImportTableWizard::slotCancelClicked); QApplication::setOverrideCursor(Qt::BusyCursor); m_importComplete = doImport(); QApplication::restoreOverrideCursor(); disconnect(button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &ImportTableWizard::slotCancelClicked); next(); } void ImportTableWizard::arriveFinishPage() { if (m_importComplete) { m_finishPageItem->setHeader(xi18n("Success")); m_finishLbl->setText(xi18nc("@info", "Table %1 has been imported.", m_alterSchemaWidget->nameWidget()->nameText())); } else { m_finishPageItem->setHeader(xi18n("Failure")); m_finishLbl->setText(xi18n("An error occured.")); } m_migrateDriver->disconnectSource(); button(QDialogButtonBox::Cancel)->setEnabled(!m_importComplete); m_finishCheckBox->setVisible(m_importComplete); finishButton()->setEnabled(m_importComplete); nextButton()->setEnabled(m_importComplete); setAppropriate(m_progressPageItem, false); } bool ImportTableWizard::fileBasedSrcSelected() const { return m_srcConnSel->selectedConnectionType() == KexiConnectionSelectorWidget::FileBased; } KexiMigrate* ImportTableWizard::prepareImport(Kexi::ObjectStatus *result) { Q_ASSERT(result); // Find a source (migration) driver name QString sourceDriverId = driverIdForSelectedSource(); if (sourceDriverId.isEmpty()) { result->setStatus(xi18n("No appropriate migration driver found."), m_migrateManager.possibleProblemsMessage()); } // Get a source (migration) driver KexiMigrate* sourceDriver = 0; if (!result->error()) { sourceDriver = m_migrateManager.driver(sourceDriverId); if (!sourceDriver || m_migrateManager.result().isError()) { qDebug() << "Import migrate driver error..."; result->setStatus(m_migrateManager.resultable()); } } // Set up source (migration) data required for connection if (sourceDriver && !result->error()) { #if 0 // Setup progress feedback for the GUI if (sourceDriver->progressSupported()) { m_progressBar->updateGeometry(); disconnect(sourceDriver, SIGNAL(progressPercent(int)), this, SLOT(progressUpdated(int))); connect(sourceDriver, SIGNAL(progressPercent(int)), this, SLOT(progressUpdated(int))); progressUpdated(0); } #endif bool keepData = true; #if 0 if (m_importTypeStructureAndDataCheckBox->isChecked()) { qDebug() << "Structure and data selected"; keepData = true; } else if (m_importTypeStructureOnlyCheckBox->isChecked()) { qDebug() << "structure only selected"; keepData = false; } else { qDebug() << "Neither radio button is selected (not possible?) presume keep data"; keepData = true; } #endif KexiMigration::Data* md = new KexiMigration::Data(); if (fileBasedSrcSelected()) { KDbConnectionData* conn_data = new KDbConnectionData(); conn_data->setDatabaseName(m_srcConnSel->selectedFileName()); md->source = conn_data; md->sourceName.clear(); } else { md->source = m_srcConnSel->selectedConnectionData(); md->sourceName = m_srcDBName->selectedProjectData()->databaseName(); } md->setShouldCopyData(keepData); sourceDriver->setData(md); return sourceDriver; } return 0; } //=========================================================== // QString ImportTableWizard::driverIdForSelectedSource() { if (fileBasedSrcSelected()) { QMimeDatabase db; QMimeType mime = db.mimeTypeForFile(m_srcConnSel->selectedFileName()); if (!mime.isValid() || mime.name() == "application/octet-stream" || mime.name() == "text/plain") { //try by URL: mime = db.mimeTypeForFile(m_srcConnSel->selectedFileName()); } if (!mime.isValid()) { return QString(); } const QStringList ids(m_migrateManager.driverIdsForMimeType(mime.name())); //! @todo do we want to return first migrate driver for the mime type or allow to select it? return ids.isEmpty() ? QString() : ids.first(); } return m_srcConnSel->selectedConnectionData() ? m_srcConnSel->selectedConnectionData()->databaseName() : QString(); } bool ImportTableWizard::doImport() { KexiGUIMessageHandler msg; KexiProject* project = KexiMainWindowIface::global()->project(); if (!project) { msg.showErrorMessage(KDbMessageHandler::Error, xi18n("No project available.")); return false; } KexiPart::Part *part = Kexi::partManager().partForPluginId("org.kexi-project.table"); if (!part) { msg.showErrorMessage(Kexi::partManager().result()); return false; } KDbTableSchema* newSchema = m_alterSchemaWidget->newSchema(); if (!newSchema) { msg.showErrorMessage(KDbMessageHandler::Error, xi18n("No table was selected to import.")); return false; } newSchema->setName(m_alterSchemaWidget->nameWidget()->nameText()); newSchema->setCaption(m_alterSchemaWidget->nameWidget()->captionText()); KexiPart::Item* partItemForSavedTable = project->createPartItem(part->info(), newSchema->name()); if (!partItemForSavedTable) { msg.showErrorMessage(project->result()); return false; } //Create the table if (!m_connection->createTable(newSchema, true)) { msg.showErrorMessage(KDbMessageHandler::Error, xi18nc("@info", "Unable to create table %1.", newSchema->name())); return false; } m_alterSchemaWidget->takeTableSchema(); //m_connection takes ownership of the KDbTableSchema object //Import the data QApplication::setOverrideCursor(Qt::BusyCursor); QList row; unsigned int fieldCount = newSchema->fieldCount(); m_migrateDriver->moveFirst(); KDbTransactionGuard tg(m_connection); if (m_connection->result().isError()) { QApplication::restoreOverrideCursor(); return false; } do { for (unsigned int i = 0; i < fieldCount; ++i) { if (m_importWasCanceled) { return false; } if (i % 100 == 0) { QApplication::processEvents(); } row.append(m_migrateDriver->value(i)); } m_connection->insertRecord(newSchema, row); row.clear(); } while (m_migrateDriver->moveNext()); if (!tg.commit()) { QApplication::restoreOverrideCursor(); return false; } QApplication::restoreOverrideCursor(); //Done so save part and update gui partItemForSavedTable->setIdentifier(newSchema->id()); project->addStoredItem(part->info(), partItemForSavedTable); return true; } void ImportTableWizard::slotConnPageItemSelected(bool isSelected) { setValid(m_srcConnPageItem, isSelected); if (isSelected && fileBasedSrcSelected()) { next(); } } void ImportTableWizard::slotTableListWidgetSelectionChanged() { setValid(m_tablesPageItem, !m_tableListWidget->selectedItems().isEmpty()); } void ImportTableWizard::slotNameChanged() { setValid(m_alterTablePageItem, !m_alterSchemaWidget->nameWidget()->captionText().isEmpty()); } void ImportTableWizard::slotCancelClicked() { m_importWasCanceled = true; } diff --git a/src/migration/importwizard.cpp b/src/migration/importwizard.cpp index dfeb84abd..3fff1906e 100644 --- a/src/migration/importwizard.cpp +++ b/src/migration/importwizard.cpp @@ -1,1140 +1,1140 @@ /* This file is part of the KDE project Copyright (C) 2004-2009 Adam Pigg Copyright (C) 2004-2016 Jarosław Staniek Copyright (C) 2005 Martin Ellis This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "importwizard.h" #include "keximigrate.h" #include "importoptionsdlg.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace KexiMigration; class Q_DECL_HIDDEN ImportWizard::Private { public: Private(QMap* args_) : srcProjectSelector(0) , fileBasedDstWasPresented(false) , setupFileBasedSrcNeeded(true) , importExecuted(false) , prjSet(0) , args(args_) { } ~Private() { delete prjSet; } QWidget *introPageWidget, *srcConnPageWidget, *srcDBPageWidget, *dstTypePageWidget, *dstPageWidget, *importTypePageWidget, *importingPageWidget, *finishPageWidget; KPageWidgetItem *introPageItem, *srcConnPageItem, *srcDBPageItem, *dstTypePageItem, *dstPageItem, *importTypePageItem, *importingPageItem, *finishPageItem; QGroupBox *importTypeGroupBox; QRadioButton *importTypeStructureAndDataCheckBox; QRadioButton *importTypeStructureOnlyCheckBox; KexiDBTitlePage* dstTitlePageWidget; KPageWidgetItem *dstTitlePageItem; KexiPrjTypeSelector *dstPrjTypeSelector; KexiConnectionSelectorWidget *srcConn, *dstConn; QString driverIdForSelectedSource; QLineEdit *dstNewDBTitleLineEdit; QLabel *dstNewDBNameLabel; QLineEdit *dstNewDBNameLineEdit; QLabel *dstNewDBNameUrlLabel; KUrlRequester *dstNewDBNameUrl; KexiStartupFileHandler *dstNewDBFileHandler; KexiProjectSelectorWidget *srcProjectSelector; QLabel *lblImportingTxt, *lblImportingErrTxt, *finishLbl; QCheckBox *openImportedProjectCheckBox; bool fileBasedDstWasPresented; bool setupFileBasedSrcNeeded; bool importExecuted; //!< used in import() KexiProjectSet* prjSet; QProgressBar *progressBar; QPushButton* importOptionsButton; QMap *args; QString predefinedDatabaseName, predefinedMimeType; KDbConnectionData *predefinedConnectionData; MigrateManager migrateManager; //!< object lives here, so status messages can be globally preserved //! Encoding for source db. Currently only used for MDB driver. //! @todo Hardcoded. Move to KexiMigrate driver's impl. QString sourceDBEncoding; }; //=========================================================== // ImportWizard::ImportWizard(QWidget *parent, QMap* args) : KAssistantDialog(parent) , d(new Private(args)) { setModal(true); setWindowTitle(xi18nc("@title:window", "Import Database")); setWindowIcon(KexiIcon("database-import")); KexiMainWindowIface::global()->setReasonableDialogSize(this); parseArguments(); setupIntro(); setupSrcConn(); setupSrcDB(); setupDstType(); setupDstTitle(); setupDst(); setupImportType(); setupImporting(); setupFinish(); connect(this, SIGNAL(currentPageChanged(KPageWidgetItem*,KPageWidgetItem*)), this, SLOT(slot_currentPageChanged(KPageWidgetItem*,KPageWidgetItem*))); connect(button(QDialogButtonBox::Help), &QPushButton::clicked, this, &ImportWizard::helpClicked); if (d->predefinedConnectionData) { // setup wizard for predefined server source d->srcConn->showAdvancedConnection(); setAppropriate(d->srcConnPageItem, false); setAppropriate(d->srcDBPageItem, false); } else if (!d->predefinedDatabaseName.isEmpty()) { // setup wizard for predefined source // (used when external project type was opened in Kexi, e.g. mdb file) setAppropriate(d->srcConnPageItem, false); setAppropriate(d->srcDBPageItem, false); d->srcConn->showSimpleConnection(); d->srcConn->setSelectedFileName(d->predefinedDatabaseName); #if 0 //disable all prev pages except "welcome" page for (int i = 0; i < indexOf(d->dstTypePage); i++) { if (page(i) != d->introPage) setAppropriate(page(i), false); } #endif } d->sourceDBEncoding = QString::fromLatin1(KexiUtils::encoding()); //default } //=========================================================== // ImportWizard::~ImportWizard() { delete d; } //=========================================================== // void ImportWizard::parseArguments() { d->predefinedConnectionData = 0; if (!d->args) return; if (!(*d->args)["databaseName"].isEmpty() && !(*d->args)["mimeType"].isEmpty()) { d->predefinedDatabaseName = (*d->args)["databaseName"]; d->predefinedMimeType = (*d->args)["mimeType"]; if (d->args->contains("connectionData")) { bool ok; d->predefinedConnectionData = new KDbConnectionData( KDbUtils::deserializeMap((*d->args)["connectionData"]), &ok); if (!ok) { delete d->predefinedConnectionData; d->predefinedConnectionData = 0; } } } d->args->clear(); } QString ImportWizard::selectedSourceFileName() const { if (d->predefinedDatabaseName.isEmpty()) return d->srcConn->selectedFileName(); return d->predefinedDatabaseName; } //=========================================================== // void ImportWizard::setupIntro() { d->introPageWidget = new QWidget(this); QVBoxLayout *vbox = new QVBoxLayout(); d->introPageWidget->setLayout(vbox); KexiUtils::setStandardMarginsAndSpacing(vbox); QLabel *lblIntro = new QLabel(d->introPageWidget); lblIntro->setAlignment(Qt::AlignTop | Qt::AlignLeft); lblIntro->setWordWrap(true); lblIntro->setTextFormat(Qt::RichText); QString msg; if (d->predefinedConnectionData) { //predefined import: server source msg = xi18nc("@info", "Database Importing Assistant is about to import %1 database " "(connection %2) into a Kexi project.", d->predefinedDatabaseName, d->predefinedConnectionData->toUserVisibleString()); } else if (!d->predefinedDatabaseName.isEmpty()) { //predefined import: file source //! @todo this message is currently ok for files only QMimeDatabase db; QMimeType mime = db.mimeTypeForName(d->predefinedMimeType); if (!mime.isValid()) { qWarning() << QString("'%1' mimetype not installed!").arg(d->predefinedMimeType); } d->driverIdForSelectedSource = driverIdForMimeType(mime); msg = xi18nc("@info", "Database Importing Assistant is about to import %1 file " "of type %2 into a Kexi project.", QDir::toNativeSeparators(d->predefinedDatabaseName), mime.isValid() ? mime.comment() : "???"); } else { msg = xi18nc("@info", "Database Importing Assistant allows you to import an existing database " "into a Kexi project."); } // note: we're using .arg() here because the msg argument is already in rich-text format QString finalMessage = xi18nc("@info", "%1" "Click Next button to continue or " "Cancel button to exit this assistant.").arg(msg); lblIntro->setText(finalMessage); vbox->addWidget(lblIntro); d->introPageItem = new KPageWidgetItem(d->introPageWidget, xi18n("Welcome to the Database Importing Assistant")); addPage(d->introPageItem); } //=========================================================== // void ImportWizard::setupSrcConn() { d->srcConnPageWidget = new QWidget(this); QVBoxLayout *vbox = new QVBoxLayout(d->srcConnPageWidget); KexiUtils::setStandardMarginsAndSpacing(vbox); d->srcConn = new KexiConnectionSelectorWidget(&Kexi::connset(), "kfiledialog:///ProjectMigrationSourceDir", KFileWidget::Opening, d->srcConnPageWidget); d->srcConn->hideConnectonIcon(); d->srcConn->showSimpleConnection(); connect(d->srcConn, &KexiConnectionSelectorWidget::connectionSelected, this, &ImportWizard::sourceConnectionSelected); QSet excludedFilters; //! @todo remove when support for kexi files as source prj is added in migration excludedFilters += KDb::defaultFileBasedDriverMimeType(); excludedFilters += "application/x-kexiproject-shortcut"; excludedFilters += "application/x-kexi-connectiondata"; d->srcConn->fileWidget->setExcludedFilters(excludedFilters); vbox->addWidget(d->srcConn); d->srcConnPageItem = new KPageWidgetItem(d->srcConnPageWidget, xi18n("Select Location for Source Database")); addPage(d->srcConnPageItem); } //=========================================================== // void ImportWizard::setupSrcDB() { // arrivesrcdbPage creates widgets on that page d->srcDBPageWidget = new QWidget(this); d->srcDBPageItem = new KPageWidgetItem(d->srcDBPageWidget, xi18n("Select Source Database")); addPage(d->srcDBPageItem); } //=========================================================== // void ImportWizard::setupDstType() { d->dstTypePageWidget = new QWidget(this); QVBoxLayout *vbox = new QVBoxLayout(d->dstTypePageWidget); KexiUtils::setStandardMarginsAndSpacing(vbox); QHBoxLayout *hbox = new QHBoxLayout; vbox->addLayout(hbox); KexiUtils::setStandardMarginsAndSpacing(hbox); QLabel *lbl = new QLabel(xi18n("Destination database type:") /*+ ' '*/, d->dstTypePageWidget); lbl->setAlignment(Qt::AlignLeft | Qt::AlignTop); lbl->setTextFormat(Qt::RichText); hbox->addWidget(lbl); d->dstPrjTypeSelector = new KexiPrjTypeSelector(d->dstTypePageWidget); hbox->addWidget(d->dstPrjTypeSelector); d->dstPrjTypeSelector->option_file->setText(xi18n("Database project stored in a file")); d->dstPrjTypeSelector->option_server->setText(xi18n("Database project stored on a server")); hbox->addStretch(1); vbox->addStretch(1); d->dstTypePageItem = new KPageWidgetItem(d->dstTypePageWidget, xi18n("Select Destination Database Type")); addPage(d->dstTypePageItem); } //=========================================================== // void ImportWizard::setupDstTitle() { d->dstTitlePageWidget = new KexiDBTitlePage(xi18n("Destination project's caption:"), this); d->dstTitlePageWidget->layout()->setMargin(KexiUtils::marginHint()); d->dstTitlePageWidget->updateGeometry(); d->dstNewDBTitleLineEdit = d->dstTitlePageWidget->le_title; connect(d->dstNewDBTitleLineEdit, SIGNAL(textChanged(QString)), this, SLOT(destinationTitleTextChanged(QString))); d->dstNewDBNameUrlLabel = d->dstTitlePageWidget->label_requester; d->dstNewDBNameUrl = d->dstTitlePageWidget->file_requester; d->dstNewDBFileHandler = new KexiStartupFileHandler( QUrl("kfiledialog:///ProjectMigrationDestinationDir"), KexiStartupFileHandler::SavingFileBasedDB, d->dstTitlePageWidget->file_requester); d->dstNewDBNameLabel = new QLabel(xi18n("Destination project's name:"), d->dstTitlePageWidget); d->dstTitlePageWidget->formLayout->setWidget(2, QFormLayout::LabelRole, d->dstNewDBNameLabel); d->dstNewDBNameLineEdit = new QLineEdit(d->dstTitlePageWidget); d->dstNewDBNameLineEdit->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); KDbIdentifierValidator *idValidator = new KDbIdentifierValidator(this); idValidator->setLowerCaseForced(true); d->dstNewDBNameLineEdit->setValidator(idValidator); d->dstTitlePageWidget->formLayout->setWidget(2, QFormLayout::FieldRole, d->dstNewDBNameLineEdit); d->dstTitlePageItem = new KPageWidgetItem(d->dstTitlePageWidget, xi18n("Enter Destination Database Project's Caption")); addPage(d->dstTitlePageItem); } void ImportWizard::destinationTitleTextChanged(const QString & text) { Q_UNUSED(text); updateDestinationDBFileName(); } void ImportWizard::updateDestinationDBFileName() { d->dstNewDBFileHandler->updateUrl(d->dstNewDBTitleLineEdit->text()); d->dstNewDBNameLineEdit->setText(d->dstNewDBTitleLineEdit->text()); } //=========================================================== // void ImportWizard::setupDst() { d->dstPageWidget = new QWidget(this); QVBoxLayout *vbox = new QVBoxLayout(d->dstPageWidget); KexiUtils::setStandardMarginsAndSpacing(vbox); d->dstConn = new KexiConnectionSelectorWidget(&Kexi::connset(), "kfiledialog:///ProjectMigrationDestinationDir", KFileWidget::Saving, d->dstPageWidget); d->dstConn->hideHelpers(); vbox->addWidget(d->dstConn); connect(d->dstConn, SIGNAL(connectionItemExecuted(ConnectionDataLVItem*)), this, SLOT(next())); d->dstConn->showSimpleConnection(); //anyway, db files will be _saved_ d->dstConn->fileWidget->setMode(KexiFileWidget::SavingFileBasedDB); d->dstPageItem = new KPageWidgetItem(d->dstPageWidget, xi18n("Select Location for Destination Database Project")); addPage(d->dstPageItem); } //=========================================================== // void ImportWizard::setupImportType() { d->importTypePageWidget = new QWidget(this); QVBoxLayout *vbox = new QVBoxLayout(d->importTypePageWidget); KexiUtils::setStandardMarginsAndSpacing(vbox); d->importTypeGroupBox = new QGroupBox(d->importTypePageWidget); vbox->addWidget(d->importTypeGroupBox); QVBoxLayout *importTypeGroupBoxLyr = new QVBoxLayout; importTypeGroupBoxLyr->addWidget( d->importTypeStructureAndDataCheckBox = new QRadioButton( xi18nc("Scope of import", "Structure and data"), d->importTypeGroupBox)); d->importTypeStructureAndDataCheckBox->setChecked(true); importTypeGroupBoxLyr->addWidget( d->importTypeStructureOnlyCheckBox = new QRadioButton( xi18nc("Scope of import", "Structure only"), d->importTypeGroupBox)); importTypeGroupBoxLyr->addStretch(1); d->importTypeGroupBox->setLayout(importTypeGroupBoxLyr); d->importTypePageItem = new KPageWidgetItem(d->importTypePageWidget, xi18n("Select Scope of Import")); addPage(d->importTypePageItem); } //=========================================================== // void ImportWizard::setupImporting() { d->importingPageWidget = new QWidget(this); d->importingPageWidget->hide(); QVBoxLayout *vbox = new QVBoxLayout(d->importingPageWidget); KexiUtils::setStandardMarginsAndSpacing(vbox); d->lblImportingTxt = new QLabel(d->importingPageWidget); d->lblImportingTxt->setAlignment(Qt::AlignTop | Qt::AlignLeft); d->lblImportingTxt->setWordWrap(true); d->lblImportingTxt->setTextFormat(Qt::RichText); d->lblImportingErrTxt = new QLabel(d->importingPageWidget); d->lblImportingErrTxt->setAlignment(Qt::AlignTop | Qt::AlignLeft); d->lblImportingErrTxt->setWordWrap(true); d->lblImportingErrTxt->setTextFormat(Qt::RichText); d->progressBar = new QProgressBar(d->importingPageWidget); d->progressBar->setRange(0, 100); d->progressBar->hide(); vbox->addWidget(d->lblImportingTxt); vbox->addWidget(d->lblImportingErrTxt); vbox->addStretch(1); QWidget *options_widget = new QWidget(d->importingPageWidget); vbox->addWidget(options_widget); QVBoxLayout *options_vbox = new QVBoxLayout(options_widget); options_vbox->setSpacing(KexiUtils::spacingHint()); QHBoxLayout *importOptionsButtonLyr = new QHBoxLayout; options_vbox->addLayout(importOptionsButtonLyr); d->importOptionsButton = new QPushButton(koIcon("configure"), xi18n("Advanced Options"), options_widget); connect(d->importOptionsButton, SIGNAL(clicked()), this, SLOT(slotOptionsButtonClicked())); importOptionsButtonLyr->addStretch(1); importOptionsButtonLyr->addWidget(d->importOptionsButton); importOptionsButtonLyr->addStretch(1); options_vbox->addStretch(1); vbox->addWidget(d->progressBar); vbox->addStretch(2); d->importingPageWidget->show(); d->importingPageItem = new KPageWidgetItem(d->importingPageWidget, xi18n("Importing")); addPage(d->importingPageItem); } //=========================================================== // void ImportWizard::setupFinish() { d->finishPageWidget = new QWidget(this); d->finishPageWidget->hide(); QVBoxLayout *vbox = new QVBoxLayout(d->finishPageWidget); KexiUtils::setStandardMarginsAndSpacing(vbox); d->finishLbl = new QLabel(d->finishPageWidget); d->finishLbl->setAlignment(Qt::AlignTop | Qt::AlignLeft); d->finishLbl->setWordWrap(true); d->finishLbl->setTextFormat(Qt::RichText); vbox->addWidget(d->finishLbl); d->openImportedProjectCheckBox = new QCheckBox(xi18n("Open imported project"), d->finishPageWidget); d->openImportedProjectCheckBox->setChecked(true); vbox->addSpacing(KexiUtils::spacingHint()); vbox->addWidget(d->openImportedProjectCheckBox); vbox->addStretch(1); d->finishPageItem = new KPageWidgetItem(d->finishPageWidget, xi18n("Success")); addPage(d->finishPageItem); } //=========================================================== // bool ImportWizard::checkUserInput() { QString issues; if (d->dstNewDBTitleLineEdit->text().isEmpty()) { issues = xi18nc("@info", "No new database name was entered."); } Kexi::ObjectStatus result; KexiMigrate* sourceDriver = prepareImport(result); if (sourceDriver && sourceDriver->isSourceAndDestinationDataSourceTheSame()) { // note: we're using .arg() here because the 'issues' argument is already in rich-text format issues = xi18nc("@info", "%1Source database is the same as destination.") .arg(issues); } if (!issues.isEmpty()) { // note: we're using .arg() here because the 'issues' argument is already in rich-text format d->lblImportingErrTxt->setText( xi18nc("@info", "Following issues were found with the data you entered:" "%1" "Please click Back button and correct these issues.") .arg(issues)); return false; } return true; } void ImportWizard::arriveSrcConnPage() { d->srcConnPageWidget->hide(); /*! @todo KexiFileWidget needs "open file" and "open server" modes in addition to just "open" */ if (d->setupFileBasedSrcNeeded) { d->setupFileBasedSrcNeeded = false; QSet additionalMimeTypes; d->srcConn->fileWidget->setMode(KexiFileWidget::Opening); d->srcConn->fileWidget->setAdditionalFilters(additionalMimeTypes); } /*! @todo Support different file extensions based on MigrationDriver */ d->srcConnPageWidget->show(); } void ImportWizard::arriveSrcDBPage() { if (fileBasedSrcSelected()) { //! @todo Back button doesn't work after selecting a file to import } else { if (!d->srcProjectSelector) { QVBoxLayout *vbox = new QVBoxLayout(d->srcDBPageWidget); d->srcProjectSelector = new KexiProjectSelectorWidget(d->srcDBPageWidget); vbox->addWidget(d->srcProjectSelector); KexiUtils::setStandardMarginsAndSpacing(vbox); d->srcProjectSelector->label()->setText(xi18n("Select source database you wish to import:")); } d->srcDBPageWidget->hide(); KDbConnectionData* condata = d->srcConn->selectedConnectionData(); Q_ASSERT(condata); Q_ASSERT(d->prjSet); d->srcProjectSelector->setProjectSet(d->prjSet); d->srcDBPageWidget->show(); } } void ImportWizard::arriveDstTitlePage() { d->dstNewDBNameUrlLabel->setVisible(fileBasedDstSelected()); d->dstNewDBNameUrl->setVisible(fileBasedDstSelected()); d->dstNewDBNameLabel->setVisible(!fileBasedDstSelected()); d->dstNewDBNameLineEdit->setVisible(!fileBasedDstSelected()); if (fileBasedSrcSelected()) { const QString fname(selectedSourceFileName()); QString suggestedDBName(QFileInfo(fname).fileName()); const QFileInfo fi(suggestedDBName); suggestedDBName = suggestedDBName.left(suggestedDBName.length() - (fi.completeSuffix().isEmpty() ? 0 : (fi.completeSuffix().length() + 1))); d->dstNewDBTitleLineEdit->setText(suggestedDBName); } else { if (d->predefinedConnectionData) { // server source db is predefined d->dstNewDBTitleLineEdit->setText(d->predefinedDatabaseName); } else { if (!d->srcProjectSelector || !d->srcProjectSelector->selectedProjectData()) { back(); //!< @todo return; } d->dstNewDBTitleLineEdit->setText(d->srcProjectSelector->selectedProjectData()->databaseName()); } } d->dstNewDBTitleLineEdit->selectAll(); d->dstNewDBTitleLineEdit->setFocus(); updateDestinationDBFileName(); } void ImportWizard::arriveDstPage() { if (fileBasedDstSelected()) { d->dstPageWidget->hide(); KAssistantDialog::next(); return; } else { d->dstConn->showAdvancedConnection(); } d->dstPageWidget->show(); } void ImportWizard::arriveImportingPage() { d->importingPageWidget->hide(); nextButton()->setEnabled(checkUserInput()); d->lblImportingTxt->setText(xi18nc("@info", "All required information has now " "been gathered. Click Next button to start importing." "Depending on size of the database this may take some time." /*"Note: You may be asked for extra " "information such as field types if " "the wizard could not automatically " "determine this for you."*/)); //temp. hack for MS Access driver only -//! @todo for other databases we will need KexiMigration::Conenction +//! @todo for other databases we will need KexiMigration::Connection //! and KexiMigration::Driver classes bool showOptions = false; if (fileBasedSrcSelected()) { Kexi::ObjectStatus result; KexiMigrate* sourceDriver = prepareImport(result); if (sourceDriver) { showOptions = !result.error() && sourceDriver->propertyValue("source_database_has_nonunicode_encoding").toBool(); sourceDriver->setData(nullptr); } } if (showOptions) d->importOptionsButton->show(); else d->importOptionsButton->hide(); d->importingPageWidget->show(); } void ImportWizard::arriveFinishPage() { } bool ImportWizard::fileBasedSrcSelected() const { if (d->predefinedConnectionData) return false; // qDebug() << (d->srcConn->selectedConnectionType()==KexiConnectionSelectorWidget::FileBased); return d->srcConn->selectedConnectionType() == KexiConnectionSelectorWidget::FileBased; } bool ImportWizard::fileBasedDstSelected() const { return d->dstPrjTypeSelector->option_file->isChecked(); } void ImportWizard::progressUpdated(int percent) { d->progressBar->setValue(percent); qApp->processEvents(); } QString ImportWizard::driverIdForMimeType(const QMimeType &mime) const { if (!mime.isValid()) { return QString(); } const QStringList ids(d->migrateManager.driverIdsForMimeType(mime.name())); //! @todo do we want to return first migrate driver for the mime type or allow to select it? return ids.isEmpty() ? QString() : ids.first(); } QString ImportWizard::findDriverIdForSelectedSource() { if (fileBasedSrcSelected()) { QMimeDatabase db; QMimeType mime = db.mimeTypeForFile(selectedSourceFileName()); if (!mime.isValid() || mime.name() == "application/octet-stream" || mime.name() == "text/plain" || mime.name() == "application/zip") { //try by URL: mime = db.mimeTypeForFile(selectedSourceFileName()); } return driverIdForMimeType(mime); } //server-based QString sourceDriverId; if (d->predefinedConnectionData) { sourceDriverId = d->predefinedConnectionData->driverId(); } else if (d->srcConn->selectedConnectionData()) { sourceDriverId = d->srcConn->selectedConnectionData()->driverId(); } const QStringList migrationDriverIds(d->migrateManager.driverIdsForSourceDriver(sourceDriverId)); //! @todo First found driver ID is picked. It's OK as long as there is one migration //! driver per source database type. How about allowing users to pick migration driver? return migrationDriverIds.isEmpty() ? QString() : migrationDriverIds.first(); } //=========================================================== // void ImportWizard::accept() { if (d->args) { if ((!fileBasedDstSelected() && !d->args->contains("destinationConnectionShortcut")) || !d->openImportedProjectCheckBox->isChecked()) { //do not open dest db if used didn't want it //for server connections, destinationConnectionShortcut must be defined d->args->remove("destinationDatabaseName"); } } KAssistantDialog::accept(); } KexiMigrate* ImportWizard::prepareImport(Kexi::ObjectStatus& result) { KexiUtils::WaitCursor wait; // Start with a driver manager KDbDriverManager manager; //qDebug() << "Creating destination driver..."; // Get a driver to the destination database KDbDriver *destDriver = manager.driver( d->dstConn->selectedConnectionData() ? d->dstConn->selectedConnectionData()->driverId() : KDb::defaultFileBasedDriverId()); if (!destDriver || manager.result().isError()) { result.setStatus(manager.resultable()); qWarning() << "Manager error:" << manager.result(); } // Set up destination connection data KDbConnectionData *cdata = 0; QScopedPointer cdataDeleter; QString dbname; if (!result.error()) { if (d->dstConn->selectedConnectionData()) { //server-based project qDebug() << "Server destination..."; cdata = d->dstConn->selectedConnectionData(); dbname = d->dstNewDBNameLineEdit->text(); } else { //file-based project qDebug() << "File Destination..."; cdata = new KDbConnectionData(); cdataDeleter.reset(cdata); // ownership won't be transferred cdata->setCaption(d->dstNewDBTitleLineEdit->text()); cdata->setDriverId(KDb::defaultFileBasedDriverId()); dbname = d->dstTitlePageWidget->file_requester->url().toLocalFile(); cdata->setDatabaseName(dbname); qDebug() << "Current file name:" << dbname; } } // Find a source (migration) driver name if (!result.error()) { if (d->driverIdForSelectedSource.isEmpty()) result.setStatus(xi18n("No appropriate migration driver found."), d->migrateManager.possibleProblemsMessage()); } // Get a source (migration) driver KexiMigrate* sourceDriver = 0; if (!result.error()) { sourceDriver = d->migrateManager.driver(d->driverIdForSelectedSource); if (!sourceDriver || d->migrateManager.result().isError()) { qDebug() << "Import migrate driver error..."; result.setStatus(d->migrateManager.resultable()); } } KexiUtils::removeWaitCursor(); // Set up source (migration) data required for connection if (sourceDriver && !result.error() && cdata) { // Setup progress feedback for the GUI if (sourceDriver->progressSupported()) { d->progressBar->updateGeometry(); disconnect(sourceDriver, SIGNAL(progressPercent(int)), this, SLOT(progressUpdated(int))); connect(sourceDriver, SIGNAL(progressPercent(int)), this, SLOT(progressUpdated(int))); progressUpdated(0); } bool keepData; if (d->importTypeStructureAndDataCheckBox->isChecked()) { qDebug() << "Structure and data selected"; keepData = true; } else if (d->importTypeStructureOnlyCheckBox->isChecked()) { qDebug() << "structure only selected"; keepData = false; } else { qDebug() << "Neither radio button is selected (not possible?) presume keep data"; keepData = true; } KexiMigration::Data* md = new KexiMigration::Data(); md->setDestinationProjectData(new KexiProjectData(*cdata, dbname)); if (fileBasedSrcSelected()) { KDbConnectionData* conn_data = new KDbConnectionData(); conn_data->setDatabaseName(selectedSourceFileName()); md->source = conn_data; md->sourceName.clear(); } else { if (d->predefinedConnectionData) md->source = d->predefinedConnectionData; else md->source = d->srcConn->selectedConnectionData(); if (!d->predefinedDatabaseName.isEmpty()) md->sourceName = d->predefinedDatabaseName; else md->sourceName = d->srcProjectSelector->selectedProjectData()->databaseName(); //! @todo Aah, this is so C-like. Move to performImport(). } md->setShouldCopyData(keepData); sourceDriver->setData(md); return sourceDriver; } return 0; } tristate ImportWizard::import() { d->importExecuted = true; Kexi::ObjectStatus result; KexiMigrate* sourceDriver = prepareImport(result); bool acceptingNeeded = false; // Perform import if (sourceDriver && !result.error()) { if (!d->sourceDBEncoding.isEmpty()) { sourceDriver->setPropertyValue("source_database_nonunicode_encoding", QVariant(d->sourceDBEncoding.toUpper().remove(' ')) // "CP1250", not "cp 1250" ); } if (!sourceDriver->checkIfDestinationDatabaseOverwritingNeedsAccepting(&result, &acceptingNeeded)) { qDebug() << "Abort import cause checkIfDestinationDatabaseOverwritingNeedsAccepting " "returned false."; return false; } qDebug() << sourceDriver->data()->destinationProjectData()->databaseName(); qDebug() << "Performing import..."; } if (sourceDriver && !result.error() && acceptingNeeded) { // ok, the destination-db already exists... if (KMessageBox::Yes != KMessageBox::warningYesNo(this, xi18nc("@info (don't add tags around %1, it's done already)", "Database %1 already exists." "Do you want to replace it with a new one?", KexiUtils::localizedStringToHtmlSubstring( sourceDriver->data()->destinationProjectData()->infoString())), 0, KGuiItem(xi18nc("@action:button Replace Database", "&Replace")), KStandardGuiItem::no())) { return cancelled; } } if (sourceDriver && !result.error() && sourceDriver->progressSupported()) { d->progressBar->show(); } if (sourceDriver && !result.error() && sourceDriver->performImport(&result)) { if (d->args) { d->args->insert("destinationDatabaseName", fileBasedDstSelected() ? sourceDriver->data()->destinationProjectData()->connectionData()->databaseName() : sourceDriver->data()->destinationProjectData()->databaseName()); QString destinationConnectionShortcut; if (d->dstConn->selectedConnectionData()) { destinationConnectionShortcut = Kexi::connset().fileNameForConnectionData(*d->dstConn->selectedConnectionData()); } if (!destinationConnectionShortcut.isEmpty()) { d->args->insert("destinationConnectionShortcut", destinationConnectionShortcut); } } d->finishPageItem->setHeader(xi18n("Success")); return true; } if (!sourceDriver || result.error()) { d->progressBar->setValue(0); d->progressBar->hide(); QString msg, details; KexiTextMessageHandler handler(&msg, &details); handler.showErrorMessage(&result); qDebug() << msg << "\n" << details; d->finishPageItem->setHeader(xi18n("Failure")); // note: we're using .arg() here because the msg and details arguments are already in rich-text format d->finishLbl->setText( xi18nc("@info", "Import failed." "%1" "%2" "You can click Back button and try again.") .arg(msg).arg(details)); return false; } return true; } void ImportWizard::reject() { KAssistantDialog::reject(); } //=========================================================== // void ImportWizard::next() { if (currentPage() == d->srcConnPageItem) { if (fileBasedSrcSelected() && /*! @todo use QUrl? */!QFileInfo(selectedSourceFileName()).isFile()) { KMessageBox::sorry(this, xi18n("Select source database filename.")); return; } KDbConnectionData* conndata = d->srcConn->selectedConnectionData(); if (!fileBasedSrcSelected() && !conndata) { KMessageBox::sorry(this, xi18n("Select source database.")); return; } d->driverIdForSelectedSource = findDriverIdForSelectedSource(); // cache KexiMigrate* import = d->migrateManager.driver(d->driverIdForSelectedSource); if (!import || d->migrateManager.result().isError()) { QString dbname; if (fileBasedSrcSelected()) dbname = QDir::toNativeSeparators(selectedSourceFileName()); else dbname = conndata ? conndata->toUserVisibleString() : QString(); KMessageBox::error(this, dbname.isEmpty() ? xi18n("Could not import database. This type is not supported.") : xi18nc("@info", "Could not import database %1. " "This type is not supported.", dbname)); return; } if (!fileBasedSrcSelected()) { // make sure we have password if needed tristate passwordNeeded = false; if (conndata->password().isEmpty()) { passwordNeeded = KexiDBPasswordDialog::getPasswordIfNeeded(conndata, this); } bool ok = passwordNeeded != cancelled; if (ok) { KexiGUIMessageHandler handler; d->prjSet = new KexiProjectSet(&handler); if (!d->prjSet->setConnectionData(conndata)) { handler.showErrorMessage(d->prjSet->result()); ok = false; } } if (!ok) { if (passwordNeeded == true) { conndata->setPassword(QString::null); // not clear(), we have to remove password } delete d->prjSet; d->prjSet = 0; return; } } } else if (currentPage() == d->dstTitlePageItem) { if (fileBasedDstSelected()) { if (QFileInfo::exists(d->dstNewDBNameUrl->url().toLocalFile())) { if (!KexiUtils::askForFileOverwriting(d->dstNewDBNameUrl->url().toLocalFile(), this)) { return; } } } } else if (currentPage() == d->importTypePageItem) { if (!fileBasedDstSelected()) { // make sure we have password if needed tristate passwordNeeded = false; KDbConnectionData* condata = d->dstConn->selectedConnectionData(); if (condata->password().isEmpty()) { passwordNeeded = KexiDBPasswordDialog::getPasswordIfNeeded(condata, this); } bool ok = passwordNeeded != cancelled; if (!ok) { if (passwordNeeded == true) { condata->setPassword(QString::null); // not clear(), we have to remove password } return; } } } else if (currentPage() == d->importingPageItem) { if (!d->importExecuted) { d->importOptionsButton->hide(); backButton()->setEnabled(false); nextButton()->setEnabled(false); finishButton()->setEnabled(false); d->lblImportingTxt->setText(xi18n("Importing in progress...")); tristate res = import(); if (true == res) { d->finishLbl->setText( xi18nc("@info", "Database has been imported into Kexi project %1.", d->dstNewDBNameLineEdit->text())); button(QDialogButtonBox::Cancel)->setEnabled(false); backButton()->setEnabled(false); nextButton()->setEnabled(true); finishButton()->setEnabled(false); d->openImportedProjectCheckBox->show(); next(); return; } d->progressBar->hide(); button(QDialogButtonBox::Cancel)->setEnabled(true); backButton()->setEnabled(true); nextButton()->setEnabled(false); finishButton()->setEnabled(false); d->openImportedProjectCheckBox->hide(); if (!res) next(); else if (~res) { arriveImportingPage(); } d->importExecuted = false; return; } } setAppropriate(d->srcDBPageItem, !fileBasedSrcSelected() && !d->predefinedConnectionData); setAppropriate(d->dstPageItem, !fileBasedDstSelected()); KAssistantDialog::next(); } void ImportWizard::back() { setAppropriate(d->srcDBPageItem, !fileBasedSrcSelected() && !d->predefinedConnectionData); KAssistantDialog::back(); } void ImportWizard::slot_currentPageChanged(KPageWidgetItem* curPage,KPageWidgetItem* prevPage) { Q_UNUSED(prevPage); if (curPage == d->introPageItem) { } else if (curPage == d->srcConnPageItem) { arriveSrcConnPage(); } else if (curPage == d->srcDBPageItem) { arriveSrcDBPage(); } else if (curPage == d->dstTypePageItem) { } else if (curPage == d->dstTitlePageItem) { arriveDstTitlePage(); } else if (curPage == d->dstPageItem) { if (fileBasedDstSelected()) { if (prevPage == d->importTypePageItem) { KAssistantDialog::back(); } else { KAssistantDialog::next(); } } else { arriveDstPage(); } } else if (curPage == d->importingPageItem) { arriveImportingPage(); } else if (curPage == d->finishPageItem) { arriveFinishPage(); } } void ImportWizard::helpClicked() { if (currentPage() == d->introPageItem) { KMessageBox::information(this, xi18n("No help is available for this page."), xi18n("Help")); } else if (currentPage() == d->srcConnPageItem) { KMessageBox::information(this, xi18n("Here you can choose the location to import data from."), xi18n("Help")); } else if (currentPage() == d->srcDBPageItem) { KMessageBox::information(this, xi18n("Here you can choose the actual database to import data from."), xi18n("Help")); } else if (currentPage() == d->dstTypePageItem) { KMessageBox::information(this, xi18n("Here you can choose the location to save the data."), xi18n("Help")); } else if (currentPage() == d->dstPageItem) { KMessageBox::information(this, xi18n("Here you can choose the location to save the data in and the new database name."), xi18n("Help")); } else if (currentPage() == d->finishPageItem || currentPage() == d->importingPageItem) { KMessageBox::information(this, xi18n("No help is available for this page."), xi18n("Help")); } } void ImportWizard::slotOptionsButtonClicked() { QPointer dlg = new OptionsDialog(selectedSourceFileName(), d->sourceDBEncoding, this); if (QDialog::Accepted == dlg->exec()) { if (d->sourceDBEncoding != dlg->encodingComboBox()->selectedEncoding()) { d->sourceDBEncoding = dlg->encodingComboBox()->selectedEncoding(); } } delete dlg; } void ImportWizard::sourceConnectionSelected(bool selected) { if (selected && fileBasedSrcSelected()) { next(); } } diff --git a/src/tests/startup/main.cpp b/src/tests/startup/main.cpp index d3b27373e..669a52f71 100644 --- a/src/tests/startup/main.cpp +++ b/src/tests/startup/main.cpp @@ -1,113 +1,113 @@ /* This file is part of the KDE project Copyright (C) 2003 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #include #include #include "main/startup/KexiStartupDialog.h" #include "main/startup/KexiConnSelector.h" #include "core/kexiprojectset.h" #include "core/kexiprojectdata.h" int main(int argc, char* argv[]) { KApplication app(argc, argv, "startup"); // Widget w; // app.setMainWidget(&w); /* KexiTableView tv; app.setMainWidget(&tv); KDbTableViewData data; KDbTableViewColumn col; col.type = QVariant::Int; col.caption = "Id"; data.addColumn( col ); col.type = QVariant::String; col.caption = "Name"; data.addColumn( col ); col.type = QVariant::Int; col.caption = "Age"; data.addColumn( col ); tv.setData(&data, false); tv.show();*/ //some connection data KexiDBConnectionSet connset; KDbConnectionData *conndata; conndata = new KDbConnectionData(); conndata->name = "My connection 1"; conndata->driverName = "mysql"; conndata->hostName = "host.net"; conndata->userName = "user"; connset.addConnectionData(conndata); conndata = new KDbConnectionData(); conndata->name = "My connection 2"; conndata->driverName = "mysql"; conndata->hostName = "myhost.org"; conndata->userName = "otheruser"; conndata->port = 53121; connset.addConnectionData(conndata); //some recent projects data KexiProjectData *prjdata; prjdata = new KexiProjectData(*conndata, "bigdb", "Big DB"); prjdata->setCaption("My Big Project"); prjdata->setDescription("This is my first biger project started yesterday. Have fun!"); KexiProjectSet prj_set; prj_set.addProjectData(prjdata); KexiStartupDialog startup(KexiStartupDialog::Everything, 0, connset, prj_set, 0, "dlg"); int e = startup.exec(); qDebug() << (e == QDialog::Accepted ? "Accepted" : "Rejected"); if (e == QDialog::Accepted) { int r = startup.result(); if (r == KexiStartupDialog::TemplateResult) { qDebug() << "Template key == " << startup.selectedTemplateKey(); if (startup.selectedTemplateKey() == "blank") { #if 0 KexiConnSelectorDialog sel(connset, 0, "sel"); e = sel.exec(); qDebug() << (e == QDialog::Accepted ? "Accepted" : "Rejected"); if (e == QDialog::Accepted) { qDebug() << "Selected conn. type: " << (sel.selectedConnectionType() == KexiConnSelectorWidget::FileBased ? "File based" : "Server based"); if (sel.selectedConnectionType() == KexiConnSelectorWidget::ServerBased) { qDebug() << "SERVER: " << sel.selectedConnectionData()->toUserVisibleString(); } } #endif } } else if (r == KexiStartupDialog::OpenExistingResult) { qDebug() << "Existing project --------"; QString selFile = startup.selectedExistingFile(); if (!selFile.isEmpty()) qDebug() << "Project File: " << selFile; else if (startup.selectedExistingConnection()) { qDebug() << "Existing connection: " << startup.selectedExistingConnection()->toUserVisibleString(); - //ok, now we are trying to show daabases for this conenction to this user + //ok, now we are trying to show daabases for this connection to this user //! @todo } } else if (r == KexiStartupDialog::OpenRecentResult) { qDebug() << "Recent project --------"; const KexiProjectData *data = startup.selectedProjectData(); if (data) { qDebug() << "Selected project: database=" << data->databaseName() << " connection=" << data->connectionData()->toUserVisibleString(); } } } }