diff --git a/src/plugins/forms/kexidatasourcepage.h b/src/plugins/forms/kexidatasourcepage.h
--- a/src/plugins/forms/kexidatasourcepage.h
+++ b/src/plugins/forms/kexidatasourcepage.h
@@ -1,5 +1,5 @@
/* This file is part of the KDE project
- Copyright (C) 2005-2009 Jarosław Staniek
+ Copyright (C) 2005-2017 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
@@ -45,6 +45,12 @@
explicit KexiDataSourcePage(QWidget *parent);
virtual ~KexiDataSourcePage();
+ //! @return name plugin ID of selected item (usually a table or a query). Can return an empty string.
+ QString selectedPluginId() const;
+
+ //! @return name of selected table or query.
+ QString selectedName() const;
+
public Q_SLOTS:
void setProject(KexiProject *prj);
void clearFormDataSourceSelection(bool alsoClearComboBox = true);
diff --git a/src/plugins/forms/kexidatasourcepage.cpp b/src/plugins/forms/kexidatasourcepage.cpp
--- a/src/plugins/forms/kexidatasourcepage.cpp
+++ b/src/plugins/forms/kexidatasourcepage.cpp
@@ -1,5 +1,5 @@
/* This file is part of the KDE project
- Copyright (C) 2005-2009 Jarosław Staniek
+ Copyright (C) 2005-2017 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
@@ -452,3 +452,12 @@
#endif
}
+QString KexiDataSourcePage::selectedPluginId() const
+{
+ return m_formDataSourceCombo->selectedPluginId();
+}
+
+QString KexiDataSourcePage::selectedName() const
+{
+ return m_formDataSourceCombo->selectedName();
+}
diff --git a/src/plugins/forms/kexiformpart.h b/src/plugins/forms/kexiformpart.h
--- a/src/plugins/forms/kexiformpart.h
+++ b/src/plugins/forms/kexiformpart.h
@@ -1,7 +1,7 @@
/* This file is part of the KDE project
Copyright (C) 2004 Lucijan Busch
Copyright (C) 2004 Cedric Pasteur
- Copyright (C) 2005-2009 Jarosław Staniek
+ Copyright (C) 2005-2017 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
@@ -28,6 +28,8 @@
#include
#include
+#include
+
class QDomDocument;
namespace KFormDesigner
{
@@ -37,12 +39,18 @@
class KDbFieldList;
class KexiDataSourcePage;
-class KexiFormPartTempData : public KexiWindowData
+class KexiFormPartTempData : public KexiWindowData, public KDbTableSchemaChangeListener
{
Q_OBJECT
public:
- explicit KexiFormPartTempData(KexiWindow* parent);
+ KexiFormPartTempData(KexiWindow* parent, KDbConnection *conn);
~KexiFormPartTempData();
+
+ //! Sets data source used for this data.
+ //! If the previous data source is different and is not empty, listener for it will be unregistered.
+ //! If the new data source is empty this temp-data object will be registered as a listener for it.
+ void setDataSource(const QString &pluginId, const QString &dataSource);
+
QPointer form;
QPointer previewForm;
QString tempForm;
@@ -52,6 +60,16 @@
//! Used when loading a form from (temporary) XML in Data View
//! to get unsaved blobs collected at design mode.
QHash unsavedLocalBLOBsByName;
+
+protected:
+ //! This temp-data acts as a listener for tracking changes in table schema
+ //! used by the form. This method closes the form on request.
+ tristate closeListener() override;
+
+private:
+ Q_DISABLE_COPY(KexiFormPartTempData)
+ class Private;
+ Private * const d;
};
//! Kexi Form Plugin
diff --git a/src/plugins/forms/kexiformpart.cpp b/src/plugins/forms/kexiformpart.cpp
--- a/src/plugins/forms/kexiformpart.cpp
+++ b/src/plugins/forms/kexiformpart.cpp
@@ -1,7 +1,7 @@
/* This file is part of the KDE project
Copyright (C) 2004 Lucijan Busch
Copyright (C) 2004 Cedric Pasteur
- Copyright (C) 2005 Jarosław Staniek
+ Copyright (C) 2005-2017 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
@@ -147,7 +147,8 @@
KexiWindowData* KexiFormPart::createWindowData(KexiWindow* window)
{
- return new KexiFormPartTempData(window);
+ KexiMainWindowIface *win = KexiMainWindowIface::global();
+ return new KexiFormPartTempData(window, win->project()->dbConnection());
}
KexiView* KexiFormPart::createView(QWidget *parent, KexiWindow* window,
@@ -378,12 +379,90 @@
//----------------
-KexiFormPartTempData::KexiFormPartTempData(KexiWindow* parent)
- : KexiWindowData(parent)
+class Q_DECL_HIDDEN KexiFormPartTempData::Private
{
+public:
+ Private(KexiFormPartTempData *temp)
+ : q(temp)
+ {
+ }
+
+ void unregisterForChanges()
+ {
+ if (dataSource.isEmpty()) {
+ return;
+ }
+ if (pluginId == "org.kexi-project.table") {
+ KDbTableSchema *table = conn->tableSchema(dataSource);
+ if (!table) {
+ return;
+ }
+ KDbTableSchemaChangeListener::unregisterForChanges(conn, table);
+ } else if (pluginId == "org.kexi-project.query") {
+ KDbQuerySchema *query = conn->querySchema(dataSource);
+ if (!query) {
+ return;
+ }
+ KDbTableSchemaChangeListener::unregisterForChanges(conn, query);
+ } else {
+ return;
+ }
+ }
+
+ void registerForChanges(const QString &newPluginId, const QString &newDataSource)
+ {
+ if (newPluginId == "org.kexi-project.table") {
+ KDbTableSchema *table = conn->tableSchema(newDataSource);
+ if (!table) {
+ return;
+ }
+ KDbTableSchemaChangeListener::registerForChanges(conn, q, table);
+ } else if (pluginId == "org.kexi-project.query") {
+ KDbQuerySchema *query = conn->querySchema(newDataSource);
+ if (!query) {
+ return;
+ }
+ KDbTableSchemaChangeListener::registerForChanges(conn, q, query);
+ } else {
+ return;
+ }
+ pluginId = newPluginId;
+ dataSource = newDataSource;
+ }
+
+ KDbConnection *conn;
+ QString pluginId;
+ QString dataSource;
+
+private:
+ KexiFormPartTempData * const q;
+};
+
+KexiFormPartTempData::KexiFormPartTempData(KexiWindow* parent, KDbConnection *conn)
+ : KexiWindowData(parent), d(new Private(this))
+{
+ d->conn = conn;
+ setName(KexiUtils::localizedStringToHtmlSubstring(
+ kxi18nc("@info", "Form %1").subs(parent->partItem()->name())));
}
KexiFormPartTempData::~KexiFormPartTempData()
{
+ KDbTableSchemaChangeListener::unregisterForChanges(d->conn, this);
+ delete d;
}
+void KexiFormPartTempData::setDataSource(const QString &pluginId, const QString &dataSource)
+{
+ if (d->pluginId != pluginId || d->dataSource != dataSource) {
+ d->unregisterForChanges();
+ d->registerForChanges(pluginId, dataSource);
+ }
+}
+
+tristate KexiFormPartTempData::closeListener()
+{
+ KexiWindow* window = static_cast(parent());
+ qDebug() << window->partItem()->name();
+ return KexiMainWindowIface::global()->closeWindow(window);
+}
diff --git a/src/plugins/forms/kexiformview.h b/src/plugins/forms/kexiformview.h
--- a/src/plugins/forms/kexiformview.h
+++ b/src/plugins/forms/kexiformview.h
@@ -1,6 +1,6 @@
/* This file is part of the KDE project
Copyright (C) 2004 Cedric Pasteur
- Copyright (C) 2004-2016 Jarosław Staniek
+ Copyright (C) 2004-2017 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
diff --git a/src/plugins/forms/kexiformview.cpp b/src/plugins/forms/kexiformview.cpp
--- a/src/plugins/forms/kexiformview.cpp
+++ b/src/plugins/forms/kexiformview.cpp
@@ -1,6 +1,6 @@
/* This file is part of the KDE project
Copyright (C) 2004 Cedric Pasteur
- Copyright (C) 2004-2016 Jarosław Staniek
+ Copyright (C) 2004-2017 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
@@ -458,6 +458,7 @@
if (!KFormDesigner::FormIO::loadFormFromString(form(), d->dbform, data)) {
return false;
}
+ tempData()->setDataSource(d->dbform->dataSourcePluginId(), d->dbform->dataSource());
}
//"autoTabStops" property is loaded -set it within the form tree as well
@@ -1064,9 +1065,16 @@
{
if (viewMode() == Kexi::DesignViewMode) {
KPropertySet *set = form()->propertySet();
- const QString dataSourcePartClass = set->propertyValue("dataSourcePartClass").toString();
+ QString dataSourcePartClass = set->propertyValue("dataSourcePartClass").toString();
const QString dataSource = set->propertyValue("dataSource").toString();
formPart()->dataSourcePage()->setFormDataSource(dataSourcePartClass, dataSource);
+ if (dataSourcePartClass.isEmpty()
+ && !formPart()->dataSourcePage()->selectedPluginId().isEmpty())
+ {
+ set->property("dataSourcePartClass")
+ .setValue(formPart()->dataSourcePage()->selectedPluginId(),
+ KProperty::ValueOption::IgnoreOld);
+ }
}
}
diff --git a/src/plugins/queries/kexiquerypart.h b/src/plugins/queries/kexiquerypart.h
--- a/src/plugins/queries/kexiquerypart.h
+++ b/src/plugins/queries/kexiquerypart.h
@@ -1,6 +1,6 @@
/* This file is part of the KDE project
Copyright (C) 2003 Lucijan Busch
- Copyright (C) 2004-2016 Jarosław Staniek
+ Copyright (C) 2004-2017 Jarosław Staniek
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -101,6 +101,38 @@
Reimplemented to mark the query obsolete by using KDbConnection::setQuerySchemaObsolete(). */
virtual tristate rename(KexiPart::Item *item, const QString& newName);
+ /**
+ * Closes objects that listenen to changes of the query schema @a query, i.e. use it.
+ *
+ * These objects can be currently:
+ * - lookup fields of tables
+ * - queries using the query directly (as subqueries) or via lookup fields
+ * - forms and reports that use the query directly as data source or via query.
+ *
+ * Scripts referencing the query programatically are not analyzed, so they can fail on next
+ * execution.
+ *
+ * This method asks the user for approval if there is at least one object that listens for
+ * changes of the schema (altering or removal). If there is no approval, returns
+ * @c cancelled. On failure @c false is returned. If @a window is @c nullptr, @c true is
+ * returned immediately because there is no window to care about.
+ *
+ * @note Unlike renaming tables, renaming queries just marks the previous query object one as
+ * "obsolete" using KDbConnection::setQuerySchemaObsolete() and keeps the existing actual object
+ * in memory so there is no risk of accessing deleted object by other objects.
+ *
+ * Special case: listener for the query @a query will be silently closed without asking for
+ * confirmation. It is ignored when looking for objects that are "blocking" changes
+ * of @a query. This exception is needed because the listener handles the data view's lifetime
+ * and the data view should be reset silently without bothering the user.
+ *
+ * @see KexiQueryPartTempData::closeListener()
+ * @see KexiTablePart::askForClosingObjectsUsingTableSchema()
+ */
+ static tristate askForClosingObjectsUsingQuerySchema(KexiWindow *window, KDbConnection *conn,
+ KDbQuerySchema *query,
+ const KLocalizedString &msg);
+
protected:
KexiWindowData* createWindowData(KexiWindow* window) override Q_REQUIRED_RESULT;
diff --git a/src/plugins/queries/kexiquerypart.cpp b/src/plugins/queries/kexiquerypart.cpp
--- a/src/plugins/queries/kexiquerypart.cpp
+++ b/src/plugins/queries/kexiquerypart.cpp
@@ -1,6 +1,6 @@
/* This file is part of the KDE project
Copyright (C) 2004 Lucijan Busch
- Copyright (C) 2004-2016 Jarosław Staniek
+ Copyright (C) 2004-2017 Jarosław Staniek
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -33,6 +33,9 @@
#include
#include
+#include
+#include
+
#include
KEXI_PLUGIN_FACTORY(KexiQueryPart, "kexi_queryplugin.json")
@@ -99,8 +102,17 @@
return false;
KDbConnection *conn = KexiMainWindowIface::global()->project()->dbConnection();
KDbQuerySchema *sch = conn->querySchema(item->identifier());
- if (sch)
+ if (sch) {
+ const tristate res = KexiQueryPart::askForClosingObjectsUsingQuerySchema(
+ KexiMainWindowIface::global()->openedWindowFor(item->identifier()), conn, sch,
+ kxi18n("You are about to delete query %1 but it is used by "
+ "following opened windows:")
+ .subs(sch->name()));
+ if (res != true) {
+ return res;
+ }
return conn->dropQuery(sch);
+ }
//last chance: just remove item
return conn->removeObject(item->identifier());
}
@@ -184,11 +196,70 @@
Q_UNUSED(newName);
if (!KexiMainWindowIface::global()->project()->dbConnection())
return false;
+ // Note: unlike in KexiTablePart::rename here we just mark the query obsolete here so no need
+ // to call KexiQueryPart::askForClosingObjectsUsingQuerySchema().
KexiMainWindowIface::global()->project()->dbConnection()
->setQuerySchemaObsolete(item->name());
return true;
}
+// static
+tristate KexiQueryPart::askForClosingObjectsUsingQuerySchema(KexiWindow *window,
+ KDbConnection *conn,
+ KDbQuerySchema *query,
+ const KLocalizedString &msg)
+{
+ Q_ASSERT(conn);
+ Q_ASSERT(query);
+ if (!window) {
+ return true;
+ }
+ QList listeners
+ = KDbTableSchemaChangeListener::listeners(conn, query);
+ KexiQueryPartTempData *temp = static_cast(window->data());
+ // Special case: listener that is equal to window->data() will be silently closed
+ // without asking for confirmation. It is not counted when looking for objects that
+ // are "blocking" changes of the query.
+ const bool tempListenerExists = listeners.removeAll(temp) > 0;
+ // Immediate success if there's no temp-data's listener to close nor other listeners to close
+ if (!tempListenerExists && listeners.isEmpty()) {
+ return true;
+ }
+
+ if (!listeners.isEmpty()) {
+ QString openedObjectsStr = "";
+ for(const KDbTableSchemaChangeListener* listener : listeners) {
+ openedObjectsStr += QString("- %1
").arg(listener->name());
+ }
+ openedObjectsStr += "
";
+ QString message = ""
+ + i18nc("@info/plain Sentence1 Sentence2 Sentence3", "%1%2%3",
+ KexiUtils::localizedStringToHtmlSubstring(msg), openedObjectsStr,
+ KexiUtils::localizedStringToHtmlSubstring(
+ kxi18nc("@info", "Do you want to close these windows and save the "
+ "design or cancel saving?")))
+ + "";
+ KGuiItem closeAndSaveItem(KStandardGuiItem::save());
+ closeAndSaveItem.setText(
+ xi18nc("@action:button Close all windows and save", "Close Windows and Save"));
+ closeAndSaveItem.setToolTip(xi18nc("@info:tooltip Close all windows and save design",
+ "Close all windows and save design"));
+ const int r = KMessageBox::questionYesNo(window, message, QString(), closeAndSaveItem,
+ KStandardGuiItem::cancel(), QString(),
+ KMessageBox::Notify | KMessageBox::Dangerous);
+ if (r != KMessageBox::Yes) {
+ return cancelled;
+ }
+ }
+ // try to close every window depending on the query (if present) and also the temp-data's
+ // listener (if present)
+ const tristate res = KDbTableSchemaChangeListener::closeListeners(conn, query, { temp });
+ if (res != true) { //do not expose closing errors twice; just cancel
+ return cancelled;
+ }
+ return true;
+}
+
//----------------
KexiQueryPartTempData::KexiQueryPartTempData(KexiWindow* window, KDbConnection *conn)
@@ -224,14 +295,13 @@
{
if (!q)
return;
- foreach(const KDbTableSchema* table, *q->tables()) {
- KDbTableSchemaChangeListener::registerForChanges(conn, this, table);
- }
+ KDbTableSchemaChangeListener::registerForChanges(conn, this, q);
}
tristate KexiQueryPartTempData::closeListener()
{
KexiWindow* window = static_cast(parent());
+ qDebug() << window->partItem()->name();
return KexiMainWindowIface::global()->closeWindow(window);
}
diff --git a/src/plugins/reports/KexiDBReportDataSource.h b/src/plugins/reports/KexiDBReportDataSource.h
--- a/src/plugins/reports/KexiDBReportDataSource.h
+++ b/src/plugins/reports/KexiDBReportDataSource.h
@@ -1,6 +1,7 @@
/*
* Kexi Report Plugin
* Copyright (C) 2007-2017 by Adam Pigg
+* Copyright (C) 2017 Jarosław Staniek
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,9 +23,10 @@
#include
#include
-#include
#include
+class KexiReportPartTempData;
+
//! @brief Implementation of database report data source
class KexiDBReportDataSource : public KReportDataSource
{
@@ -36,7 +38,8 @@
* -"org.kexi-project.query"
* -empty QString() - attempt to resolve @a objectName
*/
- KexiDBReportDataSource(const QString &objectName, const QString& pluginId, KDbConnection *conn);
+ KexiDBReportDataSource(const QString &objectName, const QString &pluginId,
+ KexiReportPartTempData *data);
virtual ~KexiDBReportDataSource();
virtual QStringList fieldNames() const;
diff --git a/src/plugins/reports/KexiDBReportDataSource.cpp b/src/plugins/reports/KexiDBReportDataSource.cpp
--- a/src/plugins/reports/KexiDBReportDataSource.cpp
+++ b/src/plugins/reports/KexiDBReportDataSource.cpp
@@ -1,6 +1,7 @@
/*
* Kexi Report Plugin
* Copyright (C) 2007-2017 by Adam Pigg
+* Copyright (C) 2017 Jarosław Staniek
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,7 +18,7 @@
*/
#include "KexiDBReportDataSource.h"
-#include
+#include "kexireportpart.h"
#include
#include
@@ -30,8 +31,8 @@
class Q_DECL_HIDDEN KexiDBReportDataSource::Private
{
public:
- explicit Private(KDbConnection *pDb)
- : cursor(0), connection(pDb), originalSchema(0), copySchema(0)
+ explicit Private(KexiReportPartTempData *data)
+ : cursor(0), tempData(data), originalSchema(0), copySchema(0)
{
}
~Private()
@@ -44,15 +45,14 @@
QString objectName;
KDbCursor *cursor;
- KDbConnection *connection;
+ KexiReportPartTempData *tempData;
KDbQuerySchema *originalSchema;
KDbQuerySchema *copySchema;
};
-KexiDBReportDataSource::KexiDBReportDataSource(const QString& objectName,
- const QString& pluginId,
- KDbConnection* pDb)
- : d(new Private(pDb))
+KexiDBReportDataSource::KexiDBReportDataSource(const QString &objectName, const QString &pluginId,
+ KexiReportPartTempData *data)
+ : d(new Private(data))
{
d->objectName = objectName;
getSchema(pluginId);
@@ -65,7 +65,7 @@
return;
KDbOrderByColumnList order;
for (int i = 0; i < sorting.count(); i++) {
- if (!order.appendField(d->connection, d->copySchema, sorting[i].field(),
+ if (!order.appendField(d->tempData->connection(), d->copySchema, sorting[i].field(),
KDbOrderByColumn::fromQt(sorting[i].order())))
{
qWarning() << "Cannot set sort field" << i << sorting[i].field();
@@ -111,17 +111,17 @@
bool KexiDBReportDataSource::open()
{
- if ( d->connection && d->cursor == 0 )
+ if ( d->tempData->connection() && d->cursor == 0 )
{
if ( d->objectName.isEmpty() )
{
return false;
}
else if ( d->copySchema)
{
qDebug() << "Opening cursor.."
- << KDbConnectionAndQuerySchema(d->connection, *d->copySchema);
- d->cursor = d->connection->executeQuery(d->copySchema, KDbCursor::Option::Buffered);
+ << KDbConnectionAndQuerySchema(d->tempData->connection(), *d->copySchema);
+ d->cursor = d->tempData->connection()->executeQuery(d->copySchema, KDbCursor::Option::Buffered);
}
@@ -140,54 +140,61 @@
{
if (d->cursor) {
const bool ok = d->cursor->close();
- d->connection->deleteCursor(d->cursor);
+ d->tempData->connection()->deleteCursor(d->cursor);
d->cursor = nullptr;
return ok;
}
return true;
}
bool KexiDBReportDataSource::getSchema(const QString& pluginId)
{
- if (d->connection)
- {
+ if (d->tempData->connection()) {
+ KDbTableSchemaChangeListener::unregisterForChanges(d->tempData->connection(), d->tempData);
delete d->originalSchema;
d->originalSchema = 0;
delete d->copySchema;
d->copySchema = 0;
+ KDbTableSchema *table = nullptr;
+ KDbQuerySchema *query = nullptr;
if ((pluginId.isEmpty() || pluginId == "org.kexi-project.table")
- && d->connection->tableSchema(d->objectName))
+ && (table = d->tempData->connection()->tableSchema(d->objectName)))
{
qDebug() << d->objectName << "is a table..";
- d->originalSchema = new KDbQuerySchema(d->connection->tableSchema(d->objectName));
+ d->originalSchema = new KDbQuerySchema(table);
}
else if ((pluginId.isEmpty() || pluginId == "org.kexi-project.query")
- && d->connection->querySchema(d->objectName))
+ && (query = d->tempData->connection()->querySchema(d->objectName)))
{
qDebug() << d->objectName << "is a query..";
- qDebug() << KDbConnectionAndQuerySchema(d->connection,
- *d->connection->querySchema(d->objectName));
- d->originalSchema
- = new KDbQuerySchema(*(d->connection->querySchema(d->objectName)), d->connection);
+ qDebug() << KDbConnectionAndQuerySchema(d->tempData->connection(), *query);
+ d->originalSchema = new KDbQuerySchema(*query, d->tempData->connection());
}
if (d->originalSchema) {
- const KDbNativeStatementBuilder builder(d->connection, KDb::DriverEscaping);
+ const KDbNativeStatementBuilder builder(d->tempData->connection(), KDb::DriverEscaping);
KDbEscapedString sql;
if (builder.generateSelectStatement(&sql, d->originalSchema)) {
qDebug() << "Original:" << sql;
} else {
qDebug() << "Original: ERROR";
+ return false;
}
- qDebug() << KDbConnectionAndQuerySchema(d->connection, *d->originalSchema);
+ qDebug() << KDbConnectionAndQuerySchema(d->tempData->connection(), *d->originalSchema);
- d->copySchema = new KDbQuerySchema(*d->originalSchema, d->connection);
- qDebug() << KDbConnectionAndQuerySchema(d->connection, *d->copySchema);
+ d->copySchema = new KDbQuerySchema(*d->originalSchema, d->tempData->connection());
+ qDebug() << KDbConnectionAndQuerySchema(d->tempData->connection(), *d->copySchema);
if (builder.generateSelectStatement(&sql, d->copySchema)) {
qDebug() << "Copy:" << sql;
} else {
qDebug() << "Copy: ERROR";
+ return false;
+ }
+ if (table) {
+ KDbTableSchemaChangeListener::registerForChanges(d->tempData->connection(), d->tempData, table);
+ } else if (query) {
+ KDbTableSchemaChangeListener::registerForChanges(d->tempData->connection(), d->tempData, query);
}
}
return true;
@@ -206,7 +213,7 @@
return -1;
}
const KDbQueryColumnInfo::Vector fieldsExpanded(d->cursor->query()->fieldsExpanded(
- d->connection, KDbQuerySchema::FieldsExpandedMode::Unique));
+ d->tempData->connection(), KDbQuerySchema::FieldsExpandedMode::Unique));
for (int i = 0; i < fieldsExpanded.size(); ++i) {
if (0 == QString::compare(fld, fieldsExpanded[i]->aliasOrName(), Qt::CaseInsensitive)) {
return i;
@@ -222,7 +229,7 @@
}
QStringList names;
const KDbQueryColumnInfo::Vector fieldsExpanded(d->originalSchema->fieldsExpanded(
- d->connection, KDbQuerySchema::FieldsExpandedMode::Unique));
+ d->tempData->connection(), KDbQuerySchema::FieldsExpandedMode::Unique));
for (int i = 0; i < fieldsExpanded.size(); i++) {
//! @todo in some Kexi mode captionOrAliasOrName() would be used here (more user-friendly)
names.append(fieldsExpanded[i]->aliasOrName());
@@ -289,7 +296,7 @@
qint64 KexiDBReportDataSource::recordCount() const
{
if (d->copySchema) {
- return d->connection->recordCount(d->copySchema);
+ return d->tempData->connection()->recordCount(d->copySchema);
}
return 1;
@@ -299,19 +306,19 @@
{
//Get the list of queries in the database
QStringList qs;
- if (d->connection && d->connection->isConnected()) {
- QList tids = d->connection->tableIds();
+ if (d->tempData->connection() && d->tempData->connection()->isConnected()) {
+ QList tids = d->tempData->connection()->tableIds();
qs << "";
for (int i = 0; i < tids.size(); ++i) {
- KDbTableSchema* tsc = d->connection->tableSchema(tids[i]);
+ KDbTableSchema* tsc = d->tempData->connection()->tableSchema(tids[i]);
if (tsc)
qs << tsc->name();
}
- QList qids = d->connection->queryIds();
+ QList qids = d->tempData->connection()->queryIds();
qs << "";
for (int i = 0; i < qids.size(); ++i) {
- KDbQuerySchema* qsc = d->connection->querySchema(qids[i]);
+ KDbQuerySchema* qsc = d->tempData->connection()->querySchema(qids[i]);
if (qsc)
qs << qsc->name();
}
@@ -322,5 +329,5 @@
KReportDataSource* KexiDBReportDataSource::create(const QString& source) const
{
- return new KexiDBReportDataSource(source, QString(), d->connection);
+ return new KexiDBReportDataSource(source, QString(), d->tempData);
}
diff --git a/src/plugins/reports/kexireportdesignview.h b/src/plugins/reports/kexireportdesignview.h
--- a/src/plugins/reports/kexireportdesignview.h
+++ b/src/plugins/reports/kexireportdesignview.h
@@ -1,7 +1,7 @@
/*
* Kexi Report Plugin
* Copyright (C) 2007-2009 by Adam Pigg
-* Copyright (C) 2011 Jarosław Staniek
+* Copyright (C) 2011-2017 Jarosław Staniek
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -49,8 +49,11 @@
void itemInserted(const QString& entity);
private:
- KReportDesigner *m_reportDesigner;
KexiReportPartTempData* tempData() const;
+ QDomElement connectionData() const;
+ void setConnectionData(const QDomElement &c);
+
+ KReportDesigner *m_reportDesigner;
QScrollArea * m_scrollArea;
//Actions
diff --git a/src/plugins/reports/kexireportdesignview.cpp b/src/plugins/reports/kexireportdesignview.cpp
--- a/src/plugins/reports/kexireportdesignview.cpp
+++ b/src/plugins/reports/kexireportdesignview.cpp
@@ -1,7 +1,7 @@
/*
* Kexi Report Plugin
* Copyright (C) 2007-2009 by Adam Pigg
-* Copyright (C) 2011 Jarosław Staniek
+* Copyright (C) 2011-2017 Jarosław Staniek
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,6 +22,7 @@
#include
#include "kexisourceselector.h"
#include
+#include
#include
@@ -113,7 +114,7 @@
QDomDocument doc("kexireport");
QDomElement root = doc.createElement("kexireport");
- QDomElement conndata = m_sourceSelector->connectionData();
+ QDomElement conndata = connectionData();
if (conndata.isNull())
qDebug() << "Null conn data!";
@@ -162,7 +163,7 @@
}
m_reportDesigner = new KReportDesigner(this, tempData()->reportDefinition);
- m_sourceSelector->setConnectionData(tempData()->connectionDefinition);
+ setConnectionData(tempData()->connectionDefinition);
m_reportDesigner->setScriptSource(qobject_cast(part()));
}
connect(m_reportDesigner, SIGNAL(itemInserted(QString)), this, SIGNAL(itemInserted(QString)));
@@ -204,12 +205,42 @@
void KexiReportDesignView::slotDataSourceChanged()
{
- m_reportDesigner->setDataSource(m_sourceSelector->createDataSource());
- tempData()->connectionDefinition = m_sourceSelector->connectionData();
+ if (m_sourceSelector->isSelectionValid()) {
+ m_reportDesigner->setDataSource(new KexiDBReportDataSource(
+ m_sourceSelector->selectedName(), m_sourceSelector->selectedPluginId(), tempData()));
+ tempData()->connectionDefinition = connectionData();
+ } else {
+ m_reportDesigner->setDataSource(nullptr);
+ tempData()->connectionDefinition = QDomElement();
+ }
setDirty(true);
}
void KexiReportDesignView::triggerAction(const QString &action)
{
m_reportDesigner->slotItem(action);
}
+
+QDomElement KexiReportDesignView::connectionData() const
+{
+ QDomDocument dd;
+ QDomElement conndata = dd.createElement("connection");
+ conndata.setAttribute("type", "internal"); // for backward compatibility, currently always
+ // internal, we used to have "external" in old Kexi
+ conndata.setAttribute("source", m_sourceSelector->selectedName());
+ conndata.setAttribute("class", m_sourceSelector->selectedPluginId());
+ return conndata;
+}
+
+void KexiReportDesignView::setConnectionData(const QDomElement &c)
+{
+ qDebug() << c;
+ if (c.attribute("type") == "internal") {
+ QString sourceClass(c.attribute("class"));
+ if (sourceClass != "org.kexi-project.table" && sourceClass != "org.kexi-project.query") {
+ sourceClass.clear(); // KexiDataSourceComboBox will try to find table, then query
+ }
+ m_sourceSelector->setDataSource(sourceClass, c.attribute("source"));
+ slotDataSourceChanged();
+ }
+}
diff --git a/src/plugins/reports/kexireportpart.h b/src/plugins/reports/kexireportpart.h
--- a/src/plugins/reports/kexireportpart.h
+++ b/src/plugins/reports/kexireportpart.h
@@ -1,7 +1,7 @@
/*
* Kexi Report Plugin
* Copyright (C) 2007-2008 by Adam Pigg
- * Copyright (C) 2011-2015 Jarosław Staniek
+ * Copyright (C) 2011-2017 Jarosław Staniek
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,19 +25,35 @@
#include
#include
+
+#include
+
#include
-class KexiReportPartTempData : public KexiWindowData
+class KexiReportPartTempData : public KexiWindowData, public KDbTableSchemaChangeListener
{
Q_OBJECT
public:
- explicit KexiReportPartTempData(KexiWindow* parent);
+ KexiReportPartTempData(KexiWindow* parent, KDbConnection *conn);
+ ~KexiReportPartTempData();
QDomElement reportDefinition;
QDomElement connectionDefinition;
/*! true, if \a document member has changed in previous view. Used on view switching.
Check this flag to see if we should refresh data for DataViewMode. */
bool reportSchemaChangedInPreviousView;
+
+ KDbConnection *connection();
+
+protected:
+ //! This temp-data acts as a listener for tracking changes in table schema
+ //! used by the report. This method closes the report on request.
+ tristate closeListener() override;
+
+private:
+ Q_DISABLE_COPY(KexiReportPartTempData)
+ class Private;
+ Private * const d;
};
/**
diff --git a/src/plugins/reports/kexireportpart.cpp b/src/plugins/reports/kexireportpart.cpp
--- a/src/plugins/reports/kexireportpart.cpp
+++ b/src/plugins/reports/kexireportpart.cpp
@@ -1,7 +1,7 @@
/*
* Kexi Report Plugin
* Copyright (C) 2007-2008 by Adam Pigg
- * Copyright (C) 2011-2015 Jarosław Staniek
+ * Copyright (C) 2011-2017 Jarosław Staniek
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -34,6 +34,7 @@
#include
#include "kexisourceselector.h"
#include
+#include
//! @internal
class Q_DECL_HIDDEN KexiReportPart::Private
@@ -157,13 +158,47 @@
KexiWindowData* KexiReportPart::createWindowData(KexiWindow* window)
{
- return new KexiReportPartTempData(window);
+ KexiMainWindowIface *win = KexiMainWindowIface::global();
+ return new KexiReportPartTempData(window, win->project()->dbConnection());
}
-KexiReportPartTempData::KexiReportPartTempData(KexiWindow* parent)
+//----------------
+
+class Q_DECL_HIDDEN KexiReportPartTempData::Private
+{
+public:
+ Private()
+ {
+ }
+ KDbConnection *conn;
+};
+
+KexiReportPartTempData::KexiReportPartTempData(KexiWindow* parent, KDbConnection *conn)
: KexiWindowData(parent)
, reportSchemaChangedInPreviousView(true /*to force reloading on startup*/)
+ , d(new Private)
+{
+ d->conn = conn;
+ setName(KexiUtils::localizedStringToHtmlSubstring(
+ kxi18nc("@info", "Report %1").subs(parent->partItem()->name())));
+}
+
+KexiReportPartTempData::~KexiReportPartTempData()
+{
+ KDbTableSchemaChangeListener::unregisterForChanges(d->conn, this);
+ delete d;
+}
+
+KDbConnection* KexiReportPartTempData::connection()
+{
+ return d->conn;
+}
+
+tristate KexiReportPartTempData::closeListener()
{
+ KexiWindow* window = static_cast(parent());
+ qDebug() << window->partItem()->name();
+ return KexiMainWindowIface::global()->closeWindow(window);
}
void KexiReportPart::setupCustomPropertyPanelTabs(QTabWidget *tab)
diff --git a/src/plugins/reports/kexireportview.cpp b/src/plugins/reports/kexireportview.cpp
--- a/src/plugins/reports/kexireportview.cpp
+++ b/src/plugins/reports/kexireportview.cpp
@@ -22,10 +22,6 @@
#include "KexiDBReportDataSource.h"
#ifndef KEXI_MOBILE
#include
- //! @todo KEXI3
-#if 0
-#include "keximigratereportdata.h"
-#endif
#endif
#include
#include
@@ -405,22 +401,10 @@
KReportDataSource* KexiReportView::createDataSource(const QDomElement &e)
{
- KReportDataSource *kodata = 0;
-
if (e.attribute("type") == "internal" && !e.attribute("source").isEmpty()) {
- kodata
- = new KexiDBReportDataSource(e.attribute("source"), e.attribute("class"),
- KexiMainWindowIface::global()->project()->dbConnection());
- }
-#ifndef KEXI_MOBILE
-//! @todo KEXI3
-#if 0
- if (e.attribute("type") == "external") {
- kodata = new KexiMigrateReportData(e.attribute("source"));
+ return new KexiDBReportDataSource(e.attribute("source"), e.attribute("class"), tempData());
}
-#endif
-#endif
- return kodata;
+ return nullptr;
}
KexiReportPartTempData* KexiReportView::tempData() const
diff --git a/src/plugins/reports/kexisourceselector.h b/src/plugins/reports/kexisourceselector.h
--- a/src/plugins/reports/kexisourceselector.h
+++ b/src/plugins/reports/kexisourceselector.h
@@ -42,9 +42,23 @@
~KexiSourceSelector();
KReportDataSource* createDataSource() const Q_REQUIRED_RESULT;
- void setConnectionData(const QDomElement &c);
+
QDomElement connectionData();
+ //! @return name plugin ID of selected item (a table or a query). Can return an empty string.
+ QString selectedPluginId() const;
+
+ //! @return name of selected table or query.
+ QString selectedName() const;
+
+ //! \return true if the current selection is valid
+ bool isSelectionValid() const;
+
+public Q_SLOTS:
+ /*! Sets item for data source described by \a pluginId and \a name.
+ If \a pluginId is empty, either "org.kexi-project.table" and "org.kexi-project.query" are tried. */
+ void setDataSource(const QString& pluginId, const QString& name);
+
Q_SIGNALS:
void dataSourceChanged();
diff --git a/src/plugins/reports/kexisourceselector.cpp b/src/plugins/reports/kexisourceselector.cpp
--- a/src/plugins/reports/kexisourceselector.cpp
+++ b/src/plugins/reports/kexisourceselector.cpp
@@ -20,7 +20,6 @@
#include "kexisourceselector.h"
#include "KexiDataSourceComboBox.h"
#include
-#include
#include
@@ -70,36 +69,22 @@
delete d;
}
-void KexiSourceSelector::setConnectionData(const QDomElement &c)
+QString KexiSourceSelector::selectedPluginId() const
{
- qDebug() << c;
- if (c.attribute("type") == "internal") {
- QString sourceClass(c.attribute("class"));
- if (sourceClass != "org.kexi-project.table" && sourceClass != "org.kexi-project.query") {
- sourceClass.clear(); // KexiDataSourceComboBox will try to find table, then query
- }
- d->dataSource->setDataSource(sourceClass, c.attribute("source"));
- emit dataSourceChanged();
- }
+ return d->dataSource->selectedPluginId();
}
-QDomElement KexiSourceSelector::connectionData()
+QString KexiSourceSelector::selectedName() const
{
- QDomDocument dd;
- QDomElement conndata = dd.createElement("connection");
- conndata.setAttribute("type", "internal"); // for backward compatibility, currently always
- // internal, we used to have "external" in old Kexi
- conndata.setAttribute("source", d->dataSource->selectedName());
- conndata.setAttribute("class", d->dataSource->selectedPluginId());
- return conndata;
+ return d->dataSource->selectedName();
}
-KReportDataSource* KexiSourceSelector::createDataSource() const
+bool KexiSourceSelector::isSelectionValid() const
{
- if (d->dataSource->isSelectionValid()) {
- return new KexiDBReportDataSource(d->dataSource->selectedName(),
- d->dataSource->selectedPluginId(), d->conn);
- }
- return nullptr;
+ return d->dataSource->isSelectionValid();
}
+void KexiSourceSelector::setDataSource(const QString& pluginId, const QString& name)
+{
+ d->dataSource->setDataSource(pluginId, name);
+}
diff --git a/src/plugins/tables/kexitabledesignerview.h b/src/plugins/tables/kexitabledesignerview.h
--- a/src/plugins/tables/kexitabledesignerview.h
+++ b/src/plugins/tables/kexitabledesignerview.h
@@ -1,5 +1,5 @@
/* This file is part of the KDE project
- Copyright (C) 2004-2012 Jarosław Staniek
+ Copyright (C) 2004-2017 Jarosław Staniek
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/src/plugins/tables/kexitabledesignerview.cpp b/src/plugins/tables/kexitabledesignerview.cpp
--- a/src/plugins/tables/kexitabledesignerview.cpp
+++ b/src/plugins/tables/kexitabledesignerview.cpp
@@ -1,5 +1,5 @@
/* This file is part of the KDE project
- Copyright (C) 2004-2012 Jarosław Staniek
+ Copyright (C) 2004-2017 Jarosław Staniek
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -1424,11 +1424,11 @@
if (res == true) {
res = KexiTablePart::askForClosingObjectsUsingTableSchema(
- window(), conn, tempData()->table(),
- xi18nc("@info",
- "You are about to change the design of table %1 "
- "but following objects using this table are opened:",
- tempData()->table()->name()));
+ window(), conn, tempData()->table(),
+ kxi18nc("@info",
+ "You are about to change the design of table %1 "
+ "but following objects using this table are open:")
+ .subs(tempData()->table()->name()));
}
if (res == true) {
@@ -1462,8 +1462,13 @@
= static_cast(*tempData()->table());
res = buildSchema(*newTable);
qDebug() << "BUILD SCHEMA:" << *newTable;
-
- res = conn->alterTable(tempData()->table(), newTable);
+ {
+ KDbTableSchema *oldTable = tempData()->table();
+ tempData()->setTable(nullptr); // needed, otherwise setTable() will access dangling
+ // pointer after conn->alterTable()
+ KexiUtils::BoolBlocker guard(&tempData()->closeWindowOnCloseListener, false);
+ res = conn->alterTable(oldTable, newTable);
+ }
if (res != true)
window()->setStatus(conn, "");
} else {
diff --git a/src/plugins/tables/kexitablepart.h b/src/plugins/tables/kexitablepart.h
--- a/src/plugins/tables/kexitablepart.h
+++ b/src/plugins/tables/kexitablepart.h
@@ -58,14 +58,21 @@
We're checking this flag to see if we should refresh data for DataViewMode. */
bool tableSchemaChangedInPreviousView;
+ //! @c true indicates that closeListener() should close the table designer window.
+ //! This is disabled in one case: upon saving of the design of this table.
+ //! @see KexiTableDesignerView::storeData()
+ bool closeWindowOnCloseListener = true;
+
protected:
//! Closes listener - this temp-data acts as a listener for tracking changes in table schema
//! that is displayed in the window's data view.
//! It just calls KexiDataTableView::setData(nullptr) is there's data set for the view
//! (i.e. if KexiDataTableView::tableView()->data() is not @c nullptr).
tristate closeListener() override;
private:
+ void closeDataInDataView();
+
Q_DISABLE_COPY(KexiTablePartTempData)
class Private;
Private * const d;
@@ -84,21 +91,33 @@
virtual tristate rename(KexiPart::Item *item, const QString& newName);
- //! Close objects that listenen to changes of the table schema @a table.
- //! Asks the user for approval if there is at least one object that listens for changes
- //! of the schema. If there is no approval, returns @c cancelled.
- //! On failure returns @c false.
- //! If @a window is @c nullptr, @c true is returned immediately because there is no window to
- //! care about.
- //! Special case: listener that is equal to window->data() will be silently closed
- //! without asking for confirmation. It is not counted when looking for objects that
- //! are "blocking" changes of @a table.
- //! This exception is needed because the listener handles the data view's lifetime
- //! and the data view should be reset silently without bothering the user.
- //! See KexiTablePartTempData::closeListener()
- static tristate askForClosingObjectsUsingTableSchema(
- KexiWindow *window, KDbConnection *conn,
- KDbTableSchema *table, const QString& msg);
+ /**
+ * Closes objects that listenen to changes of the table schema @a table, i.e. use it.
+ *
+ * These objects can be currently:
+ * - lookup fields of other tables
+ * - queries using the table directly or via lookup fields
+ * - forms and reports that use the table directly as data source or via query.
+ *
+ * Scripts referencing the table programatically are not analyzed, so they can fail on next
+ * execution.
+ *
+ * This method asks the user for approval if there is at least one object that listens for
+ * changes of the schema (altering, renaming or removal). If there is no approval, returns
+ * @c cancelled. On failure @c false is returned. If @a window is @c nullptr, @c true is
+ * returned immediately because there is no window to care about.
+ *
+ * Special case: listener for the table @a table will be silently closed without asking for
+ * confirmation. It is ignored when looking for objects that are "blocking" changes
+ * of @a table. This exception is needed because the listener handles the data view's lifetime
+ * and the data view should be reset silently without bothering the user.
+ *
+ * @see KexiTablePartTempData::closeListener()
+ * @see KexiQueryPart::askForClosingObjectsUsingQuerySchema()
+ */
+ static tristate askForClosingObjectsUsingTableSchema(KexiWindow *window, KDbConnection *conn,
+ KDbTableSchema *table,
+ const KLocalizedString &msg);
virtual KLocalizedString i18nMessage(const QString& englishMessage,
KexiWindow* window) const;
diff --git a/src/plugins/tables/kexitablepart.cpp b/src/plugins/tables/kexitablepart.cpp
--- a/src/plugins/tables/kexitablepart.cpp
+++ b/src/plugins/tables/kexitablepart.cpp
@@ -32,6 +32,7 @@
#include "kexitabledesigner_dataview.h"
#include "kexilookupcolumnpage.h"
#include
+#include
#include
@@ -133,8 +134,9 @@
if (sch) {
const tristate res = KexiTablePart::askForClosingObjectsUsingTableSchema(
KexiMainWindowIface::global()->openedWindowFor(item->identifier()), conn, sch,
- xi18n("You are about to remove table %1 but following objects using this table are opened:",
- sch->name()));
+ kxi18n("You are about to delete table %1 but it is used by "
+ "following opened windows:")
+ .subs(sch->name()));
if (res != true) {
return res;
}
@@ -153,8 +155,9 @@
return false;
const tristate res = KexiTablePart::askForClosingObjectsUsingTableSchema(
KexiMainWindowIface::global()->openedWindowFor(item->identifier()), conn, schema,
- xi18n("You are about to rename table %1 but following objects using this table are opened:",
- schema->name()));
+ kxi18n("You are about to rename table %1 but it is used by "
+ "following opened windows:")
+ .subs(schema->name()));
if (res != true) {
return res;
}
@@ -171,10 +174,11 @@
return KexiMainWindowIface::global()->project()->dbConnection()->tableSchema(object.name());
}
-//static
-tristate KexiTablePart::askForClosingObjectsUsingTableSchema(
- KexiWindow *window, KDbConnection *conn,
- KDbTableSchema *table, const QString& msg)
+// static
+tristate KexiTablePart::askForClosingObjectsUsingTableSchema(KexiWindow *window,
+ KDbConnection *conn,
+ KDbTableSchema *table,
+ const KLocalizedString &msg)
{
Q_ASSERT(conn);
Q_ASSERT(table);
@@ -194,23 +198,33 @@
}
if (!listeners.isEmpty()) {
- QString openedObjectsStr = "";
+ QString openedObjectsStr = "";
for(const KDbTableSchemaChangeListener* listener : listeners) {
- openedObjectsStr += QString("- %1
").arg(listener->name());
+ openedObjectsStr += QString("- %1
").arg(listener->name());
}
- openedObjectsStr += "
";
- const int r = KMessageBox::questionYesNo(window,
- i18nc("@info", "%1%2", msg, openedObjectsStr)
- + ""
- + xi18n("Do you want to close all windows for these objects?")
- + "",
- QString(), KGuiItem(xi18nc("@action:button Close All Windows", "Close Windows"), koIconName("window-close")), KStandardGuiItem::cancel());
+ openedObjectsStr += "";
+ QString message = ""
+ + i18nc("@info/plain Sentence1 Sentence2 Sentence3", "%1%2%3",
+ KexiUtils::localizedStringToHtmlSubstring(msg), openedObjectsStr,
+ KexiUtils::localizedStringToHtmlSubstring(
+ kxi18nc("@info", "Do you want to close these windows and save the "
+ "design or cancel saving?")))
+ + "";
+ KGuiItem closeAndSaveItem(KStandardGuiItem::save());
+ closeAndSaveItem.setText(
+ xi18nc("@action:button Close all windows and save", "Close Windows and Save"));
+ closeAndSaveItem.setToolTip(xi18nc("@info:tooltip Close all windows and save design",
+ "Close all windows and save design"));
+ const int r = KMessageBox::questionYesNo(window, message, QString(), closeAndSaveItem,
+ KStandardGuiItem::cancel(), QString(),
+ KMessageBox::Notify | KMessageBox::Dangerous);
if (r != KMessageBox::Yes) {
return cancelled;
}
}
- //try to close every window depending on the table (if present) and also the temp-data's listener (if present)
- const tristate res = KDbTableSchemaChangeListener::closeListeners(conn, table);
+ // try to close every window depending on the table (if present) and also the temp-data's
+ // listener (if present)
+ const tristate res = KDbTableSchemaChangeListener::closeListeners(conn, table, { temp });
if (res != true) { //do not expose closing errors twice; just cancel
return cancelled;
}
@@ -306,14 +320,27 @@
return d->conn;
}
+void KexiTablePartTempData::closeDataInDataView()
+{
+ const KexiWindow* window = static_cast(parent());
+ if (window->currentViewMode() != Kexi::DataViewMode) {
+ KexiTableDesigner_DataView *dataView
+ = qobject_cast(window->viewForMode(Kexi::DataViewMode));
+ if (dataView && dataView->tableView()->data()) {
+ dataView->setData(nullptr);
+ }
+ }
+}
+
void KexiTablePartTempData::setTable(KDbTableSchema *table)
{
if (d->table == table) {
return;
}
if (d->table) {
- KDbTableSchemaChangeListener::unregisterForChanges(d->conn, this, d->table);
+ KDbTableSchemaChangeListener::unregisterForChanges(d->conn, d->table);
}
+ closeDataInDataView();
d->table = table;
if (d->table) {
KDbTableSchemaChangeListener::registerForChanges(d->conn, this, d->table);
@@ -323,12 +350,10 @@
tristate KexiTablePartTempData::closeListener()
{
KexiWindow* window = static_cast(parent());
- if (window->currentViewMode() != Kexi::DataViewMode) {
- KexiTableDesigner_DataView *dataView
- = qobject_cast(window->viewForMode(Kexi::DataViewMode));
- if (dataView && dataView->tableView()->data()) {
- dataView->setData(nullptr);
- }
+ qDebug() << window->partItem()->name();
+ closeDataInDataView();
+ if (closeWindowOnCloseListener) {
+ return KexiMainWindowIface::global()->closeWindow(window);
}
return true;
}
diff --git a/src/widget/dataviewcommon/kexiformdataiteminterface.h b/src/widget/dataviewcommon/kexiformdataiteminterface.h
--- a/src/widget/dataviewcommon/kexiformdataiteminterface.h
+++ b/src/widget/dataviewcommon/kexiformdataiteminterface.h
@@ -160,7 +160,7 @@
protected:
QString m_dataSource;
- QString m_dataSourcePartClass;
+ QString m_dataSourcePartClass = QStringLiteral("org.kexi-project.table"); //!< default for cases when the part class is missing
KDbQueryColumnInfo* m_columnInfo;
KexiDisplayUtils::DisplayParameters *m_displayParametersForEnteredValue; //!< used in setDisplayDefaultValue()
KexiDisplayUtils::DisplayParameters *m_displayParametersForDefaultValue; //!< used in setDisplayDefaultValue()