File indexing completed on 2024-05-12 16:39:42

0001 /* This file is part of the KDE project
0002    Copyright (C) 2004-2012 Jarosław Staniek <staniek@kde.org>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #include "KexiView.h"
0021 #include "KexiMainWindowIface.h"
0022 #include "KexiWindow.h"
0023 #include "kexiproject.h"
0024 #include "kexipartinfo.h"
0025 #include <kexiutils/utils.h>
0026 #include <kexiutils/SmallToolButton.h>
0027 #include <kexiutils/FlowLayout.h>
0028 
0029 #include "KexiGroupButton.h"
0030 
0031 #include <KPropertySet>
0032 
0033 #include <KDbConnection>
0034 
0035 #include <KActionCollection>
0036 
0037 #include <QDebug>
0038 #include <QDialog>
0039 #include <QMenu>
0040 #include <QEvent>
0041 #include <QCloseEvent>
0042 #include <QApplication>
0043 #include <QVBoxLayout>
0044 
0045 //! @internal Action for toggling view mode
0046 class KEXICORE_EXPORT KexiToggleViewModeAction : public QAction
0047 {
0048     Q_OBJECT
0049 public:
0050     //! Creates action for toggling to view mode @a mode. @a slot should have signature
0051     //! matching switchedTo(Kexi::ViewMode mode) signal.
0052     KexiToggleViewModeAction(Kexi::ViewMode mode, QObject* parent)
0053         : QAction(
0054             QIcon::fromTheme(Kexi::iconNameForViewMode(mode)),
0055             Kexi::nameForViewMode(mode, true/*withAmpersand*/),
0056             parent)
0057     {
0058         setCheckable(true);
0059         if (mode == Kexi::DataViewMode) {
0060             setObjectName("view_data_mode");
0061             setToolTip(xi18n("Switch to data view"));
0062             setWhatsThis(xi18n("Switches to data view."));
0063         } else if (mode == Kexi::DesignViewMode) {
0064             setObjectName("view_design_mode");
0065             setToolTip(xi18n("Switch to design view"));
0066             setWhatsThis(xi18n("Switches to design view."));
0067         } else if (mode == Kexi::TextViewMode) {
0068             setObjectName("view_text_mode");
0069             setToolTip(xi18n("Switch to text view"));
0070             setWhatsThis(xi18n("Switches to text view."));
0071         } else {
0072             qWarning() << "KexiToggleViewModeAction: invalid mode " << mode;
0073         }
0074     }
0075 };
0076 
0077 //-------------------------
0078 
0079 class Q_DECL_HIDDEN KexiView::Private
0080 {
0081 public:
0082     explicit Private(KexiView *qq)
0083             : q(qq)
0084             , viewWidget(0)
0085             , parentView(0)
0086             , newlyAssignedID(-1)
0087             , viewMode(Kexi::NoViewMode) //unknown!
0088             , isDirty(false)
0089             , slotSwitchToViewModeInternalEnabled(true)
0090             , sortedProperties(false)
0091             , recentResultOfSwitchToViewModeInternal(true)
0092             , m_mainMenu(0)
0093     {
0094     }
0095 
0096     ~Private() {
0097     }
0098 
0099     void toggleViewModeButtonBack(Kexi::ViewMode mode) {
0100         QAction *a = toggleViewModeActions.value(mode);
0101         if (a) {
0102             slotSwitchToViewModeInternalEnabled = false;
0103             toggleViewModeActions.value(mode)->blockSignals(true);
0104             toggleViewModeButtons.value(mode)->blockSignals(true);
0105             toggleViewModeButtons.value(mode)->setChecked(viewMode == mode);
0106             toggleViewModeActions.value(mode)->blockSignals(false);
0107             toggleViewModeButtons.value(mode)->blockSignals(false);
0108             slotSwitchToViewModeInternalEnabled = true;
0109         }
0110     }
0111 
0112     QMenu* mainMenu()
0113     {
0114         if (m_mainMenu) {
0115             return m_mainMenu;
0116         }
0117         if (!window) {
0118             return 0;
0119         }
0120         KexiSmallToolButton* menuButton = new KexiSmallToolButton(
0121                          QIcon(),
0122                          window->part()->info()->name() + " ",
0123                          topBarHWidget);
0124         menuButton->setToolTip(xi18n("Menu for the current window"));
0125         menuButton->setWhatsThis(xi18n("Shows menu for the current window."));
0126         menuButton->setPopupMode(QToolButton::InstantPopup);
0127         topBarLyr->insertWidget(0, menuButton);
0128 
0129         m_mainMenu = new QMenu(menuButton);
0130         menuButton->setMenu(m_mainMenu);
0131         return m_mainMenu;
0132     }
0133 
0134     KexiGroupButton *addViewButton(KexiGroupButton::GroupPosition pos,
0135                                  Kexi::ViewMode mode, QWidget *parent, const char *slot,
0136                                  const QString &text, QHBoxLayout *btnLyr)
0137     {
0138         if (!window->supportsViewMode(mode)) {
0139             return 0;
0140         }
0141         QAction *a = new KexiToggleViewModeAction(mode, q);
0142         toggleViewModeActions.insert(mode, a);
0143 
0144         KexiGroupButton *btn = new KexiGroupButton(pos, parent);
0145         toggleViewModeButtons.insert(mode, btn);
0146         connect(btn, SIGNAL(toggled(bool)), q, slot);
0147         btn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
0148         btn->setText(text);
0149         btn->setIcon(a->icon());
0150         QFont f(q->font());
0151         f.setPointSizeF(KexiUtils::smallestReadableFont().pointSizeF());
0152         btn->setFont(f);
0153         btn->setToolTip(a->toolTip());
0154         btn->setWhatsThis(a->whatsThis());
0155         btn->setCheckable(true);
0156         btn->setAutoRaise(true);
0157         btnLyr->addWidget(btn);
0158         return btn;
0159     }
0160 
0161     KexiView *q;
0162     QVBoxLayout* mainLyr;
0163     QWidget *topBarHWidget;
0164     KexiFlowLayout *topBarLyr;
0165     QHash<Kexi::ViewMode, QAction*> toggleViewModeActions;
0166     QHash<Kexi::ViewMode, KexiGroupButton*> toggleViewModeButtons;
0167 
0168     KexiSmallToolButton* saveDesignButton;
0169 
0170     QString defaultIconName;
0171     KexiWindow *window;
0172     QWidget *viewWidget;
0173     KexiView *parentView;
0174 
0175     QPointer<QWidget> lastFocusedChildBeforeFocusOut;
0176 
0177     /*! Member set to newly assigned object's ID in storeNewData()
0178      and used in storeDataBlock(). This is needed because usually,
0179      storeDataBlock() can be called from storeNewData() and in this case
0180      window has not yet assigned valid identifier (it has just negative temp. number).
0181      \sa KexiWindow::id()
0182      */
0183     int newlyAssignedID;
0184 
0185     /*! Mode for this view. Initialized by KexiWindow::switchToViewMode().
0186      Can be useful when single class is used for more than one view (e.g. KexiDBForm). */
0187     Kexi::ViewMode viewMode;
0188 
0189     QList<KexiView*> children;
0190 
0191     /*! View-level actions (not shared), owned by the view. */
0192     QList<QAction*> viewActions;
0193     QHash<QByteArray, QAction*> viewActionsHash;
0194 
0195     /*! Main-meny-level actions (not shared), owned by the view. */
0196     QList<QAction*> mainMenuActions;
0197     QHash<QByteArray, QAction*> mainMenuActionsHash;
0198 
0199     bool isDirty;
0200 
0201     //! Used in slotSwitchToViewModeInternal() to disabling it
0202     bool slotSwitchToViewModeInternalEnabled;
0203 
0204     bool sortedProperties;
0205 
0206     //! Used in slotSwitchToViewModeInternal() to disabling d->window->switchToViewModeInternal(mode) call.
0207     //! Needed because there is another slotSwitchToViewModeInternal() calls if d->window->switchToViewModeInternal(mode)
0208     //! did not succeed, so for the second time we block this call.
0209     tristate recentResultOfSwitchToViewModeInternal;
0210 private:
0211     QMenu* m_mainMenu;
0212 };
0213 
0214 //----------------------------------------------------------
0215 
0216 KexiView::KexiView(QWidget *parent)
0217         : QWidget(parent)
0218         , KexiActionProxy(this)
0219         , d(new Private(this))
0220 {
0221     QWidget *wi = this;
0222     while ((wi = wi->parentWidget()) && !qobject_cast<KexiWindow*>(wi)) {
0223     }
0224     d->window = (wi && qobject_cast<KexiWindow*>(wi)) ? qobject_cast<KexiWindow*>(wi) : nullptr;
0225     if (d->window) {
0226         //init view mode number for this view (obtained from window where this view is created)
0227         if (d->window->supportsViewMode(d->window->creatingViewsMode()))
0228             d->viewMode = d->window->creatingViewsMode();
0229     }
0230     setObjectName(
0231         QString("%1_for_%2_object")
0232         .arg(Kexi::nameForViewMode(d->viewMode).replace(' ', '_'))
0233         .arg(d->window ? d->window->partItem()->name() : QString("??")));
0234 
0235     installEventFilter(this);
0236 
0237     d->mainLyr = new QVBoxLayout(this);
0238     d->mainLyr->setContentsMargins(0, 0, 0, 0);
0239 
0240     if (qobject_cast<KexiWindow*>(parentWidget())) {
0241         d->topBarHWidget = new QWidget(this);
0242         d->topBarHWidget->setFont(KexiUtils::smallestReadableFont());
0243         d->mainLyr->addWidget(d->topBarHWidget);
0244         QHBoxLayout *topBarHLyr = new QHBoxLayout(d->topBarHWidget); //needed unless KexiFlowLayout properly handles contents margins
0245         topBarHLyr->setContentsMargins(0, 0, 0, 0);
0246         topBarHLyr->addSpacing(KexiUtils::spacingHint() / 2);
0247         d->topBarLyr = new KexiFlowLayout(topBarHLyr, 0, 2);
0248 
0249         const bool userMode = KexiMainWindowIface::global()->userMode();
0250 
0251         if (userMode
0252                 || d->window->supportedViewModes() == Kexi::DataViewMode
0253                 || d->window->supportedViewModes() == Kexi::DesignViewMode
0254                 || d->window->supportedViewModes() == Kexi::TextViewMode)
0255         {
0256             // nothing to do: only single view mode supported
0257         }
0258         else {
0259             createViewModeToggleButtons();
0260         }
0261 
0262         (void)d->mainMenu();
0263 
0264         if (d->viewMode == Kexi::DesignViewMode || d->viewMode == Kexi::TextViewMode) {
0265             QAction *a = sharedAction("project_save");
0266             d->saveDesignButton = new KexiSmallToolButton(a, d->topBarHWidget);
0267             d->saveDesignButton->setText(xi18n("Save"));
0268             d->saveDesignButton->setToolTip(xi18n("Save current design"));
0269             d->saveDesignButton->setWhatsThis(xi18n("Saves changes made to the current design."));
0270             d->topBarLyr->addWidget(d->saveDesignButton);
0271 
0272             a = sharedAction("project_saveas");
0273             d->mainMenu()->addAction(a);
0274         }
0275         else {
0276             d->saveDesignButton = 0;
0277         }
0278     } else {
0279         // no toolbar
0280         d->saveDesignButton = 0;
0281         d->topBarHWidget = 0;
0282         d->topBarLyr = 0;
0283     }
0284 }
0285 
0286 KexiView::~KexiView()
0287 {
0288     delete d;
0289 }
0290 
0291 KexiWindow* KexiView::window() const
0292 {
0293     return d->window;
0294 }
0295 
0296 bool KexiView::isDirty() const
0297 {
0298     return d->isDirty;
0299 }
0300 
0301 bool KexiView::isDataEditingInProgress() const
0302 {
0303     return false;
0304 }
0305 
0306 tristate KexiView::saveDataChanges()
0307 {
0308     return true;
0309 }
0310 
0311 tristate KexiView::cancelDataChanges()
0312 {
0313     return true;
0314 }
0315 
0316 Kexi::ViewMode KexiView::viewMode() const
0317 {
0318     return d->viewMode;
0319 }
0320 
0321 KexiPart::Part* KexiView::part() const
0322 {
0323     return d->window ? d->window->part() : 0;
0324 }
0325 
0326 tristate KexiView::beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore)
0327 {
0328     Q_UNUSED(mode);
0329     Q_UNUSED(dontStore);
0330     return true;
0331 }
0332 
0333 tristate KexiView::afterSwitchFrom(Kexi::ViewMode mode)
0334 {
0335     Q_UNUSED(mode);
0336     return true;
0337 }
0338 
0339 QSize KexiView::preferredSizeHint(const QSize& otherSize)
0340 {
0341     return otherSize;
0342 }
0343 
0344 void KexiView::closeEvent(QCloseEvent * e)
0345 {
0346     bool cancel = false;
0347     emit closing(&cancel);
0348     if (cancel) {
0349         e->ignore();
0350         return;
0351     }
0352     QWidget::closeEvent(e);
0353 }
0354 
0355 KPropertySet *KexiView::propertySet()
0356 {
0357     return 0;
0358 }
0359 
0360 void KexiView::propertySetSwitched()
0361 {
0362     if (window()) {
0363         KexiMainWindowIface::global()->propertySetSwitched(window(), false/*force*/,
0364             true/*preservePrevSelection*/, d->sortedProperties);
0365     }
0366 }
0367 
0368 void KexiView::propertySetReloaded(bool preservePrevSelection,
0369                                    const QByteArray& propertyToSelect)
0370 {
0371     if (window())
0372         KexiMainWindowIface::global()->propertySetSwitched(
0373             window(), true, preservePrevSelection, d->sortedProperties, propertyToSelect);
0374 }
0375 
0376 void KexiView::setDirty(bool set)
0377 {
0378     const bool changed = (d->isDirty != set);
0379     d->isDirty = set;
0380     d->isDirty = isDirty();
0381     if (d->saveDesignButton)
0382         d->saveDesignButton->setEnabled(d->isDirty);
0383     if (d->parentView) {
0384         d->parentView->setDirty(d->isDirty);
0385     } else {
0386         if (changed && d->window)
0387             d->window->dirtyChanged(this);
0388     }
0389 }
0390 
0391 void KexiView::setDirty()
0392 {
0393     setDirty(true);
0394 }
0395 
0396 KDbObject* KexiView::storeNewData(const KDbObject& object,
0397                                            KexiView::StoreNewDataOptions options,
0398                                            bool *cancel)
0399 {
0400     Q_ASSERT(cancel);
0401     Q_UNUSED(options)
0402     Q_UNUSED(cancel)
0403     QScopedPointer<KDbObject> newObject(new KDbObject);
0404     *newObject = object;
0405 
0406     KDbConnection *conn = KexiMainWindowIface::global()->project()->dbConnection();
0407     if (!conn->storeNewObjectData(newObject.data())
0408         || !conn->removeDataBlock(newObject->id()) // for sanity
0409         || !KexiMainWindowIface::global()->project()->removeUserDataBlock(newObject->id()) // for sanity
0410        )
0411     {
0412         return 0;
0413     }
0414     d->newlyAssignedID = newObject->id();
0415     return newObject.take();
0416 }
0417 
0418 KDbObject* KexiView::copyData(const KDbObject& object,
0419                                         KexiView::StoreNewDataOptions options,
0420                                         bool *cancel)
0421 {
0422     Q_ASSERT(cancel);
0423     Q_UNUSED(options)
0424     Q_UNUSED(cancel)
0425     QScopedPointer<KDbObject> newObject(new KDbObject);
0426     *newObject = object;
0427 
0428     KDbConnection *conn = KexiMainWindowIface::global()->project()->dbConnection();
0429     if (!conn->storeNewObjectData(newObject.data())
0430         || !conn->copyDataBlock(d->window->id(), newObject->id())
0431         || !KexiMainWindowIface::global()->project()->copyUserDataBlock(d->window->id(), newObject->id())
0432        )
0433     {
0434         return 0;
0435     }
0436     d->newlyAssignedID = newObject->id();
0437     return newObject.take();
0438 }
0439 
0440 tristate KexiView::storeData(bool dontAsk)
0441 {
0442     Q_UNUSED(dontAsk);
0443     if (!d->window || !d->window->schemaObject())
0444         return false;
0445     if (!KexiMainWindowIface::global()->project()
0446             ->dbConnection()->storeObjectData(d->window->schemaObject()))
0447     {
0448         return false;
0449     }
0450     setDirty(false);
0451     return true;
0452 }
0453 
0454 bool KexiView::loadDataBlock(QString *dataString, const QString& dataID, bool canBeEmpty)
0455 {
0456     if (!d->window)
0457         return false;
0458     const tristate res = KexiMainWindowIface::global()->project()->dbConnection()
0459                          ->loadDataBlock(d->window->id(), dataString, dataID);
0460     if (canBeEmpty && ~res) {
0461         dataString->clear();
0462         return true;
0463     }
0464     return res == true;
0465 }
0466 
0467 bool KexiView::storeDataBlock(const QString &dataString, const QString &dataID)
0468 {
0469     if (!d->window)
0470         return false;
0471     int effectiveID;
0472     if (d->newlyAssignedID > 0) {//ID not yet stored within window, but we've got ID here
0473         effectiveID = d->newlyAssignedID;
0474         d->newlyAssignedID = -1;
0475     } else
0476         effectiveID = d->window->id();
0477 
0478     return effectiveID > 0
0479            && KexiMainWindowIface::global()->project()->dbConnection()->storeDataBlock(
0480                effectiveID, dataString, dataID);
0481 }
0482 
0483 bool KexiView::removeDataBlock(const QString& dataID)
0484 {
0485     if (!d->window)
0486         return false;
0487     return KexiMainWindowIface::global()->project()->dbConnection()
0488            ->removeDataBlock(d->window->id(), dataID);
0489 }
0490 
0491 bool KexiView::eventFilter(QObject *o, QEvent *e)
0492 {
0493     if (e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut) {
0494 //        qDebug() << "this=[" << o->metaObject()->className()
0495 //            << objectName() << "] o=[" << o->metaObject()->className() << o->objectName()
0496 //            << "] focusWidget=[" << (qApp->focusWidget() ? qApp->focusWidget()->metaObject()->className() : QString())
0497 //            << (qApp->focusWidget() ? qApp->focusWidget()->objectName() : QString()) << "] ev.type=" << e->type();
0498         if (KDbUtils::hasParent(this, o)) {
0499             if (e->type() == QEvent::FocusOut && qApp->focusWidget()
0500                     && !KDbUtils::hasParent(this, qApp->focusWidget())) {
0501                 //focus out: when currently focused widget is not a parent of this view
0502                 emit focus(false);
0503             } else if (e->type() == QEvent::FocusIn) {
0504                 emit focus(true);
0505             }
0506             if (e->type() == QEvent::FocusOut) {
0507 //    qDebug() << focusWidget()->className() << " " << focusWidget()->name();
0508 //    qDebug() << o->className() << " " << o->name();
0509                 KexiView *v = KDbUtils::findParent<KexiView*>(o);
0510                 if (v) {
0511                     while (v->d->parentView)
0512                         v = v->d->parentView;
0513                     if (KDbUtils::hasParent(this, static_cast<QWidget*>(v->focusWidget())))
0514                         v->d->lastFocusedChildBeforeFocusOut = static_cast<QWidget*>(v->focusWidget());
0515                 }
0516             }
0517 
0518             if (e->type() == QEvent::FocusIn && m_actionProxyParent) {
0519                 m_actionProxyParent->m_focusedChild = this;
0520             }
0521         }
0522     }
0523     return false;
0524 }
0525 
0526 void KexiView::setViewWidget(QWidget* w, bool focusProxy)
0527 {
0528     if (d->viewWidget == w)
0529         return;
0530     if (d->viewWidget) {
0531         d->viewWidget->removeEventFilter(this);
0532         d->mainLyr->removeWidget(d->viewWidget);
0533     }
0534     d->viewWidget = w;
0535     if (d->viewWidget) {
0536         d->viewWidget->setParent(this);
0537         d->mainLyr->addWidget(d->viewWidget, 1);
0538         d->viewWidget->installEventFilter(this);
0539         //}
0540         if (focusProxy)
0541             setFocusProxy(d->viewWidget); //js: ok?
0542     }
0543 }
0544 
0545 void KexiView::addChildView(KexiView* childView)
0546 {
0547     d->children.append(childView);
0548     addActionProxyChild(childView);
0549     childView->d->parentView = this;
0550     childView->installEventFilter(this);
0551 }
0552 
0553 void KexiView::removeView(Kexi::ViewMode mode)
0554 {
0555     window()->removeView(mode);
0556 }
0557 
0558 void KexiView::setFocus()
0559 {
0560     if (!d->lastFocusedChildBeforeFocusOut.isNull()) {
0561 //  qDebug() << "FOCUS: " << d->lastFocusedChildBeforeFocusOut->className() << " " << d->lastFocusedChildBeforeFocusOut->name();
0562         QWidget *w = d->lastFocusedChildBeforeFocusOut;
0563         d->lastFocusedChildBeforeFocusOut = 0;
0564         w->setFocus();
0565     } else {
0566         setFocusInternal();
0567     }
0568     KexiMainWindowIface::global()->invalidateSharedActions(this);
0569 }
0570 
0571 QAction* KexiView::sharedAction(const QString& action_name)
0572 {
0573     if (part()) {
0574         KActionCollection *ac;
0575         if ((ac = part()->actionCollectionForMode(viewMode()))) {
0576             QAction* a = ac->action(action_name);
0577             if (a)
0578                 return a;
0579         }
0580     }
0581     return KexiActionProxy::sharedAction(action_name);
0582 }
0583 
0584 void KexiView::setAvailable(const QString& action_name, bool set)
0585 {
0586     if (part()) {
0587         KActionCollection *ac;
0588         QAction* a;
0589         if ((ac = part()->actionCollectionForMode(viewMode())) && (a = ac->action(action_name))) {
0590             a->setEnabled(set);
0591         }
0592     }
0593     KexiActionProxy::setAvailable(action_name, set);
0594 }
0595 
0596 void KexiView::updateActions(bool activated)
0597 {
0598     //do nothing here
0599     //do the same for children :)
0600     foreach(KexiView* view, d->children) {
0601         view->updateActions(activated);
0602     }
0603 }
0604 
0605 void KexiView::setViewActions(const QList<QAction*>& actions)
0606 {
0607     d->viewActions = actions;
0608     d->viewActionsHash.clear();
0609     foreach(QAction* action, d->viewActions) {
0610         d->viewActionsHash.insert(action->objectName().toLatin1(), action);
0611     }
0612 }
0613 
0614 void KexiView::setMainMenuActions(const QList<QAction*>& actions)
0615 {
0616     d->mainMenuActions = actions;
0617     d->mainMenuActionsHash.clear();
0618     foreach(QAction* action, d->mainMenuActions) {
0619         d->mainMenuActionsHash.insert(action->objectName().toLatin1(), action);
0620     }
0621 }
0622 
0623 QAction* KexiView::viewAction(const char* name) const
0624 {
0625     return d->viewActionsHash.value(name);
0626 }
0627 
0628 QList<QAction*> KexiView::viewActions() const
0629 {
0630     return d->viewActions;
0631 }
0632 
0633 void KexiView::toggleViewModeButtonBack()
0634 {
0635     d->toggleViewModeButtonBack(Kexi::DataViewMode);
0636     d->toggleViewModeButtonBack(Kexi::DesignViewMode);
0637     d->toggleViewModeButtonBack(Kexi::TextViewMode);
0638 }
0639 
0640 void KexiView::createViewModeToggleButtons()
0641 {
0642     d->topBarLyr->addSpacing(KexiUtils::spacingHint());
0643 
0644     QWidget *btnCont = new QWidget(d->topBarHWidget);
0645     QHBoxLayout *btnLyr = new QHBoxLayout;
0646     btnLyr->setSpacing(0);
0647     btnLyr->setContentsMargins(0, 0, 0, 0);
0648     btnCont->setLayout(btnLyr);
0649     d->topBarLyr->addWidget(btnCont);
0650     d->topBarLyr->addSpacing(KexiUtils::spacingHint());
0651 
0652     d->addViewButton(KexiGroupButton::GroupLeft, Kexi::DataViewMode, btnCont,
0653                      SLOT(slotSwitchToDataViewModeInternal(bool)), xi18n("Data"), btnLyr);
0654     d->addViewButton(d->window->supportsViewMode(Kexi::TextViewMode) ? KexiGroupButton::GroupCenter
0655                                                                      : KexiGroupButton::GroupRight,
0656                      Kexi::DesignViewMode, btnCont,
0657                      SLOT(slotSwitchToDesignViewModeInternal(bool)), xi18n("Design"), btnLyr);
0658     KexiGroupButton *btn = d->addViewButton(KexiGroupButton::GroupRight, Kexi::TextViewMode,
0659                                           btnCont, SLOT(slotSwitchToTextViewModeInternal(bool)),
0660                                           QString(), btnLyr);
0661     if (btn) {
0662         QString customTextViewModeCaption(d->window->internalPropertyValue("textViewModeCaption").toString());
0663         if (customTextViewModeCaption.isEmpty()) {
0664             QAction *a = d->toggleViewModeActions.value(Kexi::TextViewMode);
0665             btn->setText(a->text());
0666         }
0667         else {
0668             btn->setText(customTextViewModeCaption);
0669         }
0670     }
0671 
0672     toggleViewModeButtonBack();
0673 }
0674 
0675 void KexiView::slotSwitchToDataViewModeInternal(bool)
0676 {
0677     slotSwitchToViewModeInternal(Kexi::DataViewMode);
0678 }
0679 
0680 void KexiView::slotSwitchToDesignViewModeInternal(bool)
0681 {
0682     slotSwitchToViewModeInternal(Kexi::DesignViewMode);
0683 }
0684 
0685 void KexiView::slotSwitchToTextViewModeInternal(bool)
0686 {
0687     slotSwitchToViewModeInternal(Kexi::TextViewMode);
0688 }
0689 
0690 void KexiView::slotSwitchToViewModeInternal(Kexi::ViewMode mode)
0691 {
0692     if (!d->slotSwitchToViewModeInternalEnabled)
0693         return;
0694     if (d->recentResultOfSwitchToViewModeInternal != true)
0695         d->recentResultOfSwitchToViewModeInternal = true;
0696     else
0697         d->recentResultOfSwitchToViewModeInternal = d->window->switchToViewModeInternal(mode);
0698 
0699     if (d->viewMode != mode) {
0700         //switch back visually
0701         KexiGroupButton *b = d->toggleViewModeButtons.value(mode);
0702         d->slotSwitchToViewModeInternalEnabled = false;
0703         b->setChecked(false);
0704         d->slotSwitchToViewModeInternalEnabled = true;
0705     }
0706 }
0707 
0708 void KexiView::initViewActions()
0709 {
0710     if (!d->topBarLyr)
0711         return;
0712     if (!d->viewActions.isEmpty() && d->saveDesignButton) {
0713         d->topBarLyr->addWidget(new KexiToolBarSeparator(d->topBarHWidget));
0714     }
0715     foreach(QAction* action, d->viewActions) {
0716         if (action->isSeparator()) {
0717             d->topBarLyr->addWidget(new KexiToolBarSeparator(d->topBarHWidget));
0718         } else {
0719             KexiSmallToolButton *btn = new KexiSmallToolButton(action, d->topBarHWidget);
0720             btn->setText(action->text());
0721             btn->setToolTip(action->toolTip());
0722             btn->setWhatsThis(action->whatsThis());
0723             if (action->dynamicPropertyNames().contains("iconOnly") && action->property("iconOnly").toBool() ) {
0724                 btn->setToolButtonStyle(Qt::ToolButtonIconOnly);
0725             }
0726             d->topBarLyr->addWidget(btn);
0727         }
0728     }
0729 }
0730 
0731 void KexiView::initMainMenuActions()
0732 {
0733     if (!d->topBarLyr)
0734         return;
0735     if (d->mainMenuActions.isEmpty()) {
0736         return;
0737     }
0738     d->mainMenu()->clear();
0739     foreach(QAction* action, d->mainMenuActions) {
0740         d->mainMenu()->addAction(action);
0741     }
0742 }
0743 
0744 void KexiView::setSortedProperties(bool set)
0745 {
0746     d->sortedProperties = set;
0747 }
0748 
0749 bool KexiView::saveSettings()
0750 {
0751     return true;
0752 }
0753 
0754 QString KexiView::defaultIconName() const
0755 {
0756     return d->defaultIconName;
0757 }
0758 
0759 void KexiView::setDefaultIconName(const QString& iconName)
0760 {
0761     d->defaultIconName = iconName;
0762 }
0763 
0764 QList<QVariant> KexiView::currentParameters() const
0765 {
0766     return QList<QVariant>();
0767 }
0768 
0769 #include "KexiView.moc"