diff --git a/src/plugins/tables/kexitablepart.cpp b/src/plugins/tables/kexitablepart.cpp
index 110cd7940..9f45b722b 100644
--- a/src/plugins/tables/kexitablepart.cpp
+++ b/src/plugins/tables/kexitablepart.cpp
@@ -1,361 +1,361 @@
/* This file is part of the KDE project
Copyright (C) 2003 Lucijan Busch
Copyright (C) 2002, 2003 Joseph Wenninger
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
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 "kexitablepart.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include "kexitabledesignerview.h"
#include "kexitabledesigner_dataview.h"
#include "kexilookupcolumnpage.h"
#include
#include
#include
#include
#include
#include
KEXI_PLUGIN_FACTORY(KexiTablePart, "kexi_tableplugin.json")
//! @internal
class Q_DECL_HIDDEN KexiTablePart::Private
{
public:
Private() {
}
~Private() {
delete static_cast(lookupColumnPage);
}
QPointer lookupColumnPage;
};
KexiTablePart::KexiTablePart(QObject *parent, const QVariantList& l)
: KexiPart::Part(parent,
xi18nc("Translate this word using only lowercase alphanumeric characters (a..z, 0..9). "
"Use '_' character instead of spaces. First character should be a..z character. "
"If you cannot use latin characters in your language, use english word.",
"table"),
xi18nc("tooltip", "Create new table"),
xi18nc("what's this", "Creates new table."),
l)
, d(new Private)
{
// needed for custom "identifier" property editor widget
KexiCustomPropertyFactory::init();
//! @todo js: also add Kexi::TextViewMode when we'll have SQL ALTER TABLE EDITOR!!!
}
KexiTablePart::~KexiTablePart()
{
delete d;
}
void KexiTablePart::initPartActions()
{
}
void KexiTablePart::initInstanceActions()
{
}
KexiWindowData* KexiTablePart::createWindowData(KexiWindow* window)
{
KexiMainWindowIface *win = KexiMainWindowIface::global();
return new KexiTablePartTempData(window, win->project()->dbConnection());
}
KexiView* KexiTablePart::createView(QWidget *parent, KexiWindow* window,
KexiPart::Item *item, Kexi::ViewMode viewMode, QMap*)
{
Q_ASSERT(item);
KexiMainWindowIface *win = KexiMainWindowIface::global();
if (!win || !win->project() || !win->project()->dbConnection())
return 0;
KexiTablePartTempData *temp
= static_cast(window->data());
if (!temp->table()) {
temp->setTable(win->project()->dbConnection()->tableSchema(item->name()));
qDebug() << "schema is " << temp->table();
}
if (viewMode == Kexi::DesignViewMode) {
KexiTableDesignerView *t = new KexiTableDesignerView(parent);
return t;
} else if (viewMode == Kexi::DataViewMode) {
if (!temp->table()) {
return 0; //!< @todo message
}
//we're not setting table schema here -it will be forced to set
// in KexiTableDesigner_DataView::afterSwitchFrom()
KexiTableDesigner_DataView *t = new KexiTableDesigner_DataView(parent);
return t;
}
return 0;
}
tristate KexiTablePart::remove(KexiPart::Item *item)
{
KexiProject *project = KexiMainWindowIface::global()->project();
if (!project || !project->dbConnection())
return false;
KDbConnection *conn = project->dbConnection();
KDbTableSchema *sch = conn->tableSchema(item->identifier());
if (sch) {
const tristate res = KexiTablePart::askForClosingObjectsUsingTableSchema(
KexiMainWindowIface::global()->openedWindowFor(item->identifier()), conn, sch,
kxi18n("You are about to delete table %1 but it is used by "
"following opened windows:")
.subs(sch->name()));
if (res != true) {
return res;
}
return conn->dropTable(sch);
}
//last chance: just remove item
return conn->removeObject(item->identifier());
}
tristate KexiTablePart::rename(KexiPart::Item *item, const QString& newName)
{
Q_ASSERT(item);
KDbConnection *conn = KexiMainWindowIface::global()->project()->dbConnection();
KDbTableSchema *schema = conn->tableSchema(item->identifier());
if (!schema)
return false;
const tristate res = KexiTablePart::askForClosingObjectsUsingTableSchema(
KexiMainWindowIface::global()->openedWindowFor(item->identifier()), conn, schema,
kxi18n("You are about to rename table %1 but it is used by "
- "following opened windows:")
+ "following opened windows:")
.subs(schema->name()));
if (res != true) {
return res;
}
return conn->alterTableName(schema, newName);
}
KDbObject* KexiTablePart::loadSchemaObject(KexiWindow *window, const KDbObject& object,
Kexi::ViewMode viewMode, bool *ownedByWindow)
{
Q_UNUSED(window);
Q_UNUSED(viewMode);
if (ownedByWindow)
*ownedByWindow = false;
return KexiMainWindowIface::global()->project()->dbConnection()->tableSchema(object.name());
}
// static
tristate KexiTablePart::askForClosingObjectsUsingTableSchema(KexiWindow *window,
KDbConnection *conn,
KDbTableSchema *table,
const KLocalizedString &msg)
{
Q_ASSERT(conn);
Q_ASSERT(table);
if (!window) {
return true;
}
QList listeners
= KDbTableSchemaChangeListener::listeners(conn, table);
KexiTablePartTempData *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 table.
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 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;
}
return true;
}
KLocalizedString KexiTablePart::i18nMessage(
const QString& englishMessage, KexiWindow* window) const
{
Q_UNUSED(window);
if (englishMessage == "Design of object %1 has been modified.")
return kxi18nc(I18NC_NOOP("@info", "Design of table %1 has been modified."));
if (englishMessage == "Object %1 already exists.")
return kxi18nc(I18NC_NOOP("@info", "Table %1 already exists."));
if (window->currentViewMode() == Kexi::DesignViewMode && !window->neverSaved()
&& englishMessage == ":additional message before saving design")
return kxi18nc(I18NC_NOOP("@info", "Any data in this table will be deleted upon design's saving!"));
return Part::i18nMessage(englishMessage, window);
}
void KexiTablePart::setupCustomPropertyPanelTabs(QTabWidget *tab)
{
if (!d->lookupColumnPage) {
d->lookupColumnPage = new KexiLookupColumnPage(0);
connect(d->lookupColumnPage,
SIGNAL(jumpToObjectRequested(QString,QString)),
KexiMainWindowIface::global()->thisWidget(),
SLOT(highlightObject(QString,QString)));
//! @todo add "Table" tab
/*
connect(d->dataSourcePage, SIGNAL(formDataSourceChanged(QCString,QCString)),
KFormDesigner::FormManager::self(), SLOT(setFormDataSource(QCString,QCString)));
connect(d->dataSourcePage, SIGNAL(dataSourceFieldOrExpressionChanged(QString,QString,KDbField::Type)),
KFormDesigner::FormManager::self(), SLOT(setDataSourceFieldOrExpression(QString,QString,KDbField::Type)));
connect(d->dataSourcePage, SIGNAL(insertAutoFields(QString,QString,QStringList)),
KFormDesigner::FormManager::self(), SLOT(insertAutoFields(QString,QString,QStringList)));*/
}
KexiProject *prj = KexiMainWindowIface::global()->project();
d->lookupColumnPage->setProject(prj);
//! @todo add lookup field icon
tab->addTab(d->lookupColumnPage, KexiIcon("combobox"), QString());
tab->setTabToolTip(tab->indexOf(d->lookupColumnPage), xi18n("Lookup column"));
}
KexiLookupColumnPage* KexiTablePart::lookupColumnPage() const
{
return d->lookupColumnPage;
}
//----------------
class Q_DECL_HIDDEN KexiTablePartTempData::Private
{
public:
Private()
: table(nullptr)
{
}
KDbTableSchema *table;
KDbConnection *conn;
};
KexiTablePartTempData::KexiTablePartTempData(KexiWindow* parent, KDbConnection *conn)
: KexiWindowData(parent)
, KDbTableSchemaChangeListener()
, tableSchemaChangedInPreviousView(true /*to force reloading on startup*/)
, d(new Private)
{
d->conn = conn;
setName(KexiUtils::localizedStringToHtmlSubstring(
kxi18nc("@info", "Table %1").subs(parent->partItem()->name())));
}
KexiTablePartTempData::~KexiTablePartTempData()
{
KDbTableSchemaChangeListener::unregisterForChanges(d->conn, this);
delete d;
}
KDbTableSchema* KexiTablePartTempData::table()
{
return d->table;
}
KDbConnection* KexiTablePartTempData::connection()
{
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, d->table);
}
closeDataInDataView();
d->table = table;
if (d->table) {
KDbTableSchemaChangeListener::registerForChanges(d->conn, this, d->table);
}
}
tristate KexiTablePartTempData::closeListener()
{
KexiWindow* window = static_cast(parent());
qDebug() << window->partItem()->name();
closeDataInDataView();
if (closeWindowOnCloseListener) {
return KexiMainWindowIface::global()->closeWindow(window);
}
return true;
}
#include "kexitablepart.moc"