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"