kexitablepart.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2003 Lucijan Busch <lucijan@kde.org>
3 Copyright (C) 2002, 2003 Joseph Wenninger <jowenn@kde.org>
4 Copyright (C) 2004 Jaroslaw Staniek <js@iidea.pl>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20*/
21
22#include "kexitablepart.h"
23
24#include <kdebug.h>
25#include <kgenericfactory.h>
26#include <tdemessagebox.h>
27#include <ktabwidget.h>
28#include <kiconloader.h>
29
30#include "keximainwindow.h"
31#include "kexiproject.h"
32#include "kexipartinfo.h"
33#include "widget/kexidatatable.h"
34#include "widget/tableview/kexidatatableview.h"
35#include "kexitabledesignerview.h"
36#include "kexitabledesigner_dataview.h"
37#include "kexilookupcolumnpage.h"
38
39#include <kexidb/connection.h>
40#include <kexidb/cursor.h>
41#include <kexidialogbase.h>
42
44class KexiTablePart::Private
45{
46 public:
47 Private()
48 {
49 }
50 ~Private()
51 {
52 delete static_cast<KexiLookupColumnPage*>(lookupColumnPage);
53 }
54 TQGuardedPtr<KexiLookupColumnPage> lookupColumnPage;
55};
56
57KexiTablePart::KexiTablePart(TQObject *parent, const char *name, const TQStringList &l)
58 : KexiPart::Part(parent, name, l)
59 , d(new Private())
60{
61 // REGISTERED ID:
62 m_registeredPartID = (int)KexiPart::TableObjectType;
63
64 kdDebug() << "KexiTablePart::KexiTablePart()" << endl;
65 m_names["instanceName"]
66 = i18n("Translate this word using only lowercase alphanumeric characters (a..z, 0..9). "
67 "Use '_' character instead of spaces. First character should be a..z character. "
68 "If you cannot use latin characters in your language, use english word.",
69 "table");
70 m_names["instanceCaption"] = i18n("Table");
71 m_supportedViewModes = Kexi::DataViewMode | Kexi::DesignViewMode;
72//js TODO: also add Kexi::TextViewMode when we'll have SQL ALTER TABLE EDITOR!!!
73}
74
75KexiTablePart::~KexiTablePart()
76{
77 delete d;
78}
79
80void KexiTablePart::initPartActions()
81{
82}
83
84void KexiTablePart::initInstanceActions()
85{
86//moved to main window createSharedAction(Kexi::DataViewMode, i18n("Filter"), "filter", 0, "tablepart_filter");
87
88 TDEAction *a = createSharedToggleAction(
89 Kexi::DesignViewMode, i18n("Primary Key"), "key", 0, "tablepart_toggle_pkey");
90// Kexi::DesignViewMode, i18n("Toggle Primary Key"), "key", 0, "tablepart_toggle_pkey");
91 a->setWhatsThis(i18n("Sets or removes primary key for currently selected field."));
92}
93
94KexiDialogTempData* KexiTablePart::createTempData(KexiDialogBase* dialog)
95{
96 return new KexiTablePart::TempData(dialog);
97}
98
99KexiViewBase* KexiTablePart::createView(TQWidget *parent, KexiDialogBase* dialog,
100 KexiPart::Item &item, int viewMode, TQMap<TQString,TQString>*)
101{
102 KexiMainWindow *win = dialog->mainWin();
103 if (!win || !win->project() || !win->project()->dbConnection())
104 return 0;
105
106
107 KexiTablePart::TempData *temp = static_cast<KexiTablePart::TempData*>(dialog->tempData());
108 if (!temp->table) {
109 temp->table = win->project()->dbConnection()->tableSchema(item.name());
110 kdDebug() << "KexiTablePart::execute(): schema is " << temp->table << endl;
111 }
112
113 if (viewMode == Kexi::DesignViewMode) {
114 KexiTableDesignerView *t = new KexiTableDesignerView(win, parent);
115 return t;
116 }
117 else if (viewMode == Kexi::DataViewMode) {
118 if(!temp->table)
119 return 0; //todo: message
120 //we're not setting table schema here -it will be forced to set
121 // in KexiTableDesigner_DataView::afterSwitchFrom()
122 KexiTableDesigner_DataView *t = new KexiTableDesigner_DataView(win, parent);
123 return t;
124 }
125 return 0;
126}
127
128bool KexiTablePart::remove(KexiMainWindow *win, KexiPart::Item &item)
129{
130 if (!win || !win->project() || !win->project()->dbConnection())
131 return false;
132
133 KexiDB::Connection *conn = win->project()->dbConnection();
134 KexiDB::TableSchema *sch = conn->tableSchema(item.identifier());
135
136 if (sch) {
137 tristate res = KexiTablePart::askForClosingObjectsUsingTableSchema(
138 win, *conn, *sch,
139 i18n("You are about to remove table \"%1\" but following objects using this table are opened:")
140 .arg(sch->name()));
141 return true == conn->dropTable( sch );
142 }
143 //last chance: just remove item
144 return conn->removeObject( item.identifier() );
145}
146
147tristate KexiTablePart::rename(KexiMainWindow *win, KexiPart::Item & item,
148 const TQString& newName)
149{
150//TODO: what about objects (queries/forms) that use old name?
151 KexiDB::Connection *conn = win->project()->dbConnection();
152 KexiDB::TableSchema *sch = conn->tableSchema(item.identifier());
153 if (!sch)
154 return false;
155 return conn->alterTableName(*sch, newName);
156}
157
159KexiTablePart::loadSchemaData(KexiDialogBase *dlg, const KexiDB::SchemaData& sdata, int viewMode)
160{
161 Q_UNUSED( viewMode );
162
163 return dlg->mainWin()->project()->dbConnection()->tableSchema( sdata.name() );
164}
165
166#if 0
168KexiTablePart::dataSource()
169{
170 return new KexiTableDataSource(this);
171}
172#endif
173
174tristate KexiTablePart::askForClosingObjectsUsingTableSchema(TQWidget *parent, KexiDB::Connection& conn,
175 KexiDB::TableSchema& table, const TQString& msg)
176{
177 TQPtrList<KexiDB::Connection::TableSchemaChangeListenerInterface>* listeners
178 = conn.tableSchemaChangeListeners(table);
179 if (!listeners || listeners->isEmpty())
180 return true;
181
182 TQString openedObjectsStr = "<ul>";
183 for (TQPtrListIterator<KexiDB::Connection::TableSchemaChangeListenerInterface> it(*listeners);
184 it.current(); ++it) {
185 openedObjectsStr += TQString("<li>%1</li>").arg(it.current()->listenerInfoString);
186 }
187 openedObjectsStr += "</ul>";
188 int r = KMessageBox::questionYesNo(parent,
189 "<p>"+msg+"</p><p>"+openedObjectsStr+"</p><p>"
190 +i18n("Do you want to close all windows for these objects?"),
191 TQString(), KGuiItem(i18n("Close windows"),"window-close"), KStdGuiItem::cancel());
192 tristate res;
193 if (r == KMessageBox::Yes) {
194 //try to close every window
195 res = conn.closeAllTableSchemaChangeListeners(table);
196 if (res!=true) //do not expose closing errors twice; just cancel
197 res = cancelled;
198 }
199 else
200 res = cancelled;
201
202 return res;
203}
204
205TQString
206KexiTablePart::i18nMessage(const TQCString& englishMessage, KexiDialogBase* dlg) const
207{
208 if (englishMessage=="Design of object \"%1\" has been modified.")
209 return i18n("Design of table \"%1\" has been modified.");
210
211 if (englishMessage=="Object \"%1\" already exists.")
212 return i18n("Table \"%1\" already exists.");
213
214 if (dlg->currentViewMode()==Kexi::DesignViewMode && !dlg->neverSaved()
215 && englishMessage==":additional message before saving design")
216 return i18n("Warning! Any data in this table will be removed upon design's saving!");
217
218 return englishMessage;
219}
220
221void KexiTablePart::setupCustomPropertyPanelTabs(KTabWidget *tab, KexiMainWindow* mainWin)
222{
223 if (!d->lookupColumnPage) {
224 d->lookupColumnPage = new KexiLookupColumnPage(0);
225 connect(d->lookupColumnPage, TQ_SIGNAL(jumpToObjectRequested(const TQCString&, const TQCString&)),
226 mainWin, TQ_SLOT(highlightObject(const TQCString&, const TQCString&)));
227
229
230 /*
231 connect(d->dataSourcePage, TQ_SIGNAL(formDataSourceChanged(const TQCString&, const TQCString&)),
232 KFormDesigner::FormManager::self(), TQ_SLOT(setFormDataSource(const TQCString&, const TQCString&)));
233 connect(d->dataSourcePage, TQ_SIGNAL(dataSourceFieldOrExpressionChanged(const TQString&, const TQString&, KexiDB::Field::Type)),
234 KFormDesigner::FormManager::self(), TQ_SLOT(setDataSourceFieldOrExpression(const TQString&, const TQString&, KexiDB::Field::Type)));
235 connect(d->dataSourcePage, TQ_SIGNAL(insertAutoFields(const TQString&, const TQString&, const TQStringList&)),
236 KFormDesigner::FormManager::self(), TQ_SLOT(insertAutoFields(const TQString&, const TQString&, const TQStringList&)));*/
237 }
238
239 KexiProject *prj = mainWin->project();
240 d->lookupColumnPage->setProject(prj);
241
243 tab->addTab( d->lookupColumnPage, SmallIconSet("combo"), "");
244 tab->setTabToolTip( d->lookupColumnPage, i18n("Lookup column"));
245}
246
247KexiLookupColumnPage* KexiTablePart::lookupColumnPage() const
248{
249 return d->lookupColumnPage;
250}
251
252//----------------
253
254#if 0
255KexiTableDataSource::KexiTableDataSource(KexiPart::Part *part)
256 : KexiPart::DataSource(part)
257{
258}
259
260KexiTableDataSource::~KexiTableDataSource()
261{
262}
263
265KexiTableDataSource::fields(KexiProject *project, const KexiPart::Item &it)
266{
267 kdDebug() << "KexiTableDataSource::fields(): " << it.name() << endl;
268 return project->dbConnection()->tableSchema(it.name());
269}
270
272KexiTableDataSource::cursor(KexiProject * /*project*/,
273 const KexiPart::Item &/*it*/, bool /*buffer*/)
274{
275 return 0;
276}
277#endif
278
279//----------------
280
281KexiTablePart::TempData::TempData(TQObject* parent)
282 : KexiDialogTempData(parent)
283 , table(0)
284 , tableSchemaChangedInPreviousView(true /*to force reloading on startup*/ )
285{
286}
287
288//----------------
289
293/*
294AboutData( const char *programName,
295 const char *version,
296 const char *i18nShortDescription = 0,
297 int licenseType = License_Unknown,
298 const char *i18nCopyrightStatement = 0,
299 const char *i18nText = 0,
300 const char *homePageAddress = 0,
301 const char *bugsEmailAddress = "submit@bugs.kde.org"
302);
303
304#define KEXIPART_EXPORT_FACTORY( libname, partClass, aboutData ) \
305 static KexiPart::AboutData * libname ## updateAD(KexiPart::AboutData *ad) \
306 { ad->setAppName( #libname ); return ad; } \
307 K_EXPORT_COMPONENT_FACTORY( libname, KGenericFactory<partClass>(libname ## updateAD(#libname)) )
308*/
309
310K_EXPORT_COMPONENT_FACTORY( kexihandler_table, KGenericFactory<KexiTablePart>("kexihandler_table") )
311
312#include "kexitablepart.moc"
313
Provides database connection, allowing queries and data modification.
Definition connection.h:62
TableSchema * tableSchema(int tableId)
bool removeObject(uint objId)
bool alterTableName(TableSchema &tableSchema, const TQString &newName, bool replace=false)
tristate dropTable(TableSchema *tableSchema)
Drops a table corresponding to the name in the given schema.
Provides database cursor functionality.
Definition cursor.h:67
Base class for child window of Kexi's main application window.
int currentViewMode() const
KexiDialogTempData * tempData() const
bool neverSaved() const
Privides temporary data shared between KexiDialogBase's views (KexiView's)
A page within table designer's property pane, providing lookup column editor.
Kexi's main window interface This interface is implemented by KexiMainWindowImpl class.
virtual KexiProject * project()=0
Project data of currently opened project or NULL if no project here yet.
this class provides a datasource framework for e.g.
Information about a single object that can be instantiated using Kexi Part.
The main class for kexi frontend parts like tables, queries, forms and reports.
Definition kexipart.h:66
A project's main controller.
Definition kexiproject.h:68
KexiDB::Connection * dbConnection() const
Design view of the Table Designer.
Base class for single view embeddable of in KexiDialogBase.
3-state logical type with three values: true, false and cancelled and convenient operators.
Definition tristate.h:100