1
/* This file is part of the KDE project
2
Copyright (C) 2003 Lucijan Busch <lucijan@kde.org>
3
Copyright (C) 2003-2014 JarosÅaw Staniek <staniek@kde.org>
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.
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.
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.
22
#include "kexipartinfo.h"
23
#include "kexipartitem.h"
24
//! @todo KEXI3 #include "kexistaticpart.h"
25
#include "KexiWindow.h"
26
#include "KexiWindowData.h"
28
#include "kexipartguiclient.h"
29
#include "KexiMainWindowIface.h"
31
#include <kexiutils/utils.h>
33
#include <KDbConnection>
35
#include <KActionCollection>
36
#include <KMessageBox>
48
, newObjectsAreDirty(false)
49
, instanceActionsInitialized(false)
53
//! Helper, used in Part::openInstance()
54
tristate askForOpeningInTextMode(KexiWindow *window, KexiPart::Item *item,
55
Kexi::ViewModes supportedViewModes, Kexi::ViewMode viewMode) {
56
if (viewMode != Kexi::TextViewMode
57
&& supportedViewModes & Kexi::TextViewMode
58
&& window->data()->proposeOpeningInTextViewModeBecauseOfProblems) {
60
KexiUtils::WaitCursorRemover remover;
61
//! @todo use message handler for this to enable non-gui apps
62
QString singleStatusString(window->singleStatusString());
63
if (!singleStatusString.isEmpty())
64
singleStatusString.prepend(QString("\n\n") + xi18n("Details:") + " ");
65
if (KMessageBox::No == KMessageBox::questionYesNo(0,
66
((viewMode == Kexi::DesignViewMode)
68
"Object <resource>%1</resource> could not be opened in Design View.", item->name())
69
: xi18n("Object could not be opened in Data View.")) + "\n"
70
+ xi18n("Do you want to open it in Text View?") + singleStatusString, 0,
71
KStandardGuiItem::open(), KStandardGuiItem::cancel())) {
84
QMap<int, GUIClient*> instanceGuiClients;
85
Kexi::ObjectStatus status;
87
bool newObjectsAreDirty;
88
bool instanceActionsInitialized;
92
//----------------------------------------------------------------
94
using namespace KexiPart;
96
Part::Part(QObject *parent,
97
const QString& instanceName,
98
const QString& toolTip,
99
const QString& whatsThis,
100
const QVariantList& list)
101
: PartBase(parent, list)
104
d->instanceName = KDb::stringToIdentifier(
105
instanceName.isEmpty()
106
? xi18nc("Translate this word using only lowercase alphanumeric characters (a..z, 0..9). "
107
"Use '_' character instead of spaces. First character should be a..z character. "
108
"If you cannot use latin characters in your language, use english word.",
111
d->toolTip = toolTip;
112
d->whatsThis = whatsThis;
116
Part::Part(QObject* parent, StaticPartInfo *info)
117
: PartBase(parent, QVariantList())
120
setObjectName("StaticPart");
129
void Part::createGUIClients()//KexiMainWindow *win)
132
//create part's gui client
133
d->guiClient = new GUIClient(this, false, "part");
135
//default actions for part's gui client:
136
QAction* act = info()->newObjectAction();
137
// - update action's tooltip and "what's this"
138
QString tip(toolTip());
139
if (!tip.isEmpty()) {
140
act->setToolTip(tip);
142
QString what(whatsThis());
143
if (!what.isEmpty()) {
144
act->setWhatsThis(what);
147
//default actions for part instance's gui client:
149
//let init specific actions for part instances
150
for (int mode = 1; mode <= 0x01000; mode <<= 1) {
151
if (info()->supportedViewModes() & (Kexi::ViewMode)mode) {
152
GUIClient *instanceGuiClient = new GUIClient(
153
this, true, Kexi::nameForViewMode((Kexi::ViewMode)mode).toLatin1());
154
d->instanceGuiClients.insert((Kexi::ViewMode)mode, instanceGuiClient);
157
// also add an instance common for all modes (mode==0)
158
GUIClient *instanceGuiClient = new GUIClient(this, true, "allViews");
159
d->instanceGuiClients.insert(Kexi::AllViewModes, instanceGuiClient);
165
KActionCollection* Part::actionCollectionForMode(Kexi::ViewMode viewMode) const
167
GUIClient *cli = d->instanceGuiClients.value((int)viewMode);
168
return cli ? cli->actionCollection() : 0;
171
QAction * Part::createSharedAction(Kexi::ViewMode mode, const QString &text,
172
const QString &pix_name, const QKeySequence &cut, const char *name,
173
const char *subclassName)
175
GUIClient *instanceGuiClient = d->instanceGuiClients.value((int)mode);
176
if (!instanceGuiClient) {
177
qWarning() << "no gui client for mode " << mode << "!";
180
return KexiMainWindowIface::global()->createSharedAction(text, pix_name, cut, name,
181
instanceGuiClient->actionCollection(), subclassName);
184
QAction * Part::createSharedPartAction(const QString &text,
185
const QString &pix_name, const QKeySequence &cut, const char *name,
186
const char *subclassName)
190
return KexiMainWindowIface::global()->createSharedAction(text, pix_name, cut, name,
191
d->guiClient->actionCollection(), subclassName);
194
QAction * Part::createSharedToggleAction(Kexi::ViewMode mode, const QString &text,
195
const QString &pix_name, const QKeySequence &cut, const char *name)
197
return createSharedAction(mode, text, pix_name, cut, name, "KToggleAction");
200
QAction * Part::createSharedPartToggleAction(const QString &text,
201
const QString &pix_name, const QKeySequence &cut, const char *name)
203
return createSharedPartAction(text, pix_name, cut, name, "KToggleAction");
206
void Part::setActionAvailable(const char *action_name, bool avail)
208
for (QMap<int, GUIClient*>::Iterator it = d->instanceGuiClients.begin(); it != d->instanceGuiClients.end(); ++it) {
209
QAction *act = it.value()->actionCollection()->action(action_name);
211
act->setEnabled(avail);
215
KexiMainWindowIface::global()->setActionAvailable(action_name, avail);
218
KexiWindow* Part::openInstance(QWidget* parent, KexiPart::Item *item, Kexi::ViewMode viewMode,
219
QMap<QString, QVariant>* staticObjectArgs)
222
//now it's the time for creating instance actions
223
if (!d->instanceActionsInitialized) {
224
initInstanceActions();
225
d->instanceActionsInitialized = true;
228
d->status.clearStatus();
229
KexiWindow *window = new KexiWindow(parent,
230
info()->supportedViewModes(), this, item);
232
KexiProject *project = KexiMainWindowIface::global()->project();
233
KDbObject object(project->typeIdForPluginId(info()->pluginId()));
234
object.setName(item->name());
235
object.setCaption(item->caption());
236
object.setDescription(item->description());
238
/*! @todo js: apply settings for caption displaying method; there can be option for
239
- displaying item.caption() as caption, if not empty, without instanceName
240
- displaying the same as above in tabCaption (or not) */
241
window->setId(item->identifier()); //not needed, but we did it
242
window->setWindowIcon(QIcon::fromTheme(window->iconName()));
243
KexiWindowData *windowData = createWindowData(window);
245
d->status = Kexi::ObjectStatus(KexiMainWindowIface::global()->project()->dbConnection(),
246
xi18n("Could not create object's window."), xi18n("The plugin or object definition may be corrupted."));
250
window->setData(windowData);
252
if (!item->neverSaved()) {
253
//we have to load object data for this dialog
254
loadAndSetSchemaObject(window, object, viewMode);
255
if (!window->schemaObject()) {
257
if (false == d->askForOpeningInTextMode(
258
window, item, window->supportedViewModes(), viewMode)) {
262
viewMode = Kexi::TextViewMode;
263
loadAndSetSchemaObject(window, object, viewMode);
265
if (!window->schemaObject()) {
266
if (!d->status.error())
267
d->status = Kexi::ObjectStatus(KexiMainWindowIface::global()->project()->dbConnection(),
268
xi18n("Could not load object's definition."), xi18n("Object design may be corrupted."));
270
Kexi::ObjectStatus(xi18nc("@info",
271
"You can delete <resource>%1</resource> object and create it again.",
272
item->name()), QString()));
280
bool switchingFailed = false;
282
tristate res = window->switchToViewMode(viewMode, staticObjectArgs, &dummy);
284
tristate askForOpeningInTextModeRes
285
= d->askForOpeningInTextMode(window, item, window->supportedViewModes(), viewMode);
286
if (true == askForOpeningInTextModeRes) {
287
delete window->schemaObject(); //old one
291
return openInstance(parent, item, Kexi::TextViewMode, staticObjectArgs);
292
} else if (false == askForOpeningInTextModeRes) {
293
delete window->schemaObject(); //old one
296
qWarning() << "!window, cannot switch to a view mode" <<
297
Kexi::nameForViewMode(viewMode);
300
//the window has an error info
301
switchingFailed = true;
304
switchingFailed = true;
306
if (switchingFailed) {
307
d->status = window->status();
310
qWarning() << "!window, switching to view mode failed, " <<
311
Kexi::nameForViewMode(viewMode);
314
window->registerWindow(); //ok?
317
window->setMinimumSize(window->minimumSizeHint().width(), window->minimumSizeHint().height());
319
//dirty only if it's a new object
320
if (window->selectedView()) {
321
window->selectedView()->setDirty(
322
internalPropertyValue("newObjectsAreDirty", false).toBool() ? item->neverSaved() : false);
327
KDbObject* Part::loadSchemaObject(KexiWindow *window, const KDbObject& object,
328
Kexi::ViewMode viewMode, bool *ownedByWindow)
332
KDbObject *newObject = new KDbObject();
335
*ownedByWindow = true;
339
void Part::loadAndSetSchemaObject(KexiWindow *window, const KDbObject& object,
340
Kexi::ViewMode viewMode)
342
bool schemaObjectOwned = true;
343
KDbObject* sd = loadSchemaObject(window, object, viewMode, &schemaObjectOwned);
344
window->setSchemaObject(sd);
345
window->setSchemaObjectOwned(schemaObjectOwned);
348
bool Part::loadDataBlock(KexiWindow *window, QString *dataString, const QString& dataID)
350
if (true != KexiMainWindowIface::global()->project()->dbConnection()->loadDataBlock(
351
window->id(), dataString, dataID))
353
d->status = Kexi::ObjectStatus(KexiMainWindowIface::global()->project()->dbConnection(),
354
xi18n("Could not load object's data."),
356
"Data identifier: <resource>%1</resource>.", dataID));
357
d->status.append(*window);
363
void Part::initPartActions()
367
void Part::initInstanceActions()
371
tristate Part::remove(KexiPart::Item *item)
374
KDbConnection *conn = KexiMainWindowIface::global()->project()->dbConnection();
377
return conn->removeObject(item->identifier());
380
KexiWindowData* Part::createWindowData(KexiWindow* window)
382
return new KexiWindowData(window);
385
QString Part::instanceName() const
387
return d->instanceName;
390
QString Part::toolTip() const
395
QString Part::whatsThis() const
400
tristate Part::rename(KexiPart::Item *item, const QString& newName)
407
GUIClient* Part::instanceGuiClient(Kexi::ViewMode mode) const
409
return d->instanceGuiClients.value((int)mode);
412
GUIClient* Part::guiClient() const
417
const Kexi::ObjectStatus& Part::lastOperationStatus() const
422
KDbQuerySchema* Part::currentQuery(KexiView* view)
428
KEXICORE_EXPORT QString KexiPart::fullCaptionForItem(KexiPart::Item *item, KexiPart::Part *part)
433
return item->name() + " : " + part->info()->name();