~ubuntu-branches/debian/sid/kexi/sid

« back to all changes in this revision

Viewing changes to src/core/kexipart.cpp

  • Committer: Package Import Robot
  • Author(s): Pino Toscano
  • Date: 2017-06-24 20:10:10 UTC
  • Revision ID: package-import@ubuntu.com-20170624201010-5lrzd5r2vwthwifp
Tags: upstream-3.0.1.1
ImportĀ upstreamĀ versionĀ 3.0.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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>
 
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
//! @todo KEXI3 #include "kexistaticpart.h"
 
25
#include "KexiWindow.h"
 
26
#include "KexiWindowData.h"
 
27
#include "KexiView.h"
 
28
#include "kexipartguiclient.h"
 
29
#include "KexiMainWindowIface.h"
 
30
#include "kexi.h"
 
31
#include <kexiutils/utils.h>
 
32
 
 
33
#include <KDbConnection>
 
34
 
 
35
#include <KActionCollection>
 
36
#include <KMessageBox>
 
37
 
 
38
#include <QDebug>
 
39
 
 
40
namespace KexiPart
 
41
{
 
42
//! @internal
 
43
class Part::Private
 
44
{
 
45
public:
 
46
    Private()
 
47
    : guiClient(0)
 
48
    , newObjectsAreDirty(false)
 
49
    , instanceActionsInitialized(false)
 
50
    {
 
51
    }
 
52
 
 
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) {
 
59
            //ask
 
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)
 
67
                     ? xi18nc("@info",
 
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())) {
 
72
                return false;
 
73
            }
 
74
            return true;
 
75
        }
 
76
        return cancelled;
 
77
    }
 
78
 
 
79
    QString toolTip;
 
80
    QString whatsThis;
 
81
    QString instanceName;
 
82
 
 
83
    GUIClient *guiClient;
 
84
    QMap<int, GUIClient*> instanceGuiClients;
 
85
    Kexi::ObjectStatus status;
 
86
 
 
87
    bool newObjectsAreDirty;
 
88
    bool instanceActionsInitialized;
 
89
};
 
90
}
 
91
 
 
92
//----------------------------------------------------------------
 
93
 
 
94
using namespace KexiPart;
 
95
 
 
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)
 
102
    , d(new Private())
 
103
{
 
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.",
 
109
                "object").toLower()
 
110
        : instanceName);
 
111
    d->toolTip = toolTip;
 
112
    d->whatsThis = whatsThis;
 
113
}
 
114
 
 
115
/*! @todo KEXI3
 
116
Part::Part(QObject* parent, StaticPartInfo *info)
 
117
    : PartBase(parent, QVariantList())
 
118
        , d(new Private())
 
119
{
 
120
    setObjectName("StaticPart");
 
121
    setInfo(info);
 
122
}*/
 
123
 
 
124
Part::~Part()
 
125
{
 
126
    delete d;
 
127
}
 
128
 
 
129
void Part::createGUIClients()//KexiMainWindow *win)
 
130
{
 
131
    if (!d->guiClient) {
 
132
        //create part's gui client
 
133
        d->guiClient = new GUIClient(this, false, "part");
 
134
 
 
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);
 
141
        }
 
142
        QString what(whatsThis());
 
143
        if (!what.isEmpty()) {
 
144
            act->setWhatsThis(what);
 
145
        }
 
146
 
 
147
        //default actions for part instance's gui client:
 
148
        //NONE
 
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);
 
155
            }
 
156
        }
 
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);
 
160
 
 
161
        initPartActions();
 
162
    }
 
163
}
 
164
 
 
165
KActionCollection* Part::actionCollectionForMode(Kexi::ViewMode viewMode) const
 
166
{
 
167
    GUIClient *cli = d->instanceGuiClients.value((int)viewMode);
 
168
    return cli ? cli->actionCollection() : 0;
 
169
}
 
170
 
 
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)
 
174
{
 
175
    GUIClient *instanceGuiClient = d->instanceGuiClients.value((int)mode);
 
176
    if (!instanceGuiClient) {
 
177
        qWarning() << "no gui client for mode " << mode << "!";
 
178
        return 0;
 
179
    }
 
180
    return KexiMainWindowIface::global()->createSharedAction(text, pix_name, cut, name,
 
181
            instanceGuiClient->actionCollection(), subclassName);
 
182
}
 
183
 
 
184
QAction * Part::createSharedPartAction(const QString &text,
 
185
                                      const QString &pix_name, const QKeySequence &cut, const char *name,
 
186
                                      const char *subclassName)
 
187
{
 
188
    if (!d->guiClient)
 
189
        return 0;
 
190
    return KexiMainWindowIface::global()->createSharedAction(text, pix_name, cut, name,
 
191
            d->guiClient->actionCollection(), subclassName);
 
192
}
 
193
 
 
194
QAction * Part::createSharedToggleAction(Kexi::ViewMode mode, const QString &text,
 
195
                                        const QString &pix_name, const QKeySequence &cut, const char *name)
 
196
{
 
197
    return createSharedAction(mode, text, pix_name, cut, name, "KToggleAction");
 
198
}
 
199
 
 
200
QAction * Part::createSharedPartToggleAction(const QString &text,
 
201
        const QString &pix_name, const QKeySequence &cut, const char *name)
 
202
{
 
203
    return createSharedPartAction(text, pix_name, cut, name, "KToggleAction");
 
204
}
 
205
 
 
206
void Part::setActionAvailable(const char *action_name, bool avail)
 
207
{
 
208
    for (QMap<int, GUIClient*>::Iterator it = d->instanceGuiClients.begin(); it != d->instanceGuiClients.end(); ++it) {
 
209
        QAction *act = it.value()->actionCollection()->action(action_name);
 
210
        if (act) {
 
211
            act->setEnabled(avail);
 
212
            return;
 
213
        }
 
214
    }
 
215
    KexiMainWindowIface::global()->setActionAvailable(action_name, avail);
 
216
}
 
217
 
 
218
KexiWindow* Part::openInstance(QWidget* parent, KexiPart::Item *item, Kexi::ViewMode viewMode,
 
219
                               QMap<QString, QVariant>* staticObjectArgs)
 
220
{
 
221
    Q_ASSERT(item);
 
222
    //now it's the time for creating instance actions
 
223
    if (!d->instanceActionsInitialized) {
 
224
        initInstanceActions();
 
225
        d->instanceActionsInitialized = true;
 
226
    }
 
227
 
 
228
    d->status.clearStatus();
 
229
    KexiWindow *window = new KexiWindow(parent,
 
230
                                        info()->supportedViewModes(), this, item);
 
231
 
 
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());
 
237
 
 
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);
 
244
    if (!windowData) {
 
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."));
 
247
        delete window;
 
248
        return 0;
 
249
    }
 
250
    window->setData(windowData);
 
251
 
 
252
    if (!item->neverSaved()) {
 
253
        //we have to load object data for this dialog
 
254
        loadAndSetSchemaObject(window, object, viewMode);
 
255
        if (!window->schemaObject()) {
 
256
            //last chance:
 
257
            if (false == d->askForOpeningInTextMode(
 
258
                        window, item, window->supportedViewModes(), viewMode)) {
 
259
                delete window;
 
260
                return 0;
 
261
            }
 
262
            viewMode = Kexi::TextViewMode;
 
263
            loadAndSetSchemaObject(window, object, viewMode);
 
264
        }
 
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."));
 
269
            d->status.append(
 
270
                Kexi::ObjectStatus(xi18nc("@info",
 
271
                                          "You can delete <resource>%1</resource> object and create it again.",
 
272
                                          item->name()), QString()));
 
273
 
 
274
            window->close();
 
275
            delete window;
 
276
            return 0;
 
277
        }
 
278
    }
 
279
 
 
280
    bool switchingFailed = false;
 
281
    bool dummy;
 
282
    tristate res = window->switchToViewMode(viewMode, staticObjectArgs, &dummy);
 
283
    if (!res) {
 
284
        tristate askForOpeningInTextModeRes
 
285
        = d->askForOpeningInTextMode(window, item, window->supportedViewModes(), viewMode);
 
286
        if (true == askForOpeningInTextModeRes) {
 
287
            delete window->schemaObject(); //old one
 
288
            window->close();
 
289
            delete window;
 
290
            //try in text mode
 
291
            return openInstance(parent, item, Kexi::TextViewMode, staticObjectArgs);
 
292
        } else if (false == askForOpeningInTextModeRes) {
 
293
            delete window->schemaObject(); //old one
 
294
            window->close();
 
295
            delete window;
 
296
            qWarning() << "!window, cannot switch to a view mode" <<
 
297
                Kexi::nameForViewMode(viewMode);
 
298
            return 0;
 
299
        }
 
300
        //the window has an error info
 
301
        switchingFailed = true;
 
302
    }
 
303
    if (~res)
 
304
        switchingFailed = true;
 
305
 
 
306
    if (switchingFailed) {
 
307
        d->status = window->status();
 
308
        window->close();
 
309
        delete window;
 
310
        qWarning() << "!window, switching to view mode failed, " <<
 
311
            Kexi::nameForViewMode(viewMode);
 
312
        return 0;
 
313
    }
 
314
    window->registerWindow(); //ok?
 
315
    window->show();
 
316
 
 
317
    window->setMinimumSize(window->minimumSizeHint().width(), window->minimumSizeHint().height());
 
318
 
 
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);
 
323
    }
 
324
    return window;
 
325
}
 
326
 
 
327
KDbObject* Part::loadSchemaObject(KexiWindow *window, const KDbObject& object,
 
328
        Kexi::ViewMode viewMode, bool *ownedByWindow)
 
329
{
 
330
    Q_UNUSED(window);
 
331
    Q_UNUSED(viewMode);
 
332
    KDbObject *newObject = new KDbObject();
 
333
    *newObject = object;
 
334
    if (ownedByWindow)
 
335
        *ownedByWindow = true;
 
336
    return newObject;
 
337
}
 
338
 
 
339
void Part::loadAndSetSchemaObject(KexiWindow *window, const KDbObject& object,
 
340
    Kexi::ViewMode viewMode)
 
341
{
 
342
    bool schemaObjectOwned = true;
 
343
    KDbObject* sd = loadSchemaObject(window, object, viewMode, &schemaObjectOwned);
 
344
    window->setSchemaObject(sd);
 
345
    window->setSchemaObjectOwned(schemaObjectOwned);
 
346
}
 
347
 
 
348
bool Part::loadDataBlock(KexiWindow *window, QString *dataString, const QString& dataID)
 
349
{
 
350
    if (true != KexiMainWindowIface::global()->project()->dbConnection()->loadDataBlock(
 
351
                window->id(), dataString, dataID))
 
352
    {
 
353
        d->status = Kexi::ObjectStatus(KexiMainWindowIface::global()->project()->dbConnection(),
 
354
                                       xi18n("Could not load object's data."),
 
355
                                       xi18nc("@info",
 
356
                                              "Data identifier: <resource>%1</resource>.", dataID));
 
357
        d->status.append(*window);
 
358
        return false;
 
359
    }
 
360
    return true;
 
361
}
 
362
 
 
363
void Part::initPartActions()
 
364
{
 
365
}
 
366
 
 
367
void Part::initInstanceActions()
 
368
{
 
369
}
 
370
 
 
371
tristate Part::remove(KexiPart::Item *item)
 
372
{
 
373
    Q_ASSERT(item);
 
374
    KDbConnection *conn = KexiMainWindowIface::global()->project()->dbConnection();
 
375
    if (!conn)
 
376
        return false;
 
377
    return conn->removeObject(item->identifier());
 
378
}
 
379
 
 
380
KexiWindowData* Part::createWindowData(KexiWindow* window)
 
381
{
 
382
    return new KexiWindowData(window);
 
383
}
 
384
 
 
385
QString Part::instanceName() const
 
386
{
 
387
    return d->instanceName;
 
388
}
 
389
 
 
390
QString Part::toolTip() const
 
391
{
 
392
    return d->toolTip;
 
393
}
 
394
 
 
395
QString Part::whatsThis() const
 
396
{
 
397
    return d->whatsThis;
 
398
}
 
399
 
 
400
tristate Part::rename(KexiPart::Item *item, const QString& newName)
 
401
{
 
402
    Q_UNUSED(item);
 
403
    Q_UNUSED(newName);
 
404
    return true;
 
405
}
 
406
 
 
407
GUIClient* Part::instanceGuiClient(Kexi::ViewMode mode) const
 
408
{
 
409
    return d->instanceGuiClients.value((int)mode);
 
410
}
 
411
 
 
412
GUIClient* Part::guiClient() const
 
413
{
 
414
    return d->guiClient;
 
415
}
 
416
 
 
417
const Kexi::ObjectStatus& Part::lastOperationStatus() const
 
418
{
 
419
    return d->status;
 
420
}
 
421
 
 
422
KDbQuerySchema* Part::currentQuery(KexiView* view)
 
423
{
 
424
    Q_UNUSED(view);
 
425
    return 0;
 
426
}
 
427
 
 
428
KEXICORE_EXPORT QString KexiPart::fullCaptionForItem(KexiPart::Item *item, KexiPart::Part *part)
 
429
{
 
430
    Q_ASSERT(item);
 
431
    Q_ASSERT(part);
 
432
    if (part)
 
433
        return item->name() + " : " + part->info()->name();
 
434
    return item->name();
 
435
}