kexi

kexipart.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2003 Lucijan Busch <lucijan@kde.org>
3 Copyright (C) 2003-2005 Jaroslaw Staniek <js@iidea.pl>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19*/
20
21#include "kexipart.h"
22#include "kexipartinfo.h"
23#include "kexipartitem.h"
24#include "kexistaticpart.h"
25#include "kexidialogbase.h"
26#include "kexiviewbase.h"
27
28#include "kexipartguiclient.h"
29#include "keximainwindow.h"
30//#include "kexipartdatasource.h"
31#include "kexi.h"
32
33#include <kexidb/connection.h>
34#include <kexiutils/identifier.h>
35#include <kexiutils/utils.h>
36
37#include <tqwidgetstack.h>
38
39#include <kiconloader.h>
40#include <kdebug.h>
41#include <tdemessagebox.h>
42
43namespace KexiPart {
45class PartPrivate
46{
47public:
48 PartPrivate()
49 : instanceActionsInitialized(false)
50 {
51 }
52
54 tristate askForOpeningInTextMode(KexiDialogBase *dlg, KexiPart::Item &item,
55 int supportedViewModes, int viewMode)
56 {
57 if (viewMode != Kexi::TextViewMode
58 && supportedViewModes & Kexi::TextViewMode
60 {
61 //ask
64 TQString singleStatusString( dlg->singleStatusString() );
65 if (!singleStatusString.isEmpty())
66 singleStatusString.prepend(TQString("\n\n")+i18n("Details:")+" ");
67 if (KMessageBox::No==KMessageBox::questionYesNo(0,
68 ((viewMode == Kexi::DesignViewMode)
69 ? i18n("Object \"%1\" could not be opened in Design View.").arg(item.name())
70 : i18n("Object could not be opened in Data View."))+"\n"
71 + i18n("Do you want to open it in Text View?") + singleStatusString, 0,
72 KStdGuiItem::open(), KStdGuiItem::cancel()))
73 {
74 // dlg->close(); //this will destroy dlg
75 return false;
76 }
77 return true;
78 }
79 return cancelled;
80 }
81
82 bool instanceActionsInitialized : 1;
83};
84}
85
86//----------------------------------------------------------------
87
88using namespace KexiPart;
89
90Part::Part(TQObject *parent, const char *name, const TQStringList &)
91: TQObject(parent, name)
92, m_guiClient(0)
93, m_registeredPartID(-1) //no registered ID by default
94, d(new PartPrivate())
95{
96 m_info = 0;
97 m_supportedViewModes = Kexi::DataViewMode | Kexi::DesignViewMode;
98 m_supportedUserViewModes = Kexi::DataViewMode;
99 m_mainWin = 0;
100 m_newObjectsAreDirty = false;
101}
102
103Part::Part(TQObject* parent, StaticInfo *info)
104: TQObject(parent, "StaticPart")
105, m_guiClient(0)
106, m_registeredPartID(-1) //no registered ID by default
107, d(new PartPrivate())
108{
109 m_info = info;
110 m_supportedViewModes = Kexi::DesignViewMode;
112 m_mainWin = 0;
113 m_newObjectsAreDirty = false;
114}
115
117{
118 delete d;
119}
120
122{
123 m_mainWin = win;
124 if (!m_guiClient) {
125 //create part's gui client
126 m_guiClient = new GUIClient(m_mainWin, this, false, "part");
127
128 //default actions for part's gui client:
129 TDEAction *act = new TDEAction(m_names["instanceCaption"]+"...", info()->createItemIcon(), 0, this,
130 TQ_SLOT(slotCreate()), m_mainWin->actionCollection(),
131 KexiPart::nameForCreateAction(*info()));
132 act->plug( m_mainWin->findPopupMenu("insert") );
133// new TDEAction(m_names["instance"]+"...", info()->itemIcon(), 0, this,
134// TQ_SLOT(create()), m_guiClient->actionCollection(), (info()->objectName()+"part_create").latin1());
135 //let init specific actions for parts
136// initPartActions( m_guiClient->actionCollection() );
137 m_mainWin->guiFactory()->addClient(m_guiClient); //this client is added permanently
138
139 //create part instance's gui client
140// m_instanceGuiClient = new GUIClient(win, this, true);
141
142 //default actions for part instance's gui client:
143 //NONE
144 //let init specific actions for part instances
145 for (int mode = 1; mode <= 0x01000; mode <<= 1) {
146 if (m_supportedViewModes & mode) {
147 GUIClient *instanceGuiClient = new GUIClient(m_mainWin,
148 this, true, Kexi::nameForViewMode(mode).latin1());
149 m_instanceGuiClients.insert(mode, instanceGuiClient);
150// initInstanceActions( mode, instanceGuiClient->actionCollection() );
151 }
152 }
153 // also add an instance common for all modes (mode==0)
154 GUIClient *instanceGuiClient = new GUIClient(m_mainWin, this, true, "allViews");
155 m_instanceGuiClients.insert(Kexi::AllViewModes, instanceGuiClient);
156// initInstanceActions( Kexi::AllViewModes , instanceGuiClient->actionCollection() );
157
158//todo
159 initPartActions();
160// initActions();
161 }
162}
163
164TDEActionCollection* Part::actionCollectionForMode(int viewMode) const
165{
166 KXMLGUIClient *cli = m_instanceGuiClients[viewMode];
167 return cli ? cli->actionCollection() : 0;
168}
169
170TDEAction* Part::createSharedAction(int mode, const TQString &text,
171 const TQString &pix_name, const TDEShortcut &cut, const char *name,
172 const char *subclassName)
173{
174 GUIClient *instanceGuiClient = m_instanceGuiClients[mode];
175 if (!instanceGuiClient) {
176 kdDebug() << "KexiPart::createSharedAction(): no gui client for mode " << mode << "!" << endl;
177 return 0;
178 }
179 return m_mainWin->createSharedAction(text, pix_name, cut, name,
180 instanceGuiClient->actionCollection(), subclassName);
181}
182
183TDEAction* Part::createSharedPartAction(const TQString &text,
184 const TQString &pix_name, const TDEShortcut &cut, const char *name,
185 const char *subclassName)
186{
187 if (!m_guiClient)
188 return 0;
189 return m_mainWin->createSharedAction(text, pix_name, cut, name,
190 m_guiClient->actionCollection(), subclassName);
191}
192
193TDEAction* Part::createSharedToggleAction(int mode, const TQString &text,
194 const TQString &pix_name, const TDEShortcut &cut, const char *name)
195{
196 return createSharedAction(mode, text, pix_name, cut, name, "TDEToggleAction");
197}
198
199TDEAction* Part::createSharedPartToggleAction(const TQString &text,
200 const TQString &pix_name, const TDEShortcut &cut, const char *name)
201{
202 return createSharedPartAction(text, pix_name, cut, name, "TDEToggleAction");
203}
204
205/*TDEAction* Part::sharedAction(int mode, const char* name, const char *classname)
206{
207 GUIClient *instanceGuiClient = m_instanceGuiClients[mode];
208 if (!instanceGuiClient) {
209 kdDebug() << "KexiPart::createSharedAction(): no gui client for mode " << mode << "!" << endl;
210 return 0;
211 }
212 return instanceGuiClient->actionCollection()->action(name, classname);
213}
214
215TDEAction* Part::sharedPartAction(int mode, const char* name, const char *classname)
216{
217 if (!m_guiClient)
218 return 0;
219 return m_guiClient->actionCollection()->action(name, classname);
220}*/
221
222void Part::setActionAvailable(const char *action_name, bool avail)
223{
224 TQIntDictIterator<GUIClient> it( m_instanceGuiClients );
225 for (;it.current();++it) {
226 TDEAction *act = it.current()->actionCollection()->action(action_name);
227 if (act) {
228 act->setEnabled(avail);
229 return;
230 }
231 }
232
233 m_mainWin->setActionAvailable(action_name, avail);
234}
235
237 TQMap<TQString,TQString>* staticObjectArgs)
238{
239 //now it's the time for creating instance actions
240 if (!d->instanceActionsInitialized) {
241 initInstanceActions();
242 d->instanceActionsInitialized = true;
243 }
244
245 m_status.clearStatus();
246// KexiDialogBase *dlg = createInstance(win,item,viewMode);
247// if (!dlg)
248// return 0;
249// TQString capt = TQString("%1 : %2").arg(item.name()).arg(instanceName());
250 KexiDialogBase *dlg = new KexiDialogBase(win);
251 dlg->m_supportedViewModes = m_supportedViewModes;
252// dlg->m_neverSaved = item.neverSaved();
253// dlg->m_currentViewMode = viewMode;
254 dlg->m_part = this;
255 dlg->m_item = &item;
256 dlg->updateCaption();
257
258 KexiDB::SchemaData sdata(m_info->projectPartID());
259 sdata.setName( item.name() );
260 sdata.setCaption( item.caption() );
261 sdata.setDescription( item.description() );
262
266// dlg->setCaption( capt );
267// dlg->setTabCaption( item.name() );
268 dlg->setId(item.identifier()); //not needed, but we did it
269//moved down dlg->registerDialog();
270 dlg->setIcon( SmallIcon( dlg->itemIcon() ) );
271 if (dlg->mdiParent())
272 dlg->mdiParent()->setIcon( *dlg->icon() );
273// if (dlg->mainWidget())
274// dlg->mainWidget()->setIcon( *dlg->icon() );
275 dlg->stack()->setIcon( *dlg->icon() );
276 dlg->m_tempData = createTempData(dlg);
277
278 if (!item.neverSaved()) {
279 //we have to load schema data for this dialog
280 dlg->m_schemaData = loadSchemaData(dlg, sdata, viewMode);
281 if (!dlg->m_schemaData) {
282 //last chance:
283 if (false == d->askForOpeningInTextMode(dlg, item, dlg->m_supportedViewModes, viewMode)) {
284 delete dlg;
285 return 0;
286 }
287 viewMode = Kexi::TextViewMode;
288 dlg->m_schemaData = loadSchemaData(dlg, sdata, viewMode);
289 }
290 if (!dlg->m_schemaData) {
291 if (!m_status.error())
292 m_status = Kexi::ObjectStatus( dlg->mainWin()->project()->dbConnection(),
293 i18n("Could not load object's definition."), i18n("Object design may be corrupted."));
294 m_status.append(
295 Kexi::ObjectStatus(i18n("You can delete \"%1\" object and create it again.")
296 .arg(item.name()), TQString()) );
297
298 dlg->close();
299 delete dlg;
300 return 0;
301 }
302 }
303
304 bool switchingFailed = false;
305 bool dummy;
306 tristate res = dlg->switchToViewMode( viewMode, staticObjectArgs, dummy );
307 if (!res) {
308 tristate askForOpeningInTextModeRes
309 = d->askForOpeningInTextMode(dlg, item, dlg->m_supportedViewModes, viewMode);
310// if (viewMode==Kexi::DesignViewMode && dlg->isDesignModePreloadedForTextModeHackUsed(Kexi::TextViewMode))
311// askForOpeningInTextModeRes = cancelled; //do not try
312// else
313 if (true == askForOpeningInTextModeRes) {
314 delete dlg->m_schemaData; //old one
315 dlg->close();
316 delete dlg;
317 //try in text mode
318 return openInstance(win, item, Kexi::TextViewMode, staticObjectArgs);
319 }
320 else if (false == askForOpeningInTextModeRes) {
321 delete dlg->m_schemaData; //old one
322 dlg->close();
323 delete dlg;
324 return 0;
325 }
326 //dlg has an error info
327 switchingFailed = true;
328 }
329 if (~res)
330 switchingFailed = true;
331
332 if (switchingFailed) {
333 m_status = dlg->status();
334 dlg->close();
335 delete dlg;
336 return 0;
337 }
338 dlg->registerDialog(); //ok?
339 dlg->show();
340
341 if (dlg->mdiParent() && dlg->mdiParent()->state()==KMdiChildFrm::Normal) //only resize dialog if it is in normal state
342 dlg->resize(dlg->sizeHint());
343
344 dlg->setMinimumSize(dlg->minimumSizeHint().width(),dlg->minimumSizeHint().height());
345
346 //dirty only if it's a new object
347 if (dlg->selectedView())
348 dlg->selectedView()->setDirty( m_newObjectsAreDirty ? item.neverSaved() : false );
349
350 return dlg;
351}
352
353void Part::slotCreate()
354{
355 emit newObjectRequest( m_info );
356}
357
358KexiDB::SchemaData* Part::loadSchemaData(KexiDialogBase * /*dlg*/, const KexiDB::SchemaData& sdata,
359 int /*viewMode*/)
360{
361 KexiDB::SchemaData *new_schema = new KexiDB::SchemaData();
362 *new_schema = sdata;
363 return new_schema;
364}
365
366bool Part::loadDataBlock( KexiDialogBase *dlg, TQString &dataString, const TQString& dataID)
367{
368 if (!dlg->mainWin()->project()->dbConnection()->loadDataBlock( dlg->id(), dataString, dataID )) {
369 m_status = Kexi::ObjectStatus( dlg->mainWin()->project()->dbConnection(),
370 i18n("Could not load object's data."), i18n("Data identifier: \"%1\".").arg(dataID) );
371 m_status.append( *dlg );
372 return false;
373 }
374 return true;
375}
376
377void Part::initPartActions()
378{
379}
380
381void Part::initInstanceActions()
382{
383}
384
386{
387 if (!win || !win->project() || !win->project()->dbConnection())
388 return false;
389 KexiDB::Connection *conn = win->project()->dbConnection();
390 return conn->removeObject( item.identifier() );
391}
392
397
398TQString Part::i18nMessage(const TQCString& englishMessage, KexiDialogBase* dlg) const
399{
400 Q_UNUSED(dlg);
401 return TQString(englishMessage).startsWith(":") ? TQString() : englishMessage;
402}
403
407
408TQCString Part::instanceName() const
409{
410 // "instanceName" should be already valid identifier but we're using
411 // KexiUtils::string2Identifier() to be sure translators did it right.
412 return KexiUtils::string2Identifier(m_names["instanceName"]).lower().latin1();
413}
414
415TQString Part::instanceCaption() const
416{
417 return m_names["instanceCaption"];
418}
419
420tristate Part::rename(KexiMainWindow *win, KexiPart::Item &item, const TQString& newName)
421{
422 Q_UNUSED(win);
423 Q_UNUSED(item);
424 Q_UNUSED(newName);
425 return true;
426}
427
428//-------------------------------------------------------------------------
429
430
431GUIClient::GUIClient(KexiMainWindow *win, Part* part, bool partInstanceClient, const char* nameSuffix)
432 : TQObject(part,
433 (part->info()->objectName()
434 + (nameSuffix ? TQString(":%1").arg(nameSuffix) : TQString())).latin1() )
435 , KXMLGUIClient(win)
436{
437 if(!win->project()->data()->userMode())
438 setXMLFile(TQString::fromLatin1("kexi")+part->info()->objectName()
439 +"part"+(partInstanceClient?"inst":"")+"ui.rc");
440
441// new TDEAction(part->m_names["new"], part->info()->itemIcon(), 0, this,
442// TQ_SLOT(create()), actionCollection(), (part->info()->objectName()+"part_create").latin1());
443
444// new TDEAction(i18nInstanceName+"...", part->info()->itemIcon(), 0, this,
445// TQ_SLOT(create()), actionCollection(), (part->info()->objectName()+"part_create").latin1());
446
447// win->guiFactory()->addClient(this);
448}
449
450
451#include "kexipart.moc"
452
Provides database connection, allowing queries and data modification.
Definition connection.h:62
bool removeObject(uint objId)
tristate loadDataBlock(int objectID, TQString &dataString, const TQString &dataID)
Base class for child window of Kexi's main application window.
void setId(int id)
KexiDialogTempData * tempData() const
virtual TQSize sizeHint() const
virtual TQSize minimumSizeHint() const
virtual TQString itemIcon()
KexiViewBase * selectedView() const
tristate switchToViewMode(int newViewMode)
Privides temporary data shared between KexiDialogBase's views (KexiView's)
bool proposeOpeningInTextViewModeBecauseOfProblems
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.
int projectPartID() const
TQString objectName() const
Information about a single object that can be instantiated using Kexi Part.
bool neverSaved() const
The main class for kexi frontend parts like tables, queries, forms and reports.
Definition kexipart.h:66
int m_supportedViewModes
Definition kexipart.h:301
virtual ~Part()
Definition kexipart.cpp:116
void createGUIClients(KexiMainWindow *win)
Creates GUICLients for this part, attached to win This method is called from KexiMainWindow.
Definition kexipart.cpp:121
bool m_newObjectsAreDirty
Definition kexipart.h:322
TDEAction * createSharedAction(int mode, const TQString &text, const TQString &pix_name, const TDEShortcut &cut, const char *name, const char *subclassName=0)
Definition kexipart.cpp:170
Part(TQObject *parent, const char *name, const TQStringList &)
Definition kexipart.cpp:90
TDEAction * createSharedPartAction(const TQString &text, const TQString &pix_name, const TDEShortcut &cut, const char *name, const char *subclassName=0)
Definition kexipart.cpp:183
virtual void setupCustomPropertyPanelTabs(KTabWidget *tab, KexiMainWindow *mainWin)
Definition kexipart.cpp:404
KexiDialogBase * openInstance(KexiMainWindow *win, KexiPart::Item &item, int viewMode=Kexi::DataViewMode, TQMap< TQString, TQString > *staticObjectArgs=0)
Definition kexipart.cpp:236
virtual KexiDialogTempData * createTempData(KexiDialogBase *dialog)
Definition kexipart.cpp:393
TQString instanceCaption() const
Definition kexipart.cpp:415
virtual bool remove(KexiMainWindow *win, KexiPart::Item &item)
Definition kexipart.cpp:385
TQMap< TQString, TQString > m_names
Set of i18n'd action names for, initialised on KexiPart::Part subclass ctor The names are useful beca...
Definition kexipart.h:297
TDEActionCollection * actionCollectionForMode(int viewMode) const
Definition kexipart.cpp:164
virtual tristate rename(KexiMainWindow *win, KexiPart::Item &item, const TQString &newName)
Definition kexipart.cpp:420
TDEAction * createSharedToggleAction(int mode, const TQString &text, const TQString &pix_name, const TDEShortcut &cut, const char *name)
Definition kexipart.cpp:193
GUIClient * instanceGuiClient(int mode=0) const
Definition kexipart.h:175
TDEAction * createSharedPartToggleAction(const TQString &text, const TQString &pix_name, const TDEShortcut &cut, const char *name)
Definition kexipart.cpp:199
TQCString instanceName() const
Definition kexipart.cpp:408
int m_supportedUserViewModes
Definition kexipart.h:306
virtual TQString i18nMessage(const TQCString &englishMessage, KexiDialogBase *dlg) const
Definition kexipart.cpp:398
Information about a static Kexi Part (plugin).
bool userMode() const
KexiProjectData * data() const
KexiDB::Connection * dbConnection() const
TDEAction * createSharedAction(const TQString &text, const TQString &pix_name, const TDEShortcut &cut, const char *name, TDEActionCollection *col=0, const char *subclassName=0)
void setDirty(bool set)
3-state logical type with three values: true, false and cancelled and convenient operators.
Definition tristate.h:100
KEXIUTILS_EXPORT TQString string2Identifier(const TQString &s)
KEXICORE_EXPORT TQString nameForViewMode(int m)
i18n'ed name of view mode m
Definition kexi.cpp:157
@ TextViewMode
Also known as SQL View Mode.
Definition kexi.h:48
@ AllViewModes
Usable primarily in KexiPart::initInstanceActions()
Definition kexi.h:43